*/
public class KeyedMatcher implements KeyedMatcherI
{
- final private String key;
+ private static final String COLON = ":";
+
+ final private String[] key;
final private MatcherI matcher;
/**
* Constructor given a key, a test condition and a match pattern
*
- * @param theKey
* @param cond
* @param pattern
+ * @param theKey
*/
- public KeyedMatcher(String theKey, Condition cond, String pattern)
+ public KeyedMatcher(Condition cond, String pattern, String... theKey)
{
key = theKey;
matcher = new Matcher(cond, pattern);
* to. Note that if a non-numerical condition is specified, the float will be
* converted to a string.
*
- * @param theKey
* @param cond
* @param value
+ * @param theKey
*/
- public KeyedMatcher(String theKey, Condition cond, float value)
+ public KeyedMatcher(Condition cond, float value, String... theKey)
{
key = theKey;
matcher = new Matcher(cond, value);
}
@Override
- public boolean matches(Function<String, String> valueProvider)
+ public boolean matches(Function<String[], String> valueProvider)
{
String value = valueProvider.apply(key);
return matcher.matches(value);
}
@Override
- public String getKey()
+ public String[] getKey()
{
return key;
}
public String toString()
{
StringBuilder sb = new StringBuilder();
- sb.append(key).append(" ").append(matcher.getCondition().toString())
- .append(" ");
+ sb.append(String.join(COLON, key)).append(" ")
+ .append(matcher.getCondition().toString()).append(" ");
if (matcher.getCondition().isNumeric())
{
sb.append(matcher.getPattern());
public class KeyedMatcherSetTest
{
- @Test
+ @Test(groups = "Functional")
public void testMatches()
{
/*
* a numeric matcher - MatcherTest covers more conditions
*/
- KeyedMatcherI km = new KeyedMatcher("AF", Condition.GE, -2F);
+ KeyedMatcherI km = new KeyedMatcher(Condition.GE, -2F, "AF");
KeyedMatcherSetI kms = new KeyedMatcherSet();
kms.and(km);
assertTrue(kms.matches(key -> "-2"));
/*
* a string pattern matcher
*/
- km = new KeyedMatcher("AF", Condition.Contains, "Cat");
+ km = new KeyedMatcher(Condition.Contains, "Cat", "AF");
kms = new KeyedMatcherSet();
kms.and(km);
assertTrue(kms
- .matches(key -> "AF".equals(key) ? "raining cats and dogs"
+ .matches(key -> "AF".equals(key[0]) ? "raining cats and dogs"
: "showers"));
}
- @Test
+ @Test(groups = "Functional")
public void testAnd()
{
// condition1: AF value contains "dog" (matches)
- KeyedMatcherI km1 = new KeyedMatcher("AF", Condition.Contains, "dog");
+ KeyedMatcherI km1 = new KeyedMatcher(Condition.Contains, "dog", "AF");
// condition 2: CSQ value does not contain "how" (does not match)
- KeyedMatcherI km2 = new KeyedMatcher("CSQ", Condition.NotContains,
- "how");
+ KeyedMatcherI km2 = new KeyedMatcher(Condition.NotContains, "how",
+ "CSQ");
- Function<String, String> vp = key -> "AF".equals(key) ? "raining cats and dogs"
+ Function<String[], String> vp = key -> "AF".equals(key[0])
+ ? "raining cats and dogs"
: "showers";
assertTrue(km1.matches(vp));
assertFalse(km2.matches(vp));
assertFalse(kms.matches(vp));
}
- @Test
+ @Test(groups = "Functional")
public void testToString()
{
- KeyedMatcherI km1 = new KeyedMatcher("AF", Condition.LT, 1.2f);
+ KeyedMatcherI km1 = new KeyedMatcher(Condition.LT, 1.2f, "AF");
assertEquals(km1.toString(), "AF < 1.2");
- KeyedMatcher km2 = new KeyedMatcher("CLIN_SIG", Condition.NotContains, "path");
+ KeyedMatcher km2 = new KeyedMatcher(Condition.NotContains, "path",
+ "CLIN_SIG");
assertEquals(km2.toString(), "CLIN_SIG Does not contain 'PATH'");
/*
"(AF < 1.2) OR (CLIN_SIG Does not contain 'PATH')");
}
- @Test
+ @Test(groups = "Functional")
public void testOr()
{
// condition1: AF value contains "dog" (matches)
- KeyedMatcherI km1 = new KeyedMatcher("AF", Condition.Contains, "dog");
+ KeyedMatcherI km1 = new KeyedMatcher(Condition.Contains, "dog", "AF");
// condition 2: CSQ value does not contain "how" (does not match)
- KeyedMatcherI km2 = new KeyedMatcher("CSQ", Condition.NotContains,
- "how");
+ KeyedMatcherI km2 = new KeyedMatcher(Condition.NotContains, "how",
+ "CSQ");
- Function<String, String> vp = key -> "AF".equals(key) ? "raining cats and dogs"
+ Function<String[], String> vp = key -> "AF".equals(key[0])
+ ? "raining cats and dogs"
: "showers";
assertTrue(km1.matches(vp));
assertFalse(km2.matches(vp));
assertTrue(kms.matches(vp));
}
- @Test
+ @Test(groups = "Functional")
public void testIsEmpty()
{
- KeyedMatcherI km = new KeyedMatcher("AF", Condition.GE, -2F);
+ KeyedMatcherI km = new KeyedMatcher(Condition.GE, -2F, "AF");
KeyedMatcherSetI kms = new KeyedMatcherSet();
assertTrue(kms.isEmpty());
kms.and(km);
assertFalse(kms.isEmpty());
}
- @Test
+ @Test(groups = "Functional")
public void testGetMatchers()
{
KeyedMatcherSetI kms = new KeyedMatcherSet();
/*
* one matcher:
*/
- KeyedMatcherI km1 = new KeyedMatcher("AF", Condition.GE, -2F);
+ KeyedMatcherI km1 = new KeyedMatcher(Condition.GE, -2F, "AF");
kms.and(km1);
iterator = kms.getMatchers().iterator();
assertSame(km1, iterator.next());
/*
* two matchers:
*/
- KeyedMatcherI km2 = new KeyedMatcher("AF", Condition.LT, 8F);
+ KeyedMatcherI km2 = new KeyedMatcher(Condition.LT, 8F, "AF");
kms.and(km2);
iterator = kms.getMatchers().iterator();
assertSame(km1, iterator.next());
assertSame(km2, iterator.next());
assertFalse(iterator.hasNext());
}
+
+ /**
+ * Tests for the 'compound attribute' key i.e. where first key's value is a map
+ * from which we take the value for the second key, e.g. CSQ : Consequence
+ */
+ @Test(groups = "Functional")
+ public void testMatches_compoundKey()
+ {
+ /*
+ * a numeric matcher - MatcherTest covers more conditions
+ */
+ KeyedMatcherI km = new KeyedMatcher(Condition.GE, -2F, "CSQ",
+ "Consequence");
+ KeyedMatcherSetI kms = new KeyedMatcherSet();
+ kms.and(km);
+ assertTrue(kms.matches(key -> "-2"));
+ assertTrue(kms.matches(key -> "-1"));
+ assertFalse(kms.matches(key -> "-3"));
+ assertFalse(kms.matches(key -> ""));
+ assertFalse(kms.matches(key -> "junk"));
+ assertFalse(kms.matches(key -> null));
+
+ /*
+ * a string pattern matcher
+ */
+ km = new KeyedMatcher(Condition.Contains, "Cat", "CSQ", "Consequence");
+ kms = new KeyedMatcherSet();
+ kms.and(km);
+ assertTrue(kms.matches(key -> "csq".equalsIgnoreCase(key[0])
+ && "Consequence".equalsIgnoreCase(key[1])
+ ? "raining cats and dogs"
+ : "showers"));
+ }
}
/*
* a numeric matcher - MatcherTest covers more conditions
*/
- KeyedMatcherI km = new KeyedMatcher("AF", Condition.GE, -2F);
+ KeyedMatcherI km = new KeyedMatcher(Condition.GE, -2F, "AF");
assertTrue(km.matches(key -> "-2"));
assertTrue(km.matches(key -> "-1"));
assertFalse(km.matches(key -> "-3"));
/*
* a string pattern matcher
*/
- km = new KeyedMatcher("AF", Condition.Contains, "Cat");
- assertTrue(km.matches(key -> "AF".equals(key) ? "raining cats and dogs"
- : "showers"));
+ km = new KeyedMatcher(Condition.Contains, "Cat", "AF");
+ assertTrue(
+ km.matches(key -> "AF".equals(key[0]) ? "raining cats and dogs"
+ : "showers"));
}
@Test
/*
* toString uses the i18n translation of the enum conditions
*/
- KeyedMatcherI km = new KeyedMatcher("AF", Condition.LT, 1.2f);
+ KeyedMatcherI km = new KeyedMatcher(Condition.LT, 1.2f, "AF");
assertEquals(km.toString(), "AF < 1.2");
}
@Test
public void testGetKey()
{
- KeyedMatcherI km = new KeyedMatcher("AF", Condition.GE, -2F);
- assertEquals(km.getKey(), "AF");
+ KeyedMatcherI km = new KeyedMatcher(Condition.GE, -2F, "AF");
+ assertEquals(km.getKey(), new String[] { "AF" });
+
+ /*
+ * compound key (attribute / subattribute)
+ */
+ km = new KeyedMatcher(Condition.GE, -2F, "CSQ", "Consequence");
+ assertEquals(km.getKey(), new String[] { "CSQ", "Consequence" });
}
@Test
public void testGetMatcher()
{
- KeyedMatcherI km = new KeyedMatcher("AF", Condition.GE, -2F);
+ KeyedMatcherI km = new KeyedMatcher(Condition.GE, -2F, "AF");
assertEquals(km.getMatcher().getCondition(), Condition.GE);
assertEquals(km.getMatcher().getFloatValue(), -2F);
assertEquals(km.getMatcher().getPattern(), "-2.0");
public class MatcherTest
{
- @Test
+ @Test(groups = "Functional")
public void testConstructor()
{
MatcherI m = new Matcher(Condition.Contains, "foo");
/**
* Tests for float comparison conditions
*/
- @Test
+ @Test(groups = "Functional")
public void testMatches_float()
{
/*
assertTrue(m.matches("1.9"));
}
- @Test
+ @Test(groups = "Functional")
public void testMatches_floatNullOrInvalid()
{
for (Condition cond : Condition.values())
/**
* Tests for string comparison conditions
*/
- @Test
+ @Test(groups = "Functional")
public void testMatches_pattern()
{
/*
/**
* If a float is passed with a string condition it gets converted to a string
*/
- @Test
+ @Test(groups = "Functional")
public void testMatches_floatWithStringCondition()
{
MatcherI m = new Matcher(Condition.Contains, 1.2e-6f);
assertFalse(m.matches("0.0000001f"));
}
- @Test
+ @Test(groups = "Functional")
public void testToString()
{
MatcherI m = new Matcher(Condition.LT, 1.2e-6f);
assertEquals(m.toString(), "Contains '-1.2'");
}
- @Test
+ @Test(groups = "Functional")
public void testEquals()
{
/*
assertFalse(m.equals(new Matcher(Condition.LT, -1.1f)));
}
- @Test
+ @Test(groups = "Functional")
public void testHashCode()
{
MatcherI m1 = new Matcher(Condition.NotMatches, "ABC");