Sfoglia il codice sorgente

Refactor NumberTester to be cleaner.

Sam Jaffe 6 anni fa
parent
commit
8e8ff52510

+ 5 - 5
src/main/lombok/org/leumasjaffe/json/schema/factory/SchemaV6Factory.java

@@ -50,11 +50,11 @@ class SchemaV6Factory extends SchemaFactory {
 		case "description": return FixedTester.ACCEPT;
 		case "default": return FixedTester.ACCEPT;
 		case "examples": return FixedTester.ACCEPT;
-		case "multipleOf": return new NumberTester(d -> d % value.asDouble() == 0);
-		case "maximum": return new NumberTester(d -> d <= value.asDouble());
-		case "exclusiveMaximum": return new NumberTester(d -> d < value.asDouble());
-		case "minimum": return new NumberTester(d -> d >= value.asDouble());
-		case "exclusiveMinimum": return new NumberTester(d -> d > value.asDouble());
+		case "multipleOf": return NumberTester.multipleOf(value.asDouble());
+		case "maximum": return NumberTester.maximum(value.asDouble());
+		case "exclusiveMaximum": return NumberTester.exclusiveMaximum(value.asDouble());
+		case "minimum": return NumberTester.minimum(value.asDouble());
+		case "exclusiveMinimum": return NumberTester.exclusiveMinimum(value.asDouble());
 		case "maxLength": return new SizeTester(STRING, i -> i <= value.asInt());
 		case "minLength": return new SizeTester(STRING, i -> i >= value.asInt(0));
 		case "pattern": return new SimpleTester(STRING, j -> j.asText().matches(value.asText()));

+ 39 - 5
src/main/lombok/org/leumasjaffe/json/schema/tester/NumberTester.java

@@ -1,7 +1,5 @@
 package org.leumasjaffe.json.schema.tester;
 
-import java.util.function.DoublePredicate;
-
 import org.leumasjaffe.json.schema.Tester;
 
 import com.fasterxml.jackson.databind.JsonNode;
@@ -11,10 +9,46 @@ import lombok.AccessLevel;
 import lombok.RequiredArgsConstructor;
 import lombok.experimental.FieldDefaults;
 
-@RequiredArgsConstructor
+@RequiredArgsConstructor(access=AccessLevel.PRIVATE)
 @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
 public class NumberTester implements Tester {
-	DoublePredicate pred;
+	private static enum Rule {
+		MINIMUM, EXCLUSIVE_MINIMUM, MAXIMUM, EXCLUSIVE_MAXIMUM, MULTIPLE_OF;
+
+		public boolean test(double target, double against) {
+			switch(this) {
+			case MINIMUM: return target <= against;
+			case EXCLUSIVE_MINIMUM: return target < against;
+			case MAXIMUM: return target >= against;
+			case EXCLUSIVE_MAXIMUM: return target > against;
+			case MULTIPLE_OF: return against % target == 0;
+			default: return false;
+			}
+		}
+	}
+	
+	public static NumberTester minimum(double value) {
+		return new NumberTester(Rule.MINIMUM, value);
+	}
+	
+	public static NumberTester maximum(double value) {
+		return new NumberTester(Rule.MAXIMUM, value);
+	}
+	
+	public static NumberTester exclusiveMinimum(double value) {
+		return new NumberTester(Rule.EXCLUSIVE_MINIMUM, value);
+	}
+	
+	public static NumberTester exclusiveMaximum(double value) {
+		return new NumberTester(Rule.EXCLUSIVE_MAXIMUM, value);
+	}
+	
+	public static NumberTester multipleOf(double value) {
+		return new NumberTester(Rule.MULTIPLE_OF, value);
+	}
+	
+	Rule rule;
+	double value;
 	
 	@Override
 	public JsonNodeType[] acceptedTypes() {
@@ -23,7 +57,7 @@ public class NumberTester implements Tester {
 
 	@Override
 	public boolean accepts(JsonNode node) {
-		return node.isNumber() && pred.test(node.asDouble());
+		return node.isNumber() && rule.test(value, node.asDouble());
 	}
 
 }

+ 5 - 5
src/test/java/org/leumasjaffe/json/schema/SchemaTest.java

@@ -54,9 +54,9 @@ public class SchemaTest {
 
 	private Schema getNumberSchema() {
 		Map<String, Tester> tests = new HashMap<>();
-		tests.put("minimum", new NumberTester(d -> d >= 0.0));
-		tests.put("multipleOf", new NumberTester(d -> Math.abs(d % 0.25) < 1E-7));
-		tests.put("exclusiveMaximum", new NumberTester(d -> d < 1.0));
+		tests.put("minimum", NumberTester.minimum(0.0));
+		tests.put("multipleOf", NumberTester.multipleOf(0.25));
+		tests.put("exclusiveMaximum", NumberTester.exclusiveMaximum(1.0));
 		return new Schema(tests);
 	}
 	
@@ -125,8 +125,8 @@ public class SchemaTest {
 	@Test
 	public void testHandlesOtherNumberChecks() {
 		Map<String, Tester> tests = new HashMap<>();
-		tests.put("exclusiveMinimum", new NumberTester(d -> d > 0.0));
-		tests.put("maximum", new NumberTester(d -> d <= 1.0));
+		tests.put("exclusiveMinimum", NumberTester.exclusiveMinimum(0.0));
+		tests.put("maximum", NumberTester.maximum(1.0));
 		Schema schema = new Schema(tests);
 		
 		assertThat(schema, not(accepts(new DoubleNode(0.0))));

+ 54 - 9
src/test/java/org/leumasjaffe/json/schema/tester/NumberTesterTest.java

@@ -1,7 +1,9 @@
 package org.leumasjaffe.json.schema.tester;
 
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertThat;
+import static org.leumasjaffe.json.schema.matcher.AcceptedTypes.acceptsTypes;
+import static org.leumasjaffe.json.schema.matcher.Accepts.accepts;
+import static org.leumasjaffe.json.schema.matcher.Not.not;
 
 import java.util.function.DoublePredicate;
 
@@ -16,22 +18,65 @@ public class NumberTesterTest {
 	
 	@Test
 	public void testAcceptedTypeIsArgument() {
-		assertThat(new NumberTester(nonZero).acceptedTypes(),
-				is(new JsonNodeType[]{JsonNodeType.NUMBER}));
+		assertThat(NumberTester.minimum(0.0), acceptsTypes(JsonNodeType.NUMBER));
+		assertThat(NumberTester.exclusiveMinimum(0.0), acceptsTypes(JsonNodeType.NUMBER));
+		assertThat(NumberTester.maximum(0.0), acceptsTypes(JsonNodeType.NUMBER));
+		assertThat(NumberTester.exclusiveMaximum(0.0), acceptsTypes(JsonNodeType.NUMBER));
+		assertThat(NumberTester.multipleOf(1.0), acceptsTypes(JsonNodeType.NUMBER));
 	}
 	
 	@Test
 	public void testRejectsNonNumber() {
-		assertFalse(new NumberTester(nonZero).accepts(NullNode.getInstance()));
+		assertThat(NumberTester.minimum(0.0), not(accepts(NullNode.getInstance())));
+		assertThat(NumberTester.exclusiveMinimum(0.0), not(accepts(NullNode.getInstance())));
+		assertThat(NumberTester.maximum(0.0), not(accepts(NullNode.getInstance())));
+		assertThat(NumberTester.exclusiveMaximum(0.0), not(accepts(NullNode.getInstance())));
+		assertThat(NumberTester.multipleOf(0.0), not(accepts(NullNode.getInstance())));
 	}
 
 	@Test
-	public void testRejectsFailingPred() {
-		assertFalse(new NumberTester(nonZero).accepts(new DoubleNode(0.0)));
+	public void testMinimum() {
+		final NumberTester test = NumberTester.minimum(0.0);
+		assertThat(test, not(accepts(new DoubleNode(-1E-12))));
+		assertThat(test, accepts(new DoubleNode(0.0)));
+		assertThat(test, accepts(new DoubleNode(1E-12)));
+		assertThat(test, accepts(new DoubleNode(1.0)));
 	}
 
 	@Test
-	public void testAcceptsPassingPred() {
-		assertTrue(new NumberTester(nonZero).accepts(new DoubleNode(1.0)));
+	public void testExclusiveMinimum() {
+		final NumberTester test = NumberTester.exclusiveMinimum(0.0);
+		assertThat(test, not(accepts(new DoubleNode(-1E-12))));
+		assertThat(test, not(accepts(new DoubleNode(0.0))));
+		assertThat(test, accepts(new DoubleNode(1E-12)));
+		assertThat(test, accepts(new DoubleNode(1.0)));
 	}
+
+	@Test
+	public void testMaximum() {
+		final NumberTester test = NumberTester.maximum(0.0);
+		assertThat(test, accepts(new DoubleNode(-1E-12)));
+		assertThat(test, accepts(new DoubleNode(0.0)));
+		assertThat(test, not(accepts(new DoubleNode(1E-12))));
+		assertThat(test, not(accepts(new DoubleNode(1.0))));
+	}
+
+	@Test
+	public void testExclusiveMaximum() {
+		final NumberTester test = NumberTester.exclusiveMaximum(0.0);
+		assertThat(test, accepts(new DoubleNode(-1E-12)));
+		assertThat(test, not(accepts(new DoubleNode(0.0))));
+		assertThat(test, not(accepts(new DoubleNode(1E-12))));
+		assertThat(test, not(accepts(new DoubleNode(1.0))));
+	}
+
+	@Test
+	public void testMultipleOf() {
+		final NumberTester test = NumberTester.multipleOf(1.0);
+		assertThat(test, not(accepts(new DoubleNode(-1E-12))));
+		assertThat(test, accepts(new DoubleNode(0.0)));
+		assertThat(test, not(accepts(new DoubleNode(1E-12))));
+		assertThat(test, accepts(new DoubleNode(1.0)));
+	}
+	
 }