summaryrefslogtreecommitdiffstats
path: root/predicate-search-core/src/test/java/com/yahoo/document
diff options
context:
space:
mode:
Diffstat (limited to 'predicate-search-core/src/test/java/com/yahoo/document')
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/BinaryFormatTest.java124
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/BooleanPredicateTest.java47
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/ConjunctionTest.java113
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/DisjunctionTest.java113
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/FeatureConjunctionTest.java52
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/FeatureRangeTest.java263
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/FeatureSetTest.java180
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/NegationTest.java89
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateHashTest.java102
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateOperatorTest.java17
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateParserTest.java155
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateTest.java110
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateValueTest.java17
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicatesTest.java38
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/RangeEdgePartitionTest.java62
-rw-r--r--predicate-search-core/src/test/java/com/yahoo/document/predicate/RangePartitionTest.java60
16 files changed, 1542 insertions, 0 deletions
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/BinaryFormatTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/BinaryFormatTest.java
new file mode 100644
index 00000000000..44477423fdb
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/BinaryFormatTest.java
@@ -0,0 +1,124 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import com.yahoo.slime.Inspector;
+import com.yahoo.slime.Slime;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ */
+public class BinaryFormatTest {
+
+ @Test
+ public void requireThatEncodeNullThrows() {
+ try {
+ BinaryFormat.encode(null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("predicate", e.getMessage());
+ }
+ }
+
+ @Test
+ public void requireThatDecodeNullThrows() {
+ try {
+ BinaryFormat.decode(null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("buf", e.getMessage());
+ }
+ }
+
+ @Test
+ public void requireThatDecodeEmptyThrows() {
+ try {
+ BinaryFormat.decode(new byte[0]);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ assertEquals("0", e.getMessage());
+ }
+ }
+
+ @Test
+ public void requireThatConjunctionCanBeSerialized() {
+ assertSerialize(new Conjunction(new FeatureSet("foo", "bar"), new FeatureSet("baz", "cox")));
+ }
+
+ @Test
+ public void requireThatDisjunctionCanBeSerialized() {
+ assertSerialize(new Disjunction(new FeatureSet("foo", "bar"), new FeatureSet("baz", "cox")));
+ }
+
+ @Test
+ public void requireThatFeatureRangeCanBeSerialized() {
+ assertSerialize(new FeatureRange("foo", null, null));
+ assertSerialize(new FeatureRange("foo", null, 9L));
+ assertSerialize(new FeatureRange("foo", 6L, null));
+ assertSerialize(new FeatureRange("foo", 6L, 9L));
+ }
+
+ @Test
+ public void requireThatPartitionedFeatureRangeCanBeSerialized() {
+ FeatureRange expected = new FeatureRange("foo", 8L, 20L);
+ FeatureRange f = new FeatureRange("foo", 8L, 20L);
+ f.addPartition(new RangeEdgePartition("foo=0", 0, 8, -1));
+ f.addPartition(new RangeEdgePartition("foo=20", 20, 0, 0));
+ f.addPartition(new RangePartition("foo", 10, 19, false));
+ assertSerializesTo(expected, f);
+ Slime slime = com.yahoo.slime.BinaryFormat.decode(BinaryFormat.encode(f));
+ assertEquals(BinaryFormat.TYPE_FEATURE_RANGE, slime.get().field(BinaryFormat.NODE_TYPE).asLong());
+ Inspector in1 = slime.get().field(BinaryFormat.HASHED_PARTITIONS);
+ assertEquals(1, in1.entries());
+ assertEquals(0xf2b6d1cc6322cb99L, in1.entry(0).asLong());
+ Inspector in2 = slime.get().field(BinaryFormat.HASHED_EDGE_PARTITIONS);
+ assertEquals(2, in2.entries());
+ Inspector obj1 = in2.entry(0);
+ assertEquals(0xb2b301e26efffdc2L, obj1.field(BinaryFormat.HASH).asLong());
+ assertEquals(0, obj1.field(BinaryFormat.VALUE).asLong());
+ assertEquals(0x80000008L, obj1.field(BinaryFormat.PAYLOAD).asLong());
+ Inspector obj2 = in2.entry(1);
+ assertEquals(0x22acb2ed72523c36L, obj2.field(BinaryFormat.HASH).asLong());
+ assertEquals(20, obj2.field(BinaryFormat.VALUE).asLong());
+ assertEquals(0x40000001L, obj2.field(BinaryFormat.PAYLOAD).asLong());
+ }
+
+ @Test
+ public void requireThatFeatureSetCanBeSerialized() {
+ assertSerialize(new FeatureSet("foo"));
+ assertSerialize(new FeatureSet("foo", "bar"));
+ assertSerialize(new FeatureSet("foo", "bar", "baz"));
+ }
+
+ @Test
+ public void requireThatNegationCanBeSerialized() {
+ assertSerialize(new Negation(new FeatureSet("foo", "bar")));
+ }
+
+ @Test
+ public void requireThatBooleanCanBeSerialized() {
+ assertSerialize(new BooleanPredicate(true));
+ assertSerialize(new BooleanPredicate(false));
+ }
+
+ @Test
+ public void requireThatUnknownNodeThrows() {
+ try {
+ BinaryFormat.encode(SimplePredicates.newString("foo"));
+ fail();
+ } catch (UnsupportedOperationException e) {
+
+ }
+ }
+
+ private static void assertSerializesTo(Predicate expected, Predicate predicate) {
+ assertEquals(expected, BinaryFormat.decode(BinaryFormat.encode(predicate)));
+ }
+
+ private static void assertSerialize(Predicate predicate) {
+ assertSerializesTo(predicate, predicate);
+ }
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/BooleanPredicateTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/BooleanPredicateTest.java
new file mode 100644
index 00000000000..7268b358889
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/BooleanPredicateTest.java
@@ -0,0 +1,47 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ */
+public class BooleanPredicateTest {
+
+ @Test
+ public void requireThatFalseIsAValue() {
+ assertTrue(PredicateValue.class.isAssignableFrom(BooleanPredicate.class));
+ }
+
+ @Test
+ public void requireThatCloneIsImplemented() throws CloneNotSupportedException {
+ BooleanPredicate node1 = new BooleanPredicate(true);
+ BooleanPredicate node2 = node1.clone();
+ assertEquals(node1, node2);
+ assertNotSame(node1, node2);
+ }
+
+ @Test
+ public void requireThatHashCodeIsImplemented() {
+ assertEquals(new BooleanPredicate(true).hashCode(), new BooleanPredicate(true).hashCode());
+ assertEquals(new BooleanPredicate(false).hashCode(), new BooleanPredicate(false).hashCode());
+ }
+
+ @Test
+ public void requireThatEqualsIsImplemented() {
+ BooleanPredicate lhs = new BooleanPredicate(true);
+ assertTrue(lhs.equals(lhs));
+ assertFalse(lhs.equals(new Object()));
+
+ BooleanPredicate rhs = new BooleanPredicate(false);
+ assertFalse(lhs.equals(rhs));
+ rhs.setValue(true);
+ assertTrue(lhs.equals(rhs));
+ }
+
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/ConjunctionTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/ConjunctionTest.java
new file mode 100644
index 00000000000..6e12a00ba4d
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/ConjunctionTest.java
@@ -0,0 +1,113 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ */
+public class ConjunctionTest {
+
+ @Test
+ public void requireThatConjunctionIsAnOperator() {
+ assertTrue(PredicateOperator.class.isAssignableFrom(Conjunction.class));
+ }
+
+ @Test
+ public void requireThatAccessorsWork() {
+ Conjunction node = new Conjunction();
+ Predicate a = SimplePredicates.newString("a");
+ node.addOperand(a);
+ assertEquals(Arrays.asList(a), node.getOperands());
+ Predicate b = SimplePredicates.newString("b");
+ node.addOperand(b);
+ assertEquals(Arrays.asList(a, b), node.getOperands());
+ Predicate c = SimplePredicates.newString("c");
+ Predicate d = SimplePredicates.newString("d");
+ node.addOperands(Arrays.asList(c, d));
+ assertEquals(Arrays.asList(a, b, c, d), node.getOperands());
+ Predicate e = SimplePredicates.newString("e");
+ Predicate f = SimplePredicates.newString("f");
+ node.setOperands(Arrays.asList(e, f));
+ assertEquals(Arrays.asList(e, f), node.getOperands());
+ }
+
+ @Test
+ public void requireThatConstructorsWork() {
+ Predicate foo = SimplePredicates.newString("foo");
+ Predicate bar = SimplePredicates.newString("bar");
+ Conjunction node = new Conjunction(foo, bar);
+ assertEquals(Arrays.asList(foo, bar), node.getOperands());
+
+ node = new Conjunction(Arrays.asList(foo, bar));
+ assertEquals(Arrays.asList(foo, bar), node.getOperands());
+ }
+
+ @Test
+ public void requireThatCloneIsImplemented() throws CloneNotSupportedException {
+ Conjunction node1 = new Conjunction(SimplePredicates.newString("a"), SimplePredicates.newString("b"));
+ Conjunction node2 = node1.clone();
+ assertEquals(node1, node2);
+ assertNotSame(node1, node2);
+ assertNotSame(node1.getOperands(), node2.getOperands());
+ }
+
+ @Test
+ public void requireThatHashCodeIsImplemented() {
+ assertEquals(new Conjunction().hashCode(), new Conjunction().hashCode());
+ }
+
+ @Test
+ public void requireThatEqualsIsImplemented() {
+ Conjunction lhs = new Conjunction(SimplePredicates.newString("foo"),
+ SimplePredicates.newString("bar"));
+ assertTrue(lhs.equals(lhs));
+ assertFalse(lhs.equals(new Object()));
+
+ Conjunction rhs = new Conjunction();
+ assertFalse(lhs.equals(rhs));
+ rhs.addOperand(SimplePredicates.newString("foo"));
+ assertFalse(lhs.equals(rhs));
+ rhs.addOperand(SimplePredicates.newString("bar"));
+ assertTrue(lhs.equals(rhs));
+ }
+
+ @Test
+ public void requireThatNodeDelimiterIsAND() {
+ assertEquals("", newConjunction().toString());
+ assertEquals("foo", newConjunction("foo").toString());
+ assertEquals("foo and bar", newConjunction("foo", "bar").toString());
+ assertEquals("foo and bar and baz", newConjunction("foo", "bar", "baz").toString());
+ }
+
+ @Test
+ public void requireThatSimpleConjunctionsArePrettyPrinted() {
+ assertEquals("foo and bar",
+ new Conjunction(SimplePredicates.newString("foo"),
+ SimplePredicates.newString("bar")).toString());
+ }
+
+ @Test
+ public void requireThatComplexConjunctionsArePrintedAsGroup() {
+ assertEquals("foo and bar and baz",
+ new Conjunction(SimplePredicates.newString("foo"),
+ new Conjunction(SimplePredicates.newString("bar"),
+ SimplePredicates.newString("baz"))).toString());
+ assertEquals("foo and (bar or baz)",
+ new Conjunction(SimplePredicates.newString("foo"),
+ new Disjunction(SimplePredicates.newString("bar"),
+ SimplePredicates.newString("baz"))).toString());
+ }
+
+ private static Conjunction newConjunction(String... operands) {
+ return new Conjunction(SimplePredicates.newStrings(operands));
+ }
+
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/DisjunctionTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/DisjunctionTest.java
new file mode 100644
index 00000000000..99dc46c4f5f
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/DisjunctionTest.java
@@ -0,0 +1,113 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ */
+public class DisjunctionTest {
+
+ @Test
+ public void requireThatDisjunctionIsAnOperator() {
+ assertTrue(PredicateOperator.class.isAssignableFrom(Disjunction.class));
+ }
+
+ @Test
+ public void requireThatAccessorsWork() {
+ Disjunction node = new Disjunction();
+ Predicate a = SimplePredicates.newString("a");
+ node.addOperand(a);
+ assertEquals(Arrays.asList(a), node.getOperands());
+ Predicate b = SimplePredicates.newString("b");
+ node.addOperand(b);
+ assertEquals(Arrays.asList(a, b), node.getOperands());
+ Predicate c = SimplePredicates.newString("c");
+ Predicate d = SimplePredicates.newString("d");
+ node.addOperands(Arrays.asList(c, d));
+ assertEquals(Arrays.asList(a, b, c, d), node.getOperands());
+ Predicate e = SimplePredicates.newString("e");
+ Predicate f = SimplePredicates.newString("f");
+ node.setOperands(Arrays.asList(e, f));
+ assertEquals(Arrays.asList(e, f), node.getOperands());
+ }
+
+ @Test
+ public void requireThatConstructorsWork() {
+ Predicate foo = SimplePredicates.newString("foo");
+ Predicate bar = SimplePredicates.newString("bar");
+ Disjunction node = new Disjunction(foo, bar);
+ assertEquals(Arrays.asList(foo, bar), node.getOperands());
+
+ node = new Disjunction(Arrays.asList(foo, bar));
+ assertEquals(Arrays.asList(foo, bar), node.getOperands());
+ }
+
+ @Test
+ public void requireThatCloneIsImplemented() throws CloneNotSupportedException {
+ Disjunction node1 = new Disjunction(SimplePredicates.newString("a"), SimplePredicates.newString("b"));
+ Disjunction node2 = node1.clone();
+ assertEquals(node1, node2);
+ assertNotSame(node1, node2);
+ assertNotSame(node1.getOperands(), node2.getOperands());
+ }
+
+ @Test
+ public void requireThatHashCodeIsImplemented() {
+ assertEquals(new Disjunction().hashCode(), new Disjunction().hashCode());
+ }
+
+ @Test
+ public void requireThatEqualsIsImplemented() {
+ Disjunction lhs = new Disjunction(SimplePredicates.newString("foo"),
+ SimplePredicates.newString("bar"));
+ assertTrue(lhs.equals(lhs));
+ assertFalse(lhs.equals(new Object()));
+
+ Disjunction rhs = new Disjunction();
+ assertFalse(lhs.equals(rhs));
+ rhs.addOperand(SimplePredicates.newString("foo"));
+ assertFalse(lhs.equals(rhs));
+ rhs.addOperand(SimplePredicates.newString("bar"));
+ assertTrue(lhs.equals(rhs));
+ }
+
+ @Test
+ public void requireThatNodeDelimiterIsOR() {
+ assertEquals("", newDisjunction().toString());
+ assertEquals("foo", newDisjunction("foo").toString());
+ assertEquals("foo or bar", newDisjunction("foo", "bar").toString());
+ assertEquals("foo or bar or baz", newDisjunction("foo", "bar", "baz").toString());
+ }
+
+ @Test
+ public void requireThatSimpleDisjunctionsArePrettyPrinted() {
+ assertEquals("foo or bar",
+ new Disjunction(SimplePredicates.newString("foo"),
+ SimplePredicates.newString("bar")).toString());
+ }
+
+ @Test
+ public void requireThatComplexDisjunctionsArePrintedAsGroup() {
+ assertEquals("foo or bar or baz",
+ new Disjunction(SimplePredicates.newString("foo"),
+ new Disjunction(SimplePredicates.newString("bar"),
+ SimplePredicates.newString("baz"))).toString());
+ assertEquals("foo or (bar and baz)",
+ new Disjunction(SimplePredicates.newString("foo"),
+ new Conjunction(SimplePredicates.newString("bar"),
+ SimplePredicates.newString("baz"))).toString());
+ }
+
+ private static Disjunction newDisjunction(String... operands) {
+ return new Disjunction(SimplePredicates.newStrings(operands));
+ }
+
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/FeatureConjunctionTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/FeatureConjunctionTest.java
new file mode 100644
index 00000000000..e98400e86fa
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/FeatureConjunctionTest.java
@@ -0,0 +1,52 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static com.yahoo.document.predicate.Predicates.feature;
+import static com.yahoo.document.predicate.Predicates.not;
+
+/**
+ * @author bjorncs
+ */
+public class FeatureConjunctionTest {
+
+ @Test
+ public void require_that_featureconjunction_with_valid_operands_can_be_constructed() {
+ new FeatureConjunction(Arrays.asList(
+ not(feature("a").inSet("1")),
+ feature("b").inSet("1")));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void require_that_constructor_throws_exception_if_all_operands_are_not_featuresets() {
+ new FeatureConjunction(Arrays.asList(
+ not(feature("a").inSet("1")),
+ feature("b").inRange(1, 2)));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void require_that_constructor_throws_exception_if_single_operand() {
+ new FeatureConjunction(Arrays.asList(feature("a").inSet("1")));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void require_that_constructor_throws_exception_if_no_operands() {
+ new FeatureConjunction(Collections.emptyList());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void require_that_contructor_throws_exception_if_featuresets_contain_multiple_values() {
+ new FeatureConjunction(Arrays.asList(feature("a").inSet("1"), feature("b").inSet("2", "3")));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void require_that_constructor_throws_exception_if_featureset_keys_are_not_unique() {
+ new FeatureConjunction(Arrays.asList(
+ not(feature("a").inSet("1")),
+ feature("a").inSet("2")));
+ }
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/FeatureRangeTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/FeatureRangeTest.java
new file mode 100644
index 00000000000..efcc0e5b64a
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/FeatureRangeTest.java
@@ -0,0 +1,263 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ */
+public class FeatureRangeTest {
+
+ @Test
+ public void requireThatFeatureRangeIsAValue() {
+ assertTrue(PredicateValue.class.isAssignableFrom(FeatureRange.class));
+ }
+
+ @Test
+ public void requireThatAccessorsWork() {
+ FeatureRange node = new FeatureRange("foo");
+ assertEquals("foo", node.getKey());
+ node.setKey("bar");
+ assertEquals("bar", node.getKey());
+
+ node.setFromInclusive(69L);
+ assertEquals(69, node.getFromInclusive().intValue());
+ node.setFromInclusive(null);
+ assertNull(node.getFromInclusive());
+
+ node.setToInclusive(69L);
+ assertEquals(69, node.getToInclusive().intValue());
+ node.setToInclusive(null);
+ assertNull(node.getToInclusive());
+ }
+
+ @Test
+ public void requireThatConstructorsWork() {
+ FeatureRange node = new FeatureRange("foo");
+ assertEquals("foo", node.getKey());
+ assertNull(node.getFromInclusive());
+ assertNull(node.getToInclusive());
+
+ node = new FeatureRange("foo", null, null);
+ assertEquals("foo", node.getKey());
+ assertNull(node.getFromInclusive());
+ assertNull(node.getToInclusive());
+
+ node = new FeatureRange("foo", 69L, null);
+ assertEquals("foo", node.getKey());
+ assertEquals(69, node.getFromInclusive().intValue());
+ assertNull(node.getToInclusive());
+
+ node = new FeatureRange("foo", null, 69L);
+ assertEquals("foo", node.getKey());
+ assertNull(node.getFromInclusive());
+ assertEquals(69, node.getToInclusive().intValue());
+
+ node = new FeatureRange("foo", 6L, 9L);
+ assertEquals("foo", node.getKey());
+ assertEquals(6, node.getFromInclusive().intValue());
+ assertEquals(9, node.getToInclusive().intValue());
+ }
+
+ @Test
+ public void requireThatCloneIsImplemented() throws CloneNotSupportedException {
+ FeatureRange node1 = new FeatureRange("foo", 6L, 9L);
+ FeatureRange node2 = node1.clone();
+ assertEquals(node1, node2);
+ assertNotSame(node1, node2);
+ }
+
+ @Test
+ public void requireThatHashCodeIsImplemented() {
+ assertEquals(new FeatureRange("key").hashCode(), new FeatureRange("key").hashCode());
+ }
+
+ @Test
+ public void requireThatEqualsIsImplemented() {
+ FeatureRange lhs = new FeatureRange("foo", 6L, 9L);
+ assertTrue(lhs.equals(lhs));
+ assertFalse(lhs.equals(new Object()));
+
+ FeatureRange rhs = new FeatureRange("bar");
+ assertFalse(lhs.equals(rhs));
+ rhs.setKey("foo");
+ assertFalse(lhs.equals(rhs));
+ rhs.setFromInclusive(6L);
+ assertFalse(lhs.equals(rhs));
+ rhs.setToInclusive(9L);
+ assertTrue(lhs.equals(rhs));
+ rhs.addPartition(new RangePartition("foo"));
+ assertFalse(lhs.equals(rhs));
+ lhs.addPartition(new RangePartition("foo"));
+ assertTrue(lhs.equals(rhs));
+ rhs.addPartition(new RangeEdgePartition("foo", 10, 0, 2));
+ assertFalse(lhs.equals(rhs));
+ lhs.addPartition(new RangeEdgePartition("foo", 10, 0, 2));
+ assertTrue(lhs.equals(rhs));
+ }
+
+ @Test
+ public void requireThatFeatureKeyIsMandatoryInConstructor() {
+ try {
+ new FeatureRange(null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("key", e.getMessage());
+ }
+ }
+
+ @Test
+ public void requireThatFeatureKeyIsMandatoryInSetter() {
+ FeatureRange node = new FeatureRange("foo");
+ try {
+ node.setKey(null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("key", e.getMessage());
+ }
+ assertEquals("foo", node.getKey());
+ }
+
+ @Test
+ public void requireThatRangeCanBeSingleValue() {
+ FeatureRange node = new FeatureRange("key", 6L, 6L);
+ assertEquals(6, node.getFromInclusive().intValue());
+ assertEquals(6, node.getToInclusive().intValue());
+ node.setToInclusive(9L);
+ node.setFromInclusive(9L);
+ assertEquals(9, node.getFromInclusive().intValue());
+ assertEquals(9, node.getToInclusive().intValue());
+ }
+
+ @Test
+ public void requireThatFromCanNotBeConstructedGreaterThanTo() {
+ try {
+ new FeatureRange("key", 9L, 6L);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("Expected 'to' greater than or equal to 9, got 6.", e.getMessage());
+ }
+ }
+
+ @Test
+ public void requireThatFromCanNotBeSetGreaterThanTo() {
+ FeatureRange node = new FeatureRange("key", null, 6L);
+ try {
+ node.setFromInclusive(9L);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("Expected 'from' less than or equal to 6, got 9.", e.getMessage());
+ }
+ assertNull(node.getFromInclusive());
+
+ node = new FeatureRange("key", 6L, 9L);
+ try {
+ node.setFromInclusive(69L);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("Expected 'from' less than or equal to 9, got 69.", e.getMessage());
+ }
+ assertEquals(6, node.getFromInclusive().intValue());
+ }
+
+ @Test
+ public void requireThatToCanNotBeSetLessThanFrom() {
+ FeatureRange node = new FeatureRange("key", 9L, null);
+ try {
+ node.setToInclusive(6L);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("Expected 'to' greater than or equal to 9, got 6.", e.getMessage());
+ }
+ assertNull(node.getToInclusive());
+
+ node = new FeatureRange("key", 6L, 9L);
+ try {
+ node.setToInclusive(1L);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertEquals("Expected 'to' greater than or equal to 6, got 1.", e.getMessage());
+ }
+ assertEquals(9, node.getToInclusive().intValue());
+ }
+
+ @Test
+ public void requireThatKeyIsEscapedInToString() {
+ assertEquals("foo in [6..9]",
+ new FeatureRange("foo", 6L, 9L).toString());
+ assertEquals("'\\foo' in [6..9]",
+ new FeatureRange("\foo", 6L, 9L).toString());
+ assertEquals("'\\x27foo\\x27' in [6..9]",
+ new FeatureRange("'foo'", 6L, 9L).toString());
+ }
+
+ @Test
+ public void requireThatToStringIncludesLimits() {
+ assertEquals("foo in [6..9]", new FeatureRange("foo", 6L, 9L).toString());
+ }
+
+ @Test
+ public void requireThatToStringAllowsNullLimits() {
+ assertEquals("foo in [..]", new FeatureRange("foo").toString());
+ }
+
+ @Test
+ public void requireThatToStringAllowsNullFromLimit() {
+ assertEquals("foo in [..69]", new FeatureRange("foo", null, 69L).toString());
+ }
+
+ @Test
+ public void requireThatToStringAllowsNullToLimit() {
+ assertEquals("foo in [69..]", new FeatureRange("foo", 69L, null).toString());
+ }
+
+ @Test
+ public void requireThatSimpleStringsArePrettyPrinted() {
+ assertEquals("foo in [6..9]",
+ new FeatureRange("foo", 6L, 9L).toString());
+ }
+
+ @Test
+ public void requireThatComplexStringsAreEscaped() {
+ assertEquals("'\\foo' in [6..9]",
+ new FeatureRange("\foo", 6L, 9L).toString());
+ }
+
+ @Test
+ public void requireThatRangePartitionsCanBeAdded() {
+ FeatureRange range = new FeatureRange("foo", 10L, 22L);
+ range.addPartition(new RangePartition("foo=10-19"));
+ range.addPartition(new RangePartition("foo", 0, 0x8000000000000000L, true));
+ range.addPartition(new RangeEdgePartition("foo=20", 20, 0, 2));
+ assertEquals("foo in [10..22 (foo=20+[..2],foo=10-19,foo=-9223372036854775808-0)]", range.toString());
+ }
+
+ @Test
+ public void requireThatRangePartitionsCanBeCleared() {
+ FeatureRange range = new FeatureRange("foo", 10L, 22L);
+ range.addPartition(new RangePartition("foo=10-19"));
+ range.addPartition(new RangeEdgePartition("foo=20", 20, 0, 2));
+ assertEquals("foo in [10..22 (foo=20+[..2],foo=10-19)]", range.toString());
+ range.clearPartitions();
+ assertEquals("foo in [10..22]", range.toString());
+ }
+
+ @Test
+ public void requireThatFeatureRangeCanBeBuiltFromMixedInNode() {
+ assertEquals(new FeatureRange("foo", 10L, 19L),
+ FeatureRange.buildFromMixedIn("foo", Arrays.asList("foo=10-19"), 10));
+ assertEquals(new FeatureRange("foo", -19L, -10L),
+ FeatureRange.buildFromMixedIn("foo", Arrays.asList("foo=-10-19"), 10));
+ assertEquals(new FeatureRange("foo", 10L, 19L),
+ FeatureRange.buildFromMixedIn("foo", Arrays.asList("foo=10,10,9"), 10));
+ assertEquals(new FeatureRange("foo", 10L, 19L),
+ FeatureRange.buildFromMixedIn("foo", Arrays.asList("foo=10,10,1073741833"), 10));
+ assertEquals(new FeatureRange("foo", 10L, 19L),
+ FeatureRange.buildFromMixedIn("foo", Arrays.asList("foo=10,10,2147483648"), 10));
+ }
+
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/FeatureSetTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/FeatureSetTest.java
new file mode 100644
index 00000000000..7bc9d5f2c04
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/FeatureSetTest.java
@@ -0,0 +1,180 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ */
+public class FeatureSetTest {
+
+ @Test
+ public void requireThatFeatureSetIsAValue() {
+ assertTrue(PredicateValue.class.isAssignableFrom(FeatureSet.class));
+ }
+
+ @Test
+ public void requireThatAccessorsWork() {
+ FeatureSet node = new FeatureSet("key", "valueA", "valueB");
+ assertEquals("key", node.getKey());
+ assertValues(Arrays.asList("valueA", "valueB"), node);
+ node.addValue("valueC");
+ assertValues(Arrays.asList("valueA", "valueB", "valueC"), node);
+ node.addValues(Arrays.asList("valueD", "valueE"));
+ assertValues(Arrays.asList("valueA", "valueB", "valueC", "valueD", "valueE"), node);
+ node.setValues(Arrays.asList("valueF", "valueG"));
+ assertValues(Arrays.asList("valueF", "valueG"), node);
+ }
+
+ @Test
+ public void requireThatValueSetIsMutable() {
+ FeatureSet node = new FeatureSet("key");
+ node.getValues().add("valueA");
+ assertValues(Arrays.asList("valueA"), node);
+
+ node = new FeatureSet("key", "valueA");
+ node.getValues().add("valueB");
+ assertValues(Arrays.asList("valueA", "valueB"), node);
+ }
+
+ @Test
+ public void requireThatConstructorsWork() {
+ FeatureSet node = new FeatureSet("key", "valueA", "valueB");
+ assertEquals("key", node.getKey());
+ assertValues(Arrays.asList("valueA", "valueB"), node);
+
+ node = new FeatureSet("key", Arrays.asList("valueA", "valueB"));
+ assertEquals("key", node.getKey());
+ assertValues(Arrays.asList("valueA", "valueB"), node);
+ }
+
+ @Test
+ public void requireThatCloneIsImplemented() throws CloneNotSupportedException {
+ FeatureSet node1 = new FeatureSet("key", "valueA", "valueB");
+ FeatureSet node2 = node1.clone();
+ assertEquals(node1, node2);
+ assertNotSame(node1, node2);
+ assertNotSame(node1.getValues(), node2.getValues());
+ }
+
+ @Test
+ public void requireThatHashCodeIsImplemented() {
+ assertEquals(new FeatureSet("key").hashCode(), new FeatureSet("key").hashCode());
+ }
+
+ @Test
+ public void requireThatEqualsIsImplemented() {
+ FeatureSet lhs = new FeatureSet("keyA", "valueA", "valueB");
+ assertTrue(lhs.equals(lhs));
+ assertFalse(lhs.equals(new Object()));
+
+ FeatureSet rhs = new FeatureSet("keyB");
+ assertFalse(lhs.equals(rhs));
+ rhs.setKey("keyA");
+ assertFalse(lhs.equals(rhs));
+ rhs.addValue("valueA");
+ assertFalse(lhs.equals(rhs));
+ rhs.addValue("valueB");
+ assertTrue(lhs.equals(rhs));
+ }
+
+ @Test
+ public void requireThatkeyIsMandatoryInConstructor() {
+ try {
+ new FeatureSet(null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("key", e.getMessage());
+ }
+ try {
+ new FeatureSet(null, Collections.<String>emptyList());
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("key", e.getMessage());
+ }
+ }
+
+ @Test
+ public void requireThatkeyIsMandatoryInSetter() {
+ FeatureSet node = new FeatureSet("foo");
+ try {
+ node.setKey(null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("key", e.getMessage());
+ }
+ assertEquals("foo", node.getKey());
+ }
+
+ @Test
+ public void requireThatValueIsMandatoryInSetter() {
+ FeatureSet node = new FeatureSet("foo", "bar");
+ try {
+ node.addValue(null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("value", e.getMessage());
+ }
+ assertValues(Arrays.asList("bar"), node);
+ }
+
+ @Test
+ public void requireThatKeyIsEscapedInToString() {
+ assertEquals("foo in [val]",
+ new FeatureSet("foo", "val").toString());
+ assertEquals("'\\foo' in [val]",
+ new FeatureSet("\foo", "val").toString());
+ assertEquals("'\\x27foo\\x27' in [val]",
+ new FeatureSet("'foo'", "val").toString());
+ }
+
+ @Test
+ public void requireThatValuesAreEscapedInToString() {
+ assertEquals("key in [bar, foo]",
+ new FeatureSet("key", "foo", "bar").toString());
+ assertEquals("key in ['\\foo', 'ba\\r']",
+ new FeatureSet("key", "\foo", "ba\r").toString());
+ assertEquals("key in ['\\x27bar\\x27', '\\x27foo\\x27']",
+ new FeatureSet("key", "'foo'", "'bar'").toString());
+ }
+
+ @Test
+ public void requireThatSimpleStringsArePrettyPrinted() {
+ assertEquals("foo in [bar]",
+ new FeatureSet("foo", "bar").toString());
+ }
+
+ @Test
+ public void requireThatComplexStringsAreEscaped() {
+ assertEquals("'\\foo' in ['ba\\r']",
+ new FeatureSet("\foo", "ba\r").toString());
+ }
+
+ @Test
+ public void requireThatNegatedFeatureSetsArePrettyPrinted() {
+ assertEquals("country not in [no, se]",
+ new Negation(new FeatureSet("country", "no", "se")).toString());
+ }
+
+ private static void assertValues(Collection<String> expected, FeatureSet actual) {
+ List<String> tmp = new ArrayList<>(expected);
+ for (String value : actual.getValues()) {
+ assertNotNull(value, tmp.remove(value));
+ }
+ assertTrue(tmp.toString(), tmp.isEmpty());
+ }
+
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/NegationTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/NegationTest.java
new file mode 100644
index 00000000000..95666342152
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/NegationTest.java
@@ -0,0 +1,89 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ */
+public class NegationTest {
+
+ @Test
+ public void requireThatNegationIsAnOperator() {
+ assertTrue(PredicateOperator.class.isAssignableFrom(Negation.class));
+ }
+
+ @Test
+ public void requireThatAccessorsWork() {
+ Predicate foo = SimplePredicates.newString("foo");
+ Negation node = new Negation(foo);
+ assertSame(foo, node.getOperand());
+
+ Predicate bar = SimplePredicates.newString("bar");
+ node.setOperand(bar);
+ assertSame(bar, node.getOperand());
+ }
+
+ @Test
+ public void requireThatCloneIsImplemented() throws CloneNotSupportedException {
+ Negation node1 = new Negation(SimplePredicates.newString("a"));
+ Negation node2 = node1.clone();
+ assertEquals(node1, node2);
+ assertNotSame(node1, node2);
+ assertNotSame(node1.getOperand(), node2.getOperand());
+ }
+
+ @Test
+ public void requireThatHashCodeIsImplemented() {
+ Predicate predicate = SimplePredicates.newPredicate();
+ assertEquals(new Negation(predicate).hashCode(), new Negation(predicate).hashCode());
+ }
+
+ @Test
+ public void requireThatEqualsIsImplemented() {
+ Negation lhs = new Negation(SimplePredicates.newString("foo"));
+ assertTrue(lhs.equals(lhs));
+ assertFalse(lhs.equals(new Object()));
+
+ Negation rhs = new Negation(SimplePredicates.newString("bar"));
+ assertFalse(lhs.equals(rhs));
+ rhs.setOperand(SimplePredicates.newString("foo"));
+ assertTrue(lhs.equals(rhs));
+ }
+
+ @Test
+ public void requireThatChildIsMandatoryInConstructor() {
+ try {
+ new Negation(null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("operand", e.getMessage());
+ }
+ }
+
+ @Test
+ public void requireThatChildIsMandatoryInSetter() {
+ Predicate operand = SimplePredicates.newPredicate();
+ Negation negation = new Negation(operand);
+ try {
+ negation.setOperand(null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("operand", e.getMessage());
+ }
+ assertSame(operand, negation.getOperand());
+ }
+
+ @Test
+ public void requireThatChildIsIncludedInToString() {
+ assertEquals("not (foo)", new Negation(SimplePredicates.newString("foo")).toString());
+ }
+
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateHashTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateHashTest.java
new file mode 100644
index 00000000000..759bfe9f48f
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateHashTest.java
@@ -0,0 +1,102 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author <a href="mailto:magnarn@yahoo-inc.com">Magnar Nedland</a>
+ */
+public class PredicateHashTest{
+ @Test
+ public void requireThatShortStringsGetsHashes() {
+ assertHashesTo(0x82af3d1de65ec252L, "abcdefg");
+ assertHashesTo(0xdc50d922fb0e91d6L, "雅虎");
+ assertHashesTo(0x709bd6ff1a84dc14L, "country=日本");
+ assertHashesTo(0x28e8de732ab0e809L, "foo");
+
+ assertHashesTo(0x8db63936938575bfL, "");
+ assertHashesTo(0x1d48fd74d88633acL, "a");
+ assertHashesTo(0xd30019bef51f4a75L, "ab");
+ assertHashesTo(0x9cb12e2bfea87243L, "abc");
+ assertHashesTo(0x207e64432ec23f4bL, "abcd");
+ assertHashesTo(0xbb1277971caf7a56L, "abcde");
+ assertHashesTo(0xfde595baae539176L, "abcdef");
+ assertHashesTo(0x82af3d1de65ec252L, "abcdefg");
+ assertHashesTo(0x1cac1cd5db905a5fL, "abcdefgh");
+ assertHashesTo(0x1ce1c26a201525deL, "abcdefghi");
+ assertHashesTo(0x2237a417a20c1025L, "abcdefghij");
+ assertHashesTo(0xd98f47421abc3754L, "abcdefghijk");
+ assertHashesTo(0xb974917101764d3aL, "abcdefghijkl");
+ assertHashesTo(0xde3b7ffe3e6dd61fL, "abcdefghijklm");
+ assertHashesTo(0x31d95fa68634f482L, "abcdefghijklmn");
+ assertHashesTo(0xde99d87fdbeca8faL, "abcdefghijklmn1");
+ assertHashesTo(0x0afc8571f275c392L, "abcdefghijklmn12");
+ assertHashesTo(0xbd00379443b0606cL, "abcdefghijklmn123");
+ assertHashesTo(0x855c704c68e095c5L, "abcdefghijklmn1234");
+ assertHashesTo(0xe9233cb6e4fad097L, "abcdefghijklmn12345");
+ assertHashesTo(0x1103ca46bd6e8d2fL, "abcdefghijklmn123456");
+ assertHashesTo(0x0c7097be717354d1L, "abcdefghijklmn1234567");
+ assertHashesTo(0x3e75293210127583L, "abcdefghijklmn12345678");
+ assertHashesTo(0xa66286e1294d8197L, "abcdefghijklmn123456789");
+ assertHashesTo(0x79fac97d13f4cc84L, "abcdefghijklmn1234567890");
+ }
+
+ @Test
+ public void requireThatLongStringsGetsHashes() {
+ assertHashesTo(0x79fac97d13f4cc84L, "abcdefghijklmn1234567890");
+ assertHashesTo(0xd7af1798f1d5de44L, "abcdefghijklmn1234567890a");
+ assertHashesTo(0x5a259ad887478cccL, "abcdefghijklmn1234567890ab");
+ assertHashesTo(0x4e8d95bab8d64191L, "abcdefghijklmn1234567890abc");
+ assertHashesTo(0xf63b94d31db2fe1aL, "abcdefghijklmn1234567890abcd");
+ assertHashesTo(0x47a1977d65709aceL, "abcdefghijklmn1234567890abcde");
+ assertHashesTo(0x52e1fb6d6aff3aeeL, "abcdefghijklmn1234567890abcdef");
+ assertHashesTo(0xc16de639b6e69ad3L, "abcdefghijklmn1234567890abcdefg");
+ assertHashesTo(0x87c22dd1e285dd6fL, "abcdefghijklmn1234567890abcdefgh");
+ assertHashesTo(0x775a3542d88b4972L, "abcdefghijklmn1234567890abcdefghi");
+ assertHashesTo(0x7b0c82116edf338bL, "abcdefghijklmn1234567890abcdefghij");
+ assertHashesTo(0x0fe73b58f6b23cb6L, "abcdefghijklmn1234567890abcdefghijk");
+ assertHashesTo(0x27ab8d02387e64e0L, "abcdefghijklmn1234567890abcdefghijkl");
+ assertHashesTo(0xdd161af20b41be04L, "abcdefghijklmn1234567890abcdefghijklm");
+ assertHashesTo(0x67739554f61fffcbL, "abcdefghijklmn1234567890abcdefghijklmn");
+ assertHashesTo(0xa765cc6be247dfb2L, "abcdefghijklmn1234567890abcdefghijklmn1");
+ assertHashesTo(0x9e201896cc600501L, "abcdefghijklmn1234567890abcdefghijklmn12");
+ assertHashesTo(0xfc5077792bfed491L, "abcdefghijklmn1234567890abcdefghijklmn123");
+ assertHashesTo(0x96a7acb73fd13601L, "abcdefghijklmn1234567890abcdefghijklmn1234");
+ assertHashesTo(0x45de4237e48a0ba8L, "abcdefghijklmn1234567890abcdefghijklmn12345");
+ assertHashesTo(0x3b65da96300e107eL, "abcdefghijklmn1234567890abcdefghijklmn123456");
+ assertHashesTo(0xbd95c3591ee587bdL, "abcdefghijklmn1234567890abcdefghijklmn1234567");
+ assertHashesTo(0x2688cb2d10e8629bL, "abcdefghijklmn1234567890abcdefghijklmn12345678");
+ assertHashesTo(0xcd383d98f9483ef0L, "abcdefghijklmn1234567890abcdefghijklmn123456789");
+ assertHashesTo(0x220e374268970e84L, "abcdefghijklmn1234567890abcdefghijklmn1234567890");
+ assertHashesTo(0xd50ef002ed96bf0bL, "abcdefghijklmn1234567890abcdefghijklmn1234567890a");
+ assertHashesTo(0x5ec9b42099bb25c6L, "abcdefghijklmn1234567890abcdefghijklmn1234567890ab");
+ assertHashesTo(0x05c603997a19dbceL, "abcdefghijklmn1234567890abcdefghijklmn1234567890abc");
+ assertHashesTo(0xcee3fce2a3e38762L, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcd");
+ assertHashesTo(0xc0d9791b19897f0aL, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcde");
+ assertHashesTo(0xde98d0f8250ec703L, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdef");
+ assertHashesTo(0xa7688d5834fa7d2aL, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefg");
+ assertHashesTo(0xad514e8250667cdeL, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefgh");
+ assertHashesTo(0xf562662deca536c3L, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghi");
+ assertHashesTo(0x9d1b8d2463cde877L, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghij");
+ assertHashesTo(0x24840f21eeb30861L, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijk");
+ assertHashesTo(0x40af2a3f14d31fdaL, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijkl");
+ assertHashesTo(0x3514ad5e964b5c73L, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijklm");
+ assertHashesTo(0x7bd6243490571844L, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijklmn");
+ assertHashesTo(0x273de93a3bddd9e8L, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijklmn1");
+ assertHashesTo(0x18e6850c3e2f85beL, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijklmn12");
+ assertHashesTo(0x044968ddc534d822L, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijklmn123");
+ assertHashesTo(0x7430d9d503fe624dL, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijklmn1234");
+ assertHashesTo(0xf0bb1e5239c1d88cL, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijklmn12345");
+ assertHashesTo(0x2ee1ab348b7deaa0L, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijklmn123456");
+ assertHashesTo(0x18b6da5df76680dfL, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijklmn1234567");
+ assertHashesTo(0x06c95ee4ddc93743L, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijklmn12345678");
+ assertHashesTo(0x6406e477d8ca608dL, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijklmn123456789");
+ assertHashesTo(0x203397a04178d470L, "abcdefghijklmn1234567890abcdefghijklmn1234567890abcdefghijklmn1234567890");
+ }
+
+ private void assertHashesTo(long hash, String key) {
+ assertEquals(hash, PredicateHash.hash64(key));
+ }
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateOperatorTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateOperatorTest.java
new file mode 100644
index 00000000000..b6de0bf3514
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateOperatorTest.java
@@ -0,0 +1,17 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ */
+public class PredicateOperatorTest {
+
+ @Test
+ public void requireThatOperatorIsAPredicate() {
+ assertTrue(Predicate.class.isAssignableFrom(PredicateOperator.class));
+ }
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateParserTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateParserTest.java
new file mode 100644
index 00000000000..ee161c20feb
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateParserTest.java
@@ -0,0 +1,155 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * @author <a href="mailto:magnarn@yahoo-inc.com">Magnar Nedland</a>
+ */
+
+public class PredicateParserTest {
+
+ @Test
+ public void requireThatParseErrorThrowsException() {
+ try {
+ Predicate.fromString("a in b");
+ fail("Expected an exception");
+ } catch (IllegalArgumentException e) {
+ assertEquals("line 1:5 no viable alternative at input 'b'", e.getMessage());
+ }
+ }
+
+ @Test
+ public void requireThatLexerErrorThrowsException() {
+ try {
+ Predicate.fromString("a-b in [b]");
+ fail("Expected an exception");
+ } catch (IllegalArgumentException e) {
+ assertEquals("line 1:2 no viable alternative at character 'b'", e.getMessage());
+ }
+ }
+
+ @Test
+ public void requireThatSingleValueLeafNodesParse() {
+ assertParsesTo("a in [b]", "a in [b]");
+ assertParsesTo("0 in [1]", "0 in [1]");
+ assertParsesTo("in in [in]", "in in [in]");
+ assertParsesTo("and in [or]", "and in [or]");
+ assertParsesTo("not in [not]", "not in [not]");
+ assertParsesTo("'-234' in ['+200']", "'-234' in ['+200']");
+ assertParsesTo("string in ['!@#$%^&*()[]']", "'string' in ['!@#$%^&*()[]']");
+ assertParsesTo("a in [b]", "a in [b]");
+ assertParsesTo("string in ['foo\\\\_\"\\t\\n\\f\\rbar']",
+ "string in ['foo\\\\_\\x22\\t\\n\\f\\rbar']");
+ assertParsesTo("'\\xC3\\xB8' in [b]", "'ø' in [b]");
+ assertParsesTo("'\\xEF\\xBF\\xBD' in [b]", "'\\xf8' in [b]");
+ assertParsesTo("'\\xEF\\xBF\\xBD' in [b]", "'\\xef\\xbf\\xbd' in ['b']");
+ assertParsesTo("'\\xE4\\xB8\\x9C\\xE8\\xA5\\xBF' in ['\\xE8\\x87\\xAA\\xE8\\xA1\\x8C\\xE8\\xBD\\xA6']",
+ "'东西' in ['自行车']");
+ assertParsesTo("true in [false]", "true in [false]");
+ }
+
+ @Test
+ public void requireThatMultiValueLeafNodesParse() {
+ assertParsesTo("a in [b]", "a in [b]");
+ assertParsesTo("0 in [1]", "0 in [1]");
+ assertParsesTo("in in [and, in]", "in in [in, and]");
+ assertParsesTo("a in [b, c, d, e, f]", "'a' in ['b', 'c', 'd', 'e', 'f']");
+ }
+
+ @Test
+ public void requireThatBothSingleAndDoubleQuotesWork() {
+ assertParsesTo("a in [b]", "'a' in ['b']");
+ assertParsesTo("a in [b]", "\"a\" in [\"b\"]");
+ assertParsesTo("'a\\x27' in [b]", "'a\\'' in ['b']");
+ assertParsesTo("'a\"' in [b]", "\"a\\\"\" in [\"b\"]");
+ }
+
+ @Test
+ public void requireThatRangeLeafNodesParse() {
+ assertParsesTo("a in [0..100]", "a in [0..100]");
+ assertParsesTo("0 in [..100]", "0 in [..100]");
+ assertParsesTo("0 in [0..]", "0 in [0..]");
+ assertParsesTo("0 in [..]", "0 in [..]");
+ assertParsesTo("a in [-100..100]", "a in [-100..+100]");
+ assertParsesTo("a in [-9223372036854775808..9223372036854775807]",
+ "a in [-9223372036854775808..+9223372036854775807]");
+ }
+
+ @Test
+ public void requireThatRangePartitionsAreIgnored() {
+ assertParsesTo("a in [0..100]", "a in [0..100 (a=0-99,a=100+[..0])]");
+ assertParsesTo("a in [-100..0]", "a in [-100..0 (a=-0-99,a=-100+[..0])]");
+ assertParsesTo("a in [-9223372036854775808..0]", "a in [-9223372036854775808..0 (a=-0-9223372036854775808)]");
+ assertParsesTo("a in [2..8]", "a in [2..8 (a=0+[2..8])]");
+ assertParsesTo("a in [0..8]", "a in [0..8 (a=0+[..8])]");
+ assertParsesTo("a in [2..9]", "a in [2..9 (a=0+[2..])]");
+ }
+
+ @Test
+ public void requireThatNotInSetWorks() {
+ assertParsesTo("a not in [b]", "a not in [b]");
+ }
+
+ @Test
+ public void requireThatConjunctionWorks() {
+ assertParsesTo("a in [b] and c in [d]", "a in [b] and c in [d]");
+ assertParsesTo("a in [b] and c in [d] and e in [f]", "a in [b] and c in [d] and e in [f]");
+ }
+
+ @Test
+ public void requireThatDisjunctionWorks() {
+ assertParsesTo("a in [b] or c in [d]", "a in [b] or c in [d]");
+ assertParsesTo("a in [b] or c in [d] or e in [f]", "a in [b] or c in [d] or e in [f]");
+ }
+
+ @Test
+ public void requireThatParenthesesWorks() {
+ assertParsesTo("a in [b] or c in [d]",
+ "(a in [b]) or (c in [d])");
+ assertParsesTo("a in [b] or c in [d] or e in [f]",
+ "(((a in [b]) or c in [d]) or e in [f])");
+ assertParsesTo("(a in [b] and c in [d]) or e in [f]",
+ "a in [b] and c in [d] or e in [f]");
+ assertParsesTo("a in [b] and (c in [d] or e in [f])",
+ "a in [b] and (c in [d] or e in [f])");
+ assertParsesTo("a in [b] and (c in [d] or e in [f]) and g in [h]",
+ "a in [b] and (c in [d] or e in [f]) and g in [h]");
+ }
+
+ @Test
+ public void requireThatNotOutsideParenthesesWorks() {
+ assertParsesTo("a not in [b]", "not (a in [b])");
+ }
+
+ @Test
+ public void requireThatConjunctionsCanGetMoreThanTwoChildren() {
+ Predicate p = Predicate.fromString("a in [b] and c in [d] and e in [f] and g in [h]");
+ assertTrue(p instanceof Conjunction);
+ assertEquals(4, ((Conjunction)p).getOperands().size());
+ }
+
+ @Test
+ public void requireThatDisjunctionsCanGetMoreThanTwoChildren() {
+ Predicate p = Predicate.fromString("a in [b] or c in [d] or e in [f] or g in [h]");
+ assertTrue(p instanceof Disjunction);
+ assertEquals(4, ((Disjunction)p).getOperands().size());
+ }
+
+ @Test
+ public void requireThatBooleanCanBeParsed() {
+ assertParsesTo("true", "true");
+ assertParsesTo("false", "false");
+ assertParsesTo("true or false", "true or false");
+ assertParsesTo("false and true", "false and true");
+ }
+
+ private static void assertParsesTo(String expected, String predicate_str) {
+ assertEquals(expected, // TODO: Predicate.fromString(expected)
+ Predicate.fromString(predicate_str).toString());
+ }
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateTest.java
new file mode 100644
index 00000000000..621378f394b
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateTest.java
@@ -0,0 +1,110 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import static com.yahoo.document.predicate.Predicates.and;
+import static com.yahoo.document.predicate.Predicates.feature;
+import static com.yahoo.document.predicate.Predicates.not;
+import static com.yahoo.document.predicate.Predicates.or;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ */
+public class PredicateTest {
+
+ @Test
+ public void requireThatPredicateIsCloneable() {
+ assertTrue(Cloneable.class.isAssignableFrom(Predicate.class));
+ }
+
+ @Test
+ public void requireThatANDConstructsAConjunction() {
+ Predicate foo = SimplePredicates.newString("foo");
+ Predicate bar = SimplePredicates.newString("bar");
+ Predicate predicate = and(foo, bar);
+ assertEquals(Conjunction.class, predicate.getClass());
+ assertEquals(new Conjunction(foo, bar), predicate);
+ }
+
+ @Test
+ public void requireThatORConstructsADisjunction() {
+ Predicate foo = SimplePredicates.newString("foo");
+ Predicate bar = SimplePredicates.newString("bar");
+ Predicate predicate = or(foo, bar);
+ assertEquals(Disjunction.class, predicate.getClass());
+ assertEquals(new Disjunction(foo, bar), predicate);
+ }
+
+ @Test
+ public void requireThatNOTConstructsANegation() {
+ Predicate foo = SimplePredicates.newString("foo");
+ Predicate predicate = not(foo);
+ assertEquals(Negation.class, predicate.getClass());
+ assertEquals(new Negation(foo), predicate);
+ }
+
+ @Test
+ public void requireThatFeatureBuilderCanConstructFeatureRange() {
+ assertEquals(new FeatureRange("key", 6L, 9L),
+ feature("key").inRange(6, 9));
+ assertEquals(new Negation(new FeatureRange("key", 6L, 9L)),
+ feature("key").notInRange(6, 9));
+ assertEquals(new FeatureRange("key", 7L, null),
+ feature("key").greaterThan(6));
+ assertEquals(new FeatureRange("key", 6L, null),
+ feature("key").greaterThanOrEqualTo(6));
+ assertEquals(new FeatureRange("key", null, 5L),
+ feature("key").lessThan(6));
+ assertEquals(new FeatureRange("key", null, 9L),
+ feature("key").lessThanOrEqualTo(9));
+ }
+
+ @Test
+ public void requireThatFeatureBuilderCanConstructFeatureSet() {
+ assertEquals(new FeatureSet("key", "valueA", "valueB"),
+ feature("key").inSet("valueA", "valueB"));
+ assertEquals(new Negation(new FeatureSet("key", "valueA", "valueB")),
+ feature("key").notInSet("valueA", "valueB"));
+ }
+
+ @Test
+ public void requireThatPredicatesCanBeConstructedUsingConstructors() {
+ assertEquals("country in [no, se] and age in [20..30]",
+ new Conjunction(new FeatureSet("country", "no", "se"),
+ new FeatureRange("age", 20L, 30L)).toString());
+ assertEquals("country not in [no, se] or age in [20..] or height in [..160]",
+ new Disjunction(new Negation(new FeatureSet("country", "no", "se")),
+ new FeatureRange("age", 20L, null),
+ new FeatureRange("height", null, 160L)).toString());
+ }
+
+ @Test
+ public void requireThatPredicatesCanBeBuiltUsingChainedMethodCalls() {
+ assertEquals("country not in [no, se] or age in [20..] or height in [..160]",
+ new Disjunction()
+ .addOperand(new Negation(new FeatureSet("country").addValue("no").addValue("se")))
+ .addOperand(new FeatureRange("age").setFromInclusive(20L))
+ .addOperand(new FeatureRange("height").setToInclusive(160L))
+ .toString());
+ }
+
+ @Test
+ public void requireThatPredicatesCanBeBuiltUsingSeparateMethodCalls() {
+ Conjunction conjunction = new Conjunction();
+ FeatureSet countrySet = new FeatureSet("country");
+ countrySet.addValue("no");
+ countrySet.addValue("se");
+ conjunction.addOperand(countrySet);
+ FeatureRange ageRange = new FeatureRange("age");
+ ageRange.setFromInclusive(20L);
+ conjunction.addOperand(ageRange);
+ FeatureRange heightRange = new FeatureRange("height");
+ heightRange.setToInclusive(160L);
+ conjunction.addOperand(heightRange);
+ assertEquals("country in [no, se] and age in [20..] and height in [..160]",
+ conjunction.toString());
+ }
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateValueTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateValueTest.java
new file mode 100644
index 00000000000..810e9a8717c
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicateValueTest.java
@@ -0,0 +1,17 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ */
+public class PredicateValueTest {
+
+ @Test
+ public void requireThatValueIsAPredicate() {
+ assertTrue(Predicate.class.isAssignableFrom(PredicateValue.class));
+ }
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicatesTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicatesTest.java
new file mode 100644
index 00000000000..22832eedeff
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/PredicatesTest.java
@@ -0,0 +1,38 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import static com.yahoo.document.predicate.Predicates.and;
+import static com.yahoo.document.predicate.Predicates.feature;
+import static com.yahoo.document.predicate.Predicates.not;
+import static com.yahoo.document.predicate.Predicates.or;
+import static com.yahoo.document.predicate.Predicates.value;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ */
+public class PredicatesTest {
+
+ @Test
+ public void requireThatApiIsUsable() {
+ assertEquals(
+ new Disjunction(
+ new Conjunction(new FeatureSet("country", "de", "no"),
+ new Negation(new FeatureSet("gender", "female")),
+ new FeatureRange("age", 6L, 9L)),
+ new Conjunction(new Negation(new FeatureSet("country", "se")),
+ new FeatureSet("gender", "female"),
+ new FeatureRange("age", 69L, null))),
+ or(and(feature("country").inSet("de", "no"),
+ feature("gender").notInSet("female"),
+ feature("age").inRange(6, 9)),
+ and(not(feature("country").inSet("se")),
+ feature("gender").inSet("female"),
+ feature("age").greaterThanOrEqualTo(69))));
+
+ assertEquals(new BooleanPredicate(true), value(true));
+ assertEquals(new BooleanPredicate(false), value(false));
+ }
+}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/RangeEdgePartitionTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/RangeEdgePartitionTest.java
new file mode 100644
index 00000000000..d9f6714d8c8
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/RangeEdgePartitionTest.java
@@ -0,0 +1,62 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author <a href="mailto:magnarn@yahoo-inc.com">Magnar Nedland</a>
+ */
+public class RangeEdgePartitionTest {
+
+ @Test
+ public void requireThatRangeEdgePartitionIsAValue() {
+ assertTrue(PredicateValue.class.isAssignableFrom(RangeEdgePartition.class));
+ }
+
+ @Test
+ public void requireThatConstructorsWork() {
+ RangeEdgePartition part = new RangeEdgePartition("foo=10", 10, 0, -1);
+ assertEquals("foo=10", part.getLabel());
+ assertEquals(0, part.getLowerBound());
+ assertEquals(-1, part.getUpperBound());
+ }
+
+ @Test
+ public void requireThatCloneIsImplemented() throws CloneNotSupportedException {
+ RangeEdgePartition node1 = new RangeEdgePartition("foo=10", 10, 0, 0);
+ RangeEdgePartition node2 = node1.clone();
+ assertEquals(node1, node2);
+ assertNotSame(node1, node2);
+ }
+
+ @Test
+ public void requireThatHashCodeIsImplemented() {
+ assertEquals(new RangeEdgePartition("foo=-10", 10, 2, 3).hashCode(),
+ new RangeEdgePartition("foo=-10", 10, 2, 3).hashCode());
+ }
+
+ @Test
+ public void requireThatEqualsIsImplemented() {
+ RangeEdgePartition lhs = new RangeEdgePartition("foo=10", 10, 5, 10);
+ assertTrue(lhs.equals(lhs));
+ assertFalse(lhs.equals(new Object()));
+
+ RangeEdgePartition rhs = new RangeEdgePartition("foo=20", 20, 0, 0);
+ assertFalse(lhs.equals(rhs));
+ rhs = new RangeEdgePartition("foo=10", 10, 5, 10);
+ assertTrue(lhs.equals(rhs));
+ assertFalse(lhs.equals(new RangeEdgePartition("foo=10", 10, 5, 11)));
+ assertFalse(lhs.equals(new RangeEdgePartition("foo=10", 10, 6, 10)));
+ assertFalse(lhs.equals(new RangeEdgePartition("foo=10", 11, 5, 10)));
+ assertFalse(lhs.equals(new RangeEdgePartition("foo=11", 10, 5, 10)));
+ }
+
+ @Test
+ public void requireThatKeyIsEscapedInToString() {
+ assertEquals("foo=10+[2..3]", new RangeEdgePartition("foo=10", 10, 2, 3).toString());
+ assertEquals("'\\foo=10'+[2..3]", new RangeEdgePartition("\foo=10", 10, 2, 3).toString());
+ assertEquals("'\\x27foo\\x27=10'+[2..3]", new RangeEdgePartition("'foo'=10", 10, 2, 3).toString());
+ }}
diff --git a/predicate-search-core/src/test/java/com/yahoo/document/predicate/RangePartitionTest.java b/predicate-search-core/src/test/java/com/yahoo/document/predicate/RangePartitionTest.java
new file mode 100644
index 00000000000..b9d2c865e9b
--- /dev/null
+++ b/predicate-search-core/src/test/java/com/yahoo/document/predicate/RangePartitionTest.java
@@ -0,0 +1,60 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.predicate;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author <a href="mailto:magnarn@yahoo-inc.com">Magnar Nedland</a>
+ */
+public class RangePartitionTest {
+
+ @Test
+ public void requireThatRangePartitionIsAValue() {
+ assertTrue(PredicateValue.class.isAssignableFrom(RangePartition.class));
+ }
+
+ @Test
+ public void requireThatConstructorsWork() {
+ RangePartition part = new RangePartition("foo=10-19");
+ assertEquals("foo=10-19", part.getLabel());
+ part = new RangePartition("foo", 10, 19, false);
+ assertEquals("foo=10-19", part.getLabel());
+ part = new RangePartition("foo", 10, 19, true);
+ assertEquals("foo=-19-10", part.getLabel());
+ }
+
+ @Test
+ public void requireThatCloneIsImplemented() throws CloneNotSupportedException {
+ RangePartition node1 = new RangePartition("foo=300-399");
+ RangePartition node2 = node1.clone();
+ assertEquals(node1, node2);
+ assertNotSame(node1, node2);
+ }
+
+ @Test
+ public void requireThatHashCodeIsImplemented() {
+ assertEquals(new RangePartition("foo=0-9").hashCode(), new RangePartition("foo=0-9").hashCode());
+ }
+
+ @Test
+ public void requireThatEqualsIsImplemented() {
+ RangePartition lhs = new RangePartition("foo=10-19");
+ assertTrue(lhs.equals(lhs));
+ assertFalse(lhs.equals(new Object()));
+
+ RangePartition rhs = new RangePartition("bar=1000-1999");
+ assertFalse(lhs.equals(rhs));
+ rhs = new RangePartition("foo=10-19");
+ assertTrue(lhs.equals(rhs));
+ }
+
+ @Test
+ public void requireThatKeyIsEscapedInToString() {
+ assertEquals("foo=10-19", new RangePartition("foo=10-19").toString());
+ assertEquals("'\\foo=10-19'", new RangePartition("\foo=10-19").toString());
+ assertEquals("'\\x27foo\\x27=10-19'", new RangePartition("'foo'=10-19").toString());
+ }
+}