Skip to content

Commit aa5308f

Browse files
committed
Initial commit
0 parents  commit aa5308f

File tree

8 files changed

+324
-0
lines changed

8 files changed

+324
-0
lines changed

pom.xml

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>net.joshka</groupId>
8+
<artifactId>junit-javax.json</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13+
<java.version>1.8</java.version>
14+
<junit.platform.version>1.0.3</junit.platform.version>
15+
<junit.jupiter.version>5.0.3</junit.jupiter.version>
16+
<javax.json.version>1.1.2</javax.json.version>
17+
</properties>
18+
19+
<build>
20+
<plugins>
21+
<plugin>
22+
<groupId>org.apache.maven.plugins</groupId>
23+
<artifactId>maven-compiler-plugin</artifactId>
24+
<configuration>
25+
<source>${java.version}</source>
26+
<target>${java.version}</target>
27+
</configuration>
28+
<version>3.7.0</version>
29+
</plugin>
30+
<plugin>
31+
<artifactId>maven-surefire-plugin</artifactId>
32+
<version>2.19.1</version>
33+
<configuration>
34+
<includes>
35+
<include>**/Test*.java</include>
36+
<include>**/*Test.java</include>
37+
<include>**/*Tests.java</include>
38+
<include>**/*TestCase.java</include>
39+
</includes>
40+
</configuration>
41+
<dependencies>
42+
<dependency>
43+
<groupId>org.junit.platform</groupId>
44+
<artifactId>junit-platform-surefire-provider</artifactId>
45+
<version>${junit.platform.version}</version>
46+
</dependency>
47+
<dependency>
48+
<groupId>org.junit.jupiter</groupId>
49+
<artifactId>junit-jupiter-engine</artifactId>
50+
<version>${junit.jupiter.version}</version>
51+
</dependency>
52+
</dependencies>
53+
</plugin>
54+
<plugin>
55+
<groupId>org.jacoco</groupId>
56+
<artifactId>jacoco-maven-plugin</artifactId>
57+
<version>0.8.0</version>
58+
<executions>
59+
<execution>
60+
<id>default-prepare-agent</id>
61+
<goals>
62+
<goal>prepare-agent</goal>
63+
</goals>
64+
</execution>
65+
<execution>
66+
<id>default-report</id>
67+
<goals>
68+
<goal>report</goal>
69+
</goals>
70+
</execution>
71+
<execution>
72+
<id>default-check</id>
73+
<goals>
74+
<goal>check</goal>
75+
</goals>
76+
</execution>
77+
</executions>
78+
<configuration>
79+
<rules>
80+
<rule>
81+
<element>BUNDLE</element>
82+
<limits>
83+
<limit>
84+
<counter>COMPLEXITY</counter>
85+
<value>COVEREDRATIO</value>
86+
<minimum>0.80</minimum>
87+
</limit>
88+
</limits>
89+
</rule>
90+
</rules>
91+
</configuration>
92+
</plugin>
93+
</plugins>
94+
</build>
95+
96+
<dependencies>
97+
<dependency>
98+
<groupId>org.junit.jupiter</groupId>
99+
<artifactId>junit-jupiter-api</artifactId>
100+
<version>${junit.jupiter.version}</version>
101+
</dependency>
102+
<dependency>
103+
<groupId>org.junit.jupiter</groupId>
104+
<artifactId>junit-jupiter-params</artifactId>
105+
<version>${junit.jupiter.version}</version>
106+
</dependency>
107+
<dependency>
108+
<groupId>javax.json</groupId>
109+
<artifactId>javax.json-api</artifactId>
110+
<version>${javax.json.version}</version>
111+
</dependency>
112+
<dependency>
113+
<groupId>org.glassfish</groupId>
114+
<artifactId>javax.json</artifactId>
115+
<version>${javax.json.version}</version>
116+
<scope>test</scope>
117+
</dependency>
118+
<dependency>
119+
<groupId>org.junit.jupiter</groupId>
120+
<artifactId>junit-jupiter-engine</artifactId>
121+
<version>${junit.jupiter.version}</version>
122+
<scope>test</scope>
123+
</dependency>
124+
<!-- To avoid compiler warnings about @API annotations in JUnit code -->
125+
<dependency>
126+
<groupId>org.apiguardian</groupId>
127+
<artifactId>apiguardian-api</artifactId>
128+
<version>1.0.0</version>
129+
<scope>test</scope>
130+
</dependency>
131+
<dependency>
132+
<groupId>org.assertj</groupId>
133+
<artifactId>assertj-core</artifactId>
134+
<version>3.9.0</version>
135+
<scope>test</scope>
136+
</dependency>
137+
<dependency>
138+
<groupId>org.mockito</groupId>
139+
<artifactId>mockito-core</artifactId>
140+
<version>2.13.0</version>
141+
<scope>test</scope>
142+
</dependency>
143+
<dependency>
144+
<groupId>org.jacoco</groupId>
145+
<artifactId>jacoco-maven-plugin</artifactId>
146+
<version>0.8.0</version>
147+
</dependency>
148+
</dependencies>
149+
</project>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package net.joshka.junit.javax.json;
2+
3+
import org.junit.jupiter.api.extension.ExtensionContext;
4+
import org.junit.jupiter.params.provider.Arguments;
5+
import org.junit.jupiter.params.provider.ArgumentsProvider;
6+
import org.junit.jupiter.params.support.AnnotationConsumer;
7+
import org.junit.platform.commons.util.Preconditions;
8+
9+
import javax.json.Json;
10+
import javax.json.JsonReader;
11+
import javax.json.JsonStructure;
12+
import javax.json.JsonValue;
13+
import java.io.InputStream;
14+
import java.util.Arrays;
15+
import java.util.function.BiFunction;
16+
import java.util.stream.Stream;
17+
18+
public class JsonFileArgumentsProvider implements AnnotationConsumer<JsonFileSource>, ArgumentsProvider {
19+
20+
private final BiFunction<Class<?>, String, InputStream> inputStreamProvider;
21+
22+
private String[] resources;
23+
24+
public JsonFileArgumentsProvider() {
25+
this(Class::getResourceAsStream);
26+
}
27+
28+
public JsonFileArgumentsProvider(BiFunction<Class<?>, String, InputStream> inputStreamProvider) {
29+
this.inputStreamProvider = inputStreamProvider;
30+
}
31+
32+
private static Stream<JsonValue> values(InputStream inputStream) {
33+
try (JsonReader reader = Json.createReader(inputStream)) {
34+
JsonStructure structure = reader.read();
35+
return structure.getValueType() == JsonValue.ValueType.ARRAY
36+
? structure.asJsonArray().stream()
37+
: Stream.of(structure);
38+
}
39+
}
40+
41+
@Override
42+
public void accept(JsonFileSource jsonFileSource) {
43+
resources = jsonFileSource.resources();
44+
}
45+
46+
@Override
47+
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
48+
return Arrays.stream(resources)
49+
.map(resource -> openInputStream(context, resource))
50+
.flatMap(JsonFileArgumentsProvider::values)
51+
.map(Arguments::of);
52+
}
53+
54+
private InputStream openInputStream(ExtensionContext context, String resource) {
55+
Class<?> testClass = context.getRequiredTestClass();
56+
InputStream inputStream = inputStreamProvider.apply(testClass, resource);
57+
return Preconditions.notNull(inputStream,
58+
() -> "Classpath resource does not exist: " + resource);
59+
}
60+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package net.joshka.junit.javax.json;
2+
3+
import org.junit.jupiter.params.provider.ArgumentsSource;
4+
5+
import java.lang.annotation.*;
6+
7+
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
8+
@Retention(RetentionPolicy.RUNTIME)
9+
@Documented
10+
@ArgumentsSource(JsonFileArgumentsProvider.class)
11+
public @interface JsonFileSource {
12+
13+
String[] resources();
14+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package net.joshka.junit.javax.json;
2+
3+
import org.junit.jupiter.api.DisplayName;
4+
import org.junit.jupiter.api.Test;
5+
import org.junit.jupiter.api.extension.ExtensionContext;
6+
import org.junit.jupiter.params.ParameterizedTest;
7+
import org.junit.platform.commons.util.PreconditionViolationException;
8+
9+
import javax.json.JsonNumber;
10+
import javax.json.JsonObject;
11+
import javax.json.JsonString;
12+
import java.io.InputStream;
13+
import java.util.function.BiFunction;
14+
15+
import static org.assertj.core.api.Assertions.*;
16+
import static org.mockito.Mockito.mock;
17+
import static org.mockito.Mockito.when;
18+
19+
class JsonFileArgumentsProviderTest {
20+
21+
@Test
22+
@DisplayName("default constructor does not throw")
23+
void defaultConstructor() {
24+
assertThatCode(JsonFileArgumentsProvider::new)
25+
.doesNotThrowAnyException();
26+
}
27+
28+
/**
29+
* When passed <code>{"key":"value"}</code>, is executed a single time
30+
* @param object the parsed JsonObject
31+
*/
32+
@ParameterizedTest
33+
@JsonFileSource(resources = "/single-object.json")
34+
@DisplayName("provides a single object")
35+
void singleObject(JsonObject object) {
36+
assertThat(object.getString("key")).isEqualTo("value");
37+
}
38+
39+
/**
40+
* When passed <code>[{"key":"value1"},{"key","value2"]}</code>, is
41+
* executed once per element of the array
42+
* @param object the parsed JsonObject array element
43+
*/
44+
@ParameterizedTest
45+
@JsonFileSource(resources = "/array-of-objects.json")
46+
@DisplayName("provides an array of objects")
47+
void arrayOfObjects(JsonObject object) {
48+
assertThat(object.getString("key")).startsWith("value");
49+
}
50+
51+
/**
52+
* When passed <code>[1, 2]}</code>, is executed once per array element
53+
* @param number the parsed JsonNumber for each array element
54+
*/
55+
@ParameterizedTest
56+
@JsonFileSource(resources = "/array-of-numbers.json")
57+
@DisplayName("provides an array of numbers")
58+
void arrayOfNumbers(JsonNumber number) {
59+
assertThat(number.intValue()).isGreaterThan(0);
60+
}
61+
62+
/**
63+
* When passed <code>["value1","value2"}</code>, is executed once per array
64+
* element
65+
* @param string the parsed JsonString for each array element
66+
*/
67+
@ParameterizedTest
68+
@JsonFileSource(resources = "/array-of-strings.json")
69+
@DisplayName("provides an array of strings")
70+
void arrayOfStrings(JsonString string) {
71+
assertThat(string.getString()).startsWith("value");
72+
}
73+
74+
@Test
75+
@DisplayName("missing resource throws exception")
76+
void missingResource() {
77+
BiFunction<Class<?>, String, InputStream> inputStreamProvider = (aClass, resource) -> null;
78+
ExtensionContext context = mock(ExtensionContext.class);
79+
JsonFileSource source = mock(JsonFileSource.class);
80+
when(source.resources()).thenReturn(new String[]{"not-found.json"});
81+
JsonFileArgumentsProvider provider = new JsonFileArgumentsProvider(inputStreamProvider);
82+
provider.accept(source);
83+
84+
assertThatExceptionOfType(PreconditionViolationException.class)
85+
.isThrownBy(() -> provider.provideArguments(context).forEach(o -> {}))
86+
.withMessage("Classpath resource does not exist: not-found.json");
87+
}
88+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[1, 2]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[
2+
{
3+
"key":"value1"
4+
},
5+
{
6+
"key":"value2"
7+
}
8+
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
["value1", "value2"]

src/test/resources/single-object.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"key":"value"
3+
}

0 commit comments

Comments
 (0)