fbbdbd5f3349ff80bdf3d5d20a16b82d83362039
[jalview.git] / test / jalview / datamodel / features / FeatureMatcherTest.java
1 package jalview.datamodel.features;
2
3 import static org.testng.Assert.assertEquals;
4 import static org.testng.Assert.assertFalse;
5 import static org.testng.Assert.assertNull;
6 import static org.testng.Assert.assertSame;
7 import static org.testng.Assert.assertTrue;
8
9 import jalview.datamodel.SequenceFeature;
10 import jalview.util.MessageManager;
11 import jalview.util.matcher.Condition;
12
13 import java.util.Locale;
14
15 import org.testng.annotations.Test;
16
17 public class FeatureMatcherTest
18 {
19   @Test(groups = "Functional")
20   public void testMatches_byLabel()
21   {
22     SequenceFeature sf = new SequenceFeature("Cath", "this is my label", 11,
23             12, "grp");
24
25     /*
26      * contains - not case sensitive
27      */
28     assertTrue(
29             FeatureMatcher.byLabel(Condition.Contains, "IS").matches(sf));
30     assertTrue(FeatureMatcher.byLabel(Condition.Contains, "").matches(sf));
31     assertFalse(
32             FeatureMatcher.byLabel(Condition.Contains, "ISNT").matches(sf));
33
34     /*
35      * does not contain
36      */
37     assertTrue(FeatureMatcher.byLabel(Condition.NotContains, "isnt")
38             .matches(sf));
39     assertFalse(FeatureMatcher.byLabel(Condition.NotContains, "is")
40             .matches(sf));
41
42     /*
43      * matches
44      */
45     assertTrue(FeatureMatcher.byLabel(Condition.Matches, "THIS is MY label")
46             .matches(sf));
47     assertFalse(FeatureMatcher.byLabel(Condition.Matches, "THIS is MY")
48             .matches(sf));
49
50     /*
51      * does not match
52      */
53     assertFalse(FeatureMatcher
54             .byLabel(Condition.NotMatches, "THIS is MY label").matches(sf));
55     assertTrue(FeatureMatcher.byLabel(Condition.NotMatches, "THIS is MY")
56             .matches(sf));
57
58     /*
59      * is present / not present
60      */
61     assertTrue(FeatureMatcher.byLabel(Condition.Present, "").matches(sf));
62     assertFalse(
63             FeatureMatcher.byLabel(Condition.NotPresent, "").matches(sf));
64   }
65
66   @Test(groups = "Functional")
67   public void testMatches_byScore()
68   {
69     SequenceFeature sf = new SequenceFeature("Cath", "this is my label", 11,
70             12, 3.2f, "grp");
71
72     assertTrue(FeatureMatcher.byScore(Condition.LT, "3.3").matches(sf));
73     assertFalse(FeatureMatcher.byScore(Condition.LT, "3.2").matches(sf));
74     assertFalse(FeatureMatcher.byScore(Condition.LT, "2.2").matches(sf));
75
76     assertTrue(FeatureMatcher.byScore(Condition.LE, "3.3").matches(sf));
77     assertTrue(FeatureMatcher.byScore(Condition.LE, "3.2").matches(sf));
78     assertFalse(FeatureMatcher.byScore(Condition.LE, "2.2").matches(sf));
79
80     assertFalse(FeatureMatcher.byScore(Condition.EQ, "3.3").matches(sf));
81     assertTrue(FeatureMatcher.byScore(Condition.EQ, "3.2").matches(sf));
82
83     assertFalse(FeatureMatcher.byScore(Condition.GE, "3.3").matches(sf));
84     assertTrue(FeatureMatcher.byScore(Condition.GE, "3.2").matches(sf));
85     assertTrue(FeatureMatcher.byScore(Condition.GE, "2.2").matches(sf));
86
87     assertFalse(FeatureMatcher.byScore(Condition.GT, "3.3").matches(sf));
88     assertFalse(FeatureMatcher.byScore(Condition.GT, "3.2").matches(sf));
89     assertTrue(FeatureMatcher.byScore(Condition.GT, "2.2").matches(sf));
90   }
91
92   @Test(groups = "Functional")
93   public void testMatches_byAttribute()
94   {
95     /*
96      * a numeric matcher - MatcherTest covers more conditions
97      */
98     FeatureMatcherI fm = FeatureMatcher
99             .byAttribute(Condition.GE, "-2", "AF");
100     SequenceFeature sf = new SequenceFeature("Cath", "desc", 11, 12, "grp");
101     assertFalse(fm.matches(sf));
102     sf.setValue("AF", "foobar");
103     assertFalse(fm.matches(sf));
104     sf.setValue("AF", "-2");
105     assertTrue(fm.matches(sf));
106     sf.setValue("AF", "-1");
107     assertTrue(fm.matches(sf));
108     sf.setValue("AF", "-3");
109     assertFalse(fm.matches(sf));
110     sf.setValue("AF", "");
111     assertFalse(fm.matches(sf));
112
113     /*
114      * a string pattern matcher
115      */
116     fm = FeatureMatcher.byAttribute(Condition.Contains, "Cat", "AF");
117     assertFalse(fm.matches(sf));
118     sf.setValue("AF", "raining cats and dogs");
119     assertTrue(fm.matches(sf));
120
121     fm = FeatureMatcher.byAttribute(Condition.Present, "", "AC");
122     assertFalse(fm.matches(sf));
123     sf.setValue("AC", "21");
124     assertTrue(fm.matches(sf));
125
126     fm = FeatureMatcher.byAttribute(Condition.NotPresent, "", "AC_Females");
127     assertTrue(fm.matches(sf));
128     sf.setValue("AC_Females", "21");
129     assertFalse(fm.matches(sf));
130   }
131
132   @Test(groups = "Functional")
133   public void testToString()
134   {
135     Locale.setDefault(Locale.ENGLISH);
136
137     /*
138      * toString uses the i18n translation of the enum conditions
139      */
140     FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.LT, "1.2",
141             "AF");
142     assertEquals(fm.toString(), "AF < 1.2");
143
144     /*
145      * Present / NotPresent omit the value pattern
146      */
147     fm = FeatureMatcher.byAttribute(Condition.Present, "", "AF");
148     assertEquals(fm.toString(), "AF is present");
149     fm = FeatureMatcher.byAttribute(Condition.NotPresent, "", "AF");
150     assertEquals(fm.toString(), "AF is not present");
151
152     /*
153      * by Label
154      */
155     fm = FeatureMatcher.byLabel(Condition.Matches, "foobar");
156     assertEquals(fm.toString(),
157             MessageManager.getString("label.label") + " matches 'foobar'");
158
159     /*
160      * by Score
161      */
162     fm = FeatureMatcher.byScore(Condition.GE, "12.2");
163     assertEquals(fm.toString(),
164             MessageManager.getString("label.score") + " >= 12.2");
165   }
166
167   @Test(groups = "Functional")
168   public void testGetAttribute()
169   {
170     FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.GE, "-2",
171             "AF");
172     assertEquals(fm.getAttribute(), new String[] { "AF" });
173
174     /*
175      * compound key (attribute / subattribute)
176      */
177     fm = FeatureMatcher.byAttribute(Condition.GE, "-2F", "CSQ",
178             "Consequence");
179     assertEquals(fm.getAttribute(), new String[] { "CSQ", "Consequence" });
180
181     /*
182      * answers null if match is by Label or by Score
183      */
184     assertNull(FeatureMatcher.byLabel(Condition.NotContains, "foo")
185             .getAttribute());
186     assertNull(FeatureMatcher.byScore(Condition.LE, "-1").getAttribute());
187   }
188
189   @Test(groups = "Functional")
190   public void testIsByLabel()
191   {
192     assertTrue(FeatureMatcher.byLabel(Condition.NotContains, "foo")
193             .isByLabel());
194     assertFalse(FeatureMatcher.byScore(Condition.LE, "-1").isByLabel());
195     assertFalse(FeatureMatcher.byAttribute(Condition.LE, "-1", "AC")
196             .isByLabel());
197   }
198
199   @Test(groups = "Functional")
200   public void testIsByScore()
201   {
202     assertFalse(FeatureMatcher.byLabel(Condition.NotContains, "foo")
203             .isByScore());
204     assertTrue(FeatureMatcher.byScore(Condition.LE, "-1").isByScore());
205     assertFalse(FeatureMatcher.byAttribute(Condition.LE, "-1", "AC")
206             .isByScore());
207   }
208
209   @Test(groups = "Functional")
210   public void testGetMatcher()
211   {
212     FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.GE, "-2f",
213             "AF");
214     assertEquals(fm.getMatcher().getCondition(), Condition.GE);
215     assertEquals(fm.getMatcher().getFloatValue(), -2F);
216     assertEquals(fm.getMatcher().getPattern(), "-2.0");
217   }
218
219   @Test(groups = "Functional")
220   public void testFromString()
221   {
222     FeatureMatcherI fm = FeatureMatcher.fromString("'AF' LT 1.2");
223     assertFalse(fm.isByLabel());
224     assertFalse(fm.isByScore());
225     assertEquals(fm.getAttribute(), new String[] { "AF" });
226     assertSame(Condition.LT, fm.getMatcher().getCondition());
227     assertEquals(fm.getMatcher().getFloatValue(), 1.2f);
228     assertEquals(fm.getMatcher().getPattern(), "1.2");
229
230     // quotes are optional, condition is not case sensitive
231     fm = FeatureMatcher.fromString("AF lt '1.2'");
232     assertFalse(fm.isByLabel());
233     assertFalse(fm.isByScore());
234     assertEquals(fm.getAttribute(), new String[] { "AF" });
235     assertSame(Condition.LT, fm.getMatcher().getCondition());
236     assertEquals(fm.getMatcher().getFloatValue(), 1.2f);
237     assertEquals(fm.getMatcher().getPattern(), "1.2");
238
239     fm = FeatureMatcher.fromString("'AF' Present");
240     assertFalse(fm.isByLabel());
241     assertFalse(fm.isByScore());
242     assertEquals(fm.getAttribute(), new String[] { "AF" });
243     assertSame(Condition.Present, fm.getMatcher().getCondition());
244
245     fm = FeatureMatcher.fromString("CSQ:Consequence contains damaging");
246     assertFalse(fm.isByLabel());
247     assertFalse(fm.isByScore());
248     assertEquals(fm.getAttribute(), new String[] { "CSQ", "Consequence" });
249     assertSame(Condition.Contains, fm.getMatcher().getCondition());
250     assertEquals(fm.getMatcher().getPattern(), "damaging");
251
252     // keyword Label is not case sensitive
253     fm = FeatureMatcher.fromString("LABEL Matches 'foobar'");
254     assertTrue(fm.isByLabel());
255     assertFalse(fm.isByScore());
256     assertNull(fm.getAttribute());
257     assertSame(Condition.Matches, fm.getMatcher().getCondition());
258     assertEquals(fm.getMatcher().getPattern(), "foobar");
259
260     fm = FeatureMatcher.fromString("'Label' matches 'foo bar'");
261     assertTrue(fm.isByLabel());
262     assertFalse(fm.isByScore());
263     assertNull(fm.getAttribute());
264     assertSame(Condition.Matches, fm.getMatcher().getCondition());
265     assertEquals(fm.getMatcher().getPattern(), "foo bar");
266
267     // quotes optional on pattern
268     fm = FeatureMatcher.fromString("'Label' matches foo bar");
269     assertTrue(fm.isByLabel());
270     assertFalse(fm.isByScore());
271     assertNull(fm.getAttribute());
272     assertSame(Condition.Matches, fm.getMatcher().getCondition());
273     assertEquals(fm.getMatcher().getPattern(), "foo bar");
274
275     fm = FeatureMatcher.fromString("Score GE 12.2");
276     assertFalse(fm.isByLabel());
277     assertTrue(fm.isByScore());
278     assertNull(fm.getAttribute());
279     assertSame(Condition.GE, fm.getMatcher().getCondition());
280     assertEquals(fm.getMatcher().getPattern(), "12.2");
281     assertEquals(fm.getMatcher().getFloatValue(), 12.2f);
282
283     // keyword Score is not case sensitive
284     fm = FeatureMatcher.fromString("'SCORE' ge '12.2'");
285     assertFalse(fm.isByLabel());
286     assertTrue(fm.isByScore());
287     assertNull(fm.getAttribute());
288     assertSame(Condition.GE, fm.getMatcher().getCondition());
289     assertEquals(fm.getMatcher().getPattern(), "12.2");
290     assertEquals(fm.getMatcher().getFloatValue(), 12.2f);
291
292     // invalid numeric pattern
293     assertNull(FeatureMatcher.fromString("Score eq twelve"));
294     // unbalanced opening quote
295     assertNull(FeatureMatcher.fromString("'Score ge 12.2"));
296     // unbalanced pattern quote
297     assertNull(FeatureMatcher.fromString("'Score' ge '12.2"));
298     // pattern missing
299     assertNull(FeatureMatcher.fromString("Score ge"));
300     // condition and pattern missing
301     assertNull(FeatureMatcher.fromString("Score"));
302     // everything missing
303     assertNull(FeatureMatcher.fromString(""));
304   }
305
306   /**
307    * Tests for toStableString which (unlike toString) does not i18n the
308    * conditions
309    */
310   @Test(groups = "Functional")
311   public void testToStableString()
312   {
313     // attribute name not quoted unless it contains space
314     FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.LT, "1.2",
315             "AF");
316     assertEquals(fm.toStableString(), "AF LT 1.2");
317
318     /*
319      * Present / NotPresent omit the value pattern
320      */
321     fm = FeatureMatcher.byAttribute(Condition.Present, "", "AF");
322     assertEquals(fm.toStableString(), "AF Present");
323     fm = FeatureMatcher.byAttribute(Condition.NotPresent, "", "AF");
324     assertEquals(fm.toStableString(), "AF NotPresent");
325
326     /*
327      * by Label
328      * pattern not quoted unless it contains space
329      */
330     fm = FeatureMatcher.byLabel(Condition.Matches, "foobar");
331     assertEquals(fm.toStableString(), "Label Matches foobar");
332
333     fm = FeatureMatcher.byLabel(Condition.Matches, "foo bar");
334     assertEquals(fm.toStableString(), "Label Matches 'foo bar'");
335
336     /*
337      * by Score
338      */
339     fm = FeatureMatcher.byScore(Condition.GE, "12.2");
340     assertEquals(fm.toStableString(), "Score GE 12.2");
341   }
342 }