Clover icon

Coverage Report

  1. Project Clover database Thu Nov 7 2024 17:01:39 GMT
  2. Package jalview.datamodel.features

File FeatureMatcherSetTest.java

 

Code metrics

0
191
9
1
439
284
12
0.06
21.22
9
1.33

Classes

Class Line # Actions
FeatureMatcherSetTest 40 191 12
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
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.
11    *
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.
16    *
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.
20    */
21    package jalview.datamodel.features;
22   
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;
28    import static org.testng.Assert.fail;
29   
30    import jalview.datamodel.SequenceFeature;
31    import jalview.util.matcher.Condition;
32   
33    import java.util.HashMap;
34    import java.util.Iterator;
35    import java.util.Locale;
36    import java.util.Map;
37   
38    import org.testng.annotations.Test;
39   
 
40    public class FeatureMatcherSetTest
41    {
 
42  0 toggle @Test(groups = "Functional")
43    public void testMatches_byAttribute()
44    {
45    /*
46    * a numeric matcher - MatcherTest covers more conditions
47    */
48  0 FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.GE, "-2",
49    "AF");
50  0 FeatureMatcherSetI fms = new FeatureMatcherSet();
51  0 fms.and(fm);
52  0 SequenceFeature sf = new SequenceFeature("Cath", "desc", 11, 12, "grp");
53  0 assertFalse(fms.matches(sf));
54  0 sf.setValue("AF", "foobar");
55  0 assertFalse(fms.matches(sf));
56  0 sf.setValue("AF", "-2");
57  0 assertTrue(fms.matches(sf));
58  0 sf.setValue("AF", "-1");
59  0 assertTrue(fms.matches(sf));
60  0 sf.setValue("AF", "-3");
61  0 assertFalse(fms.matches(sf));
62  0 sf.setValue("AF", "");
63  0 assertFalse(fms.matches(sf));
64   
65    /*
66    * a string pattern matcher
67    */
68  0 fm = FeatureMatcher.byAttribute(Condition.Contains, "Cat", "AF");
69  0 fms = new FeatureMatcherSet();
70  0 fms.and(fm);
71  0 assertFalse(fms.matches(sf));
72  0 sf.setValue("AF", "raining cats and dogs");
73  0 assertTrue(fms.matches(sf));
74    }
75   
 
76  0 toggle @Test(groups = "Functional")
77    public void testAnd()
78    {
79    // condition1: AF value contains "dog" (matches)
80  0 FeatureMatcherI fm1 = FeatureMatcher.byAttribute(Condition.Contains,
81    "dog", "AF");
82    // condition 2: CSQ value does not contain "how" (does not match)
83  0 FeatureMatcherI fm2 = FeatureMatcher.byAttribute(Condition.NotContains,
84    "how", "CSQ");
85   
86  0 SequenceFeature sf = new SequenceFeature("Cath", "helix domain", 11, 12,
87    6.2f, "grp");
88  0 sf.setValue("AF", "raining cats and dogs");
89  0 sf.setValue("CSQ", "showers");
90   
91  0 assertTrue(fm1.matches(sf));
92  0 assertFalse(fm2.matches(sf));
93   
94  0 FeatureMatcherSetI fms = new FeatureMatcherSet();
95  0 assertTrue(fms.matches(sf)); // if no conditions, then 'all' pass
96  0 fms.and(fm1);
97  0 assertTrue(fms.matches(sf));
98  0 fms.and(fm2);
99  0 assertFalse(fms.matches(sf));
100   
101    /*
102    * OR a failed attribute condition with a matched label condition
103    */
104  0 fms = new FeatureMatcherSet();
105  0 fms.and(fm2);
106  0 assertFalse(fms.matches(sf));
107  0 FeatureMatcher byLabelPass = FeatureMatcher.byLabel(Condition.Contains,
108    "Helix");
109  0 fms.or(byLabelPass);
110  0 assertTrue(fms.matches(sf));
111   
112    /*
113    * OR a failed attribute condition with a failed score condition
114    */
115  0 fms = new FeatureMatcherSet();
116  0 fms.and(fm2);
117  0 assertFalse(fms.matches(sf));
118  0 FeatureMatcher byScoreFail = FeatureMatcher.byScore(Condition.LT,
119    "5.9");
120  0 fms.or(byScoreFail);
121  0 assertFalse(fms.matches(sf));
122   
123    /*
124    * OR failed attribute and score conditions with matched label condition
125    */
126  0 fms = new FeatureMatcherSet();
127  0 fms.or(fm2);
128  0 fms.or(byScoreFail);
129  0 assertFalse(fms.matches(sf));
130  0 fms.or(byLabelPass);
131  0 assertTrue(fms.matches(sf));
132    }
133   
 
134  0 toggle @Test(groups = "Functional")
135    public void testToString()
136    {
137  0 Locale.setDefault(Locale.ENGLISH);
138  0 FeatureMatcherI fm1 = FeatureMatcher.byAttribute(Condition.LT, "1.2",
139    "AF");
140  0 assertEquals(fm1.toString(), "AF < 1.2");
141   
142  0 FeatureMatcher fm2 = FeatureMatcher.byAttribute(Condition.NotContains,
143    "path", "CLIN_SIG");
144  0 assertEquals(fm2.toString(), "CLIN_SIG does not contain 'path'");
145   
146    /*
147    * AND them
148    */
149  0 FeatureMatcherSetI fms = new FeatureMatcherSet();
150  0 assertEquals(fms.toString(), "");
151  0 fms.and(fm1);
152  0 assertEquals(fms.toString(), "AF < 1.2");
153  0 fms.and(fm2);
154  0 assertEquals(fms.toString(),
155    "(AF < 1.2) and (CLIN_SIG does not contain 'path')");
156   
157    /*
158    * OR them
159    */
160  0 fms = new FeatureMatcherSet();
161  0 assertEquals(fms.toString(), "");
162  0 fms.or(fm1);
163  0 assertEquals(fms.toString(), "AF < 1.2");
164  0 fms.or(fm2);
165  0 assertEquals(fms.toString(),
166    "(AF < 1.2) or (CLIN_SIG does not contain 'path')");
167   
168  0 try
169    {
170  0 fms.and(fm1);
171  0 fail("Expected exception");
172    } catch (IllegalStateException e)
173    {
174    // expected
175    }
176    }
177   
 
178  0 toggle @Test(groups = "Functional")
179    public void testOr()
180    {
181    // condition1: AF value contains "dog" (matches)
182  0 FeatureMatcherI fm1 = FeatureMatcher.byAttribute(Condition.Contains,
183    "dog", "AF");
184    // condition 2: CSQ value does not contain "how" (does not match)
185  0 FeatureMatcherI fm2 = FeatureMatcher.byAttribute(Condition.NotContains,
186    "how", "CSQ");
187   
188  0 SequenceFeature sf = new SequenceFeature("Cath", "desc", 11, 12, "grp");
189  0 sf.setValue("AF", "raining cats and dogs");
190  0 sf.setValue("CSQ", "showers");
191   
192  0 assertTrue(fm1.matches(sf));
193  0 assertFalse(fm2.matches(sf));
194   
195  0 FeatureMatcherSetI fms = new FeatureMatcherSet();
196  0 assertTrue(fms.matches(sf)); // if no conditions, then 'all' pass
197  0 fms.or(fm1);
198  0 assertTrue(fms.matches(sf));
199  0 fms.or(fm2);
200  0 assertTrue(fms.matches(sf)); // true or false makes true
201   
202  0 fms = new FeatureMatcherSet();
203  0 fms.or(fm2);
204  0 assertFalse(fms.matches(sf));
205  0 fms.or(fm1);
206  0 assertTrue(fms.matches(sf)); // false or true makes true
207   
208  0 try
209    {
210  0 fms.and(fm2);
211  0 fail("Expected exception");
212    } catch (IllegalStateException e)
213    {
214    // expected
215    }
216    }
217   
 
218  0 toggle @Test(groups = "Functional")
219    public void testIsEmpty()
220    {
221  0 FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.GE, "-2.0",
222    "AF");
223  0 FeatureMatcherSetI fms = new FeatureMatcherSet();
224  0 assertTrue(fms.isEmpty());
225  0 fms.and(fm);
226  0 assertFalse(fms.isEmpty());
227    }
228   
 
229  0 toggle @Test(groups = "Functional")
230    public void testGetMatchers()
231    {
232  0 FeatureMatcherSetI fms = new FeatureMatcherSet();
233   
234    /*
235    * empty iterable:
236    */
237  0 Iterator<FeatureMatcherI> iterator = fms.getMatchers().iterator();
238  0 assertFalse(iterator.hasNext());
239   
240    /*
241    * one matcher:
242    */
243  0 FeatureMatcherI fm1 = FeatureMatcher.byAttribute(Condition.GE, "-2",
244    "AF");
245  0 fms.and(fm1);
246  0 iterator = fms.getMatchers().iterator();
247  0 assertSame(fm1, iterator.next());
248  0 assertFalse(iterator.hasNext());
249   
250    /*
251    * two matchers:
252    */
253  0 FeatureMatcherI fm2 = FeatureMatcher.byAttribute(Condition.LT, "8f",
254    "AF");
255  0 fms.and(fm2);
256  0 iterator = fms.getMatchers().iterator();
257  0 assertSame(fm1, iterator.next());
258  0 assertSame(fm2, iterator.next());
259  0 assertFalse(iterator.hasNext());
260    }
261   
262    /**
263    * Tests for the 'compound attribute' key i.e. where first key's value is a
264    * map from which we take the value for the second key, e.g. CSQ : Consequence
265    */
 
266  0 toggle @Test(groups = "Functional")
267    public void testMatches_compoundKey()
268    {
269    /*
270    * a numeric matcher - MatcherTest covers more conditions
271    */
272  0 FeatureMatcherI fm = FeatureMatcher.byAttribute(Condition.GE, "-2",
273    "CSQ", "Consequence");
274  0 SequenceFeature sf = new SequenceFeature("Cath", "desc", 2, 10, "grp");
275  0 FeatureMatcherSetI fms = new FeatureMatcherSet();
276  0 fms.and(fm);
277  0 assertFalse(fms.matches(sf));
278  0 Map<String, String> csq = new HashMap<>();
279  0 sf.setValue("CSQ", csq);
280  0 assertFalse(fms.matches(sf));
281  0 csq.put("Consequence", "-2");
282  0 assertTrue(fms.matches(sf));
283  0 csq.put("Consequence", "-1");
284  0 assertTrue(fms.matches(sf));
285  0 csq.put("Consequence", "-3");
286  0 assertFalse(fms.matches(sf));
287  0 csq.put("Consequence", "");
288  0 assertFalse(fms.matches(sf));
289  0 csq.put("Consequence", "junk");
290  0 assertFalse(fms.matches(sf));
291   
292    /*
293    * a string pattern matcher
294    */
295  0 fm = FeatureMatcher.byAttribute(Condition.Contains, "Cat", "CSQ",
296    "Consequence");
297  0 fms = new FeatureMatcherSet();
298  0 fms.and(fm);
299  0 assertFalse(fms.matches(sf));
300  0 csq.put("PolyPhen", "damaging");
301  0 assertFalse(fms.matches(sf));
302  0 csq.put("Consequence", "damaging");
303  0 assertFalse(fms.matches(sf));
304  0 csq.put("Consequence", "Catastrophic");
305  0 assertTrue(fms.matches(sf));
306    }
307   
308    /**
309    * Tests for toStableString which (unlike toString) does not i18n the
310    * conditions
311    *
312    * @see FeatureMatcherTest#testToStableString()
313    */
 
314  0 toggle @Test(groups = "Functional")
315    public void testToStableString()
316    {
317  0 FeatureMatcherI fm1 = FeatureMatcher.byAttribute(Condition.LT, "1.2",
318    "AF");
319  0 assertEquals(fm1.toStableString(), "AF LT 1.2");
320   
321  0 FeatureMatcher fm2 = FeatureMatcher.byAttribute(Condition.NotContains,
322    "path", "CLIN_SIG");
323  0 assertEquals(fm2.toStableString(), "CLIN_SIG NotContains path");
324   
325    /*
326    * AND them
327    */
328  0 FeatureMatcherSetI fms = new FeatureMatcherSet();
329  0 assertEquals(fms.toStableString(), "");
330  0 fms.and(fm1);
331    // no brackets needed if a single condition
332  0 assertEquals(fms.toStableString(), "AF LT 1.2");
333    // brackets if more than one condition
334  0 fms.and(fm2);
335  0 assertEquals(fms.toStableString(),
336    "(AF LT 1.2) AND (CLIN_SIG NotContains path)");
337   
338    /*
339    * OR them
340    */
341  0 fms = new FeatureMatcherSet();
342  0 assertEquals(fms.toStableString(), "");
343  0 fms.or(fm1);
344  0 assertEquals(fms.toStableString(), "AF LT 1.2");
345  0 fms.or(fm2);
346  0 assertEquals(fms.toStableString(),
347    "(AF LT 1.2) OR (CLIN_SIG NotContains path)");
348   
349    /*
350    * attribute or value including space is quoted
351    */
352  0 FeatureMatcher fm3 = FeatureMatcher.byAttribute(Condition.NotMatches,
353    "foo bar", "CSQ", "Poly Phen");
354  0 assertEquals(fm3.toStableString(),
355    "'CSQ:Poly Phen' NotMatches 'foo bar'");
356  0 fms.or(fm3);
357  0 assertEquals(fms.toStableString(),
358    "(AF LT 1.2) OR (CLIN_SIG NotContains path) OR ('CSQ:Poly Phen' NotMatches 'foo bar')");
359   
360  0 try
361    {
362  0 fms.and(fm1);
363  0 fail("Expected exception");
364    } catch (IllegalStateException e)
365    {
366    // expected
367    }
368    }
369   
370    /**
371    * Tests for parsing a string representation of a FeatureMatcherSet
372    *
373    * @see FeatureMatcherSetTest#testToStableString()
374    */
 
375  0 toggle @Test(groups = "Functional")
376    public void testFromString()
377    {
378  0 String descriptor = "AF LT 1.2";
379  0 FeatureMatcherSetI fms = FeatureMatcherSet.fromString(descriptor);
380   
381    /*
382    * shortcut asserts by verifying a 'roundtrip',
383    * which we trust if other tests pass :-)
384    */
385  0 assertEquals(fms.toStableString(), descriptor);
386   
387    // brackets optional, quotes optional, condition case insensitive
388  0 fms = FeatureMatcherSet.fromString("('AF' lt '1.2')");
389  0 assertEquals(fms.toStableString(), descriptor);
390   
391  0 descriptor = "(AF LT 1.2) AND (CLIN_SIG NotContains path)";
392  0 fms = FeatureMatcherSet.fromString(descriptor);
393  0 assertEquals(fms.toStableString(), descriptor);
394   
395    // AND is not case-sensitive
396  0 fms = FeatureMatcherSet
397    .fromString("(AF LT 1.2) and (CLIN_SIG NotContains path)");
398  0 assertEquals(fms.toStableString(), descriptor);
399   
400  0 descriptor = "(AF LT 1.2) OR (CLIN_SIG NotContains path)";
401  0 fms = FeatureMatcherSet.fromString(descriptor);
402  0 assertEquals(fms.toStableString(), descriptor);
403   
404    // OR is not case-sensitive
405  0 fms = FeatureMatcherSet
406    .fromString("(AF LT 1.2) or (CLIN_SIG NotContains path)");
407  0 assertEquals(fms.toStableString(), descriptor);
408   
409    // can get away without brackets on last match condition
410  0 fms = FeatureMatcherSet
411    .fromString("(AF LT 1.2) or CLIN_SIG NotContains path");
412  0 assertEquals(fms.toStableString(), descriptor);
413   
414  0 descriptor = "(AF LT 1.2) OR (CLIN_SIG NotContains path) OR ('CSQ:Poly Phen' NotMatches 'foo bar')";
415  0 fms = FeatureMatcherSet.fromString(descriptor);
416  0 assertEquals(fms.toStableString(), descriptor);
417   
418    // can't mix OR and AND
419  0 descriptor = "(AF LT 1.2) OR (CLIN_SIG NotContains path) AND ('CSQ:Poly Phen' NotMatches 'foo bar')";
420  0 assertNull(FeatureMatcherSet.fromString(descriptor));
421   
422    // can't mix AND and OR
423  0 descriptor = "(AF LT 1.2) and (CLIN_SIG NotContains path) or ('CSQ:Poly Phen' NotMatches 'foo bar')";
424  0 assertNull(FeatureMatcherSet.fromString(descriptor));
425   
426    // brackets missing
427  0 assertNull(FeatureMatcherSet
428    .fromString("AF LT 1.2 or CLIN_SIG NotContains path"));
429   
430    // invalid conjunction
431  0 assertNull(FeatureMatcherSet.fromString("(AF LT 1.2) but (AF GT -2)"));
432   
433    // unbalanced quote (1)
434  0 assertNull(FeatureMatcherSet.fromString("('AF lt '1.2')"));
435   
436    // unbalanced quote (2)
437  0 assertNull(FeatureMatcherSet.fromString("('AF' lt '1.2)"));
438    }
439    }