JAL-3746 apply copyright to tests
[jalview.git] / test / jalview / util / matcher / MatcherTest.java
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.util.matcher;
22
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertFalse;
25 import static org.testng.Assert.assertNotEquals;
26 import static org.testng.Assert.assertSame;
27 import static org.testng.Assert.assertTrue;
28 import static org.testng.Assert.fail;
29
30 import java.util.Locale;
31
32 import org.testng.annotations.Test;
33
34 import jalview.util.matcher.Matcher.PatternType;
35 import junit.extensions.PA;
36
37 public class MatcherTest
38 {
39   @Test(groups = "Functional")
40   public void testConstructor()
41   {
42     MatcherI m = new Matcher(Condition.Contains, "foo");
43     assertEquals(m.getCondition(), Condition.Contains);
44     assertEquals(m.getPattern(), "foo");
45     assertEquals(PA.getValue(m, "uppercasePattern"), "FOO");
46     assertEquals(PA.getValue(m, "floatValue"), 0f);
47     assertEquals(PA.getValue(m, "longValue"), 0L);
48     assertSame(PA.getValue(m, "patternType"), PatternType.String);
49
50     m = new Matcher(Condition.GT, -2.1f);
51     assertEquals(m.getCondition(), Condition.GT);
52     assertEquals(m.getPattern(), "-2.1");
53     assertEquals(PA.getValue(m, "floatValue"), -2.1f);
54     assertEquals(PA.getValue(m, "longValue"), 0L);
55     assertSame(PA.getValue(m, "patternType"), PatternType.Float);
56
57     m = new Matcher(Condition.NotContains, "-1.2f");
58     assertEquals(m.getCondition(), Condition.NotContains);
59     assertEquals(m.getPattern(), "-1.2f");
60     assertEquals(PA.getValue(m, "floatValue"), 0f);
61     assertEquals(PA.getValue(m, "longValue"), 0L);
62     assertSame(PA.getValue(m, "patternType"), PatternType.String);
63
64     m = new Matcher(Condition.GE, "-1.2f");
65     assertEquals(m.getCondition(), Condition.GE);
66     assertEquals(m.getPattern(), "-1.2");
67     assertEquals(PA.getValue(m, "floatValue"), -1.2f);
68     assertEquals(PA.getValue(m, "longValue"), 0L);
69     assertSame(PA.getValue(m, "patternType"), PatternType.Float);
70
71     m = new Matcher(Condition.GE, "113890813");
72     assertEquals(m.getCondition(), Condition.GE);
73     assertEquals(m.getPattern(), "113890813");
74     assertEquals(PA.getValue(m, "floatValue"), 0f);
75     assertEquals(PA.getValue(m, "longValue"), 113890813L);
76     assertSame(PA.getValue(m, "patternType"), PatternType.Integer);
77
78     m = new Matcher(Condition.GE, "-987f");
79     assertEquals(m.getCondition(), Condition.GE);
80     assertEquals(m.getPattern(), "-987.0");
81     assertEquals(PA.getValue(m, "floatValue"), -987f);
82     assertEquals(PA.getValue(m, "longValue"), 0L);
83     assertSame(PA.getValue(m, "patternType"), PatternType.Float);
84
85     try
86     {
87       new Matcher(null, 0f);
88       fail("Expected exception");
89     } catch (NullPointerException e)
90     {
91       // expected
92     }
93
94     try
95     {
96       new Matcher(Condition.LT, "123,456");
97       fail("Expected exception");
98     } catch (NumberFormatException e)
99     {
100       // expected - see Long.valueOf()
101     }
102
103     try
104     {
105       new Matcher(Condition.LT, "123_456");
106       fail("Expected exception");
107     } catch (NumberFormatException e)
108     {
109       // expected - see Long.valueOf()
110     }
111
112     try
113     {
114       new Matcher(Condition.LT, "123456L");
115       fail("Expected exception");
116     } catch (NumberFormatException e)
117     {
118       // expected - see Long.valueOf()
119     }
120   }
121
122   /**
123    * Tests for float comparison conditions
124    */
125   @Test(groups = "Functional")
126   public void testMatches_float()
127   {
128     /*
129      * EQUALS test
130      */
131     MatcherI m = new Matcher(Condition.EQ, 2f);
132     assertTrue(m.matches("2"));
133     assertTrue(m.matches("2.0"));
134     assertFalse(m.matches("2.01"));
135
136     /*
137      * NOT EQUALS test
138      */
139     m = new Matcher(Condition.NE, 2f);
140     assertFalse(m.matches("2"));
141     assertFalse(m.matches("2.0"));
142     assertTrue(m.matches("2.01"));
143
144     /*
145      * >= test
146      */
147     m = new Matcher(Condition.GE, "2f");
148     assertTrue(m.matches("2"));
149     assertTrue(m.matches("2.1"));
150     assertFalse(m.matches("1.9"));
151
152     /*
153      * > test
154      */
155     m = new Matcher(Condition.GT, 2f);
156     assertFalse(m.matches("2"));
157     assertTrue(m.matches("2.1"));
158     assertFalse(m.matches("1.9"));
159
160     /*
161      * <= test
162      */
163     m = new Matcher(Condition.LE, "2.0f");
164     assertTrue(m.matches("2"));
165     assertFalse(m.matches("2.1"));
166     assertTrue(m.matches("1.9"));
167
168     /*
169      * < test
170      */
171     m = new Matcher(Condition.LT, 2f);
172     assertFalse(m.matches("2"));
173     assertFalse(m.matches("2.1"));
174     assertTrue(m.matches("1.9"));
175   }
176
177   /**
178    * Verifies that all numeric match conditions fail when applied to non-numeric
179    * or null values
180    */
181   @Test(groups = "Functional")
182   public void testNumericMatch_nullOrInvalidValue()
183   {
184     for (Condition cond : Condition.values())
185     {
186       if (cond.isNumeric())
187       {
188         MatcherI m1 = new Matcher(cond, 2.1f);
189         MatcherI m2 = new Matcher(cond, 2345L);
190         assertFalse(m1.matches(null));
191         assertFalse(m1.matches(""));
192         assertFalse(m1.matches("two"));
193         assertFalse(m2.matches(null));
194         assertFalse(m2.matches(""));
195         assertFalse(m2.matches("two"));
196       }
197     }
198   }
199
200   /**
201    * Tests for string comparison conditions
202    */
203   @Test(groups = "Functional")
204   public void testMatches_pattern()
205   {
206     /*
207      * Contains
208      */
209     MatcherI m = new Matcher(Condition.Contains, "benign");
210     assertTrue(m.matches("benign"));
211     assertTrue(m.matches("MOSTLY BENIGN OBSERVED")); // not case-sensitive
212     assertFalse(m.matches("pathogenic"));
213     assertFalse(m.matches(null));
214
215     /*
216      * does not contain
217      */
218     m = new Matcher(Condition.NotContains, "benign");
219     assertFalse(m.matches("benign"));
220     assertFalse(m.matches("MOSTLY BENIGN OBSERVED")); // not case-sensitive
221     assertTrue(m.matches("pathogenic"));
222     assertTrue(m.matches(null)); // null value passes this condition
223
224     /*
225      * matches
226      */
227     m = new Matcher(Condition.Matches, "benign");
228     assertTrue(m.matches("benign"));
229     assertTrue(m.matches(" Benign ")); // trim before testing
230     assertFalse(m.matches("MOSTLY BENIGN"));
231     assertFalse(m.matches("pathogenic"));
232     assertFalse(m.matches(null));
233
234     /*
235      * does not match
236      */
237     m = new Matcher(Condition.NotMatches, "benign");
238     assertFalse(m.matches("benign"));
239     assertFalse(m.matches(" Benign ")); // trimmed before testing
240     assertTrue(m.matches("MOSTLY BENIGN"));
241     assertTrue(m.matches("pathogenic"));
242     assertTrue(m.matches(null));
243
244     /*
245      * value is present (is not null)
246      */
247     m = new Matcher(Condition.Present, null);
248     assertTrue(m.matches("benign"));
249     assertTrue(m.matches(""));
250     assertFalse(m.matches(null));
251
252     /*
253      * value is not present (is null)
254      */
255     m = new Matcher(Condition.NotPresent, null);
256     assertFalse(m.matches("benign"));
257     assertFalse(m.matches(""));
258     assertTrue(m.matches(null));
259
260     /*
261      * a number with a string match condition will be treated as string
262      * (these cases shouldn't arise as the match() method is coded)
263      */
264     Matcher m1 = new Matcher(Condition.Contains, "32");
265     assertFalse(m1.matchesFloat("-203f", 0f));
266     assertTrue(m1.matchesFloat("-4321.0f", 0f));
267     assertFalse(m1.matchesFloat("-203", 0f));
268     assertTrue(m1.matchesFloat("-4321", 0f));
269     assertFalse(m1.matchesLong("-203"));
270     assertTrue(m1.matchesLong("-4321"));
271     assertFalse(m1.matchesLong("-203f"));
272     assertTrue(m1.matchesLong("-4321.0f"));
273   }
274
275   /**
276    * If a float is passed with a string condition it gets converted to a string
277    */
278   @Test(groups = "Functional")
279   public void testMatches_floatWithStringCondition()
280   {
281     MatcherI m = new Matcher(Condition.Contains, 1.2e-6f);
282     assertEquals(m.getPattern(), "1.2E-6");
283     assertEquals(PA.getValue(m, "uppercasePattern"), "1.2E-6");
284     assertEquals(PA.getValue(m, "floatValue"), 0f);
285     assertEquals(PA.getValue(m, "longValue"), 0L);
286     assertSame(PA.getValue(m, "patternType"), PatternType.String);
287     assertTrue(m.matches("1.2e-6"));
288
289     m = new Matcher(Condition.Contains, 0.0000001f);
290     assertEquals(m.getPattern(), "1.0E-7");
291     assertTrue(m.matches("1.0e-7"));
292     assertTrue(m.matches("1.0E-7"));
293     assertFalse(m.matches("0.0000001f"));
294   }
295
296   @Test(groups = "Functional")
297   public void testToString()
298   {
299     Locale.setDefault(Locale.ENGLISH);
300
301     MatcherI m = new Matcher(Condition.LT, 1.2e-6f);
302     assertEquals(m.toString(), "< 1.2E-6");
303
304     m = new Matcher(Condition.GE, "20200413");
305     assertEquals(m.toString(), ">= 20200413");
306
307     m = new Matcher(Condition.NotMatches, "ABC");
308     assertEquals(m.toString(), "Does not match 'ABC'");
309
310     m = new Matcher(Condition.Contains, -1.2f);
311     assertEquals(m.toString(), "Contains '-1.2'");
312   }
313
314   @Test(groups = "Functional")
315   public void testEquals()
316   {
317     /*
318      * string condition
319      */
320     MatcherI m = new Matcher(Condition.NotMatches, "ABC");
321     assertFalse(m.equals(null));
322     assertFalse(m.equals("foo"));
323     assertTrue(m.equals(m));
324     assertTrue(m.equals(new Matcher(Condition.NotMatches, "ABC")));
325     // not case-sensitive:
326     assertTrue(m.equals(new Matcher(Condition.NotMatches, "abc")));
327     assertFalse(m.equals(new Matcher(Condition.Matches, "ABC")));
328     assertFalse(m.equals(new Matcher(Condition.NotMatches, "def")));
329
330     /*
331      * numeric conditions - float values
332      */
333     m = new Matcher(Condition.LT, -1f);
334     assertFalse(m.equals(null));
335     assertFalse(m.equals("foo"));
336     assertTrue(m.equals(m));
337     assertTrue(m.equals(new Matcher(Condition.LT, -1f)));
338     assertTrue(m.equals(new Matcher(Condition.LT, "-1f")));
339     assertTrue(m.equals(new Matcher(Condition.LT, "-1.00f")));
340     assertFalse(m.equals(new Matcher(Condition.LE, -1f)));
341     assertFalse(m.equals(new Matcher(Condition.GE, -1f)));
342     assertFalse(m.equals(new Matcher(Condition.NE, -1f)));
343     assertFalse(m.equals(new Matcher(Condition.LT, 1f)));
344     assertFalse(m.equals(new Matcher(Condition.LT, -1.1f)));
345
346     /*
347      * numeric conditions - integer values
348      */
349     m = new Matcher(Condition.LT, -123456);
350     assertFalse(m.equals(null));
351     assertFalse(m.equals("foo"));
352     assertTrue(m.equals(m));
353     assertTrue(m.equals(new Matcher(Condition.LT, -123456)));
354     assertFalse(m.equals(new Matcher(Condition.LT, +123456)));
355     assertTrue(m.equals(new Matcher(Condition.LT, "-123456")));
356     assertFalse(m.equals(new Matcher(Condition.LT, -123456f)));
357     assertFalse(m.equals(new Matcher(Condition.LT, "-123456f")));
358   }
359
360   @Test(groups = "Functional")
361   public void testHashCode()
362   {
363     MatcherI m1 = new Matcher(Condition.NotMatches, "ABC");
364     MatcherI m2 = new Matcher(Condition.NotMatches, "ABC");
365     MatcherI m3 = new Matcher(Condition.NotMatches, "AB");
366     MatcherI m4 = new Matcher(Condition.Matches, "ABC");
367     assertEquals(m1.hashCode(), m2.hashCode());
368     assertNotEquals(m1.hashCode(), m3.hashCode());
369     assertNotEquals(m1.hashCode(), m4.hashCode());
370     assertNotEquals(m3.hashCode(), m4.hashCode());
371   }
372
373   /**
374    * Tests for integer comparison conditions
375    */
376   @Test(groups = "Functional")
377   public void testMatches_long()
378   {
379     /*
380      * EQUALS test
381      */
382     MatcherI m = new Matcher(Condition.EQ, 2);
383     assertTrue(m.matches("2"));
384     assertTrue(m.matches("+2"));
385     assertFalse(m.matches("3"));
386     // a float value may be passed to an integer matcher
387     assertTrue(m.matches("2.0"));
388     assertTrue(m.matches("2.000000f"));
389     assertFalse(m.matches("2.01"));
390
391     /*
392      * NOT EQUALS test
393      */
394     m = new Matcher(Condition.NE, 123);
395     assertFalse(m.matches("123"));
396     assertFalse(m.matches("123.0"));
397     assertTrue(m.matches("-123"));
398
399     /*
400      * >= test
401      */
402     m = new Matcher(Condition.GE, "113890813");
403     assertTrue(m.matches("113890813"));
404     assertTrue(m.matches("113890814"));
405     assertFalse(m.matches("-113890813"));
406
407     /*
408      * > test
409      */
410     m = new Matcher(Condition.GT, 113890813);
411     assertFalse(m.matches("113890813"));
412     assertTrue(m.matches("113890814"));
413
414     /*
415      * <= test
416      */
417     m = new Matcher(Condition.LE, "113890813");
418     assertTrue(m.matches("113890813"));
419     assertFalse(m.matches("113890814"));
420     assertTrue(m.matches("113890812"));
421
422     /*
423      * < test
424      */
425     m = new Matcher(Condition.LT, 113890813);
426     assertFalse(m.matches("113890813"));
427     assertFalse(m.matches("113890814"));
428     assertTrue(m.matches("113890812"));
429   }
430
431   /**
432    * Tests comparing a float value with an integer condition
433    */
434   @Test(groups = "Functional")
435   public void testMatches_floatValueIntegerCondition()
436   {
437     MatcherI m = new Matcher(Condition.GT, 1234);
438     assertEquals(PA.getValue(m, "longValue"), 1234L);
439     assertSame(PA.getValue(m, "patternType"), PatternType.Integer);
440     assertTrue(m.matches("1235"));
441     assertTrue(m.matches("9867.345"));
442     assertTrue(m.matches("9867.345f"));
443   }
444 }