1 package jalview.datamodel.features;
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;
9 import java.util.Locale;
11 import org.testng.annotations.Test;
13 import jalview.datamodel.SequenceFeature;
14 import jalview.util.MessageManager;
15 import jalview.util.matcher.Condition;
16 import jalview.util.matcher.Matcher;
17 import jalview.util.matcher.MatcherI;
18 import junit.extensions.PA;
20 public class FeatureMatcherTest
22 @Test(groups = "Functional")
23 public void testMatches_byLabel()
25 SequenceFeature sf = new SequenceFeature("Cath", "this is my label", 11,
29 * contains - not case sensitive
32 FeatureMatcher.byLabel(Condition.Contains, "IS").matches(sf));
33 assertTrue(FeatureMatcher.byLabel(Condition.Contains, "").matches(sf));
35 FeatureMatcher.byLabel(Condition.Contains, "ISNT").matches(sf));
40 assertTrue(FeatureMatcher.byLabel(Condition.NotContains, "isnt")
42 assertFalse(FeatureMatcher.byLabel(Condition.NotContains, "is")
48 assertTrue(FeatureMatcher.byLabel(Condition.Matches, "THIS is MY label")
50 assertFalse(FeatureMatcher.byLabel(Condition.Matches, "THIS is MY")
56 assertFalse(FeatureMatcher
57 .byLabel(Condition.NotMatches, "THIS is MY label").matches(sf));
58 assertTrue(FeatureMatcher.byLabel(Condition.NotMatches, "THIS is MY")
62 * is present / not present
64 assertTrue(FeatureMatcher.byLabel(Condition.Present, "").matches(sf));
66 FeatureMatcher.byLabel(Condition.NotPresent, "").matches(sf));
69 @Test(groups = "Functional")
70 public void testMatches_byScore()
72 SequenceFeature sf = new SequenceFeature("Cath", "this is my label", 11,
75 assertTrue(FeatureMatcher.byScore(Condition.LT, "3.3").matches(sf));
76 assertFalse(FeatureMatcher.byScore(Condition.LT, "3.2").matches(sf));
77 assertFalse(FeatureMatcher.byScore(Condition.LT, "2.2").matches(sf));
79 assertTrue(FeatureMatcher.byScore(Condition.LE, "3.3").matches(sf));
80 assertTrue(FeatureMatcher.byScore(Condition.LE, "3.2").matches(sf));
81 assertFalse(FeatureMatcher.byScore(Condition.LE, "2.2").matches(sf));
83 assertFalse(FeatureMatcher.byScore(Condition.EQ, "3.3").matches(sf));
84 assertTrue(FeatureMatcher.byScore(Condition.EQ, "3.2").matches(sf));
86 assertFalse(FeatureMatcher.byScore(Condition.GE, "3.3").matches(sf));
87 assertTrue(FeatureMatcher.byScore(Condition.GE, "3.2").matches(sf));
88 assertTrue(FeatureMatcher.byScore(Condition.GE, "2.2").matches(sf));
90 assertFalse(FeatureMatcher.byScore(Condition.GT, "3.3").matches(sf));
91 assertFalse(FeatureMatcher.byScore(Condition.GT, "3.2").matches(sf));
92 assertTrue(FeatureMatcher.byScore(Condition.GT, "2.2").matches(sf));
95 @Test(groups = "Functional")
96 public void testMatches_byAttribute()
99 * a numeric matcher - MatcherTest covers more conditions
101 FeatureMatcherI fm = FeatureMatcher
102 .byAttribute(Condition.GE, "-2", "AF");
103 SequenceFeature sf = new SequenceFeature("Cath", "desc", 11, 12, "grp");
104 assertFalse(fm.matches(sf));
105 sf.setValue("AF", "foobar");
106 assertFalse(fm.matches(sf));
107 sf.setValue("AF", "-2");
108 assertTrue(fm.matches(sf));
109 sf.setValue("AF", "-1");
110 assertTrue(fm.matches(sf));
111 sf.setValue("AF", "-3");
112 assertFalse(fm.matches(sf));
113 sf.setValue("AF", "");
114 assertFalse(fm.matches(sf));
117 * a string pattern matcher
119 fm = FeatureMatcher.byAttribute(Condition.Contains, "Cat", "AF");
120 assertFalse(fm.matches(sf));
121 sf.setValue("AF", "raining cats and dogs");
122 assertTrue(fm.matches(sf));
124 fm = FeatureMatcher.byAttribute(Condition.Present, "", "AC");
125 assertFalse(fm.matches(sf));
126 sf.setValue("AC", "21");
127 assertTrue(fm.matches(sf));
129 fm = FeatureMatcher.byAttribute(Condition.NotPresent, "", "AC_Females");
130 assertTrue(fm.matches(sf));
131 sf.setValue("AC_Females", "21");
132 assertFalse(fm.matches(sf));
135 @Test(groups = "Functional")
136 public void testToString()
138 Locale.setDefault(Locale.ENGLISH);
141 * toString uses the i18n translation of the enum conditions
143 FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.LT, "1.2",
145 assertEquals(fm.toString(), "AF < 1.2");
148 * Present / NotPresent omit the value pattern
150 fm = FeatureMatcher.byAttribute(Condition.Present, "", "AF");
151 assertEquals(fm.toString(), "AF is present");
152 fm = FeatureMatcher.byAttribute(Condition.NotPresent, "", "AF");
153 assertEquals(fm.toString(), "AF is not present");
158 fm = FeatureMatcher.byLabel(Condition.Matches, "foobar");
159 assertEquals(fm.toString(),
160 MessageManager.getString("label.label") + " matches 'foobar'");
165 fm = FeatureMatcher.byScore(Condition.GE, "12.2");
166 assertEquals(fm.toString(),
167 MessageManager.getString("label.score") + " >= 12.2");
170 @Test(groups = "Functional")
171 public void testGetAttribute()
173 FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.GE, "-2",
175 assertEquals(fm.getAttribute(), new String[] { "AF" });
178 * compound key (attribute / subattribute)
180 fm = FeatureMatcher.byAttribute(Condition.GE, "-2F", "CSQ",
182 assertEquals(fm.getAttribute(), new String[] { "CSQ", "Consequence" });
185 * answers null if match is by Label or by Score
187 assertNull(FeatureMatcher.byLabel(Condition.NotContains, "foo")
189 assertNull(FeatureMatcher.byScore(Condition.LE, "-1").getAttribute());
192 @Test(groups = "Functional")
193 public void testIsByAttribute()
195 assertFalse(FeatureMatcher.byLabel(Condition.NotContains, "foo")
197 assertFalse(FeatureMatcher.byScore(Condition.LE, "-1").isByAttribute());
198 assertTrue(FeatureMatcher.byAttribute(Condition.LE, "-1", "AC")
202 @Test(groups = "Functional")
203 public void testIsByLabel()
205 assertTrue(FeatureMatcher.byLabel(Condition.NotContains, "foo")
207 assertFalse(FeatureMatcher.byScore(Condition.LE, "-1").isByLabel());
208 assertFalse(FeatureMatcher.byAttribute(Condition.LE, "-1", "AC")
212 @Test(groups = "Functional")
213 public void testIsByScore()
215 assertFalse(FeatureMatcher.byLabel(Condition.NotContains, "foo")
217 assertTrue(FeatureMatcher.byScore(Condition.LE, "-1").isByScore());
218 assertFalse(FeatureMatcher.byAttribute(Condition.LE, "-1", "AC")
222 @Test(groups = "Functional")
223 public void testGetMatcher()
225 FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.GE, "-2f",
227 assertEquals(fm.getMatcher().getCondition(), Condition.GE);
228 assertEquals(PA.getValue(fm.getMatcher(), "floatValue"), -2F);
229 assertEquals(fm.getMatcher().getPattern(), "-2.0");
232 @Test(groups = "Functional")
233 public void testFromString()
235 FeatureMatcherI fm = FeatureMatcher.fromString("'AF' LT 1.2");
236 assertFalse(fm.isByLabel());
237 assertFalse(fm.isByScore());
238 assertEquals(fm.getAttribute(), new String[] { "AF" });
239 MatcherI matcher = fm.getMatcher();
240 assertSame(Condition.LT, matcher.getCondition());
241 assertEquals(PA.getValue(matcher, "floatValue"), 1.2f);
242 assertSame(PA.getValue(matcher, "patternType"),
243 Matcher.PatternType.Float);
244 assertEquals(matcher.getPattern(), "1.2");
246 // quotes are optional, condition is not case sensitive
247 fm = FeatureMatcher.fromString("AF lt '1.2'");
248 matcher = fm.getMatcher();
249 assertFalse(fm.isByLabel());
250 assertFalse(fm.isByScore());
251 assertEquals(fm.getAttribute(), new String[] { "AF" });
252 assertSame(Condition.LT, matcher.getCondition());
253 assertEquals(PA.getValue(matcher, "floatValue"), 1.2F);
254 assertEquals(matcher.getPattern(), "1.2");
256 fm = FeatureMatcher.fromString("'AF' Present");
257 matcher = fm.getMatcher();
258 assertFalse(fm.isByLabel());
259 assertFalse(fm.isByScore());
260 assertEquals(fm.getAttribute(), new String[] { "AF" });
261 assertSame(Condition.Present, matcher.getCondition());
262 assertSame(PA.getValue(matcher, "patternType"),
263 Matcher.PatternType.String);
265 fm = FeatureMatcher.fromString("CSQ:Consequence contains damaging");
266 matcher = fm.getMatcher();
267 assertFalse(fm.isByLabel());
268 assertFalse(fm.isByScore());
269 assertEquals(fm.getAttribute(), new String[] { "CSQ", "Consequence" });
270 assertSame(Condition.Contains, matcher.getCondition());
271 assertEquals(matcher.getPattern(), "damaging");
273 // keyword Label is not case sensitive
274 fm = FeatureMatcher.fromString("LABEL Matches 'foobar'");
275 matcher = fm.getMatcher();
276 assertTrue(fm.isByLabel());
277 assertFalse(fm.isByScore());
278 assertNull(fm.getAttribute());
279 assertSame(Condition.Matches, matcher.getCondition());
280 assertEquals(matcher.getPattern(), "foobar");
282 fm = FeatureMatcher.fromString("'Label' matches 'foo bar'");
283 matcher = fm.getMatcher();
284 assertTrue(fm.isByLabel());
285 assertFalse(fm.isByScore());
286 assertNull(fm.getAttribute());
287 assertSame(Condition.Matches, matcher.getCondition());
288 assertEquals(matcher.getPattern(), "foo bar");
290 // quotes optional on pattern
291 fm = FeatureMatcher.fromString("'Label' matches foo bar");
292 matcher = fm.getMatcher();
293 assertTrue(fm.isByLabel());
294 assertFalse(fm.isByScore());
295 assertNull(fm.getAttribute());
296 assertSame(Condition.Matches, matcher.getCondition());
297 assertEquals(matcher.getPattern(), "foo bar");
300 fm = FeatureMatcher.fromString("Score GE 12");
301 matcher = fm.getMatcher();
302 assertFalse(fm.isByLabel());
303 assertTrue(fm.isByScore());
304 assertNull(fm.getAttribute());
305 assertSame(Condition.GE, matcher.getCondition());
306 assertEquals(matcher.getPattern(), "12");
307 assertEquals(PA.getValue(matcher, "floatValue"), 0f);
308 assertEquals(PA.getValue(matcher, "longValue"), 12L);
309 assertSame(PA.getValue(matcher, "patternType"),
310 Matcher.PatternType.Integer);
312 // keyword Score is not case sensitive
313 fm = FeatureMatcher.fromString("'SCORE' ge '12.2'");
314 matcher = fm.getMatcher();
315 assertFalse(fm.isByLabel());
316 assertTrue(fm.isByScore());
317 assertNull(fm.getAttribute());
318 assertSame(Condition.GE, matcher.getCondition());
319 assertEquals(matcher.getPattern(), "12.2");
320 assertEquals(PA.getValue(matcher, "floatValue"), 12.2F);
322 // invalid numeric pattern
323 assertNull(FeatureMatcher.fromString("Score eq twelve"));
324 // unbalanced opening quote
325 assertNull(FeatureMatcher.fromString("'Score ge 12.2"));
326 // unbalanced pattern quote
327 assertNull(FeatureMatcher.fromString("'Score' ge '12.2"));
329 assertNull(FeatureMatcher.fromString("Score ge"));
330 // condition and pattern missing
331 assertNull(FeatureMatcher.fromString("Score"));
332 // everything missing
333 assertNull(FeatureMatcher.fromString(""));
337 * Tests for toStableString which (unlike toString) does not i18n the
340 @Test(groups = "Functional")
341 public void testToStableString()
343 // attribute name not quoted unless it contains space
344 FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.LT, "1.2",
346 assertEquals(fm.toStableString(), "AF LT 1.2");
349 * Present / NotPresent omit the value pattern
351 fm = FeatureMatcher.byAttribute(Condition.Present, "", "AF");
352 assertEquals(fm.toStableString(), "AF Present");
353 fm = FeatureMatcher.byAttribute(Condition.NotPresent, "", "AF");
354 assertEquals(fm.toStableString(), "AF NotPresent");
358 * pattern not quoted unless it contains space
360 fm = FeatureMatcher.byLabel(Condition.Matches, "foobar");
361 assertEquals(fm.toStableString(), "Label Matches foobar");
363 fm = FeatureMatcher.byLabel(Condition.Matches, "foo bar");
364 assertEquals(fm.toStableString(), "Label Matches 'foo bar'");
369 fm = FeatureMatcher.byScore(Condition.GE, "12.2");
370 assertEquals(fm.toStableString(), "Score GE 12.2");