Skip to content

Commit

Permalink
replace old static annotation with a more dynamic way
Browse files Browse the repository at this point in the history
currently unclear if it is the right way or must we implement the
keywords in a more mutable state and use this for the annotion.
  • Loading branch information
sebastian-toepfer committed Oct 5, 2023
1 parent 4b76e28 commit 26a193f
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ default Collection<KeywordCategory> categories() {
return Set.of(KeywordCategory.ANNOTATION);
}

JsonValue value();
JsonValue valueFor(JsonValue value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@
*
* see: https://json-schema.org/draft/2020-12/json-schema-core.html#name-json-schema-objects-and-key
*/
public final class DefaultAnnotation implements Annotation {
public final class StaticAnnotation implements Annotation {

private final String name;
private final JsonValue value;

public DefaultAnnotation(final String name, final JsonValue value) {
public StaticAnnotation(final String name, final JsonValue value) {
this.name = Objects.requireNonNull(name);
this.value = Objects.requireNonNullElse(value, JsonValue.NULL);
}
Expand All @@ -48,7 +48,7 @@ public boolean hasName(final String name) {
}

@Override
public JsonValue value() {
public JsonValue valueFor(final JsonValue instance) {
return value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void should_return_this_as_annotation() {
private static class TestAnnotation implements Annotation {

@Override
public JsonValue value() {
public JsonValue valueFor(JsonValue value) {
throw new UnsupportedOperationException("Not supported yet.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,26 @@
import static org.hamcrest.Matchers.is;

import jakarta.json.Json;
import jakarta.json.JsonValue;
import org.junit.jupiter.api.Test;

class DefaultAnnotationTest {
class StaticAnnotationTest {

@Test
void should_know_his_name() {
assertThat(new DefaultAnnotation("myname", Json.createValue("string")).hasName("myname"), is(true));
assertThat(new StaticAnnotation("myname", Json.createValue("string")).hasName("myname"), is(true));
}

@Test
void should_know_other_names() {
assertThat(new DefaultAnnotation("myname", Json.createValue("string")).hasName("id"), is(false));
assertThat(new StaticAnnotation("myname", Json.createValue("string")).hasName("id"), is(false));
}

@Test
void should_return_his_value() {
assertThat(new DefaultAnnotation("myname", Json.createValue("string")).value(), is(Json.createValue("string")));
assertThat(
new StaticAnnotation("myname", Json.createValue("string")).valueFor(JsonValue.FALSE),
is(Json.createValue("string"))
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
package io.github.sebastiantoepfer.jsonschema.core;

import io.github.sebastiantoepfer.jsonschema.JsonSchema;
import io.github.sebastiantoepfer.jsonschema.keyword.DefaultAnnotation;
import io.github.sebastiantoepfer.jsonschema.keyword.Keyword;
import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType;
import io.github.sebastiantoepfer.jsonschema.keyword.StaticAnnotation;
import jakarta.json.JsonValue;
import java.util.Objects;

Expand All @@ -45,6 +45,6 @@ public String name() {

@Override
public Keyword createKeyword(final JsonSchema schema, final JsonValue value) {
return new DefaultAnnotation(name(), value);
return new StaticAnnotation(name(), value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,18 @@ public Collection<KeywordCategory> categories() {
}

@Override
public JsonValue value() {
public JsonValue valueFor(final JsonValue value) {
final JsonValue result;
if (appliesToAny()) {
if (appliesToAnyFor(value.asJsonArray())) {
result = JsonValue.TRUE;
} else {
result = JsonValue.FALSE;
}
return result;
}

private boolean appliesToAny() {
return startIndex() < 0;
private boolean appliesToAnyFor(final JsonArray value) {
return startIndexFor(value) == -1;
}

@Override
Expand All @@ -114,18 +114,42 @@ public boolean applyTo(final JsonValue instance) {

private boolean matchesSchema(final JsonArray items) {
final Validator itemValidator = validator();
return items.stream().skip(startIndex() + 1).map(itemValidator::validate).allMatch(Collection::isEmpty);
return items
.stream()
.skip(startIndexFor(items) + 1L)
.map(itemValidator::validate)
.allMatch(Collection::isEmpty);
}

private long startIndex() {
private int startIndexFor(final JsonArray value) {
return owner()
.keywordByName("prefixItems")
.map(Keyword::asAnnotation)
.map(Annotation::value)
.filter(InstanceType.INTEGER::isInstance)
.map(JsonNumber.class::cast)
.map(JsonNumber::longValue)
.orElse(-1L);
.map(anno -> anno.valueFor(value))
.map(v -> new MaxIndexCalculator(value, v))
.map(MaxIndexCalculator::maxIndex)
.orElse(-1);
}

private static class MaxIndexCalculator {

private final JsonArray array;
private final JsonValue index;

public MaxIndexCalculator(final JsonArray array, final JsonValue index) {
this.array = array;
this.index = index;
}

int maxIndex() {
final int result;
if (index == JsonValue.TRUE) {
result = array.size();
} else {
result = ((JsonNumber) index).intValue();
}
return result;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,14 @@ public boolean hasName(final String name) {
}

@Override
public JsonValue value() {
return Json.createValue(schemas.size() - 1);
public JsonValue valueFor(final JsonValue value) {
final JsonValue result;
if (value.asJsonArray().size() == schemas.size()) {
result = JsonValue.TRUE;
} else {
result = Json.createValue(Math.min(value.asJsonArray().size(), schemas.size()) - 1);
}
return result;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
package io.github.sebastiantoepfer.jsonschema.core.vocab.core;

import io.github.sebastiantoepfer.jsonschema.JsonSchema;
import io.github.sebastiantoepfer.jsonschema.keyword.DefaultAnnotation;
import io.github.sebastiantoepfer.jsonschema.keyword.Keyword;
import io.github.sebastiantoepfer.jsonschema.keyword.KeywordType;
import io.github.sebastiantoepfer.jsonschema.keyword.StaticAnnotation;
import jakarta.json.JsonValue;

/**
Expand All @@ -42,6 +42,6 @@ public String name() {

@Override
public Keyword createKeyword(final JsonSchema schema, final JsonValue value) {
return new DefaultAnnotation(name(), value);
return new StaticAnnotation(name(), value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ void should_produces_true_if_is_applied_to_any_instance() {
new ItemsKeywordType()
.createKeyword(new DefaultJsonSchemaFactory().create(JsonValue.TRUE), JsonValue.EMPTY_JSON_OBJECT)
.asAnnotation()
.value(),
.valueFor(Json.createArrayBuilder().add(1).build()),
is(JsonValue.TRUE)
);
}
Expand Down Expand Up @@ -155,7 +155,7 @@ void should_return_false_if_not_applies_to_any_item() {
JsonValue.FALSE
)
.asAnnotation()
.value(),
.valueFor(Json.createArrayBuilder().add(1).build()),
is(JsonValue.FALSE)
);
}
Expand All @@ -167,12 +167,15 @@ void should_be_valid_if_invaliditem_is_already_checked_by_prefixItems() {
.createKeyword(
new DefaultJsonSchemaFactory()
.create(
Json.createObjectBuilder().add("prefixItems", Json.createArrayBuilder().add(true)).build()
Json
.createObjectBuilder()
.add("prefixItems", Json.createArrayBuilder().add(true).add(true))
.build()
),
JsonValue.FALSE
Json.createObjectBuilder().add("type", "integer").build()
)
.asApplicator()
.applyTo(Json.createArrayBuilder().add("1").build()),
.applyTo(Json.createArrayBuilder().add("1").add("2").add(1).build()),
is(true)
);
}
Expand All @@ -186,10 +189,10 @@ void should_be_invalid_if_invaliditem_is_not_already_checked_by_prefixItems() {
.create(
Json.createObjectBuilder().add("prefixItems", Json.createArrayBuilder().add(true)).build()
),
JsonValue.FALSE
Json.createObjectBuilder().add("type", "integer").build()
)
.asApplicator()
.applyTo(Json.createArrayBuilder().add("1").add("2").build()),
.applyTo(Json.createArrayBuilder().add("1").add("2").add(1).build()),
is(false)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,33 @@ void should_not_be_createbale_from_non_array() {
}

@Test
void should_return_one_as_value() {
void should_return_zero_as_value() {
assertThat(
new PrefixItemsKeywordType()
.createKeyword(
new DefaultJsonSchemaFactory().create(JsonValue.TRUE),
Json.createArrayBuilder().add(JsonValue.TRUE).build()
)
.asAnnotation()
.value(),
.valueFor(Json.createArrayBuilder().add(1).add(2).build()),
is(Json.createValue(0))
);
}

@Test
void should_retrun_true_if_is_applies_to_all_values() {
assertThat(
new PrefixItemsKeywordType()
.createKeyword(
new DefaultJsonSchemaFactory().create(JsonValue.TRUE),
Json.createArrayBuilder().add(JsonValue.TRUE).add(JsonValue.TRUE).build()
)
.asAnnotation()
.valueFor(Json.createArrayBuilder().add(1).add(2).build()),
is(JsonValue.TRUE)
);
}

@Test
void should_be_valid_for_non_arrays() {
assertThat(
Expand Down

0 comments on commit 26a193f

Please sign in to comment.