Skip to content

Commit 2fb1500

Browse files
committed
tests(schema): OpenRPCTestSupport; parameterized tests (types, patterns); RemoteSchemaServerRefTest; refactor OpenRPC IT to support class; keep builds green
1 parent 1955c95 commit 2fb1500

File tree

8 files changed

+198
-24
lines changed

8 files changed

+198
-24
lines changed

json-java21-schema/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@
4646
<artifactId>junit-jupiter-engine</artifactId>
4747
<scope>test</scope>
4848
</dependency>
49+
<dependency>
50+
<groupId>org.junit.jupiter</groupId>
51+
<artifactId>junit-jupiter-params</artifactId>
52+
<scope>test</scope>
53+
</dependency>
4954
<dependency>
5055
<groupId>org.assertj</groupId>
5156
<artifactId>assertj-core</artifactId>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.github.simbo1905.json.schema;
2+
3+
import org.junit.jupiter.params.provider.Arguments;
4+
5+
import java.util.stream.Stream;
6+
7+
final class JsonSamples {
8+
private JsonSamples() {}
9+
10+
static Stream<Arguments> simpleTypes() {
11+
return Stream.of(
12+
Arguments.of("string", "\"hello\"", true),
13+
Arguments.of("string", "42", false),
14+
Arguments.of("number", "42", true),
15+
Arguments.of("number", "3.14", true),
16+
Arguments.of("number", "\"x\"", false),
17+
Arguments.of("boolean", "true", true),
18+
Arguments.of("boolean", "false", true),
19+
Arguments.of("boolean", "1", false),
20+
Arguments.of("null", "null", true),
21+
Arguments.of("null", "\"null\"", false)
22+
);
23+
}
24+
25+
static Stream<Arguments> patterns() {
26+
return Stream.of(
27+
Arguments.of("^abc$", "\"abc\"", true),
28+
Arguments.of("^abc$", "\"ab\"", false),
29+
Arguments.of("^[0-9]+$", "\"123\"", true),
30+
Arguments.of("^[0-9]+$", "\"12a\"", false)
31+
);
32+
}
33+
}
34+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.github.simbo1905.json.schema;
2+
3+
import jdk.sandbox.java.util.json.Json;
4+
import org.junit.jupiter.params.ParameterizedTest;
5+
import org.junit.jupiter.params.provider.Arguments;
6+
import org.junit.jupiter.params.provider.MethodSource;
7+
8+
import java.util.stream.Stream;
9+
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
12+
class JsonSchemaPatternParamTest extends JsonSchemaTestBase {
13+
14+
static Stream<Arguments> providePatterns() { return JsonSamples.patterns(); }
15+
16+
@ParameterizedTest(name = "pattern={0} value={1} -> {2}")
17+
@MethodSource("providePatterns")
18+
void validatesPatterns(String pattern, String json, boolean expected) {
19+
String schema = "{\"type\":\"string\",\"pattern\":\"" + pattern.replace("\\", "\\\\") + "\"}";
20+
var compiled = JsonSchema.compile(Json.parse(schema));
21+
var result = compiled.validate(Json.parse(json));
22+
assertThat(result.valid()).isEqualTo(expected);
23+
}
24+
}
25+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package io.github.simbo1905.json.schema;
2+
3+
import jdk.sandbox.java.util.json.Json;
4+
import org.junit.jupiter.api.Test;
5+
import org.junit.jupiter.api.extension.RegisterExtension;
6+
7+
import java.util.Set;
8+
9+
import static org.assertj.core.api.Assertions.assertThat;
10+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
11+
12+
class JsonSchemaRemoteServerRefTest extends JsonSchemaTestBase {
13+
14+
@RegisterExtension
15+
static final RemoteSchemaServerRule SERVER = new RemoteSchemaServerRule();
16+
17+
@Test
18+
void resolves_pointer_inside_remote_doc_via_http() {
19+
var policy = JsonSchema.FetchPolicy.defaults().withAllowedSchemes(Set.of("http","https"));
20+
var options = JsonSchema.CompileOptions.remoteDefaults(new VirtualThreadHttpFetcher()).withFetchPolicy(policy);
21+
var schema = Json.parse("{\"$ref\":\"" + SERVER.url("/a.json") + "#/$defs/X\"}");
22+
var compiled = JsonSchema.compile(schema, JsonSchema.Options.DEFAULT, options);
23+
assertThat(compiled.validate(Json.parse("1")).valid()).isTrue();
24+
assertThat(compiled.validate(Json.parse("0")).valid()).isFalse();
25+
}
26+
27+
@Test
28+
void remote_cycle_logs_error_taxonomy() {
29+
var policy = JsonSchema.FetchPolicy.defaults().withAllowedSchemes(Set.of("http","https"));
30+
var options = JsonSchema.CompileOptions.remoteDefaults(new VirtualThreadHttpFetcher()).withFetchPolicy(policy);
31+
try (CapturedLogs logs = captureLogs(java.util.logging.Level.SEVERE)) {
32+
try { JsonSchema.compile(Json.parse("{\"$ref\":\"" + SERVER.url("/cycle1.json") + "#\"}"), JsonSchema.Options.DEFAULT, options); } catch (RuntimeException ignored) {}
33+
assertThat(logs.lines().stream().anyMatch(s -> s.startsWith("ERROR: CYCLE:"))).isTrue();
34+
}
35+
}
36+
}
37+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.github.simbo1905.json.schema;
2+
3+
import jdk.sandbox.java.util.json.Json;
4+
import org.junit.jupiter.params.ParameterizedTest;
5+
import org.junit.jupiter.params.provider.Arguments;
6+
import org.junit.jupiter.params.provider.MethodSource;
7+
8+
import java.util.stream.Stream;
9+
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
12+
class JsonSchemaTypeAndEnumParamTest extends JsonSchemaTestBase {
13+
14+
static Stream<Arguments> provideSimpleTypes() { return JsonSamples.simpleTypes(); }
15+
16+
@ParameterizedTest(name = "type={0} value={1} -> {2}")
17+
@MethodSource("provideSimpleTypes")
18+
void validatesSimpleTypes(String type, String json, boolean expected) {
19+
String schema = "{\"type\":\"" + type + "\"}";
20+
var compiled = JsonSchema.compile(Json.parse(schema));
21+
var result = compiled.validate(Json.parse(json));
22+
assertThat(result.valid()).isEqualTo(expected);
23+
}
24+
}
25+

json-java21-schema/src/test/java/io/github/simbo1905/json/schema/OpenRPCSchemaValidationIT.java

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,31 +38,16 @@ private static String readResource(String name) throws IOException {
3838
Stream<DynamicTest> validateOpenRPCExamples() throws Exception {
3939
LOG.info(() -> "TEST: " + getClass().getSimpleName() + "#validateOpenRPCExamples");
4040
// Compile the minimal OpenRPC schema (self-contained, no remote $ref)
41-
String schemaJson = readResource("openrpc/schema.json");
42-
JsonSchema schema = JsonSchema.compile(Json.parse(schemaJson));
41+
JsonSchema schema = OpenRPCTestSupport.loadOpenRpcSchema();
4342

4443
// Discover example files
45-
URL dirUrl = Objects.requireNonNull(getClass().getClassLoader().getResource("openrpc/examples"),
46-
"missing openrpc examples directory");
47-
Path dir = Path.of(dirUrl.toURI());
48-
49-
try (Stream<Path> files = Files.list(dir)) {
50-
List<Path> jsons = files
51-
.filter(p -> p.getFileName().toString().endsWith(".json"))
52-
.sorted()
53-
.toList();
54-
55-
assertThat(jsons).isNotEmpty();
56-
57-
return jsons.stream().map(path -> DynamicTest.dynamicTest(path.getFileName().toString(), () -> {
58-
LOG.info(() -> "TEST: " + getClass().getSimpleName() + "#" + path.getFileName());
59-
String doc = Files.readString(path, StandardCharsets.UTF_8);
60-
boolean expectedValid = !path.getFileName().toString().contains("-bad-");
61-
boolean actualValid = schema.validate(Json.parse(doc)).valid();
62-
Assertions.assertThat(actualValid)
63-
.as("validation of %s", path.getFileName())
64-
.isEqualTo(expectedValid);
65-
}));
66-
}
44+
List<String> names = OpenRPCTestSupport.exampleNames();
45+
assertThat(names).isNotEmpty();
46+
return names.stream().map(name -> DynamicTest.dynamicTest(name, () -> {
47+
LOG.info(() -> "TEST: " + getClass().getSimpleName() + "#" + name);
48+
boolean expectedValid = !name.contains("-bad-");
49+
boolean actualValid = OpenRPCTestSupport.validateExample(name).valid();
50+
Assertions.assertThat(actualValid).as("validation of %s", name).isEqualTo(expectedValid);
51+
}));
6752
}
6853
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package io.github.simbo1905.json.schema;
2+
3+
import jdk.sandbox.java.util.json.Json;
4+
import jdk.sandbox.java.util.json.JsonValue;
5+
6+
import java.io.IOException;
7+
import java.net.URISyntaxException;
8+
import java.net.URL;
9+
import java.nio.charset.StandardCharsets;
10+
import java.nio.file.Files;
11+
import java.nio.file.Path;
12+
import java.util.Comparator;
13+
import java.util.List;
14+
import java.util.Objects;
15+
import java.util.stream.Stream;
16+
17+
final class OpenRPCTestSupport {
18+
private OpenRPCTestSupport() {}
19+
20+
static JsonSchema loadOpenRpcSchema() {
21+
return JsonSchema.compile(readJson("openrpc/schema.json"));
22+
}
23+
24+
static JsonValue readJson(String resourcePath) {
25+
return Json.parse(readText(resourcePath));
26+
}
27+
28+
static String readText(String resourcePath) {
29+
try {
30+
URL url = Objects.requireNonNull(OpenRPCTestSupport.class.getClassLoader().getResource(resourcePath), resourcePath);
31+
return Files.readString(Path.of(url.toURI()), StandardCharsets.UTF_8);
32+
} catch (URISyntaxException | IOException e) {
33+
throw new RuntimeException("Failed to read resource: " + resourcePath, e);
34+
}
35+
}
36+
37+
static List<String> exampleNames() {
38+
try {
39+
URL dirUrl = Objects.requireNonNull(OpenRPCTestSupport.class.getClassLoader().getResource("openrpc/examples"), "missing openrpc/examples directory");
40+
try (Stream<Path> s = Files.list(Path.of(dirUrl.toURI()))) {
41+
return s.filter(p -> p.getFileName().toString().endsWith(".json"))
42+
.map(p -> p.getFileName().toString())
43+
.sorted(Comparator.naturalOrder())
44+
.toList();
45+
}
46+
} catch (Exception e) {
47+
throw new RuntimeException("Failed to list openrpc examples", e);
48+
}
49+
}
50+
51+
static JsonSchema.ValidationResult validateExample(String name) {
52+
JsonSchema schema = loadOpenRpcSchema();
53+
JsonValue doc = readJson("openrpc/examples/" + name);
54+
return schema.validate(doc);
55+
}
56+
}
57+

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@
7575
<version>${junit.jupiter.version}</version>
7676
<scope>test</scope>
7777
</dependency>
78+
<dependency>
79+
<groupId>org.junit.jupiter</groupId>
80+
<artifactId>junit-jupiter-params</artifactId>
81+
<version>${junit.jupiter.version}</version>
82+
<scope>test</scope>
83+
</dependency>
7884
<dependency>
7985
<groupId>org.assertj</groupId>
8086
<artifactId>assertj-core</artifactId>

0 commit comments

Comments
 (0)