diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/Rule.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/Rule.java index 4bb978ec..cb28b179 100644 --- a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/Rule.java +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/Rule.java @@ -27,7 +27,10 @@ import io.github.sebastiantoepfer.ddd.common.Printable; import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleName; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.ValidateableCodePoint; import java.util.Objects; +import java.util.function.Predicate; +import java.util.stream.IntStream; public final class Rule implements Printable { @@ -47,6 +50,15 @@ public boolean hasRuleName(final RuleName name) { return Objects.equals(this.name, name); } + Predicate asPredicate() { + return s -> + IntStream + .range(0, s.length()) + .boxed() + .map(i -> ValidateableCodePoint.of(i, s.codePointAt(i))) + .allMatch(elements::isValidFor); + } + @Override public > T printOn(final T media) { return media.withValue("name", name).withValue("type", "rule").withValue("elements", elements); diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/RuleTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/RuleTest.java index 124baa5c..9494d5c9 100644 --- a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/RuleTest.java +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/RuleTest.java @@ -31,11 +31,16 @@ import io.github.sebastiantoepfer.ddd.media.core.HashMapMedia; import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Alternative; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Concatenation; import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleName; import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleReference; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.SequenceGroup; import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.StringElement; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.VariableRepetition; import nl.jqno.equalsverifier.EqualsVerifier; import org.hamcrest.Matcher; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; class RuleTest { @@ -78,4 +83,49 @@ void should_be_printable() { ) ); } + + @Nested + class Validation { + + private Rule ruleName; + + @BeforeEach + void initRule() { + ruleName = + Rule.of( + RuleName.of("rulename"), + Concatenation.of( + CoreRules.ALPHA, + VariableRepetition.of( + SequenceGroup.of(Alternative.of(CoreRules.ALPHA, CoreRules.DIGIT, StringElement.of("-"))) + ) + ) + ); + } + + @Test + void should_be_valid_for_alphas_only() { + assertThat(ruleName.asPredicate().test("rulename"), is(true)); + } + + @Test + void should_be_valid_for_valid_alpha_and_digits() { + assertThat(ruleName.asPredicate().test("rul3nam3"), is(true)); + } + + @Test + void should_be_valid_for_valid_alpha_and_minus() { + assertThat(ruleName.asPredicate().test("rule-name"), is(true)); + } + + @Test + void should_be_invalid_for_value_with_digist_at_start() { + assertThat(ruleName.asPredicate().test("1rule"), is(false)); + } + + @Test + void should_be_invalid_for_value_with_solidus() { + assertThat(ruleName.asPredicate().test("rule/name"), is(false)); + } + } }