Skip to content

Commit 2ff1fba

Browse files
committed
feat(validate): DefaultValidator skeleton with dispatch + boolean/null/ref/enum/const
1 parent fd6d8e8 commit 2ff1fba

2 files changed

Lines changed: 133 additions & 0 deletions

File tree

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.retailsvc.http.validate;
2+
3+
import com.retailsvc.http.ValidationException;
4+
import com.retailsvc.http.spec.schema.AllOfSchema;
5+
import com.retailsvc.http.spec.schema.AnyOfSchema;
6+
import com.retailsvc.http.spec.schema.ArraySchema;
7+
import com.retailsvc.http.spec.schema.BooleanSchema;
8+
import com.retailsvc.http.spec.schema.ConstSchema;
9+
import com.retailsvc.http.spec.schema.EnumSchema;
10+
import com.retailsvc.http.spec.schema.IntegerSchema;
11+
import com.retailsvc.http.spec.schema.NotSchema;
12+
import com.retailsvc.http.spec.schema.NullSchema;
13+
import com.retailsvc.http.spec.schema.NumberSchema;
14+
import com.retailsvc.http.spec.schema.ObjectSchema;
15+
import com.retailsvc.http.spec.schema.OneOfSchema;
16+
import com.retailsvc.http.spec.schema.RefSchema;
17+
import com.retailsvc.http.spec.schema.Schema;
18+
import com.retailsvc.http.spec.schema.StringSchema;
19+
import com.retailsvc.http.spec.schema.TypeName;
20+
import java.util.Objects;
21+
import java.util.function.Function;
22+
23+
public final class DefaultValidator implements Validator {
24+
private final Function<String, Schema> refResolver;
25+
26+
public DefaultValidator(Function<String, Schema> refResolver) {
27+
this.refResolver = refResolver;
28+
}
29+
30+
@Override
31+
public void validate(Object value, Schema schema, String pointer) {
32+
if (value == null && schema.types().contains(TypeName.NULL)) return;
33+
34+
switch (schema) {
35+
case RefSchema r -> validate(value, refResolver.apply(r.pointer()), pointer);
36+
case BooleanSchema b -> validateBoolean(value, pointer);
37+
case NullSchema n -> require(value == null, pointer, "type", "expected null");
38+
case StringSchema s -> validateString(value, s, pointer);
39+
case IntegerSchema i -> validateInteger(value, i, pointer);
40+
case NumberSchema n -> validateNumber(value, n, pointer);
41+
case ObjectSchema o -> validateObject(value, o, pointer);
42+
case ArraySchema a -> validateArray(value, a, pointer);
43+
case EnumSchema e ->
44+
require(e.values().contains(value), pointer, "enum", "value not in enum");
45+
case ConstSchema c ->
46+
require(Objects.equals(c.value(), value), pointer, "const", "value does not equal const");
47+
case OneOfSchema o -> throw new UnsupportedOperationException("oneOf not yet supported");
48+
case AnyOfSchema a -> throw new UnsupportedOperationException("anyOf not yet supported");
49+
case AllOfSchema a -> throw new UnsupportedOperationException("allOf not yet supported");
50+
case NotSchema n -> throw new UnsupportedOperationException("not not yet supported");
51+
}
52+
}
53+
54+
private void validateBoolean(Object value, String pointer) {
55+
require(value instanceof Boolean, pointer, "type", "expected boolean");
56+
}
57+
58+
private void validateString(Object value, StringSchema s, String pointer) {
59+
throw new UnsupportedOperationException("E3 implements string");
60+
}
61+
62+
private void validateInteger(Object value, IntegerSchema s, String pointer) {
63+
throw new UnsupportedOperationException("E3 implements integer");
64+
}
65+
66+
private void validateNumber(Object value, NumberSchema s, String pointer) {
67+
throw new UnsupportedOperationException("E3 implements number");
68+
}
69+
70+
private void validateObject(Object value, ObjectSchema s, String pointer) {
71+
throw new UnsupportedOperationException("E4 implements object");
72+
}
73+
74+
private void validateArray(Object value, ArraySchema s, String pointer) {
75+
throw new UnsupportedOperationException("E4 implements array");
76+
}
77+
78+
static void require(boolean condition, String pointer, String keyword, String message) {
79+
if (!condition) {
80+
throw new ValidationException(new ValidationError(pointer, keyword, message, null));
81+
}
82+
}
83+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.retailsvc.http.validate;
2+
3+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
4+
5+
import com.retailsvc.http.ValidationException;
6+
import com.retailsvc.http.spec.schema.BooleanSchema;
7+
import com.retailsvc.http.spec.schema.NullSchema;
8+
import com.retailsvc.http.spec.schema.OneOfSchema;
9+
import com.retailsvc.http.spec.schema.TypeName;
10+
import java.util.List;
11+
import java.util.Set;
12+
import org.junit.jupiter.api.Test;
13+
14+
class DefaultValidatorDispatchTest {
15+
private final Validator v =
16+
new DefaultValidator(
17+
name -> {
18+
throw new AssertionError("no refs");
19+
});
20+
21+
@Test
22+
void nullSchemaAcceptsNull() {
23+
v.validate(null, new NullSchema(), "");
24+
}
25+
26+
@Test
27+
void nullSchemaRejectsNonNull() {
28+
assertThatThrownBy(() -> v.validate("x", new NullSchema(), "/v"))
29+
.isInstanceOf(ValidationException.class)
30+
.extracting(t -> ((ValidationException) t).error().keyword())
31+
.isEqualTo("type");
32+
}
33+
34+
@Test
35+
void booleanSchemaAcceptsBoolean() {
36+
v.validate(true, new BooleanSchema(Set.of(TypeName.BOOLEAN)), "/v");
37+
}
38+
39+
@Test
40+
void booleanSchemaRejectsString() {
41+
assertThatThrownBy(() -> v.validate("x", new BooleanSchema(Set.of(TypeName.BOOLEAN)), "/v"))
42+
.isInstanceOf(ValidationException.class);
43+
}
44+
45+
@Test
46+
void combinatorThrowsUnsupported() {
47+
assertThatThrownBy(() -> v.validate("x", new OneOfSchema(List.of()), "/v"))
48+
.isInstanceOf(UnsupportedOperationException.class);
49+
}
50+
}

0 commit comments

Comments
 (0)