Skip to content

Commit

Permalink
Merge pull request #132 from sebastian-toepfer/simplify_tests
Browse files Browse the repository at this point in the history
Simplify tests
  • Loading branch information
sebastian-toepfer authored Jun 10, 2024
2 parents a2b486f + f696547 commit 9114ca6
Show file tree
Hide file tree
Showing 65 changed files with 1,265 additions and 1,549 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ public Keywords(final Collection<VocabularyDefinition> vocabDefs) {
if (
vocabDefs
.stream()
.filter(vocabDef -> MANDANTORY_VOCABS.containsKey(vocabDef.id()))
.anyMatch(not(VocabularyDefinition::required))
.filter(vocabDef -> MANDANTORY_VOCABS.keySet().stream().anyMatch(vocabDef::hasid))
.anyMatch(not(VocabularyDefinition::isRequired))
) {
throw new IllegalArgumentException("can not be created without core vocabulary is requiered!");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ public String name() {

@Override
public Keyword createKeyword(final JsonSchema schema) {
return schema.asSubSchema(name).map(keywordCreator).orElseThrow(IllegalArgumentException::new);
return schema.asSubSchema(name()).map(keywordCreator).orElseThrow(IllegalArgumentException::new);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
*/
package io.github.sebastiantoepfer.jsonschema.core.vocab.applicator;

import static java.util.function.Predicate.not;

import io.github.sebastiantoepfer.ddd.common.Media;
import io.github.sebastiantoepfer.jsonschema.InstanceType;
import io.github.sebastiantoepfer.jsonschema.JsonSubSchema;
import io.github.sebastiantoepfer.jsonschema.JsonSchema;
import io.github.sebastiantoepfer.jsonschema.keyword.Annotation;
import io.github.sebastiantoepfer.jsonschema.keyword.Applicator;
import io.github.sebastiantoepfer.jsonschema.keyword.Keyword;
Expand All @@ -38,8 +40,6 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;

/**
Expand All @@ -61,10 +61,15 @@
final class AdditionalPropertiesKeyword implements Applicator, Annotation {

static final String NAME = "additionalProperties";
private final JsonSubSchema additionalPropertiesSchema;
private final Collection<Annotation> affectedBy;
private final JsonSchema additionalPropertiesSchema;

public AdditionalPropertiesKeyword(final JsonSubSchema additionalPropertiesSchema) {
public AdditionalPropertiesKeyword(
final Collection<Annotation> affectedBy,
final JsonSchema additionalPropertiesSchema
) {
this.additionalPropertiesSchema = additionalPropertiesSchema;
this.affectedBy = List.copyOf(affectedBy);
}

@Override
Expand Down Expand Up @@ -93,16 +98,12 @@ public JsonValue valueFor(final JsonValue instance) {

private Stream<Map.Entry<String, JsonValue>> findPropertiesForValidation(final JsonObject instance) {
final Collection<String> ignoredProperties = findPropertyNamesAlreadyConveredByOthersIn(instance);
return instance.entrySet().stream().filter(Predicate.not(e -> ignoredProperties.contains(e.getKey())));
return instance.entrySet().stream().filter(not(e -> ignoredProperties.contains(e.getKey())));
}

private Collection<String> findPropertyNamesAlreadyConveredByOthersIn(final JsonValue instance) {
return Stream.of(
additionalPropertiesSchema.owner().keywordByName("properties"),
additionalPropertiesSchema.owner().keywordByName("patternProperties")
)
.flatMap(Optional::stream)
.map(Keyword::asAnnotation)
return affectedBy
.stream()
.map(anno -> anno.valueFor(instance))
.map(JsonValue::asJsonArray)
.flatMap(Collection::stream)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@
import io.github.sebastiantoepfer.jsonschema.core.keyword.type.AffectByType;
import io.github.sebastiantoepfer.jsonschema.core.keyword.type.AffectedBy;
import io.github.sebastiantoepfer.jsonschema.core.keyword.type.AffectedByKeywordType;
import io.github.sebastiantoepfer.jsonschema.core.keyword.type.Affects;
import io.github.sebastiantoepfer.jsonschema.core.keyword.type.AffectsKeywordType;
import io.github.sebastiantoepfer.jsonschema.core.keyword.type.NamedJsonSchemaKeywordType;
import io.github.sebastiantoepfer.jsonschema.core.keyword.type.SchemaArrayKeywordType;
import io.github.sebastiantoepfer.jsonschema.core.keyword.type.SubSchemaKeywordType;
import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType;
import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.DefaultVocabulary;
import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.ListVocabulary;
import jakarta.json.Json;
import jakarta.json.JsonValue;
import java.net.URI;
import java.util.List;
import java.util.Optional;
Expand All @@ -48,17 +52,47 @@ public final class ApplicatorVocabulary implements Vocabulary {
private final Vocabulary vocab;

public ApplicatorVocabulary() {
this.vocab = new DefaultVocabulary(
this.vocab = new ListVocabulary(
URI.create("https://json-schema.org/draft/2020-12/vocab/applicator"),
new SchemaArrayKeywordType(AllOfKeyword.NAME, AllOfKeyword::new),
new SchemaArrayKeywordType(AnyOfKeyword.NAME, AnyOfKeyword::new),
new SchemaArrayKeywordType(OneOfKeyword.NAME, OneOfKeyword::new),
new SubSchemaKeywordType(NotKeyword.NAME, NotKeyword::new),
new NamedJsonSchemaKeywordType(PropertiesKeyword.NAME, PropertiesKeyword::new),
new SubSchemaKeywordType(AdditionalPropertiesKeyword.NAME, AdditionalPropertiesKeyword::new),
//nomally affectedBy ... but we had the needed function only in affects :(
new AffectsKeywordType(
AdditionalPropertiesKeyword.NAME,
List.of(
new Affects("properties", JsonValue.EMPTY_JSON_ARRAY),
new Affects("patternProperties", JsonValue.EMPTY_JSON_ARRAY)
),
(affects, schema) ->
new SubSchemaKeywordType(
AdditionalPropertiesKeyword.NAME,
s -> new AdditionalPropertiesKeyword(affects, s)
).createKeyword(schema)
),
new NamedJsonSchemaKeywordType(PatternPropertiesKeyword.NAME, PatternPropertiesKeyword::new),
new NamedJsonSchemaKeywordType(DependentSchemasKeyword.NAME, DependentSchemasKeyword::new),
new SubSchemaKeywordType(ItemsKeyword.NAME, ItemsKeyword::new),
//this example shows my missunderstanding from affects, affectedBy and keywordtypes :(
new AffectedByKeywordType(
ItemsKeyword.NAME,
List.of(
new AffectedBy(AffectByType.EXTENDS, "minItems"),
new AffectedBy(AffectByType.EXTENDS, "maxItems")
),
//nomally affectedBy too ... but we had the needed function only in affects :(
schema ->
new AffectsKeywordType(
ItemsKeyword.NAME,
List.of(new Affects("prefixItems", Json.createValue(-1))),
(affects, subSchema) ->
new SubSchemaKeywordType(
ItemsKeyword.NAME,
s -> new ItemsKeyword(affects, s)
).createKeyword(subSchema)
).createKeyword(schema)
),
new SchemaArrayKeywordType(PrefixItemsKeyword.NAME, PrefixItemsKeyword::new),
new AffectedByKeywordType(
ContainsKeyword.NAME,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,16 @@

import io.github.sebastiantoepfer.ddd.common.Media;
import io.github.sebastiantoepfer.jsonschema.InstanceType;
import io.github.sebastiantoepfer.jsonschema.JsonSubSchema;
import io.github.sebastiantoepfer.jsonschema.Validator;
import io.github.sebastiantoepfer.jsonschema.JsonSchema;
import io.github.sebastiantoepfer.jsonschema.keyword.Annotation;
import io.github.sebastiantoepfer.jsonschema.keyword.Applicator;
import io.github.sebastiantoepfer.jsonschema.keyword.Keyword;
import jakarta.json.JsonArray;
import jakarta.json.JsonNumber;
import jakarta.json.JsonValue;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

/**
* <b>items</b> : <i>Schema</i><br/>
Expand All @@ -56,9 +55,11 @@
final class ItemsKeyword implements Applicator, Annotation {

static final String NAME = "items";
private final JsonSubSchema schema;
private final Collection<Annotation> affectedBys;
private final JsonSchema schema;

public ItemsKeyword(final JsonSubSchema schema) {
public ItemsKeyword(final Collection<Annotation> affectedBys, final JsonSchema schema) {
this.affectedBys = List.copyOf(affectedBys);
this.schema = Objects.requireNonNull(schema);
}

Expand Down Expand Up @@ -89,28 +90,35 @@ public JsonValue valueFor(final JsonValue value) {
}

private boolean appliesToAnyFor(final JsonArray value) {
return startIndexFor(value) == -1;
return itemsForValidation(value).anyMatch(schema.validator()::isValid);
}

@Override
public boolean applyTo(final JsonValue instance) {
return !InstanceType.ARRAY.isInstance(instance) || matchesSchema(instance.asJsonArray());
return !InstanceType.ARRAY.isInstance(instance) || applyTo(instance.asJsonArray());
}

private boolean matchesSchema(final JsonArray items) {
final Validator itemValidator = schema.validator();
return items.stream().skip(startIndexFor(items) + 1L).allMatch(itemValidator::isValid);
private boolean applyTo(final JsonArray items) {
return itemsForValidation(items).allMatch(schema.validator()::isValid);
}

private Stream<JsonValue> itemsForValidation(final JsonArray items) {
return items.stream().skip(startIndexFor(items) + 1L);
}

private int startIndexFor(final JsonArray value) {
return schema
.owner()
.keywordByName("prefixItems")
.map(Keyword::asAnnotation)
.map(anno -> anno.valueFor(value))
.map(v -> new MaxIndexCalculator(value, v))
.map(MaxIndexCalculator::maxIndex)
.orElse(-1);
final int result;
if (affectedBys.isEmpty()) {
result = -1;
} else {
result = affectedBys
.stream()
.map(anno -> anno.valueFor(value))
.map(v -> new MaxIndexCalculator(value, v))
.mapToInt(MaxIndexCalculator::maxIndex)
.sum();
}
return result;
}

private static class MaxIndexCalculator {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

import io.github.sebastiantoepfer.jsonschema.Vocabulary;
import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType;
import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.DefaultVocabulary;
import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.ListVocabulary;
import java.net.URI;
import java.util.Optional;

Expand All @@ -41,7 +41,7 @@ public final class ContentVocabulary implements Vocabulary {
private final Vocabulary vocab;

public ContentVocabulary() {
this.vocab = new DefaultVocabulary(URI.create("https://json-schema.org/draft/2020-12/vocab/content"));
this.vocab = new ListVocabulary(URI.create("https://json-schema.org/draft/2020-12/vocab/content"));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import io.github.sebastiantoepfer.jsonschema.core.keyword.type.NamedJsonSchemaKeywordType;
import io.github.sebastiantoepfer.jsonschema.core.keyword.type.StringKeywordType;
import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType;
import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.DefaultVocabulary;
import io.github.sebastiantoepfer.jsonschema.vocabulary.spi.ListVocabulary;
import jakarta.json.spi.JsonProvider;
import java.net.URI;
import java.util.Optional;
Expand All @@ -37,7 +37,7 @@ public final class CoreVocabulary implements Vocabulary {
private final Vocabulary vocab;

public CoreVocabulary(final JsonProvider jsonContext) {
this.vocab = new DefaultVocabulary(
this.vocab = new ListVocabulary(
URI.create("https://json-schema.org/draft/2020-12/vocab/core"),
new StringKeywordType(jsonContext, SchemaKeyword.NAME, value -> new SchemaKeyword(URI.create(value))),
new StringKeywordType(jsonContext, IdKeyword.NAME, value -> new IdKeyword(URI.create(value))),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import io.github.sebastiantoepfer.jsonschema.keyword.Applicator;
import jakarta.json.Json;
import jakarta.json.JsonPointer;
import jakarta.json.JsonReader;
import jakarta.json.JsonStructure;
import jakarta.json.JsonValue;
import java.io.IOException;
Expand All @@ -52,10 +51,12 @@ final class RefKeyword implements Applicator {
static final String NAME = "$ref";
private final JsonSchema schema;
private final URI uri;
private final SchemaRegistry schemaRegistry;

public RefKeyword(final JsonSchema schema, final URI uri) {
public RefKeyword(final JsonSchema schema, final URI uri, final SchemaRegistry schemaRegistry) {
this.schema = Objects.requireNonNull(schema);
this.uri = Objects.requireNonNull(uri);
this.schemaRegistry = Objects.requireNonNull(schemaRegistry);
}

@Override
Expand All @@ -74,23 +75,23 @@ public boolean hasName(final String name) {
}

private JsonSchema retrieveJsonSchema() {
final JsonValue json;
final JsonSchema json;
try {
if (isRemote()) {
json = retrieveValueFromRemoteLocation();
json = retrieveSchemaFromRegistry();
} else {
json = retrieveValueFromLocalSchema();
json = retrieveSchemaFromLocalSchema();
}
return JsonSchemas.load(json);
} catch (IOException ex) {
throw new IllegalStateException("can not load schema!", ex);
}
}

private JsonValue retrieveValueFromLocalSchema() throws IOException {
private JsonSchema retrieveSchemaFromLocalSchema() throws IOException {
final JsonPointer pointer = createPointer();
if (pointer.containsValue(searchAnchor())) {
return pointer.getValue(searchAnchor());
return JsonSchemas.load(pointer.getValue(searchAnchor()));
} else {
throw new IOException("can not find referenced value.");
}
Expand All @@ -111,10 +112,8 @@ private JsonPointer createPointer() {
return pointer;
}

private JsonValue retrieveValueFromRemoteLocation() throws IOException {
try (final JsonReader reader = Json.createReader(uri.toURL().openStream())) {
return reader.readValue();
}
private JsonSchema retrieveSchemaFromRegistry() throws IOException {
return schemaRegistry.schemaForUrl(uri);
}

private boolean isRemote() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@
final class RefKeywordType implements KeywordType {

private final JsonProvider jsonContext;
private final SchemaRegistry schemaRegistry;

public RefKeywordType(final JsonProvider jsonContext) {
this.jsonContext = Objects.requireNonNull(jsonContext);
this.schemaRegistry = new SchemaRegistry.RemoteSchemaRegistry();
}

@Override
Expand All @@ -49,7 +51,7 @@ public Keyword createKeyword(final JsonSchema schema) {
return new StringKeywordType(
jsonContext,
RefKeyword.NAME,
s -> new RefKeyword(schema, URI.create(s))
s -> new RefKeyword(schema, URI.create(s), schemaRegistry)
).createKeyword(schema);
}
}
Loading

0 comments on commit 9114ca6

Please sign in to comment.