2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.datamodel.features;
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertFalse;
25 import static org.testng.Assert.assertNull;
26 import static org.testng.Assert.assertSame;
27 import static org.testng.Assert.assertTrue;
29 import java.util.Locale;
31 import org.testng.annotations.Test;
33 import jalview.datamodel.SequenceFeature;
34 import jalview.util.MessageManager;
35 import jalview.util.matcher.Condition;
36 import jalview.util.matcher.Matcher;
37 import jalview.util.matcher.MatcherI;
38 import junit.extensions.PA;
40 public class FeatureMatcherTest
42 @Test(groups = "Functional")
43 public void testMatches_byLabel()
45 SequenceFeature sf = new SequenceFeature("Cath", "this is my label", 11,
49 * contains - not case sensitive
52 FeatureMatcher.byLabel(Condition.Contains, "IS").matches(sf));
53 assertTrue(FeatureMatcher.byLabel(Condition.Contains, "").matches(sf));
55 FeatureMatcher.byLabel(Condition.Contains, "ISNT").matches(sf));
60 assertTrue(FeatureMatcher.byLabel(Condition.NotContains, "isnt")
62 assertFalse(FeatureMatcher.byLabel(Condition.NotContains, "is")
68 assertTrue(FeatureMatcher.byLabel(Condition.Matches, "THIS is MY label")
70 assertFalse(FeatureMatcher.byLabel(Condition.Matches, "THIS is MY")
76 assertFalse(FeatureMatcher
77 .byLabel(Condition.NotMatches, "THIS is MY label").matches(sf));
78 assertTrue(FeatureMatcher.byLabel(Condition.NotMatches, "THIS is MY")
82 * is present / not present
84 assertTrue(FeatureMatcher.byLabel(Condition.Present, "").matches(sf));
86 FeatureMatcher.byLabel(Condition.NotPresent, "").matches(sf));
89 @Test(groups = "Functional")
90 public void testMatches_byScore()
92 SequenceFeature sf = new SequenceFeature("Cath", "this is my label", 11,
95 assertTrue(FeatureMatcher.byScore(Condition.LT, "3.3").matches(sf));
96 assertFalse(FeatureMatcher.byScore(Condition.LT, "3.2").matches(sf));
97 assertFalse(FeatureMatcher.byScore(Condition.LT, "2.2").matches(sf));
99 assertTrue(FeatureMatcher.byScore(Condition.LE, "3.3").matches(sf));
100 assertTrue(FeatureMatcher.byScore(Condition.LE, "3.2").matches(sf));
101 assertFalse(FeatureMatcher.byScore(Condition.LE, "2.2").matches(sf));
103 assertFalse(FeatureMatcher.byScore(Condition.EQ, "3.3").matches(sf));
104 assertTrue(FeatureMatcher.byScore(Condition.EQ, "3.2").matches(sf));
106 assertFalse(FeatureMatcher.byScore(Condition.GE, "3.3").matches(sf));
107 assertTrue(FeatureMatcher.byScore(Condition.GE, "3.2").matches(sf));
108 assertTrue(FeatureMatcher.byScore(Condition.GE, "2.2").matches(sf));
110 assertFalse(FeatureMatcher.byScore(Condition.GT, "3.3").matches(sf));
111 assertFalse(FeatureMatcher.byScore(Condition.GT, "3.2").matches(sf));
112 assertTrue(FeatureMatcher.byScore(Condition.GT, "2.2").matches(sf));
115 @Test(groups = "Functional")
116 public void testMatches_byAttribute()
119 * a numeric matcher - MatcherTest covers more conditions
121 FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.GE, "-2",
123 SequenceFeature sf = new SequenceFeature("Cath", "desc", 11, 12, "grp");
124 assertFalse(fm.matches(sf));
125 sf.setValue("AF", "foobar");
126 assertFalse(fm.matches(sf));
127 sf.setValue("AF", "-2");
128 assertTrue(fm.matches(sf));
129 sf.setValue("AF", "-1");
130 assertTrue(fm.matches(sf));
131 sf.setValue("AF", "-3");
132 assertFalse(fm.matches(sf));
133 sf.setValue("AF", "");
134 assertFalse(fm.matches(sf));
137 * a string pattern matcher
139 fm = FeatureMatcher.byAttribute(Condition.Contains, "Cat", "AF");
140 assertFalse(fm.matches(sf));
141 sf.setValue("AF", "raining cats and dogs");
142 assertTrue(fm.matches(sf));
144 fm = FeatureMatcher.byAttribute(Condition.Present, "", "AC");
145 assertFalse(fm.matches(sf));
146 sf.setValue("AC", "21");
147 assertTrue(fm.matches(sf));
149 fm = FeatureMatcher.byAttribute(Condition.NotPresent, "", "AC_Females");
150 assertTrue(fm.matches(sf));
151 sf.setValue("AC_Females", "21");
152 assertFalse(fm.matches(sf));
155 @Test(groups = "Functional")
156 public void testToString()
158 Locale.setDefault(Locale.ENGLISH);
161 * toString uses the i18n translation of the enum conditions
163 FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.LT, "1.2",
165 assertEquals(fm.toString(), "AF < 1.2");
168 * Present / NotPresent omit the value pattern
170 fm = FeatureMatcher.byAttribute(Condition.Present, "", "AF");
171 assertEquals(fm.toString(), "AF is present");
172 fm = FeatureMatcher.byAttribute(Condition.NotPresent, "", "AF");
173 assertEquals(fm.toString(), "AF is not present");
178 fm = FeatureMatcher.byLabel(Condition.Matches, "foobar");
179 assertEquals(fm.toString(),
180 MessageManager.getString("label.label") + " matches 'foobar'");
185 fm = FeatureMatcher.byScore(Condition.GE, "12.2");
186 assertEquals(fm.toString(),
187 MessageManager.getString("label.score") + " >= 12.2");
190 @Test(groups = "Functional")
191 public void testGetAttribute()
193 FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.GE, "-2",
195 assertEquals(fm.getAttribute(), new String[] { "AF" });
198 * compound key (attribute / subattribute)
200 fm = FeatureMatcher.byAttribute(Condition.GE, "-2F", "CSQ",
202 assertEquals(fm.getAttribute(), new String[] { "CSQ", "Consequence" });
205 * answers null if match is by Label or by Score
207 assertNull(FeatureMatcher.byLabel(Condition.NotContains, "foo")
209 assertNull(FeatureMatcher.byScore(Condition.LE, "-1").getAttribute());
212 @Test(groups = "Functional")
213 public void testIsByAttribute()
215 assertFalse(FeatureMatcher.byLabel(Condition.NotContains, "foo")
217 assertFalse(FeatureMatcher.byScore(Condition.LE, "-1").isByAttribute());
218 assertTrue(FeatureMatcher.byAttribute(Condition.LE, "-1", "AC")
222 @Test(groups = "Functional")
223 public void testIsByLabel()
225 assertTrue(FeatureMatcher.byLabel(Condition.NotContains, "foo")
227 assertFalse(FeatureMatcher.byScore(Condition.LE, "-1").isByLabel());
228 assertFalse(FeatureMatcher.byAttribute(Condition.LE, "-1", "AC")
232 @Test(groups = "Functional")
233 public void testIsByScore()
235 assertFalse(FeatureMatcher.byLabel(Condition.NotContains, "foo")
237 assertTrue(FeatureMatcher.byScore(Condition.LE, "-1").isByScore());
238 assertFalse(FeatureMatcher.byAttribute(Condition.LE, "-1", "AC")
242 @Test(groups = "Functional")
243 public void testGetMatcher()
245 FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.GE, "-2f",
247 assertEquals(fm.getMatcher().getCondition(), Condition.GE);
248 assertEquals(PA.getValue(fm.getMatcher(), "floatValue"), -2F);
249 assertEquals(fm.getMatcher().getPattern(), "-2.0");
252 @Test(groups = "Functional")
253 public void testFromString()
255 FeatureMatcherI fm = FeatureMatcher.fromString("'AF' LT 1.2");
256 assertFalse(fm.isByLabel());
257 assertFalse(fm.isByScore());
258 assertEquals(fm.getAttribute(), new String[] { "AF" });
259 MatcherI matcher = fm.getMatcher();
260 assertSame(Condition.LT, matcher.getCondition());
261 assertEquals(PA.getValue(matcher, "floatValue"), 1.2f);
262 assertSame(PA.getValue(matcher, "patternType"),
263 Matcher.PatternType.Float);
264 assertEquals(matcher.getPattern(), "1.2");
266 // quotes are optional, condition is not case sensitive
267 fm = FeatureMatcher.fromString("AF lt '1.2'");
268 matcher = fm.getMatcher();
269 assertFalse(fm.isByLabel());
270 assertFalse(fm.isByScore());
271 assertEquals(fm.getAttribute(), new String[] { "AF" });
272 assertSame(Condition.LT, matcher.getCondition());
273 assertEquals(PA.getValue(matcher, "floatValue"), 1.2F);
274 assertEquals(matcher.getPattern(), "1.2");
276 fm = FeatureMatcher.fromString("'AF' Present");
277 matcher = fm.getMatcher();
278 assertFalse(fm.isByLabel());
279 assertFalse(fm.isByScore());
280 assertEquals(fm.getAttribute(), new String[] { "AF" });
281 assertSame(Condition.Present, matcher.getCondition());
282 assertSame(PA.getValue(matcher, "patternType"),
283 Matcher.PatternType.String);
285 fm = FeatureMatcher.fromString("CSQ:Consequence contains damaging");
286 matcher = fm.getMatcher();
287 assertFalse(fm.isByLabel());
288 assertFalse(fm.isByScore());
289 assertEquals(fm.getAttribute(), new String[] { "CSQ", "Consequence" });
290 assertSame(Condition.Contains, matcher.getCondition());
291 assertEquals(matcher.getPattern(), "damaging");
293 // keyword Label is not case sensitive
294 fm = FeatureMatcher.fromString("LABEL Matches 'foobar'");
295 matcher = fm.getMatcher();
296 assertTrue(fm.isByLabel());
297 assertFalse(fm.isByScore());
298 assertNull(fm.getAttribute());
299 assertSame(Condition.Matches, matcher.getCondition());
300 assertEquals(matcher.getPattern(), "foobar");
302 fm = FeatureMatcher.fromString("'Label' matches 'foo bar'");
303 matcher = fm.getMatcher();
304 assertTrue(fm.isByLabel());
305 assertFalse(fm.isByScore());
306 assertNull(fm.getAttribute());
307 assertSame(Condition.Matches, matcher.getCondition());
308 assertEquals(matcher.getPattern(), "foo bar");
310 // quotes optional on pattern
311 fm = FeatureMatcher.fromString("'Label' matches foo bar");
312 matcher = fm.getMatcher();
313 assertTrue(fm.isByLabel());
314 assertFalse(fm.isByScore());
315 assertNull(fm.getAttribute());
316 assertSame(Condition.Matches, matcher.getCondition());
317 assertEquals(matcher.getPattern(), "foo bar");
320 fm = FeatureMatcher.fromString("Score GE 12");
321 matcher = fm.getMatcher();
322 assertFalse(fm.isByLabel());
323 assertTrue(fm.isByScore());
324 assertNull(fm.getAttribute());
325 assertSame(Condition.GE, matcher.getCondition());
326 assertEquals(matcher.getPattern(), "12");
327 assertEquals(PA.getValue(matcher, "floatValue"), 0f);
328 assertEquals(PA.getValue(matcher, "longValue"), 12L);
329 assertSame(PA.getValue(matcher, "patternType"),
330 Matcher.PatternType.Integer);
332 // keyword Score is not case sensitive
333 fm = FeatureMatcher.fromString("'SCORE' ge '12.2'");
334 matcher = fm.getMatcher();
335 assertFalse(fm.isByLabel());
336 assertTrue(fm.isByScore());
337 assertNull(fm.getAttribute());
338 assertSame(Condition.GE, matcher.getCondition());
339 assertEquals(matcher.getPattern(), "12.2");
340 assertEquals(PA.getValue(matcher, "floatValue"), 12.2F);
342 // invalid numeric pattern
343 assertNull(FeatureMatcher.fromString("Score eq twelve"));
344 // unbalanced opening quote
345 assertNull(FeatureMatcher.fromString("'Score ge 12.2"));
346 // unbalanced pattern quote
347 assertNull(FeatureMatcher.fromString("'Score' ge '12.2"));
349 assertNull(FeatureMatcher.fromString("Score ge"));
350 // condition and pattern missing
351 assertNull(FeatureMatcher.fromString("Score"));
352 // everything missing
353 assertNull(FeatureMatcher.fromString(""));
357 * Tests for toStableString which (unlike toString) does not i18n the
360 @Test(groups = "Functional")
361 public void testToStableString()
363 // attribute name not quoted unless it contains space
364 FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.LT, "1.2",
366 assertEquals(fm.toStableString(), "AF LT 1.2");
369 * Present / NotPresent omit the value pattern
371 fm = FeatureMatcher.byAttribute(Condition.Present, "", "AF");
372 assertEquals(fm.toStableString(), "AF Present");
373 fm = FeatureMatcher.byAttribute(Condition.NotPresent, "", "AF");
374 assertEquals(fm.toStableString(), "AF NotPresent");
378 * pattern not quoted unless it contains space
380 fm = FeatureMatcher.byLabel(Condition.Matches, "foobar");
381 assertEquals(fm.toStableString(), "Label Matches foobar");
383 fm = FeatureMatcher.byLabel(Condition.Matches, "foo bar");
384 assertEquals(fm.toStableString(), "Label Matches 'foo bar'");
389 fm = FeatureMatcher.byScore(Condition.GE, "12.2");
390 assertEquals(fm.toStableString(), "Score GE 12.2");