Clover icon

Coverage Report

  1. Project Clover database Tue Mar 10 2026 14:58:44 GMT
  2. Package jalview.datamodel.features

File FeatureMatcherTest.java

 

Code metrics

0
170
11
1
392
260
11
0.06
15.45
11
1

Classes

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