Clover icon

Coverage Report

  1. Project Clover database Tue Mar 10 2026 14:58:44 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.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.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  0 toggle @BeforeClass(alwaysRun = true)
56    public void setUpJvOptionPane()
57    {
58  0 JvOptionPane.setInteractiveMode(false);
59  0 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
60    }
61   
62    private AlignFrame af;
63   
64    private AlignmentI al;
65   
66    private AlignViewportI av;
67   
 
68  0 toggle @BeforeClass(groups = "Functional")
69    public void setUp()
70    {
71  0 Cache.loadProperties("test/jalview/io/testProps.jvprops");
72  0 Cache.setPropertyNoSave("PAD_GAPS",
73    Boolean.FALSE.toString());
74   
75    //@formatter:off
76  0 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  0 af = new FileLoader().LoadFileWaitTillLoaded(seqData,
83    DataSourceType.PASTE);
84  0 av = af.getViewport();
85  0 al = av.getAlignment();
86  0 al.getSequenceAt(0).addSequenceFeature(
87    new SequenceFeature("BBBB", "FeatureB", 9, 11, ""));
88  0 al.getSequenceAt(3).addSequenceFeature(
89    new SequenceFeature("BBAB", "FeatureA", 1, 3, ""));
90  0 al.getSequenceAt(3).addSequenceFeature(
91    new SequenceFeature("AAAA", "FeatureA", 9, 11, ""));
92    }
93   
 
94  0 toggle @AfterMethod(alwaysRun = true)
95    public void tearDownAfterTest()
96    {
97  0 if (av!=null) {
98  0 av.setSelectionGroup(null);
99    }
100    }
101   
102    /**
103    * Test for find matches of a regular expression
104    */
 
105  0 toggle @Test(groups = "Functional")
106    public void testFind_regex()
107    {
108    /*
109    * find next match only
110    */
111  0 Finder f = new Finder(av);
112  0 f.findNext("E.H", false, false, false, false); // 'E, any character, H'
113    // should match seq2 efH only
114  0 SearchResultsI sr = f.getSearchResults();
115  0 assertEquals(sr.getCount(), 1);
116  0 List<SearchResultMatchI> matches = sr.getResults();
117  0 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
118  0 assertEquals(matches.get(0).getStart(), 5);
119  0 assertEquals(matches.get(0).getEnd(), 7);
120   
121  0 f = new Finder(av);
122  0 f.findAll("E.H", false, false, false, false); // 'E, any character, H'
123    // should match seq2 efH and seq3 EFH
124  0 sr = f.getSearchResults();
125  0 assertEquals(sr.getCount(), 2);
126  0 matches = sr.getResults();
127  0 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
128  0 assertSame(matches.get(1).getSequence(), al.getSequenceAt(2));
129  0 assertEquals(matches.get(0).getStart(), 5);
130  0 assertEquals(matches.get(0).getEnd(), 7);
131  0 assertEquals(matches.get(1).getStart(), 4);
132  0 assertEquals(matches.get(1).getEnd(), 6);
133    }
134   
 
135  0 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  0 Finder f = new Finder(av);
143  0 f.findAll("M", false, false, false, false);
144  0 SearchResultsI sr = f.getSearchResults();
145  0 assertEquals(sr.getCount(), 5);
146   
147    }
148   
149    /**
150    * Test for (undocumented) find residue by position
151    */
 
152  0 toggle @Test(groups = "Functional")
153    public void testFind_residueNumber()
154    {
155  0 Finder f = new Finder(av);
156   
157    /*
158    * find first match should return seq1 residue 9
159    */
160  0 f.findNext("9", false, false, false, false);
161  0 SearchResultsI sr = f.getSearchResults();
162  0 assertEquals(sr.getCount(), 1);
163  0 List<SearchResultMatchI> matches = sr.getResults();
164  0 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
165  0 assertEquals(matches.get(0).getStart(), 9);
166  0 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  0 f = new Finder(av);
173  0 String name = al.getSequenceAt(0).getName();
174  0 al.getSequenceAt(0).setName("Q9XA0");
175  0 f.findAll("9", false, false, false, false);
176  0 sr = f.getSearchResults();
177  0 assertEquals(sr.getCount(), 2);
178  0 matches = sr.getResults();
179  0 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
180  0 assertSame(matches.get(1).getSequence(), al.getSequenceAt(3));
181  0 assertEquals(matches.get(0).getStart(), 9);
182  0 assertEquals(matches.get(0).getEnd(), 9);
183  0 assertEquals(matches.get(1).getStart(), 9);
184  0 assertEquals(matches.get(1).getEnd(), 9);
185  0 al.getSequenceAt(0).setName(name);
186   
187    /*
188    * parsing of search string as integer is strict
189    */
190  0 f = new Finder(av);
191  0 f.findNext(" 9", false, false, false, false);
192  0 assertTrue(f.getSearchResults().isEmpty());
193    }
194   
195    /**
196    * Test for find next action
197    */
 
198  0 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  0 Finder f = new Finder(av);
206  0 PA.setValue(f, "sequenceIndex", 1);
207  0 PA.setValue(f, "residueIndex", -1);
208  0 f.findNext("e", false, false, false, false); // matches id
209   
210  0 assertTrue(f.getSearchResults().isEmpty());
211  0 assertEquals(f.getIdMatches().size(), 1);
212  0 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  0 assertEquals(PA.getValue(f, "residueIndex"), 0);
217  0 f = new Finder(av);
218  0 PA.setValue(f, "sequenceIndex", 1);
219  0 PA.setValue(f, "residueIndex", 0);
220  0 f.findNext("e", false, false, false, false); // matches in sequence
221  0 assertTrue(f.getIdMatches().isEmpty());
222  0 assertEquals(f.getSearchResults().getCount(), 1);
223  0 List<SearchResultMatchI> matches = f.getSearchResults().getResults();
224  0 assertEquals(matches.get(0).getStart(), 5);
225  0 assertEquals(matches.get(0).getEnd(), 5);
226  0 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
227    // still in the second sequence
228  0 assertEquals(PA.getValue(f, "sequenceIndex"), 1);
229    // next residue offset to search from is 5
230  0 assertEquals(PA.getValue(f, "residueIndex"), 5);
231   
232    // find next from end of sequence - finds next sequence id
233  0 f = new Finder(av);
234  0 PA.setValue(f, "sequenceIndex", 1);
235  0 PA.setValue(f, "residueIndex", 7);
236  0 f.findNext("e", false, false, false, false);
237  0 assertEquals(f.getIdMatches().size(), 1);
238  0 assertSame(f.getIdMatches().get(0), al.getSequenceAt(2));
239  0 assertTrue(f.getSearchResults().isEmpty());
240    }
241   
242    /**
243    * Test for matching within sequence descriptions
244    */
 
245  0 toggle @Test(groups = "Functional")
246    public void testFind_inDescription()
247    {
248  0 AlignmentI al2 = new Alignment(al);
249  0 al2.getSequenceAt(0).setDescription("BRAF");
250  0 al2.getSequenceAt(1).setDescription("braf");
251   
252  0 AlignViewportI av2 = new AlignViewport(al2);
253   
254    /*
255    * find first match only
256    */
257  0 Finder f = new Finder(av2);
258  0 f.findNext("rAF", false, true, false, false);
259  0 assertEquals(f.getIdMatches().size(), 1);
260  0 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
261  0 assertTrue(f.getSearchResults().isEmpty());
262   
263    /*
264    * find all matches
265    */
266  0 f = new Finder(av2);
267  0 f.findAll("rAF", false, true, false, false);
268  0 assertEquals(f.getIdMatches().size(), 2);
269  0 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
270  0 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
271  0 assertTrue(f.getSearchResults().isEmpty());
272   
273    /*
274    * case sensitive
275    */
276  0 f = new Finder(av2);
277  0 f.findAll("RAF", true, true, false, false);
278  0 assertEquals(f.getIdMatches().size(), 1);
279  0 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
280  0 assertTrue(f.getSearchResults().isEmpty());
281   
282    /*
283    * match sequence id, description and sequence!
284    */
285  0 al2.getSequenceAt(0).setDescription("the efh sequence");
286  0 al2.getSequenceAt(0).setName("mouseEFHkinase");
287  0 al2.getSequenceAt(1).setName("humanEFHkinase");
288  0 f = new Finder(av2);
289   
290    /*
291    * sequence matches should have no duplicates
292    */
293  0 f.findAll("EFH", false, true, false, false);
294  0 assertEquals(f.getIdMatches().size(), 2);
295  0 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
296  0 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
297   
298  0 assertEquals(f.getSearchResults().getCount(), 2);
299  0 SearchResultMatchI match = f.getSearchResults().getResults().get(0);
300  0 assertSame(match.getSequence(), al2.getSequenceAt(1));
301  0 assertEquals(match.getStart(), 5);
302  0 assertEquals(match.getEnd(), 7);
303  0 match = f.getSearchResults().getResults().get(1);
304  0 assertSame(match.getSequence(), al2.getSequenceAt(2));
305  0 assertEquals(match.getStart(), 4);
306  0 assertEquals(match.getEnd(), 6);
307    }
308   
309    /**
310    * Test for matching within sequence ids
311    */
 
312  0 toggle @Test(groups = "Functional")
313    public void testFindAll_sequenceIds()
314    {
315  0 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  0 f.findAll("SEQ1", false, false, false, false);
322  0 assertEquals(f.getIdMatches().size(), 1);
323  0 assertSame(f.getIdMatches().get(0), al.getSequenceAt(0));
324  0 SearchResultsI searchResults = f.getSearchResults();
325  0 assertTrue(searchResults.isEmpty());
326   
327    /*
328    * case sensitive
329    */
330  0 f = new Finder(av);
331  0 f.findAll("SEQ1", true, false, false, false);
332  0 searchResults = f.getSearchResults();
333  0 assertTrue(searchResults.isEmpty());
334   
335    /*
336    * match both sequence id and sequence
337    */
338  0 AlignmentI al2 = new Alignment(al);
339  0 AlignViewportI av2 = new AlignViewport(al2);
340  0 al2.addSequence(new Sequence("aBz", "xyzabZpqrAbZ"));
341  0 f = new Finder(av2);
342  0 f.findAll("ABZ", false, false, false, false);
343  0 assertEquals(f.getIdMatches().size(), 1);
344  0 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(4));
345  0 searchResults = f.getSearchResults();
346  0 assertEquals(searchResults.getCount(), 2);
347  0 SearchResultMatchI match = searchResults.getResults().get(0);
348  0 assertSame(match.getSequence(), al2.getSequenceAt(4));
349  0 assertEquals(match.getStart(), 4);
350  0 assertEquals(match.getEnd(), 6);
351  0 match = searchResults.getResults().get(1);
352  0 assertSame(match.getSequence(), al2.getSequenceAt(4));
353  0 assertEquals(match.getStart(), 10);
354  0 assertEquals(match.getEnd(), 12);
355    }
356   
357    /**
358    * Test finding next match of a sequence pattern in an alignment
359    */
 
360  0 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  0 FinderI f = new Finder(av);
371  0 f.findNext("EfH", false, false, false, false);
372  0 SearchResultsI searchResults = f.getSearchResults();
373  0 assertEquals(searchResults.getCount(), 1);
374  0 SearchResultMatchI match = searchResults.getResults().get(0);
375  0 assertSame(match.getSequence(), al.getSequenceAt(1));
376  0 assertEquals(match.getStart(), 5);
377  0 assertEquals(match.getEnd(), 7);
378   
379    /*
380    * I should be found in seq1 (twice) and seq2 (once)
381    */
382  0 f = new Finder(av);
383  0 f.findNext("I", false, false, false, false); // find next: seq1/16
384  0 searchResults = f.getSearchResults();
385  0 assertEquals(searchResults.getCount(), 1);
386  0 match = searchResults.getResults().get(0);
387  0 assertSame(match.getSequence(), al.getSequenceAt(0));
388  0 assertEquals(match.getStart(), 16);
389  0 assertEquals(match.getEnd(), 16);
390   
391  0 f.findNext("I", false, false, false, false); // find next: seq1/18
392  0 searchResults = f.getSearchResults();
393  0 assertEquals(searchResults.getCount(), 1);
394  0 match = searchResults.getResults().get(0);
395  0 assertSame(match.getSequence(), al.getSequenceAt(0));
396  0 assertEquals(match.getStart(), 18);
397  0 assertEquals(match.getEnd(), 18);
398   
399  0 f.findNext("I", false, false, false, false); // find next: seq2/8
400  0 searchResults = f.getSearchResults();
401  0 assertEquals(searchResults.getCount(), 1);
402  0 match = searchResults.getResults().get(0);
403  0 assertSame(match.getSequence(), al.getSequenceAt(1));
404  0 assertEquals(match.getStart(), 8);
405  0 assertEquals(match.getEnd(), 8);
406   
407  0 f.findNext("I", false, false, false, false);
408  0 assertTrue(f.getSearchResults().isEmpty());
409   
410    /*
411    * find should reset to start of alignment after a failed search
412    */
413  0 f.findNext("I", false, false, false, false); // find next: seq1/16
414  0 searchResults = f.getSearchResults();
415  0 assertEquals(searchResults.getCount(), 1);
416  0 match = searchResults.getResults().get(0);
417  0 assertSame(match.getSequence(), al.getSequenceAt(0));
418  0 assertEquals(match.getStart(), 16);
419  0 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  0 toggle @Test(groups = "Functional")
427    public void testFindAll_maximalResultOnly()
428    {
429  0 Finder f = new Finder(av);
430  0 f.findAll("M+", false, false, false, false);
431  0 SearchResultsI searchResults = f.getSearchResults();
432  0 assertEquals(searchResults.getCount(), 1);
433  0 SearchResultMatchI match = searchResults.getResults().get(0);
434  0 assertSame(match.getSequence(), al.getSequenceAt(3));
435  0 assertEquals(match.getStart(), 4); // dataset sequence positions
436  0 assertEquals(match.getEnd(), 8); // base 1
437    }
438   
439    /**
440    * Test finding all matches of a sequence pattern in an alignment
441    */
 
442  0 toggle @Test(groups = "Functional")
443    public void testFindAll()
444    {
445  0 Finder f = new Finder(av);
446  0 f.findAll("EfH", false, false, false, false);
447  0 SearchResultsI searchResults = f.getSearchResults();
448  0 assertEquals(searchResults.getCount(), 2);
449  0 SearchResultMatchI match = searchResults.getResults().get(0);
450  0 assertSame(match.getSequence(), al.getSequenceAt(1));
451  0 assertEquals(match.getStart(), 5);
452  0 assertEquals(match.getEnd(), 7);
453  0 match = searchResults.getResults().get(1);
454  0 assertSame(match.getSequence(), al.getSequenceAt(2));
455  0 assertEquals(match.getStart(), 4);
456  0 assertEquals(match.getEnd(), 6);
457   
458    /*
459    * find all I should find 2 positions in seq1, 1 in seq2
460    */
461  0 f.findAll("I", false, false, false, false);
462  0 searchResults = f.getSearchResults();
463  0 assertEquals(searchResults.getCount(), 3);
464  0 match = searchResults.getResults().get(0);
465  0 assertSame(match.getSequence(), al.getSequenceAt(0));
466  0 assertEquals(match.getStart(), 16);
467  0 assertEquals(match.getEnd(), 16);
468  0 match = searchResults.getResults().get(1);
469  0 assertSame(match.getSequence(), al.getSequenceAt(0));
470  0 assertEquals(match.getStart(), 18);
471  0 assertEquals(match.getEnd(), 18);
472  0 match = searchResults.getResults().get(2);
473  0 assertSame(match.getSequence(), al.getSequenceAt(1));
474  0 assertEquals(match.getStart(), 8);
475  0 assertEquals(match.getEnd(), 8);
476    }
477   
478    /**
479    * Test finding all matches, case-sensitive
480    */
 
481  0 toggle @Test(groups = "Functional")
482    public void testFindAll_caseSensitive()
483    {
484  0 Finder f = new Finder(av);
485   
486    /*
487    * BC should match seq1/9-10 and seq2/2-3
488    */
489  0 f.findAll("BC", true, false, false, false);
490  0 SearchResultsI searchResults = f.getSearchResults();
491  0 assertEquals(searchResults.getCount(), 2);
492  0 SearchResultMatchI match = searchResults.getResults().get(0);
493  0 assertSame(match.getSequence(), al.getSequenceAt(0));
494  0 assertEquals(match.getStart(), 9);
495  0 assertEquals(match.getEnd(), 10);
496  0 match = searchResults.getResults().get(1);
497  0 assertSame(match.getSequence(), al.getSequenceAt(1));
498  0 assertEquals(match.getStart(), 2);
499  0 assertEquals(match.getEnd(), 3);
500   
501    /*
502    * bc should match seq3/1-2
503    */
504  0 f = new Finder(av);
505  0 f.findAll("bc", true, false, false, false);
506  0 searchResults = f.getSearchResults();
507  0 assertEquals(searchResults.getCount(), 1);
508  0 match = searchResults.getResults().get(0);
509  0 assertSame(match.getSequence(), al.getSequenceAt(2));
510  0 assertEquals(match.getStart(), 1);
511  0 assertEquals(match.getEnd(), 2);
512   
513  0 f.findAll("bC", true, false, false, false);
514  0 assertTrue(f.getSearchResults().isEmpty());
515    }
516   
517    /**
518    * Test finding next match of a sequence pattern in a selection group
519    */
 
520  0 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  0 SequenceGroup sg = new SequenceGroup();
529  0 sg.setStartRes(3);
530  0 sg.setEndRes(5);
531  0 sg.addSequence(al.getSequenceAt(1), false);
532  0 sg.addSequence(al.getSequenceAt(2), false);
533  0 av.setSelectionGroup(sg);
534   
535  0 FinderI f = new Finder(av);
536  0 f.findNext("b", false, false, false, false);
537  0 assertTrue(f.getIdMatches().isEmpty());
538  0 SearchResultsI searchResults = f.getSearchResults();
539  0 assertEquals(searchResults.getCount(), 1);
540  0 SearchResultMatchI match = searchResults.getResults().get(0);
541  0 assertSame(match.getSequence(), al.getSequenceAt(1));
542  0 assertEquals(match.getStart(), 2);
543  0 assertEquals(match.getEnd(), 2);
544   
545    /*
546    * a second Find should not return the 'b' in seq3 as outside the selection
547    */
548  0 f.findNext("b", false, false, false, false);
549  0 assertTrue(f.getSearchResults().isEmpty());
550  0 assertTrue(f.getIdMatches().isEmpty());
551   
552  0 f = new Finder(av);
553  0 f.findNext("d", false, false, false, false);
554  0 assertTrue(f.getIdMatches().isEmpty());
555  0 searchResults = f.getSearchResults();
556  0 assertEquals(searchResults.getCount(), 1);
557  0 match = searchResults.getResults().get(0);
558  0 assertSame(match.getSequence(), al.getSequenceAt(1));
559  0 assertEquals(match.getStart(), 4);
560  0 assertEquals(match.getEnd(), 4);
561  0 f.findNext("d", false, false, false, false);
562  0 assertTrue(f.getIdMatches().isEmpty());
563  0 searchResults = f.getSearchResults();
564  0 assertEquals(searchResults.getCount(), 1);
565  0 match = searchResults.getResults().get(0);
566  0 assertSame(match.getSequence(), al.getSequenceAt(2));
567  0 assertEquals(match.getStart(), 3);
568  0 assertEquals(match.getEnd(), 3);
569    }
570   
571    /**
572    * Test finding all matches of a search pattern in a selection group
573    */
 
574  0 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  0 SequenceGroup sg = new SequenceGroup();
583  0 sg.setStartRes(3);
584  0 sg.setEndRes(5);
585  0 sg.addSequence(al.getSequenceAt(1), false);
586  0 sg.addSequence(al.getSequenceAt(2), false);
587  0 av.setSelectionGroup(sg);
588   
589    /*
590    * search for 'e' should match two sequence ids and one residue
591    */
592  0 Finder f = new Finder(av);
593  0 f.findAll("e", false, false, false, false);
594  0 assertEquals(f.getIdMatches().size(), 2);
595  0 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
596  0 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
597  0 SearchResultsI searchResults = f.getSearchResults();
598  0 assertEquals(searchResults.getCount(), 1);
599  0 SearchResultMatchI match = searchResults.getResults().get(0);
600  0 assertSame(match.getSequence(), al.getSequenceAt(2));
601  0 assertEquals(match.getStart(), 4);
602  0 assertEquals(match.getEnd(), 4);
603   
604    /*
605    * search for 'Q' should match two sequence ids only
606    */
607  0 f = new Finder(av);
608  0 f.findAll("Q", false, false, false, false);
609  0 assertEquals(f.getIdMatches().size(), 2);
610  0 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
611  0 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
612  0 assertTrue(f.getSearchResults().isEmpty());
613    }
614   
615    /**
616    * Test finding in selection with a sequence too short to reach it
617    */
 
618  0 toggle @Test(groups = "Functional")
619    public void testFind_findAllInSelectionWithShortSequence()
620    {
621    /*
622    * select all sequences, columns 10-12
623    * BCD
624    * cdE
625    */
626  0 SequenceGroup sg = new SequenceGroup();
627  0 sg.setStartRes(9);
628  0 sg.setEndRes(11);
629  0 sg.addSequence(al.getSequenceAt(0), false);
630  0 sg.addSequence(al.getSequenceAt(1), false);
631  0 sg.addSequence(al.getSequenceAt(2), false);
632  0 sg.addSequence(al.getSequenceAt(3), false);
633  0 av.setSelectionGroup(sg);
634   
635    /*
636    * search for 'I' should match two sequence positions
637    */
638  0 Finder f = new Finder(av);
639  0 f.findAll("I", false, false, false, false);
640  0 assertTrue(f.getIdMatches().isEmpty());
641  0 SearchResultsI searchResults = f.getSearchResults();
642  0 assertEquals(searchResults.getCount(), 2);
643  0 SearchResultMatchI match = searchResults.getResults().get(0);
644  0 assertSame(match.getSequence(), al.getSequenceAt(0));
645  0 assertEquals(match.getStart(), 16);
646  0 assertEquals(match.getEnd(), 16);
647  0 match = searchResults.getResults().get(1);
648  0 assertSame(match.getSequence(), al.getSequenceAt(1));
649  0 assertEquals(match.getStart(), 8);
650  0 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  0 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  0 HiddenColumns hc = new HiddenColumns();
673  0 hc.hideColumns(3, 3);
674  0 al.setHiddenColumns(hc);
675  0 Finder f = new Finder(av);
676  0 f.findAll("aaa", false, false, false, false);
677  0 SearchResultsI searchResults = f.getSearchResults();
678  0 assertEquals(searchResults.getCount(), 2);
679  0 SearchResultMatchI match = searchResults.getResults().get(0);
680  0 assertSame(match.getSequence(), al.getSequenceAt(3));
681  0 assertEquals(match.getStart(), 1);
682  0 assertEquals(match.getEnd(), 3);
683  0 match = searchResults.getResults().get(1);
684  0 assertSame(match.getSequence(), al.getSequenceAt(3));
685  0 assertEquals(match.getStart(), 9);
686  0 assertEquals(match.getEnd(), 11);
687   
688    /*
689    * hide 2-4 (CD- -BC bcd ---)
690    */
691  0 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  0 f = new Finder(av);
698  0 f.findAll("D", false, false, false, false);
699  0 searchResults = f.getSearchResults();
700  0 assertEquals(searchResults.getCount(), 1);
701  0 match = searchResults.getResults().get(0);
702  0 assertSame(match.getSequence(), al.getSequenceAt(1));
703  0 assertEquals(match.getStart(), 4);
704  0 assertEquals(match.getEnd(), 4);
705   
706    /*
707    * search for AD should fail although these are now
708    * consecutive in the visible columns
709    */
710  0 f = new Finder(av);
711  0 f.findAll("AD", false, false, false, false);
712  0 searchResults = f.getSearchResults();
713  0 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  0 f = new Finder(av);
720  0 f.findAll("aaa", false, false, false, false);
721  0 searchResults = f.getSearchResults();
722  0 assertEquals(searchResults.getCount(), 2);
723  0 match = searchResults.getResults().get(0);
724  0 assertSame(match.getSequence(), al.getSequenceAt(3));
725  0 assertEquals(match.getStart(), 1);
726  0 assertEquals(match.getEnd(), 3);
727  0 match = searchResults.getResults().get(1);
728  0 assertSame(match.getSequence(), al.getSequenceAt(3));
729  0 assertEquals(match.getStart(), 9);
730  0 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  0 hc.hideColumns(2, 5);
738  0 f = new Finder(av);
739  0 f.findAll("aaa", false, false, false, false);
740  0 searchResults = f.getSearchResults();
741  0 assertEquals(searchResults.getCount(), 2);
742  0 match = searchResults.getResults().get(0);
743  0 assertSame(match.getSequence(), al.getSequenceAt(3));
744  0 assertEquals(match.getStart(), 1);
745  0 assertEquals(match.getEnd(), 3);
746  0 match = searchResults.getResults().get(1);
747  0 assertSame(match.getSequence(), al.getSequenceAt(3));
748  0 assertEquals(match.getStart(), 9);
749  0 assertEquals(match.getEnd(), 11);
750   
751    /*
752    * find all 'BE' should not match across hidden columns in seq1
753    */
754  0 f.findAll("BE", false, false, false, false);
755  0 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  0 hc.revealAllHiddenColumns(new ColumnSelection());
762  0 hc.hideColumns(8, 13);
763  0 f = new Finder(av);
764  0 f.findNext("H", false, false, false, false);
765  0 searchResults = f.getSearchResults();
766  0 assertEquals(searchResults.getCount(), 1);
767  0 match = searchResults.getResults().get(0);
768  0 assertSame(match.getSequence(), al.getSequenceAt(2));
769  0 assertEquals(match.getStart(), 6);
770  0 assertEquals(match.getEnd(), 6);
771    }
772   
 
773  0 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  0 HiddenColumns hc = new HiddenColumns();
788  0 hc.hideColumns(2, 4);
789  0 hc.hideColumns(6, 7);
790  0 al.setHiddenColumns(hc);
791   
792    /*
793    * select rows 2-3
794    */
795  0 SequenceGroup sg = new SequenceGroup();
796  0 sg.addSequence(al.getSequenceAt(1), false);
797  0 sg.addSequence(al.getSequenceAt(2), false);
798  0 sg.setStartRes(0);
799  0 sg.setEndRes(13);
800  0 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  0 Finder f = new Finder(av);
807  0 f.findAll("[AH]", false, false, false, false);
808  0 SearchResultsI searchResults = f.getSearchResults();
809  0 assertEquals(searchResults.getCount(), 2);
810  0 SearchResultMatchI match = searchResults.getResults().get(0);
811  0 assertSame(match.getSequence(), al.getSequenceAt(1));
812  0 assertEquals(match.getStart(), 1);
813  0 assertEquals(match.getEnd(), 1);
814  0 match = searchResults.getResults().get(1);
815  0 assertSame(match.getSequence(), al.getSequenceAt(1));
816  0 assertEquals(match.getStart(), 7);
817  0 assertEquals(match.getEnd(), 7);
818    }
819   
 
820  0 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  0 HiddenColumns hc = new HiddenColumns();
831  0 hc.hideColumns(2, 4);
832  0 hc.hideColumns(7, 7);
833  0 al.setHiddenColumns(hc);
834   
835    /*
836    * now have
837    * 015689
838    * AB-E-GHI
839    * A-DeHI
840    * --EF
841    * aaaMMMMaaa
842    */
843  0 Finder f = new Finder(av);
844  0 f.findAll("abe", false, false, false, true); // true = ignore hidden
845  0 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  0 assertEquals(searchResults.getCount(), 1);
852  0 assertEquals(searchResults.getResults().size(), 2);
853  0 SearchResultMatchI match = searchResults.getResults().get(0);
854  0 assertSame(match.getSequence(), al.getSequenceAt(0));
855  0 assertEquals(match.getStart(), 8); // A
856  0 assertEquals(match.getEnd(), 9); // B
857  0 match = searchResults.getResults().get(1);
858  0 assertSame(match.getSequence(), al.getSequenceAt(0));
859  0 assertEquals(match.getStart(), 12); // E
860  0 assertEquals(match.getEnd(), 12);
861   
862  0 f = new Finder(av);
863  0 f.findNext("a.E", false, false, false, true);
864  0 searchResults = f.getSearchResults();
865  0 assertEquals(searchResults.getCount(), 1);
866  0 assertEquals(searchResults.getResults().size(), 2);
867  0 match = searchResults.getResults().get(0);
868  0 assertSame(match.getSequence(), al.getSequenceAt(0));
869  0 assertEquals(match.getStart(), 8); // A
870  0 assertEquals(match.getEnd(), 9); // B
871  0 match = searchResults.getResults().get(1);
872  0 assertSame(match.getSequence(), al.getSequenceAt(0));
873  0 assertEquals(match.getStart(), 12); // E
874  0 assertEquals(match.getEnd(), 12);
875   
876  0 f.findNext("a.E", false, false, false, true);
877  0 searchResults = f.getSearchResults();
878  0 assertEquals(searchResults.getCount(), 1);
879  0 assertEquals(searchResults.getResults().size(), 2);
880  0 match = searchResults.getResults().get(0);
881  0 assertSame(match.getSequence(), al.getSequenceAt(1));
882  0 assertEquals(match.getStart(), 1); // a
883  0 assertEquals(match.getEnd(), 1);
884  0 match = searchResults.getResults().get(1);
885  0 assertSame(match.getSequence(), al.getSequenceAt(1));
886  0 assertEquals(match.getStart(), 4); // D
887  0 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  0 f.findAll("BEG", false, false, false, true);
894  0 searchResults = f.getSearchResults();
895  0 assertEquals(searchResults.getCount(), 1);
896  0 assertEquals(searchResults.getResults().size(), 3);
897  0 match = searchResults.getResults().get(0);
898  0 assertSame(match.getSequence(), al.getSequenceAt(0));
899  0 assertEquals(match.getStart(), 9); // B
900  0 assertEquals(match.getEnd(), 9);
901  0 match = searchResults.getResults().get(1);
902  0 assertSame(match.getSequence(), al.getSequenceAt(0));
903  0 assertEquals(match.getStart(), 12); // E
904  0 assertEquals(match.getEnd(), 12);
905  0 match = searchResults.getResults().get(2);
906  0 assertSame(match.getSequence(), al.getSequenceAt(0));
907  0 assertEquals(match.getStart(), 14); // G
908  0 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  0 SequenceGroup selection = new SequenceGroup();
916  0 selection.setStartRes(0);
917  0 selection.setEndRes(9);
918  0 al.getSequences().forEach(seq -> selection.addSequence(seq, false));
919  0 av.setSelectionGroup(selection);
920  0 f.findAll("A.*H", false, false, false, true);
921  0 searchResults = f.getSearchResults();
922  0 assertEquals(searchResults.getCount(), 1);
923  0 assertEquals(searchResults.getResults().size(), 3);
924    // match made of contiguous matches A, DE, H
925  0 match = searchResults.getResults().get(0);
926  0 assertSame(match.getSequence(), al.getSequenceAt(1));
927  0 assertEquals(match.getStart(), 1); // A
928  0 assertEquals(match.getEnd(), 1);
929  0 match = searchResults.getResults().get(1);
930  0 assertSame(match.getSequence(), al.getSequenceAt(1));
931  0 assertEquals(match.getStart(), 4); // D
932  0 assertEquals(match.getEnd(), 5); // E
933  0 match = searchResults.getResults().get(2);
934  0 assertSame(match.getSequence(), al.getSequenceAt(1));
935  0 assertEquals(match.getStart(), 7); // H (there is no G)
936  0 assertEquals(match.getEnd(), 7);
937    }
938   
 
939  0 toggle @Test(groups = "Functional")
940    public void testFind_featuresOnly()
941    {
942  0 Finder f = new Finder(av);
943    // no match when not searching feature descriptions
944  0 f.findAll("Feature", false, false, false, true);
945  0 assertEquals(f.getSearchResults().getCount(), 0);
946   
947    // no match when case sensitive on feature descriptions
948  0 f.findAll("feature", true, false, true, true);
949  0 assertEquals(f.getSearchResults().getCount(), 0);
950   
951    // search feature descriptions - all match
952  0 f.findAll("Feature", false, false, true, true);
953  0 assertEquals(f.getSearchResults().getCount(), 3);
954   
955  0 List<SequenceI> seqs = f.getSearchResults().getMatchingSubSequences();
956    // assume order is preserved in results
957  0 assertEquals(al.getSequenceAt(0).getDatasetSequence(),
958    seqs.get(0).getDatasetSequence());
959  0 assertEquals(seqs.get(0).getStart(), 9);
960  0 assertEquals(seqs.get(0).getEnd(), 11);
961  0 assertEquals(al.getSequenceAt(3).getDatasetSequence(),
962    seqs.get(1).getDatasetSequence());
963  0 assertEquals(seqs.get(1).getStart(), 9);
964  0 assertEquals(seqs.get(1).getEnd(), 11);
965  0 assertEquals(al.getSequenceAt(3).getDatasetSequence(),
966    seqs.get(2).getDatasetSequence());
967  0 assertEquals(seqs.get(2).getStart(), 1);
968  0 assertEquals(seqs.get(2).getEnd(), 3);
969   
970  0 SequenceI sq = null;
971    // search feature descriptions incrementally
972    // assume same order as before
973  0 f.findNext("Feature", false, false, true, true);
974  0 assertEquals(f.getSearchResults().getCount(), 1);
975  0 sq = f.getSearchResults().getMatchingSubSequences().get(0);
976  0 assertEquals(sq.getSequenceAsString(),
977    seqs.get(0).getSequenceAsString());
978   
979    // ..
980  0 f.findNext("Feature", false, false, true, true);
981  0 assertEquals(f.getSearchResults().getCount(), 1);
982  0 sq = f.getSearchResults().getMatchingSubSequences().get(0);
983  0 assertEquals(sq.getSequenceAsString(),
984    seqs.get(1).getSequenceAsString());
985   
986    // ..
987  0 f.findNext("Feature", false, false, true, true);
988  0 assertEquals(f.getSearchResults().getCount(), 1);
989  0 sq = f.getSearchResults().getMatchingSubSequences().get(0);
990  0 assertEquals(sq.getSequenceAsString(),
991    seqs.get(2).getSequenceAsString());
992   
993    }
994    }