Clover icon

Coverage Report

  1. Project Clover database Wed Dec 3 2025 17:03:17 GMT
  2. Package jalview.analysis

File FinderTest.java

 

Code metrics

2
523
20
1
994
652
21
0.04
26.15
20
1.05

Classes

Class Line # Actions
FinderTest 53 523 21
0.9981651399.8%
 

Contributing tests

This file is covered by 17 tests. .

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.analysis;
22   
23    import static org.testng.Assert.assertEquals;
24    import static org.testng.Assert.assertSame;
25    import static org.testng.Assert.assertTrue;
26   
27    import java.util.List;
28   
29    import org.testng.annotations.AfterMethod;
30    import org.testng.annotations.BeforeClass;
31    import org.testng.annotations.Test;
32   
33    import jalview.api.AlignViewportI;
34    import jalview.api.FinderI;
35    import jalview.bin.Cache;
36    import jalview.datamodel.Alignment;
37    import jalview.datamodel.AlignmentI;
38    import jalview.datamodel.ColumnSelection;
39    import jalview.datamodel.HiddenColumns;
40    import jalview.datamodel.SearchResultMatchI;
41    import jalview.datamodel.SearchResultsI;
42    import jalview.datamodel.Sequence;
43    import jalview.datamodel.SequenceFeature;
44    import jalview.datamodel.SequenceGroup;
45    import jalview.datamodel.SequenceI;
46    import jalview.gui.AlignFrame;
47    import jalview.gui.AlignViewport;
48    import jalview.gui.JvOptionPane;
49    import jalview.io.DataSourceType;
50    import jalview.io.FileLoader;
51    import junit.extensions.PA;
52   
 
53    public class FinderTest
54    {
 
55  1 toggle @BeforeClass(alwaysRun = true)
56    public void setUpJvOptionPane()
57    {
58  1 JvOptionPane.setInteractiveMode(false);
59  1 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
60    }
61   
62    private AlignFrame af;
63   
64    private AlignmentI al;
65   
66    private AlignViewportI av;
67   
 
68  1 toggle @BeforeClass(groups = "Functional")
69    public void setUp()
70    {
71  1 Cache.loadProperties("test/jalview/io/testProps.jvprops");
72  1 Cache.setPropertyNoSave("PAD_GAPS",
73    Boolean.FALSE.toString());
74   
75    //@formatter:off
76  1 String seqData =
77    "seq1/8-18 ABCD--EF-GHIJI\n" +
78    "seq2 A--BCDefHI\n" +
79    "seq3 --bcdEFH\n" +
80    "seq4 aa---aMMMMMaaa\n";
81    //@formatter:on
82  1 af = new FileLoader().LoadFileWaitTillLoaded(seqData,
83    DataSourceType.PASTE);
84  1 av = af.getViewport();
85  1 al = av.getAlignment();
86  1 al.getSequenceAt(0).addSequenceFeature(
87    new SequenceFeature("BBBB", "FeatureB", 9, 11, ""));
88  1 al.getSequenceAt(3).addSequenceFeature(
89    new SequenceFeature("BBAB", "FeatureA", 1, 3, ""));
90  1 al.getSequenceAt(3).addSequenceFeature(
91    new SequenceFeature("AAAA", "FeatureA", 9, 11, ""));
92    }
93   
 
94  17 toggle @AfterMethod(alwaysRun = true)
95    public void tearDownAfterTest()
96    {
97  17 if (av!=null) {
98  17 av.setSelectionGroup(null);
99    }
100    }
101   
102    /**
103    * Test for find matches of a regular expression
104    */
 
105  1 toggle @Test(groups = "Functional")
106    public void testFind_regex()
107    {
108    /*
109    * find next match only
110    */
111  1 Finder f = new Finder(av);
112  1 f.findNext("E.H", false, false, false, false); // 'E, any character, H'
113    // should match seq2 efH only
114  1 SearchResultsI sr = f.getSearchResults();
115  1 assertEquals(sr.getCount(), 1);
116  1 List<SearchResultMatchI> matches = sr.getResults();
117  1 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
118  1 assertEquals(matches.get(0).getStart(), 5);
119  1 assertEquals(matches.get(0).getEnd(), 7);
120   
121  1 f = new Finder(av);
122  1 f.findAll("E.H", false, false, false, false); // 'E, any character, H'
123    // should match seq2 efH and seq3 EFH
124  1 sr = f.getSearchResults();
125  1 assertEquals(sr.getCount(), 2);
126  1 matches = sr.getResults();
127  1 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
128  1 assertSame(matches.get(1).getSequence(), al.getSequenceAt(2));
129  1 assertEquals(matches.get(0).getStart(), 5);
130  1 assertEquals(matches.get(0).getEnd(), 7);
131  1 assertEquals(matches.get(1).getStart(), 4);
132  1 assertEquals(matches.get(1).getEnd(), 6);
133    }
134   
 
135  1 toggle @Test(groups = "Functional")
136    public void testFind_findAll()
137    {
138    /*
139    * simple JAL-3765 test
140    * single symbol should find *all* matching symbols
141    */
142  1 Finder f = new Finder(av);
143  1 f.findAll("M", false, false, false, false);
144  1 SearchResultsI sr = f.getSearchResults();
145  1 assertEquals(sr.getCount(), 5);
146   
147    }
148   
149    /**
150    * Test for (undocumented) find residue by position
151    */
 
152  1 toggle @Test(groups = "Functional")
153    public void testFind_residueNumber()
154    {
155  1 Finder f = new Finder(av);
156   
157    /*
158    * find first match should return seq1 residue 9
159    */
160  1 f.findNext("9", false, false, false, false);
161  1 SearchResultsI sr = f.getSearchResults();
162  1 assertEquals(sr.getCount(), 1);
163  1 List<SearchResultMatchI> matches = sr.getResults();
164  1 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
165  1 assertEquals(matches.get(0).getStart(), 9);
166  1 assertEquals(matches.get(0).getEnd(), 9);
167   
168    /*
169    * find all matches should return seq1 and seq4 (others are too short)
170    * (and not matches in sequence ids)
171    */
172  1 f = new Finder(av);
173  1 String name = al.getSequenceAt(0).getName();
174  1 al.getSequenceAt(0).setName("Q9XA0");
175  1 f.findAll("9", false, false, false, false);
176  1 sr = f.getSearchResults();
177  1 assertEquals(sr.getCount(), 2);
178  1 matches = sr.getResults();
179  1 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
180  1 assertSame(matches.get(1).getSequence(), al.getSequenceAt(3));
181  1 assertEquals(matches.get(0).getStart(), 9);
182  1 assertEquals(matches.get(0).getEnd(), 9);
183  1 assertEquals(matches.get(1).getStart(), 9);
184  1 assertEquals(matches.get(1).getEnd(), 9);
185  1 al.getSequenceAt(0).setName(name);
186   
187    /*
188    * parsing of search string as integer is strict
189    */
190  1 f = new Finder(av);
191  1 f.findNext(" 9", false, false, false, false);
192  1 assertTrue(f.getSearchResults().isEmpty());
193    }
194   
195    /**
196    * Test for find next action
197    */
 
198  1 toggle @Test(groups = "Functional")
199    public void testFindNext()
200    {
201    /*
202    * start at second sequence; residueIndex of -1
203    * means sequence id / description is searched
204    */
205  1 Finder f = new Finder(av);
206  1 PA.setValue(f, "sequenceIndex", 1);
207  1 PA.setValue(f, "residueIndex", -1);
208  1 f.findNext("e", false, false, false, false); // matches id
209   
210  1 assertTrue(f.getSearchResults().isEmpty());
211  1 assertEquals(f.getIdMatches().size(), 1);
212  1 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
213   
214    // residueIndex is now 0 - for use in next find next
215    // searching A--BCDefHI
216  1 assertEquals(PA.getValue(f, "residueIndex"), 0);
217  1 f = new Finder(av);
218  1 PA.setValue(f, "sequenceIndex", 1);
219  1 PA.setValue(f, "residueIndex", 0);
220  1 f.findNext("e", false, false, false, false); // matches in sequence
221  1 assertTrue(f.getIdMatches().isEmpty());
222  1 assertEquals(f.getSearchResults().getCount(), 1);
223  1 List<SearchResultMatchI> matches = f.getSearchResults().getResults();
224  1 assertEquals(matches.get(0).getStart(), 5);
225  1 assertEquals(matches.get(0).getEnd(), 5);
226  1 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
227    // still in the second sequence
228  1 assertEquals(PA.getValue(f, "sequenceIndex"), 1);
229    // next residue offset to search from is 5
230  1 assertEquals(PA.getValue(f, "residueIndex"), 5);
231   
232    // find next from end of sequence - finds next sequence id
233  1 f = new Finder(av);
234  1 PA.setValue(f, "sequenceIndex", 1);
235  1 PA.setValue(f, "residueIndex", 7);
236  1 f.findNext("e", false, false, false, false);
237  1 assertEquals(f.getIdMatches().size(), 1);
238  1 assertSame(f.getIdMatches().get(0), al.getSequenceAt(2));
239  1 assertTrue(f.getSearchResults().isEmpty());
240    }
241   
242    /**
243    * Test for matching within sequence descriptions
244    */
 
245  1 toggle @Test(groups = "Functional")
246    public void testFind_inDescription()
247    {
248  1 AlignmentI al2 = new Alignment(al);
249  1 al2.getSequenceAt(0).setDescription("BRAF");
250  1 al2.getSequenceAt(1).setDescription("braf");
251   
252  1 AlignViewportI av2 = new AlignViewport(al2);
253   
254    /*
255    * find first match only
256    */
257  1 Finder f = new Finder(av2);
258  1 f.findNext("rAF", false, true, false, false);
259  1 assertEquals(f.getIdMatches().size(), 1);
260  1 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
261  1 assertTrue(f.getSearchResults().isEmpty());
262   
263    /*
264    * find all matches
265    */
266  1 f = new Finder(av2);
267  1 f.findAll("rAF", false, true, false, false);
268  1 assertEquals(f.getIdMatches().size(), 2);
269  1 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
270  1 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
271  1 assertTrue(f.getSearchResults().isEmpty());
272   
273    /*
274    * case sensitive
275    */
276  1 f = new Finder(av2);
277  1 f.findAll("RAF", true, true, false, false);
278  1 assertEquals(f.getIdMatches().size(), 1);
279  1 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
280  1 assertTrue(f.getSearchResults().isEmpty());
281   
282    /*
283    * match sequence id, description and sequence!
284    */
285  1 al2.getSequenceAt(0).setDescription("the efh sequence");
286  1 al2.getSequenceAt(0).setName("mouseEFHkinase");
287  1 al2.getSequenceAt(1).setName("humanEFHkinase");
288  1 f = new Finder(av2);
289   
290    /*
291    * sequence matches should have no duplicates
292    */
293  1 f.findAll("EFH", false, true, false, false);
294  1 assertEquals(f.getIdMatches().size(), 2);
295  1 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
296  1 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
297   
298  1 assertEquals(f.getSearchResults().getCount(), 2);
299  1 SearchResultMatchI match = f.getSearchResults().getResults().get(0);
300  1 assertSame(match.getSequence(), al2.getSequenceAt(1));
301  1 assertEquals(match.getStart(), 5);
302  1 assertEquals(match.getEnd(), 7);
303  1 match = f.getSearchResults().getResults().get(1);
304  1 assertSame(match.getSequence(), al2.getSequenceAt(2));
305  1 assertEquals(match.getStart(), 4);
306  1 assertEquals(match.getEnd(), 6);
307    }
308   
309    /**
310    * Test for matching within sequence ids
311    */
 
312  1 toggle @Test(groups = "Functional")
313    public void testFindAll_sequenceIds()
314    {
315  1 Finder f = new Finder(av);
316   
317    /*
318    * case insensitive; seq1 occurs twice in sequence id but
319    * only one match should be returned
320    */
321  1 f.findAll("SEQ1", false, false, false, false);
322  1 assertEquals(f.getIdMatches().size(), 1);
323  1 assertSame(f.getIdMatches().get(0), al.getSequenceAt(0));
324  1 SearchResultsI searchResults = f.getSearchResults();
325  1 assertTrue(searchResults.isEmpty());
326   
327    /*
328    * case sensitive
329    */
330  1 f = new Finder(av);
331  1 f.findAll("SEQ1", true, false, false, false);
332  1 searchResults = f.getSearchResults();
333  1 assertTrue(searchResults.isEmpty());
334   
335    /*
336    * match both sequence id and sequence
337    */
338  1 AlignmentI al2 = new Alignment(al);
339  1 AlignViewportI av2 = new AlignViewport(al2);
340  1 al2.addSequence(new Sequence("aBz", "xyzabZpqrAbZ"));
341  1 f = new Finder(av2);
342  1 f.findAll("ABZ", false, false, false, false);
343  1 assertEquals(f.getIdMatches().size(), 1);
344  1 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(4));
345  1 searchResults = f.getSearchResults();
346  1 assertEquals(searchResults.getCount(), 2);
347  1 SearchResultMatchI match = searchResults.getResults().get(0);
348  1 assertSame(match.getSequence(), al2.getSequenceAt(4));
349  1 assertEquals(match.getStart(), 4);
350  1 assertEquals(match.getEnd(), 6);
351  1 match = searchResults.getResults().get(1);
352  1 assertSame(match.getSequence(), al2.getSequenceAt(4));
353  1 assertEquals(match.getStart(), 10);
354  1 assertEquals(match.getEnd(), 12);
355    }
356   
357    /**
358    * Test finding next match of a sequence pattern in an alignment
359    */
 
360  1 toggle @Test(groups = "Functional")
361    public void testFind_findNext()
362    {
363    // "seq1/8-18 ABCD--EF-GHIJI\n" +
364    // "seq2 A--BCDefHI\n" +
365    // "seq3 --bcdEFH\n" +
366    // "seq4 aa---aMMMMMaaa\n";
367    /*
368    * efh should be matched in seq2 only
369    */
370  1 FinderI f = new Finder(av);
371  1 f.findNext("EfH", false, false, false, false);
372  1 SearchResultsI searchResults = f.getSearchResults();
373  1 assertEquals(searchResults.getCount(), 1);
374  1 SearchResultMatchI match = searchResults.getResults().get(0);
375  1 assertSame(match.getSequence(), al.getSequenceAt(1));
376  1 assertEquals(match.getStart(), 5);
377  1 assertEquals(match.getEnd(), 7);
378   
379    /*
380    * I should be found in seq1 (twice) and seq2 (once)
381    */
382  1 f = new Finder(av);
383  1 f.findNext("I", false, false, false, false); // find next: seq1/16
384  1 searchResults = f.getSearchResults();
385  1 assertEquals(searchResults.getCount(), 1);
386  1 match = searchResults.getResults().get(0);
387  1 assertSame(match.getSequence(), al.getSequenceAt(0));
388  1 assertEquals(match.getStart(), 16);
389  1 assertEquals(match.getEnd(), 16);
390   
391  1 f.findNext("I", false, false, false, false); // find next: seq1/18
392  1 searchResults = f.getSearchResults();
393  1 assertEquals(searchResults.getCount(), 1);
394  1 match = searchResults.getResults().get(0);
395  1 assertSame(match.getSequence(), al.getSequenceAt(0));
396  1 assertEquals(match.getStart(), 18);
397  1 assertEquals(match.getEnd(), 18);
398   
399  1 f.findNext("I", false, false, false, false); // find next: seq2/8
400  1 searchResults = f.getSearchResults();
401  1 assertEquals(searchResults.getCount(), 1);
402  1 match = searchResults.getResults().get(0);
403  1 assertSame(match.getSequence(), al.getSequenceAt(1));
404  1 assertEquals(match.getStart(), 8);
405  1 assertEquals(match.getEnd(), 8);
406   
407  1 f.findNext("I", false, false, false, false);
408  1 assertTrue(f.getSearchResults().isEmpty());
409   
410    /*
411    * find should reset to start of alignment after a failed search
412    */
413  1 f.findNext("I", false, false, false, false); // find next: seq1/16
414  1 searchResults = f.getSearchResults();
415  1 assertEquals(searchResults.getCount(), 1);
416  1 match = searchResults.getResults().get(0);
417  1 assertSame(match.getSequence(), al.getSequenceAt(0));
418  1 assertEquals(match.getStart(), 16);
419  1 assertEquals(match.getEnd(), 16);
420    }
421   
422    /**
423    * Test for JAL-2302 to verify that sub-matches are not included in a find all
424    * result
425    */
 
426  1 toggle @Test(groups = "Functional")
427    public void testFindAll_maximalResultOnly()
428    {
429  1 Finder f = new Finder(av);
430  1 f.findAll("M+", false, false, false, false);
431  1 SearchResultsI searchResults = f.getSearchResults();
432  1 assertEquals(searchResults.getCount(), 1);
433  1 SearchResultMatchI match = searchResults.getResults().get(0);
434  1 assertSame(match.getSequence(), al.getSequenceAt(3));
435  1 assertEquals(match.getStart(), 4); // dataset sequence positions
436  1 assertEquals(match.getEnd(), 8); // base 1
437    }
438   
439    /**
440    * Test finding all matches of a sequence pattern in an alignment
441    */
 
442  1 toggle @Test(groups = "Functional")
443    public void testFindAll()
444    {
445  1 Finder f = new Finder(av);
446  1 f.findAll("EfH", false, false, false, false);
447  1 SearchResultsI searchResults = f.getSearchResults();
448  1 assertEquals(searchResults.getCount(), 2);
449  1 SearchResultMatchI match = searchResults.getResults().get(0);
450  1 assertSame(match.getSequence(), al.getSequenceAt(1));
451  1 assertEquals(match.getStart(), 5);
452  1 assertEquals(match.getEnd(), 7);
453  1 match = searchResults.getResults().get(1);
454  1 assertSame(match.getSequence(), al.getSequenceAt(2));
455  1 assertEquals(match.getStart(), 4);
456  1 assertEquals(match.getEnd(), 6);
457   
458    /*
459    * find all I should find 2 positions in seq1, 1 in seq2
460    */
461  1 f.findAll("I", false, false, false, false);
462  1 searchResults = f.getSearchResults();
463  1 assertEquals(searchResults.getCount(), 3);
464  1 match = searchResults.getResults().get(0);
465  1 assertSame(match.getSequence(), al.getSequenceAt(0));
466  1 assertEquals(match.getStart(), 16);
467  1 assertEquals(match.getEnd(), 16);
468  1 match = searchResults.getResults().get(1);
469  1 assertSame(match.getSequence(), al.getSequenceAt(0));
470  1 assertEquals(match.getStart(), 18);
471  1 assertEquals(match.getEnd(), 18);
472  1 match = searchResults.getResults().get(2);
473  1 assertSame(match.getSequence(), al.getSequenceAt(1));
474  1 assertEquals(match.getStart(), 8);
475  1 assertEquals(match.getEnd(), 8);
476    }
477   
478    /**
479    * Test finding all matches, case-sensitive
480    */
 
481  1 toggle @Test(groups = "Functional")
482    public void testFindAll_caseSensitive()
483    {
484  1 Finder f = new Finder(av);
485   
486    /*
487    * BC should match seq1/9-10 and seq2/2-3
488    */
489  1 f.findAll("BC", true, false, false, false);
490  1 SearchResultsI searchResults = f.getSearchResults();
491  1 assertEquals(searchResults.getCount(), 2);
492  1 SearchResultMatchI match = searchResults.getResults().get(0);
493  1 assertSame(match.getSequence(), al.getSequenceAt(0));
494  1 assertEquals(match.getStart(), 9);
495  1 assertEquals(match.getEnd(), 10);
496  1 match = searchResults.getResults().get(1);
497  1 assertSame(match.getSequence(), al.getSequenceAt(1));
498  1 assertEquals(match.getStart(), 2);
499  1 assertEquals(match.getEnd(), 3);
500   
501    /*
502    * bc should match seq3/1-2
503    */
504  1 f = new Finder(av);
505  1 f.findAll("bc", true, false, false, false);
506  1 searchResults = f.getSearchResults();
507  1 assertEquals(searchResults.getCount(), 1);
508  1 match = searchResults.getResults().get(0);
509  1 assertSame(match.getSequence(), al.getSequenceAt(2));
510  1 assertEquals(match.getStart(), 1);
511  1 assertEquals(match.getEnd(), 2);
512   
513  1 f.findAll("bC", true, false, false, false);
514  1 assertTrue(f.getSearchResults().isEmpty());
515    }
516   
517    /**
518    * Test finding next match of a sequence pattern in a selection group
519    */
 
520  1 toggle @Test(groups = "Functional")
521    public void testFindNext_inSelection()
522    {
523    /*
524    * select sequences 2 and 3, columns 4-6 which contains
525    * BCD
526    * cdE
527    */
528  1 SequenceGroup sg = new SequenceGroup();
529  1 sg.setStartRes(3);
530  1 sg.setEndRes(5);
531  1 sg.addSequence(al.getSequenceAt(1), false);
532  1 sg.addSequence(al.getSequenceAt(2), false);
533  1 av.setSelectionGroup(sg);
534   
535  1 FinderI f = new Finder(av);
536  1 f.findNext("b", false, false, false, false);
537  1 assertTrue(f.getIdMatches().isEmpty());
538  1 SearchResultsI searchResults = f.getSearchResults();
539  1 assertEquals(searchResults.getCount(), 1);
540  1 SearchResultMatchI match = searchResults.getResults().get(0);
541  1 assertSame(match.getSequence(), al.getSequenceAt(1));
542  1 assertEquals(match.getStart(), 2);
543  1 assertEquals(match.getEnd(), 2);
544   
545    /*
546    * a second Find should not return the 'b' in seq3 as outside the selection
547    */
548  1 f.findNext("b", false, false, false, false);
549  1 assertTrue(f.getSearchResults().isEmpty());
550  1 assertTrue(f.getIdMatches().isEmpty());
551   
552  1 f = new Finder(av);
553  1 f.findNext("d", false, false, false, false);
554  1 assertTrue(f.getIdMatches().isEmpty());
555  1 searchResults = f.getSearchResults();
556  1 assertEquals(searchResults.getCount(), 1);
557  1 match = searchResults.getResults().get(0);
558  1 assertSame(match.getSequence(), al.getSequenceAt(1));
559  1 assertEquals(match.getStart(), 4);
560  1 assertEquals(match.getEnd(), 4);
561  1 f.findNext("d", false, false, false, false);
562  1 assertTrue(f.getIdMatches().isEmpty());
563  1 searchResults = f.getSearchResults();
564  1 assertEquals(searchResults.getCount(), 1);
565  1 match = searchResults.getResults().get(0);
566  1 assertSame(match.getSequence(), al.getSequenceAt(2));
567  1 assertEquals(match.getStart(), 3);
568  1 assertEquals(match.getEnd(), 3);
569    }
570   
571    /**
572    * Test finding all matches of a search pattern in a selection group
573    */
 
574  1 toggle @Test(groups = "Functional")
575    public void testFindAll_inSelection()
576    {
577    /*
578    * select sequences 2 and 3, columns 4-6 which contains
579    * BCD
580    * cdE
581    */
582  1 SequenceGroup sg = new SequenceGroup();
583  1 sg.setStartRes(3);
584  1 sg.setEndRes(5);
585  1 sg.addSequence(al.getSequenceAt(1), false);
586  1 sg.addSequence(al.getSequenceAt(2), false);
587  1 av.setSelectionGroup(sg);
588   
589    /*
590    * search for 'e' should match two sequence ids and one residue
591    */
592  1 Finder f = new Finder(av);
593  1 f.findAll("e", false, false, false, false);
594  1 assertEquals(f.getIdMatches().size(), 2);
595  1 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
596  1 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
597  1 SearchResultsI searchResults = f.getSearchResults();
598  1 assertEquals(searchResults.getCount(), 1);
599  1 SearchResultMatchI match = searchResults.getResults().get(0);
600  1 assertSame(match.getSequence(), al.getSequenceAt(2));
601  1 assertEquals(match.getStart(), 4);
602  1 assertEquals(match.getEnd(), 4);
603   
604    /*
605    * search for 'Q' should match two sequence ids only
606    */
607  1 f = new Finder(av);
608  1 f.findAll("Q", false, false, false, false);
609  1 assertEquals(f.getIdMatches().size(), 2);
610  1 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
611  1 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
612  1 assertTrue(f.getSearchResults().isEmpty());
613    }
614   
615    /**
616    * Test finding in selection with a sequence too short to reach it
617    */
 
618  1 toggle @Test(groups = "Functional")
619    public void testFind_findAllInSelectionWithShortSequence()
620    {
621    /*
622    * select all sequences, columns 10-12
623    * BCD
624    * cdE
625    */
626  1 SequenceGroup sg = new SequenceGroup();
627  1 sg.setStartRes(9);
628  1 sg.setEndRes(11);
629  1 sg.addSequence(al.getSequenceAt(0), false);
630  1 sg.addSequence(al.getSequenceAt(1), false);
631  1 sg.addSequence(al.getSequenceAt(2), false);
632  1 sg.addSequence(al.getSequenceAt(3), false);
633  1 av.setSelectionGroup(sg);
634   
635    /*
636    * search for 'I' should match two sequence positions
637    */
638  1 Finder f = new Finder(av);
639  1 f.findAll("I", false, false, false, false);
640  1 assertTrue(f.getIdMatches().isEmpty());
641  1 SearchResultsI searchResults = f.getSearchResults();
642  1 assertEquals(searchResults.getCount(), 2);
643  1 SearchResultMatchI match = searchResults.getResults().get(0);
644  1 assertSame(match.getSequence(), al.getSequenceAt(0));
645  1 assertEquals(match.getStart(), 16);
646  1 assertEquals(match.getEnd(), 16);
647  1 match = searchResults.getResults().get(1);
648  1 assertSame(match.getSequence(), al.getSequenceAt(1));
649  1 assertEquals(match.getStart(), 8);
650  1 assertEquals(match.getEnd(), 8);
651    }
652   
653    /**
654    * Test that find does not report hidden positions, but does report matches
655    * that span hidden gaps
656    */
 
657  1 toggle @Test(groups = "Functional")
658    public void testFind_withHiddenColumns()
659    {
660    /*
661    * 0 5 9
662    * ABCD--EF-GHI
663    * A--BCDefHI
664    * --bcdEFH
665    * aa---aMMMMMaaa
666    */
667   
668    /*
669    * hide column 3 only, search for aaa
670    * should find two matches: aa-[-]-aa and trailing aaa
671    */
672  1 HiddenColumns hc = new HiddenColumns();
673  1 hc.hideColumns(3, 3);
674  1 al.setHiddenColumns(hc);
675  1 Finder f = new Finder(av);
676  1 f.findAll("aaa", false, false, false, false);
677  1 SearchResultsI searchResults = f.getSearchResults();
678  1 assertEquals(searchResults.getCount(), 2);
679  1 SearchResultMatchI match = searchResults.getResults().get(0);
680  1 assertSame(match.getSequence(), al.getSequenceAt(3));
681  1 assertEquals(match.getStart(), 1);
682  1 assertEquals(match.getEnd(), 3);
683  1 match = searchResults.getResults().get(1);
684  1 assertSame(match.getSequence(), al.getSequenceAt(3));
685  1 assertEquals(match.getStart(), 9);
686  1 assertEquals(match.getEnd(), 11);
687   
688    /*
689    * hide 2-4 (CD- -BC bcd ---)
690    */
691  1 hc.hideColumns(2, 4);
692   
693    /*
694    * find all search for D should ignore hidden positions in seq1 and seq3,
695    * find the visible D in seq2
696    */
697  1 f = new Finder(av);
698  1 f.findAll("D", false, false, false, false);
699  1 searchResults = f.getSearchResults();
700  1 assertEquals(searchResults.getCount(), 1);
701  1 match = searchResults.getResults().get(0);
702  1 assertSame(match.getSequence(), al.getSequenceAt(1));
703  1 assertEquals(match.getStart(), 4);
704  1 assertEquals(match.getEnd(), 4);
705   
706    /*
707    * search for AD should fail although these are now
708    * consecutive in the visible columns
709    */
710  1 f = new Finder(av);
711  1 f.findAll("AD", false, false, false, false);
712  1 searchResults = f.getSearchResults();
713  1 assertTrue(searchResults.isEmpty());
714   
715    /*
716    * find all 'aaa' should find both start and end of seq4
717    * (first run includes hidden gaps)
718    */
719  1 f = new Finder(av);
720  1 f.findAll("aaa", false, false, false, false);
721  1 searchResults = f.getSearchResults();
722  1 assertEquals(searchResults.getCount(), 2);
723  1 match = searchResults.getResults().get(0);
724  1 assertSame(match.getSequence(), al.getSequenceAt(3));
725  1 assertEquals(match.getStart(), 1);
726  1 assertEquals(match.getEnd(), 3);
727  1 match = searchResults.getResults().get(1);
728  1 assertSame(match.getSequence(), al.getSequenceAt(3));
729  1 assertEquals(match.getStart(), 9);
730  1 assertEquals(match.getEnd(), 11);
731   
732    /*
733    * hide columns 2-5:
734    * find all 'aaa' should match twice in seq4
735    * (first match partly hidden, second all visible)
736    */
737  1 hc.hideColumns(2, 5);
738  1 f = new Finder(av);
739  1 f.findAll("aaa", false, false, false, false);
740  1 searchResults = f.getSearchResults();
741  1 assertEquals(searchResults.getCount(), 2);
742  1 match = searchResults.getResults().get(0);
743  1 assertSame(match.getSequence(), al.getSequenceAt(3));
744  1 assertEquals(match.getStart(), 1);
745  1 assertEquals(match.getEnd(), 3);
746  1 match = searchResults.getResults().get(1);
747  1 assertSame(match.getSequence(), al.getSequenceAt(3));
748  1 assertEquals(match.getStart(), 9);
749  1 assertEquals(match.getEnd(), 11);
750   
751    /*
752    * find all 'BE' should not match across hidden columns in seq1
753    */
754  1 f.findAll("BE", false, false, false, false);
755  1 assertTrue(f.getSearchResults().isEmpty());
756   
757    /*
758    * boundary case: hide columns at end of alignment
759    * search for H should match seq3/6 only
760    */
761  1 hc.revealAllHiddenColumns(new ColumnSelection());
762  1 hc.hideColumns(8, 13);
763  1 f = new Finder(av);
764  1 f.findNext("H", false, false, false, false);
765  1 searchResults = f.getSearchResults();
766  1 assertEquals(searchResults.getCount(), 1);
767  1 match = searchResults.getResults().get(0);
768  1 assertSame(match.getSequence(), al.getSequenceAt(2));
769  1 assertEquals(match.getStart(), 6);
770  1 assertEquals(match.getEnd(), 6);
771    }
772   
 
773  1 toggle @Test(groups = "Functional")
774    public void testFind_withHiddenColumnsAndSelection()
775    {
776    /*
777    * 0 5 9
778    * ABCD--EF-GHI
779    * A--BCDefHI
780    * --bcdEFH
781    * aa---aMMMMMaaa
782    */
783   
784    /*
785    * hide columns 2-4 and 6-7
786    */
787  1 HiddenColumns hc = new HiddenColumns();
788  1 hc.hideColumns(2, 4);
789  1 hc.hideColumns(6, 7);
790  1 al.setHiddenColumns(hc);
791   
792    /*
793    * select rows 2-3
794    */
795  1 SequenceGroup sg = new SequenceGroup();
796  1 sg.addSequence(al.getSequenceAt(1), false);
797  1 sg.addSequence(al.getSequenceAt(2), false);
798  1 sg.setStartRes(0);
799  1 sg.setEndRes(13);
800  1 av.setSelectionGroup(sg);
801   
802    /*
803    * find all search for A or H
804    * should match seq2/1, seq2/7, not seq3/6
805    */
806  1 Finder f = new Finder(av);
807  1 f.findAll("[AH]", false, false, false, false);
808  1 SearchResultsI searchResults = f.getSearchResults();
809  1 assertEquals(searchResults.getCount(), 2);
810  1 SearchResultMatchI match = searchResults.getResults().get(0);
811  1 assertSame(match.getSequence(), al.getSequenceAt(1));
812  1 assertEquals(match.getStart(), 1);
813  1 assertEquals(match.getEnd(), 1);
814  1 match = searchResults.getResults().get(1);
815  1 assertSame(match.getSequence(), al.getSequenceAt(1));
816  1 assertEquals(match.getStart(), 7);
817  1 assertEquals(match.getEnd(), 7);
818    }
819   
 
820  1 toggle @Test(groups = "Functional")
821    public void testFind_ignoreHiddenColumns()
822    {
823    /*
824    * 0 5 9
825    * ABCD--EF-GHI
826    * A--BCDefHI
827    * --bcdEFH
828    * aa---aMMMMMaaa
829    */
830  1 HiddenColumns hc = new HiddenColumns();
831  1 hc.hideColumns(2, 4);
832  1 hc.hideColumns(7, 7);
833  1 al.setHiddenColumns(hc);
834   
835    /*
836    * now have
837    * 015689
838    * AB-E-GHI
839    * A-DeHI
840    * --EF
841    * aaaMMMMaaa
842    */
843  1 Finder f = new Finder(av);
844  1 f.findAll("abe", false, false, false, true); // true = ignore hidden
845  1 SearchResultsI searchResults = f.getSearchResults();
846   
847    /*
848    * match of seq1 ABE made up of AB and E
849    * note only one match is counted
850    */
851  1 assertEquals(searchResults.getCount(), 1);
852  1 assertEquals(searchResults.getResults().size(), 2);
853  1 SearchResultMatchI match = searchResults.getResults().get(0);
854  1 assertSame(match.getSequence(), al.getSequenceAt(0));
855  1 assertEquals(match.getStart(), 8); // A
856  1 assertEquals(match.getEnd(), 9); // B
857  1 match = searchResults.getResults().get(1);
858  1 assertSame(match.getSequence(), al.getSequenceAt(0));
859  1 assertEquals(match.getStart(), 12); // E
860  1 assertEquals(match.getEnd(), 12);
861   
862  1 f = new Finder(av);
863  1 f.findNext("a.E", false, false, false, true);
864  1 searchResults = f.getSearchResults();
865  1 assertEquals(searchResults.getCount(), 1);
866  1 assertEquals(searchResults.getResults().size(), 2);
867  1 match = searchResults.getResults().get(0);
868  1 assertSame(match.getSequence(), al.getSequenceAt(0));
869  1 assertEquals(match.getStart(), 8); // A
870  1 assertEquals(match.getEnd(), 9); // B
871  1 match = searchResults.getResults().get(1);
872  1 assertSame(match.getSequence(), al.getSequenceAt(0));
873  1 assertEquals(match.getStart(), 12); // E
874  1 assertEquals(match.getEnd(), 12);
875   
876  1 f.findNext("a.E", false, false, false, true);
877  1 searchResults = f.getSearchResults();
878  1 assertEquals(searchResults.getCount(), 1);
879  1 assertEquals(searchResults.getResults().size(), 2);
880  1 match = searchResults.getResults().get(0);
881  1 assertSame(match.getSequence(), al.getSequenceAt(1));
882  1 assertEquals(match.getStart(), 1); // a
883  1 assertEquals(match.getEnd(), 1);
884  1 match = searchResults.getResults().get(1);
885  1 assertSame(match.getSequence(), al.getSequenceAt(1));
886  1 assertEquals(match.getStart(), 4); // D
887  1 assertEquals(match.getEnd(), 5); // e
888   
889    /*
890    * find all matching across two hidden column regions
891    * note one 'match' is returned as three contiguous matches
892    */
893  1 f.findAll("BEG", false, false, false, true);
894  1 searchResults = f.getSearchResults();
895  1 assertEquals(searchResults.getCount(), 1);
896  1 assertEquals(searchResults.getResults().size(), 3);
897  1 match = searchResults.getResults().get(0);
898  1 assertSame(match.getSequence(), al.getSequenceAt(0));
899  1 assertEquals(match.getStart(), 9); // B
900  1 assertEquals(match.getEnd(), 9);
901  1 match = searchResults.getResults().get(1);
902  1 assertSame(match.getSequence(), al.getSequenceAt(0));
903  1 assertEquals(match.getStart(), 12); // E
904  1 assertEquals(match.getEnd(), 12);
905  1 match = searchResults.getResults().get(2);
906  1 assertSame(match.getSequence(), al.getSequenceAt(0));
907  1 assertEquals(match.getStart(), 14); // G
908  1 assertEquals(match.getEnd(), 14);
909   
910    /*
911    * now select columns 0-9 and search for A.*H
912    * this should match in the second sequence (split as 3 matches)
913    * but not the first (as H is outside the selection)
914    */
915  1 SequenceGroup selection = new SequenceGroup();
916  1 selection.setStartRes(0);
917  1 selection.setEndRes(9);
918  1 al.getSequences().forEach(seq -> selection.addSequence(seq, false));
919  1 av.setSelectionGroup(selection);
920  1 f.findAll("A.*H", false, false, false, true);
921  1 searchResults = f.getSearchResults();
922  1 assertEquals(searchResults.getCount(), 1);
923  1 assertEquals(searchResults.getResults().size(), 3);
924    // match made of contiguous matches A, DE, H
925  1 match = searchResults.getResults().get(0);
926  1 assertSame(match.getSequence(), al.getSequenceAt(1));
927  1 assertEquals(match.getStart(), 1); // A
928  1 assertEquals(match.getEnd(), 1);
929  1 match = searchResults.getResults().get(1);
930  1 assertSame(match.getSequence(), al.getSequenceAt(1));
931  1 assertEquals(match.getStart(), 4); // D
932  1 assertEquals(match.getEnd(), 5); // E
933  1 match = searchResults.getResults().get(2);
934  1 assertSame(match.getSequence(), al.getSequenceAt(1));
935  1 assertEquals(match.getStart(), 7); // H (there is no G)
936  1 assertEquals(match.getEnd(), 7);
937    }
938   
 
939  1 toggle @Test(groups = "Functional")
940    public void testFind_featuresOnly()
941    {
942  1 Finder f = new Finder(av);
943    // no match when not searching feature descriptions
944  1 f.findAll("Feature", false, false, false, true);
945  1 assertEquals(f.getSearchResults().getCount(), 0);
946   
947    // no match when case sensitive on feature descriptions
948  1 f.findAll("feature", true, false, true, true);
949  1 assertEquals(f.getSearchResults().getCount(), 0);
950   
951    // search feature descriptions - all match
952  1 f.findAll("Feature", false, false, true, true);
953  1 assertEquals(f.getSearchResults().getCount(), 3);
954   
955  1 List<SequenceI> seqs = f.getSearchResults().getMatchingSubSequences();
956    // assume order is preserved in results
957  1 assertEquals(al.getSequenceAt(0).getDatasetSequence(),
958    seqs.get(0).getDatasetSequence());
959  1 assertEquals(seqs.get(0).getStart(), 9);
960  1 assertEquals(seqs.get(0).getEnd(), 11);
961  1 assertEquals(al.getSequenceAt(3).getDatasetSequence(),
962    seqs.get(1).getDatasetSequence());
963  1 assertEquals(seqs.get(1).getStart(), 9);
964  1 assertEquals(seqs.get(1).getEnd(), 11);
965  1 assertEquals(al.getSequenceAt(3).getDatasetSequence(),
966    seqs.get(2).getDatasetSequence());
967  1 assertEquals(seqs.get(2).getStart(), 1);
968  1 assertEquals(seqs.get(2).getEnd(), 3);
969   
970  1 SequenceI sq = null;
971    // search feature descriptions incrementally
972    // assume same order as before
973  1 f.findNext("Feature", false, false, true, true);
974  1 assertEquals(f.getSearchResults().getCount(), 1);
975  1 sq = f.getSearchResults().getMatchingSubSequences().get(0);
976  1 assertEquals(sq.getSequenceAsString(),
977    seqs.get(0).getSequenceAsString());
978   
979    // ..
980  1 f.findNext("Feature", false, false, true, true);
981  1 assertEquals(f.getSearchResults().getCount(), 1);
982  1 sq = f.getSearchResults().getMatchingSubSequences().get(0);
983  1 assertEquals(sq.getSequenceAsString(),
984    seqs.get(1).getSequenceAsString());
985   
986    // ..
987  1 f.findNext("Feature", false, false, true, true);
988  1 assertEquals(f.getSearchResults().getCount(), 1);
989  1 sq = f.getSearchResults().getMatchingSubSequences().get(0);
990  1 assertEquals(sq.getSequenceAsString(),
991    seqs.get(2).getSequenceAsString());
992   
993    }
994    }