Predicate implements Cloneable { @Override public final String toString() { StringBuilder out = new StringBuilder(); appendTo(out); return out.toString(); }  @Override Predicate clone(); @Override final String toString(); static String asciiEncode(String str); static String asciiDecode(String str); static Predicate fromBinary(byte[] buf); static Predicate fromString(String str);  }
@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()); }