From d10d43dd3c564b7be0ab304de8ac7f2b9f410c44 Mon Sep 17 00:00:00 2001 From: Sebastian Toepfer <61313468+sebastian-toepfer@users.noreply.github.com> Date: Sun, 10 Sep 2023 16:31:36 +0200 Subject: [PATCH] replace own testengine with parameterized test let the code their -> for the case we unterstand how java modules, pitest and junit-engines work together. currently we load the test in a parameterized test with a copy of the resource loading code from the engine (bad i know). --- core/pom.xml | 31 ++++- .../jsonschema/core/InstanceTypeTest.java | 56 ++++++++ .../jsonschema/core/JsonSchemasTest.java | 39 ++++++ .../impl/keyword/BasicVocabularyTest.java | 8 +- .../core/impl/keyword/TypeTest.java | 25 ++++ .../spi/DefaultJsonSchemaFactoryTest.java | 61 +++++++++ .../core/impl/spi/DefaultJsonSchemaTest.java | 50 +++++++ .../core/impl/spi/EmptyJsonSchemaTest.java | 41 ++++++ .../core/impl/spi/FalseJsonSchemaTest.java | 42 ++++++ .../core/impl/spi/JsonValuesArguments.java | 44 +++++++ .../core/impl/spi/TrueJsonSchemaTest.java | 41 ++++++ ...dapterLoader.java => JsonTestSuiteIT.java} | 29 ++-- .../core/testsuite/JsonTestSuiteTestCase.java | 28 ++++ .../JsonTestSuiteTestCaseProvider.java | 124 ++++++++++++++++++ .../jsonschema/core/testsuite/Resource.java | 68 ++++++++++ .../jsonschema/core/testsuite/Resources.java | 119 +++++++++++++++++ core/src/test/java/module-info.java | 2 +- pom.xml | 3 + 18 files changed, 783 insertions(+), 28 deletions(-) create mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/InstanceTypeTest.java create mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/JsonSchemasTest.java create mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/DefaultJsonSchemaFactoryTest.java create mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/DefaultJsonSchemaTest.java create mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/EmptyJsonSchemaTest.java create mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/FalseJsonSchemaTest.java create mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/JsonValuesArguments.java create mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/TrueJsonSchemaTest.java rename core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/{JsonSchemaSchemaTestValidatorAdapterLoader.java => JsonTestSuiteIT.java} (56%) create mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteTestCase.java create mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteTestCaseProvider.java create mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/Resource.java create mode 100644 core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/Resources.java diff --git a/core/pom.xml b/core/pom.xml index 86e23439..715ee569 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -19,14 +19,13 @@ test - ${project.groupId} - json-schema-testsuite-junit-platform-engine - ${project.version} + org.junit.jupiter + junit-jupiter-engine test org.junit.jupiter - junit-jupiter-engine + junit-jupiter-params test @@ -46,6 +45,12 @@ jakarta.json-api provided + + + org.eclipse.parsson + parsson + test + @@ -104,6 +109,24 @@ + + + org.apache.maven.plugins + maven-surefire-plugin + + + run-jsonschema-testsuite + + test + + + + **/JsonTestSuiteIT.java + + + + + diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/InstanceTypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/InstanceTypeTest.java new file mode 100644 index 00000000..576f459f --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/InstanceTypeTest.java @@ -0,0 +1,56 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import jakarta.json.Json; +import jakarta.json.JsonValue; +import org.junit.jupiter.api.Test; + +class InstanceTypeTest { + + @Test + void should_be_true_if_instancetype_is_correct() { + assertThat(InstanceType.NULL.isInstance(JsonValue.NULL), is(true)); + assertThat(InstanceType.BOOLEAN.isInstance(JsonValue.FALSE), is(true)); + assertThat(InstanceType.BOOLEAN.isInstance(JsonValue.TRUE), is(true)); + assertThat(InstanceType.OBJECT.isInstance(JsonValue.EMPTY_JSON_OBJECT), is(true)); + assertThat(InstanceType.ARRAY.isInstance(JsonValue.EMPTY_JSON_ARRAY), is(true)); + assertThat(InstanceType.NUMBER.isInstance(Json.createValue(23L)), is(true)); + assertThat(InstanceType.INTEGER.isInstance(Json.createValue(23L)), is(true)); + assertThat(InstanceType.INTEGER.isInstance(Json.createValue(0.0)), is(true)); + } + + @Test + void should_be_false_for_non_integers() { + assertThat(InstanceType.INTEGER.isInstance(Json.createValue(23.2)), is(false)); + } + + @Test + void should_be_false_for_nonnumbers() { + assertThat(InstanceType.INTEGER.isInstance(Json.createValue("test")), is(false)); + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/JsonSchemasTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/JsonSchemasTest.java new file mode 100644 index 00000000..aab4ad4c --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/JsonSchemasTest.java @@ -0,0 +1,39 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +import org.junit.jupiter.api.Test; + +class JsonSchemasTest { + + @Test + void should_return_a_schema() { + assertThat(JsonSchemas.load("{}"), is(not(nullValue()))); + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/keyword/BasicVocabularyTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/keyword/BasicVocabularyTest.java index 63eb5e96..8675dc79 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/keyword/BasicVocabularyTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/keyword/BasicVocabularyTest.java @@ -28,6 +28,7 @@ import com.github.npathai.hamcrestopt.OptionalMatchers; import io.github.sebastiantoepfer.jsonschema.core.keyword.KeywordType; +import jakarta.json.JsonValue; import java.net.URI; import org.junit.jupiter.api.Test; @@ -52,8 +53,11 @@ void should_return_the_type_keywordtype() { @Test void should_return_the_custom_annotation_for_unknow_keyword() { assertThat( - new BasicVocabulary().findKeywordTypeByName("unknow").map(KeywordType::name), - OptionalMatchers.isPresentAndIs("unknow") + new BasicVocabulary() + .findKeywordTypeByName("unknow") + .map(keywordType -> keywordType.createKeyword(JsonValue.FALSE)) + .map(keyword -> keyword.hasName("unknow")), + OptionalMatchers.isPresentAndIs(true) ); } } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/keyword/TypeTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/keyword/TypeTest.java index 500b1734..14009169 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/keyword/TypeTest.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/keyword/TypeTest.java @@ -26,7 +26,9 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import io.github.sebastiantoepfer.jsonschema.core.keyword.Assertion; import jakarta.json.Json; +import jakarta.json.JsonValue; import org.junit.jupiter.api.Test; class TypeTest { @@ -40,4 +42,27 @@ void should_know_his_name() { void should_know_other_names() { assertThat(new Type(Json.createValue("string")).hasName("id"), is(false)); } + + @Test + void should_use_stringvalue_to_validate_type() { + final Assertion typeAssertion = new Type(Json.createValue("string")).asAssertion(); + + assertThat(typeAssertion.isValidFor(Json.createValue("value")), is(true)); + assertThat(typeAssertion.isValidFor(JsonValue.EMPTY_JSON_OBJECT), is(false)); + assertThat(typeAssertion.isValidFor(Json.createValue(1L)), is(false)); + assertThat(typeAssertion.isValidFor(JsonValue.EMPTY_JSON_ARRAY), is(false)); + } + + @Test + void should_use_arrayvalue_to_validate_type() { + final Assertion typeAssertion = new Type( + Json.createArrayBuilder().add(Json.createValue("string")).add(Json.createValue("object")).build() + ) + .asAssertion(); + + assertThat(typeAssertion.isValidFor(Json.createValue("value")), is(true)); + assertThat(typeAssertion.isValidFor(JsonValue.EMPTY_JSON_OBJECT), is(true)); + assertThat(typeAssertion.isValidFor(Json.createValue(1L)), is(false)); + assertThat(typeAssertion.isValidFor(JsonValue.EMPTY_JSON_ARRAY), is(false)); + } } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/DefaultJsonSchemaFactoryTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/DefaultJsonSchemaFactoryTest.java new file mode 100644 index 00000000..6f32bd25 --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/DefaultJsonSchemaFactoryTest.java @@ -0,0 +1,61 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.impl.spi; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; + +import jakarta.json.Json; +import jakarta.json.JsonValue; +import org.junit.jupiter.api.Test; + +class DefaultJsonSchemaFactoryTest { + + @Test + void should_return_truejsonschema_for_true() { + assertThat(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), is(instanceOf(TrueJsonSchema.class))); + } + + @Test + void should_return_truejsonschema_for_false() { + assertThat(new DefaultJsonSchemaFactory().create(JsonValue.FALSE), is(instanceOf(FalseJsonSchema.class))); + } + + @Test + void should_return_emptyjsonschema_for_emptyobject() { + assertThat( + new DefaultJsonSchemaFactory().create(JsonValue.EMPTY_JSON_OBJECT), + is(instanceOf(EmptyJsonSchema.class)) + ); + } + + @Test + void should_return_defaultjsonschema_for_everything_else() { + assertThat( + new DefaultJsonSchemaFactory().create(Json.createObjectBuilder().add("type", "string").build()), + is(instanceOf(DefaultJsonSchema.class)) + ); + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/DefaultJsonSchemaTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/DefaultJsonSchemaTest.java new file mode 100644 index 00000000..3c24f818 --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/DefaultJsonSchemaTest.java @@ -0,0 +1,50 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.impl.spi; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; + +import jakarta.json.Json; +import jakarta.json.JsonValue; +import org.junit.jupiter.api.Test; + +class DefaultJsonSchemaTest { + + private final DefaultJsonSchema schema = new DefaultJsonSchema( + Json.createObjectBuilder().add("type", "string").build() + ); + + @Test + void should_be_valid_for_string() { + assertThat(schema.validator().validate(Json.createValue("test")), is(empty())); + } + + @Test + void should_be_invalid_for_object() { + assertThat(schema.validator().validate(JsonValue.EMPTY_JSON_OBJECT), is(not(empty()))); + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/EmptyJsonSchemaTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/EmptyJsonSchemaTest.java new file mode 100644 index 00000000..4696b9cf --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/EmptyJsonSchemaTest.java @@ -0,0 +1,41 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.impl.spi; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; + +import jakarta.json.JsonValue; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; + +class EmptyJsonSchemaTest { + + @ParameterizedTest + @ArgumentsSource(JsonValuesArguments.class) + void should_be_valid_for_everything(final JsonValue value) { + assertThat(new EmptyJsonSchema().validator().validate(value), is(empty())); + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/FalseJsonSchemaTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/FalseJsonSchemaTest.java new file mode 100644 index 00000000..f44f9256 --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/FalseJsonSchemaTest.java @@ -0,0 +1,42 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.impl.spi; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; + +import jakarta.json.JsonValue; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; + +class FalseJsonSchemaTest { + + @ParameterizedTest + @ArgumentsSource(JsonValuesArguments.class) + void should_be_invalid_for_everything(final JsonValue value) { + assertThat(new FalseJsonSchema().validator().validate(value), is(not(empty()))); + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/JsonValuesArguments.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/JsonValuesArguments.java new file mode 100644 index 00000000..49a51704 --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/JsonValuesArguments.java @@ -0,0 +1,44 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.impl.spi; + +import jakarta.json.JsonValue; +import java.util.stream.Stream; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.ArgumentsProvider; + +public class JsonValuesArguments implements ArgumentsProvider { + + @Override + public Stream provideArguments(final ExtensionContext context) throws Exception { + return Stream.of( + Arguments.of(JsonValue.EMPTY_JSON_ARRAY), + Arguments.of(JsonValue.EMPTY_JSON_OBJECT), + Arguments.of(JsonValue.FALSE), + Arguments.of(JsonValue.TRUE), + Arguments.of(JsonValue.NULL) + ); + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/TrueJsonSchemaTest.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/TrueJsonSchemaTest.java new file mode 100644 index 00000000..939e0ca7 --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/impl/spi/TrueJsonSchemaTest.java @@ -0,0 +1,41 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.impl.spi; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; + +import jakarta.json.JsonValue; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; + +class TrueJsonSchemaTest { + + @ParameterizedTest + @ArgumentsSource(JsonValuesArguments.class) + void should_be_valid_for_everything(final JsonValue value) { + assertThat(new TrueJsonSchema().validator().validate(value), is(empty())); + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonSchemaSchemaTestValidatorAdapterLoader.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteIT.java similarity index 56% rename from core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonSchemaSchemaTestValidatorAdapterLoader.java rename to core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteIT.java index 866ec232..a7f77238 100644 --- a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonSchemaSchemaTestValidatorAdapterLoader.java +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteIT.java @@ -23,29 +23,16 @@ */ package io.github.sebastiantoepfer.jsonschema.core.testsuite; -import io.github.sebastiantoepfer.jsonschema.core.JsonSchemas; -import io.github.sebastiantoepfer.jsonschema.core.Validator; -import io.github.sebastiantoepfer.jsonschema.testsuite.junit.SchemaTestValidatorLoader; -import java.util.Objects; +import static org.junit.jupiter.api.Assertions.assertTrue; -public final class JsonSchemaSchemaTestValidatorAdapterLoader implements SchemaTestValidatorLoader { +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; - @Override - public SchemaTestValidator loadSchemaTestValidator(final String schema) { - return new SchemaTestValidatorAdapter(JsonSchemas.load(schema).validator()); - } - - private static class SchemaTestValidatorAdapter implements SchemaTestValidator { - - private final Validator validator; - - public SchemaTestValidatorAdapter(final Validator validator) { - this.validator = Objects.requireNonNull(validator); - } +class JsonTestSuiteIT { - @Override - public boolean validate(final String data) { - return validator.validate(data).isEmpty(); - } + @ParameterizedTest(name = "{0}") + @ArgumentsSource(JsonTestSuiteTestCaseProvider.class) + void runJsonTestSuite(final JsonTestSuiteTestCase testcase) { + assertTrue(testcase.isValid()); } } diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteTestCase.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteTestCase.java new file mode 100644 index 00000000..42358e35 --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteTestCase.java @@ -0,0 +1,28 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.testsuite; + +interface JsonTestSuiteTestCase { + boolean isValid(); +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteTestCaseProvider.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteTestCaseProvider.java new file mode 100644 index 00000000..914616fb --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/JsonTestSuiteTestCaseProvider.java @@ -0,0 +1,124 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.testsuite; + +import io.github.sebastiantoepfer.jsonschema.core.JsonSchemas; +import jakarta.json.Json; +import jakarta.json.JsonObject; +import jakarta.json.JsonValue; +import jakarta.json.stream.JsonParser; +import java.util.Objects; +import java.util.stream.Stream; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.ArgumentsProvider; + +class JsonTestSuiteTestCaseProvider implements ArgumentsProvider { + + @Override + public Stream provideArguments(final ExtensionContext context) throws Exception { + return new Resources() + .all() + .filter(resource -> resource.hasExtension("json")) + .map(JsonSchemaTestSuites::new) + .flatMap(JsonSchemaTestSuites::allTestCases) + .map(Arguments::of); + } + + private static class JsonSchemaTestSuites { + + private final Resource jsonResource; + + public JsonSchemaTestSuites(final Resource jsonResource) { + this.jsonResource = Objects.requireNonNull(jsonResource); + } + + Stream allTestCases() { + final Stream result; + final JsonParser parser = Json.createParser(jsonResource.content()); + if (parser.next() == JsonParser.Event.START_ARRAY) { + result = + parser + .getArrayStream() + .onClose(() -> parser.close()) + .map(JsonValue::asJsonObject) + .map(JsonSchemaTestSuite::new) + .flatMap(JsonSchemaTestSuite::allTestCases); + } else { + parser.close(); + result = Stream.empty(); + } + return result; + } + + private class JsonSchemaTestSuite { + + private final JsonObject testsuite; + + public JsonSchemaTestSuite(final JsonObject testsuite) { + this.testsuite = Objects.requireNonNull(testsuite); + } + + Stream allTestCases() { + return testsuite + .getJsonArray("tests") + .stream() + .map(test -> new JsonSchemaTest(testsuite.get("schema"), test.asJsonObject())); + } + + private class JsonSchemaTest implements JsonTestSuiteTestCase { + + private final JsonValue schema; + private final JsonObject test; + + public JsonSchemaTest(final JsonValue schema, final JsonObject test) { + this.schema = schema; + this.test = test; + } + + @Override + public boolean isValid() { + return ( + JsonSchemas.load(schema).validator().validate(test.get("data")).isEmpty() == + test.getBoolean("valid") + ); + } + + @Override + public String toString() { + return ( + "JsonSchemaTest{" + + "schema=" + + schema + + ", test=" + + test + + " in " + + JsonSchemaTestSuites.this.jsonResource.name() + + '}' + ); + } + } + } + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/Resource.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/Resource.java new file mode 100644 index 00000000..cfa43487 --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/Resource.java @@ -0,0 +1,68 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.testsuite; + +import java.io.InputStream; +import java.util.Objects; + +final record Resource(String name) { + boolean hasName(final String name) { + return Objects.equals(this.name, name); + } + + boolean hasExtension(final String extension) { + return name.endsWith(".".concat(extension)); + } + + InputStream content() { + return Resource.class.getClassLoader().getResourceAsStream(name); + } + + @Override + public String toString() { + return "Resource{" + "name=" + name + '}'; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Resource other = (Resource) obj; + return (this.name == null) ? (other.name == null) : this.name.equals(other.name); + } +} diff --git a/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/Resources.java b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/Resources.java new file mode 100644 index 00000000..26f785d8 --- /dev/null +++ b/core/src/test/java/io/github/sebastiantoepfer/jsonschema/core/testsuite/Resources.java @@ -0,0 +1,119 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.core.testsuite; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Objects; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.regex.Pattern; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +final class Resources { + + private final String baseDir; + + public Resources() { + this("."); + } + + public Resources(final String baseDir) { + this.baseDir = baseDir; + } + + Stream all() { + try { + return StreamSupport + .stream( + Spliterators.spliteratorUnknownSize( + Resource.class.getClassLoader().getResources(baseDir).asIterator(), + Spliterator.ORDERED + ), + false + ) + .map(url -> { + try { + return url.toURI(); + } catch (URISyntaxException e) { + throw new IllegalStateException(e); + } + }) + .filter(uri -> "file".equals(uri.getScheme())) + .map(Paths::get) + .map(PathResources::new) + .flatMap(PathResources::toResources); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + private static class PathResources { + + private static final Pattern PATH_SEPARATOR = Pattern.compile(File.pathSeparator); + private final Path path; + + public PathResources(final Path path) { + this.path = Objects.requireNonNull(path); + } + + Stream toResources() { + final Stream result; + try { + if (path.toFile().isFile()) { + result = + Stream.of( + new Resource( + path + .toFile() + .getAbsolutePath() + .substring( + PATH_SEPARATOR + .splitAsStream(System.getProperty("java.class.path")) + .map(Path::of) + .filter(path::startsWith) + .map(Path::toFile) + .map(File::getAbsolutePath) + .map(String::length) + .map(i -> i + 1) + .findAny() + .orElse(0) + ) + ) + ); + } else { + result = Files.list(path).map(PathResources::new).flatMap(PathResources::toResources); + } + } catch (IOException e) { + throw new IllegalStateException(e); + } + return result; + } + } +} diff --git a/core/src/test/java/module-info.java b/core/src/test/java/module-info.java index 1d06fa1a..d1eae398 100644 --- a/core/src/test/java/module-info.java +++ b/core/src/test/java/module-info.java @@ -24,8 +24,8 @@ open module io.github.sebastiantoepfer.jsonschema.core { requires jakarta.json; - requires io.github.sebastiantoepfer.jsonschema.testsuite.junit; requires org.junit.jupiter.api; + requires org.junit.jupiter.params; requires org.junit.jupiter.engine; requires org.hamcrest; } diff --git a/pom.xml b/pom.xml index a73a1e9c..f8d0afb6 100644 --- a/pom.xml +++ b/pom.xml @@ -244,6 +244,9 @@ toString hashCode + + **IT +