package jalview.datamodel.features; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; import jalview.datamodel.SequenceFeature; import jalview.util.MessageManager; import jalview.util.matcher.Condition; import java.util.Locale; import org.testng.annotations.Test; public class FeatureMatcherTest { @Test(groups = "Functional") public void testMatches_byLabel() { SequenceFeature sf = new SequenceFeature("Cath", "this is my label", 11, 12, "grp"); /* * contains - not case sensitive */ assertTrue( FeatureMatcher.byLabel(Condition.Contains, "IS").matches(sf)); assertTrue(FeatureMatcher.byLabel(Condition.Contains, "").matches(sf)); assertFalse( FeatureMatcher.byLabel(Condition.Contains, "ISNT").matches(sf)); /* * does not contain */ assertTrue(FeatureMatcher.byLabel(Condition.NotContains, "isnt") .matches(sf)); assertFalse(FeatureMatcher.byLabel(Condition.NotContains, "is") .matches(sf)); /* * matches */ assertTrue(FeatureMatcher.byLabel(Condition.Matches, "THIS is MY label") .matches(sf)); assertFalse(FeatureMatcher.byLabel(Condition.Matches, "THIS is MY") .matches(sf)); /* * does not match */ assertFalse(FeatureMatcher .byLabel(Condition.NotMatches, "THIS is MY label").matches(sf)); assertTrue(FeatureMatcher.byLabel(Condition.NotMatches, "THIS is MY") .matches(sf)); /* * is present / not present */ assertTrue(FeatureMatcher.byLabel(Condition.Present, "").matches(sf)); assertFalse( FeatureMatcher.byLabel(Condition.NotPresent, "").matches(sf)); } @Test(groups = "Functional") public void testMatches_byScore() { SequenceFeature sf = new SequenceFeature("Cath", "this is my label", 11, 12, 3.2f, "grp"); assertTrue(FeatureMatcher.byScore(Condition.LT, "3.3").matches(sf)); assertFalse(FeatureMatcher.byScore(Condition.LT, "3.2").matches(sf)); assertFalse(FeatureMatcher.byScore(Condition.LT, "2.2").matches(sf)); assertTrue(FeatureMatcher.byScore(Condition.LE, "3.3").matches(sf)); assertTrue(FeatureMatcher.byScore(Condition.LE, "3.2").matches(sf)); assertFalse(FeatureMatcher.byScore(Condition.LE, "2.2").matches(sf)); assertFalse(FeatureMatcher.byScore(Condition.EQ, "3.3").matches(sf)); assertTrue(FeatureMatcher.byScore(Condition.EQ, "3.2").matches(sf)); assertFalse(FeatureMatcher.byScore(Condition.GE, "3.3").matches(sf)); assertTrue(FeatureMatcher.byScore(Condition.GE, "3.2").matches(sf)); assertTrue(FeatureMatcher.byScore(Condition.GE, "2.2").matches(sf)); assertFalse(FeatureMatcher.byScore(Condition.GT, "3.3").matches(sf)); assertFalse(FeatureMatcher.byScore(Condition.GT, "3.2").matches(sf)); assertTrue(FeatureMatcher.byScore(Condition.GT, "2.2").matches(sf)); } @Test(groups = "Functional") public void testMatches_byAttribute() { /* * a numeric matcher - MatcherTest covers more conditions */ FeatureMatcherI fm = FeatureMatcher .byAttribute(Condition.GE, "-2", "AF"); SequenceFeature sf = new SequenceFeature("Cath", "desc", 11, 12, "grp"); assertFalse(fm.matches(sf)); sf.setValue("AF", "foobar"); assertFalse(fm.matches(sf)); sf.setValue("AF", "-2"); assertTrue(fm.matches(sf)); sf.setValue("AF", "-1"); assertTrue(fm.matches(sf)); sf.setValue("AF", "-3"); assertFalse(fm.matches(sf)); sf.setValue("AF", ""); assertFalse(fm.matches(sf)); /* * a string pattern matcher */ fm = FeatureMatcher.byAttribute(Condition.Contains, "Cat", "AF"); assertFalse(fm.matches(sf)); sf.setValue("AF", "raining cats and dogs"); assertTrue(fm.matches(sf)); fm = FeatureMatcher.byAttribute(Condition.Present, "", "AC"); assertFalse(fm.matches(sf)); sf.setValue("AC", "21"); assertTrue(fm.matches(sf)); fm = FeatureMatcher.byAttribute(Condition.NotPresent, "", "AC_Females"); assertTrue(fm.matches(sf)); sf.setValue("AC_Females", "21"); assertFalse(fm.matches(sf)); } @Test(groups = "Functional") public void testToString() { Locale.setDefault(Locale.ENGLISH); /* * toString uses the i18n translation of the enum conditions */ FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.LT, "1.2", "AF"); assertEquals(fm.toString(), "AF < 1.2"); /* * Present / NotPresent omit the value pattern */ fm = FeatureMatcher.byAttribute(Condition.Present, "", "AF"); assertEquals(fm.toString(), "AF is present"); fm = FeatureMatcher.byAttribute(Condition.NotPresent, "", "AF"); assertEquals(fm.toString(), "AF is not present"); /* * by Label */ fm = FeatureMatcher.byLabel(Condition.Matches, "foobar"); assertEquals(fm.toString(), MessageManager.getString("label.label") + " matches 'foobar'"); /* * by Score */ fm = FeatureMatcher.byScore(Condition.GE, "12.2"); assertEquals(fm.toString(), MessageManager.getString("label.score") + " >= 12.2"); } @Test(groups = "Functional") public void testGetAttribute() { FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.GE, "-2", "AF"); assertEquals(fm.getAttribute(), new String[] { "AF" }); /* * compound key (attribute / subattribute) */ fm = FeatureMatcher.byAttribute(Condition.GE, "-2F", "CSQ", "Consequence"); assertEquals(fm.getAttribute(), new String[] { "CSQ", "Consequence" }); /* * answers null if match is by Label or by Score */ assertNull(FeatureMatcher.byLabel(Condition.NotContains, "foo") .getAttribute()); assertNull(FeatureMatcher.byScore(Condition.LE, "-1").getAttribute()); } @Test(groups = "Functional") public void testIsByAttribute() { assertFalse(FeatureMatcher.byLabel(Condition.NotContains, "foo") .isByAttribute()); assertFalse(FeatureMatcher.byScore(Condition.LE, "-1").isByAttribute()); assertTrue(FeatureMatcher.byAttribute(Condition.LE, "-1", "AC") .isByAttribute()); } @Test(groups = "Functional") public void testIsByLabel() { assertTrue(FeatureMatcher.byLabel(Condition.NotContains, "foo") .isByLabel()); assertFalse(FeatureMatcher.byScore(Condition.LE, "-1").isByLabel()); assertFalse(FeatureMatcher.byAttribute(Condition.LE, "-1", "AC") .isByLabel()); } @Test(groups = "Functional") public void testIsByScore() { assertFalse(FeatureMatcher.byLabel(Condition.NotContains, "foo") .isByScore()); assertTrue(FeatureMatcher.byScore(Condition.LE, "-1").isByScore()); assertFalse(FeatureMatcher.byAttribute(Condition.LE, "-1", "AC") .isByScore()); } @Test(groups = "Functional") public void testGetMatcher() { FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.GE, "-2f", "AF"); assertEquals(fm.getMatcher().getCondition(), Condition.GE); assertEquals(fm.getMatcher().getFloatValue(), -2F); assertEquals(fm.getMatcher().getPattern(), "-2.0"); } @Test(groups = "Functional") public void testFromString() { FeatureMatcherI fm = FeatureMatcher.fromString("'AF' LT 1.2"); assertFalse(fm.isByLabel()); assertFalse(fm.isByScore()); assertEquals(fm.getAttribute(), new String[] { "AF" }); assertSame(Condition.LT, fm.getMatcher().getCondition()); assertEquals(fm.getMatcher().getFloatValue(), 1.2f); assertEquals(fm.getMatcher().getPattern(), "1.2"); // quotes are optional, condition is not case sensitive fm = FeatureMatcher.fromString("AF lt '1.2'"); assertFalse(fm.isByLabel()); assertFalse(fm.isByScore()); assertEquals(fm.getAttribute(), new String[] { "AF" }); assertSame(Condition.LT, fm.getMatcher().getCondition()); assertEquals(fm.getMatcher().getFloatValue(), 1.2f); assertEquals(fm.getMatcher().getPattern(), "1.2"); fm = FeatureMatcher.fromString("'AF' Present"); assertFalse(fm.isByLabel()); assertFalse(fm.isByScore()); assertEquals(fm.getAttribute(), new String[] { "AF" }); assertSame(Condition.Present, fm.getMatcher().getCondition()); fm = FeatureMatcher.fromString("CSQ:Consequence contains damaging"); assertFalse(fm.isByLabel()); assertFalse(fm.isByScore()); assertEquals(fm.getAttribute(), new String[] { "CSQ", "Consequence" }); assertSame(Condition.Contains, fm.getMatcher().getCondition()); assertEquals(fm.getMatcher().getPattern(), "damaging"); // keyword Label is not case sensitive fm = FeatureMatcher.fromString("LABEL Matches 'foobar'"); assertTrue(fm.isByLabel()); assertFalse(fm.isByScore()); assertNull(fm.getAttribute()); assertSame(Condition.Matches, fm.getMatcher().getCondition()); assertEquals(fm.getMatcher().getPattern(), "foobar"); fm = FeatureMatcher.fromString("'Label' matches 'foo bar'"); assertTrue(fm.isByLabel()); assertFalse(fm.isByScore()); assertNull(fm.getAttribute()); assertSame(Condition.Matches, fm.getMatcher().getCondition()); assertEquals(fm.getMatcher().getPattern(), "foo bar"); // quotes optional on pattern fm = FeatureMatcher.fromString("'Label' matches foo bar"); assertTrue(fm.isByLabel()); assertFalse(fm.isByScore()); assertNull(fm.getAttribute()); assertSame(Condition.Matches, fm.getMatcher().getCondition()); assertEquals(fm.getMatcher().getPattern(), "foo bar"); fm = FeatureMatcher.fromString("Score GE 12.2"); assertFalse(fm.isByLabel()); assertTrue(fm.isByScore()); assertNull(fm.getAttribute()); assertSame(Condition.GE, fm.getMatcher().getCondition()); assertEquals(fm.getMatcher().getPattern(), "12.2"); assertEquals(fm.getMatcher().getFloatValue(), 12.2f); // keyword Score is not case sensitive fm = FeatureMatcher.fromString("'SCORE' ge '12.2'"); assertFalse(fm.isByLabel()); assertTrue(fm.isByScore()); assertNull(fm.getAttribute()); assertSame(Condition.GE, fm.getMatcher().getCondition()); assertEquals(fm.getMatcher().getPattern(), "12.2"); assertEquals(fm.getMatcher().getFloatValue(), 12.2f); // invalid numeric pattern assertNull(FeatureMatcher.fromString("Score eq twelve")); // unbalanced opening quote assertNull(FeatureMatcher.fromString("'Score ge 12.2")); // unbalanced pattern quote assertNull(FeatureMatcher.fromString("'Score' ge '12.2")); // pattern missing assertNull(FeatureMatcher.fromString("Score ge")); // condition and pattern missing assertNull(FeatureMatcher.fromString("Score")); // everything missing assertNull(FeatureMatcher.fromString("")); } /** * Tests for toStableString which (unlike toString) does not i18n the * conditions */ @Test(groups = "Functional") public void testToStableString() { // attribute name not quoted unless it contains space FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.LT, "1.2", "AF"); assertEquals(fm.toStableString(), "AF LT 1.2"); /* * Present / NotPresent omit the value pattern */ fm = FeatureMatcher.byAttribute(Condition.Present, "", "AF"); assertEquals(fm.toStableString(), "AF Present"); fm = FeatureMatcher.byAttribute(Condition.NotPresent, "", "AF"); assertEquals(fm.toStableString(), "AF NotPresent"); /* * by Label * pattern not quoted unless it contains space */ fm = FeatureMatcher.byLabel(Condition.Matches, "foobar"); assertEquals(fm.toStableString(), "Label Matches foobar"); fm = FeatureMatcher.byLabel(Condition.Matches, "foo bar"); assertEquals(fm.toStableString(), "Label Matches 'foo bar'"); /* * by Score */ fm = FeatureMatcher.byScore(Condition.GE, "12.2"); assertEquals(fm.toStableString(), "Score GE 12.2"); } }