JAL-1270 JAL-2416 JAL-2839 set alwaysRun=true in test AfterMethod!
[jalview.git] / test / jalview / analysis / FinderTest.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.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 jalview.api.AlignViewportI;
28 import jalview.api.FinderI;
29 import jalview.bin.Cache;
30 import jalview.datamodel.Alignment;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.ColumnSelection;
33 import jalview.datamodel.HiddenColumns;
34 import jalview.datamodel.SearchResultMatchI;
35 import jalview.datamodel.SearchResultsI;
36 import jalview.datamodel.Sequence;
37 import jalview.datamodel.SequenceGroup;
38 import jalview.gui.AlignFrame;
39 import jalview.gui.AlignViewport;
40 import jalview.gui.JvOptionPane;
41 import jalview.io.DataSourceType;
42 import jalview.io.FileLoader;
43
44 import java.util.List;
45
46 import org.testng.annotations.AfterMethod;
47 import org.testng.annotations.BeforeClass;
48 import org.testng.annotations.Test;
49
50 import junit.extensions.PA;
51
52 public class FinderTest
53 {
54   @BeforeClass(alwaysRun = true)
55   public void setUpJvOptionPane()
56   {
57     JvOptionPane.setInteractiveMode(false);
58     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
59   }
60
61   private AlignFrame af;
62
63   private AlignmentI al;
64
65   private AlignViewportI av;
66
67   @BeforeClass(groups = "Functional")
68   public void setUp()
69   {
70     Cache.loadProperties("test/jalview/io/testProps.jvprops");
71     Cache.applicationProperties.setProperty("PAD_GAPS",
72             Boolean.FALSE.toString());
73
74     String seqData = "seq1seq1/8-18 ABCD--EF-GHIJI\n" + "seq2 A--BCDefHI\n"
75             + "seq3 --bcdEFH\n" + "seq4 aa---aMMMMMaaa\n";
76     af = new FileLoader().LoadFileWaitTillLoaded(seqData,
77             DataSourceType.PASTE);
78     av = af.getViewport();
79     al = av.getAlignment();
80   }
81
82   @AfterMethod(alwaysRun = true)
83   public void tearDownAfterTest()
84   {
85     av.setSelectionGroup(null);
86   }
87
88   /**
89    * Test for find matches of a regular expression
90    */
91   @Test(groups = "Functional")
92   public void testFind_regex()
93   {
94     /*
95      * find next match only
96      */
97     Finder f = new Finder(av);
98     f.findNext("E.H", false, false); // 'E, any character, H'
99     // should match seq2 efH only
100     SearchResultsI sr = f.getSearchResults();
101     assertEquals(sr.getSize(), 1);
102     List<SearchResultMatchI> matches = sr.getResults();
103     assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
104     assertEquals(matches.get(0).getStart(), 5);
105     assertEquals(matches.get(0).getEnd(), 7);
106
107     f = new Finder(av);
108     f.findAll("E.H", false, false); // 'E, any character, H'
109     // should match seq2 efH and seq3 EFH
110     sr = f.getSearchResults();
111     assertEquals(sr.getSize(), 2);
112     matches = sr.getResults();
113     assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
114     assertSame(matches.get(1).getSequence(), al.getSequenceAt(2));
115     assertEquals(matches.get(0).getStart(), 5);
116     assertEquals(matches.get(0).getEnd(), 7);
117     assertEquals(matches.get(1).getStart(), 4);
118     assertEquals(matches.get(1).getEnd(), 6);
119   }
120
121   /**
122    * Test for (undocumented) find residue by position
123    */
124   @Test(groups = "Functional")
125   public void testFind_residueNumber()
126   {
127     Finder f = new Finder(av);
128
129     /*
130      * find first match should return seq1 residue 9
131      */
132     f.findNext("9", false, false);
133     SearchResultsI sr = f.getSearchResults();
134     assertEquals(sr.getSize(), 1);
135     List<SearchResultMatchI> matches = sr.getResults();
136     assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
137     assertEquals(matches.get(0).getStart(), 9);
138     assertEquals(matches.get(0).getEnd(), 9);
139
140     /*
141      * find all matches should return seq1 and seq4 (others are too short)
142      */
143     f = new Finder(av);
144     f.findAll("9", false, false);
145     sr = f.getSearchResults();
146     assertEquals(sr.getSize(), 2);
147     matches = sr.getResults();
148     assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
149     assertSame(matches.get(1).getSequence(), al.getSequenceAt(3));
150     assertEquals(matches.get(0).getStart(), 9);
151     assertEquals(matches.get(0).getEnd(), 9);
152     assertEquals(matches.get(1).getStart(), 9);
153     assertEquals(matches.get(1).getEnd(), 9);
154
155     /*
156      * parsing of search string as integer is strict
157      */
158     f = new Finder(av);
159     f.findNext(" 9", false, false);
160     assertTrue(f.getSearchResults().isEmpty());
161   }
162
163   /**
164    * Test for find next action
165    */
166   @Test(groups = "Functional")
167   public void testFindNext()
168   {
169     /*
170      * start at second sequence; colIndex of -1
171      * means sequence id / description is searched
172      */
173     Finder f = new Finder(av);
174     PA.setValue(f, "sequenceIndex", 1);
175     PA.setValue(f, "columnIndex", -1);
176     f.findNext("e", false, false); // matches id
177
178     assertTrue(f.getSearchResults().isEmpty());
179     assertEquals(f.getIdMatches().size(), 1);
180     assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
181
182     // colIndex is now 0 - for use in next find next
183     // searching A--BCDefHI
184     assertEquals(PA.getValue(f, "columnIndex"), 0);
185     f = new Finder(av);
186     PA.setValue(f, "sequenceIndex", 1);
187     PA.setValue(f, "columnIndex", 0);
188     f.findNext("e", false, false); // matches in sequence
189     assertTrue(f.getIdMatches().isEmpty());
190     assertEquals(f.getSearchResults().getSize(), 1);
191     List<SearchResultMatchI> matches = f.getSearchResults().getResults();
192     assertEquals(matches.get(0).getStart(), 5);
193     assertEquals(matches.get(0).getEnd(), 5);
194     assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
195     // still in the second sequence
196     assertEquals(PA.getValue(f, "sequenceIndex"), 1);
197     // next column position to search from is 7
198     assertEquals(PA.getValue(f, "columnIndex"), 7);
199
200     // find next from end of sequence - finds next sequence id
201     f = new Finder(av);
202     PA.setValue(f, "sequenceIndex", 1);
203     PA.setValue(f, "columnIndex", 7);
204     f.findNext("e", false, false);
205     assertEquals(f.getIdMatches().size(), 1);
206     assertSame(f.getIdMatches().get(0), al.getSequenceAt(2));
207     assertTrue(f.getSearchResults().isEmpty());
208   }
209
210   /**
211    * Test for matching within sequence descriptions
212    */
213   @Test(groups = "Functional")
214   public void testFind_inDescription()
215   {
216     AlignmentI al2 = new Alignment(al);
217     al2.getSequenceAt(0).setDescription("BRAF");
218     al2.getSequenceAt(1).setDescription("braf");
219
220     AlignViewportI av2 = new AlignViewport(al2);
221
222     /*
223      * find first match only
224      */
225     Finder f = new Finder(av2);
226     f.findNext("rAF", false, true);
227     assertEquals(f.getIdMatches().size(), 1);
228     assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
229     assertTrue(f.getSearchResults().isEmpty());
230
231     /*
232      * find all matches
233      */
234     f = new Finder(av2);
235     f.findAll("rAF", false, true);
236     assertEquals(f.getIdMatches().size(), 2);
237     assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
238     assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
239     assertTrue(f.getSearchResults().isEmpty());
240
241     /*
242      * case sensitive
243      */
244     f = new Finder(av2);
245     f.findAll("RAF", true, true);
246     assertEquals(f.getIdMatches().size(), 1);
247     assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
248     assertTrue(f.getSearchResults().isEmpty());
249
250     /*
251      * match sequence id, description and sequence!
252      */
253     al2.getSequenceAt(0).setDescription("the efh sequence");
254     al2.getSequenceAt(0).setName("mouseEFHkinase");
255     al2.getSequenceAt(1).setName("humanEFHkinase");
256     f = new Finder(av2);
257
258     /*
259      * sequence matches should have no duplicates
260      */
261     f.findAll("EFH", false, true);
262     assertEquals(f.getIdMatches().size(), 2);
263     assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
264     assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
265
266     assertEquals(f.getSearchResults().getSize(), 2);
267     SearchResultMatchI match = f.getSearchResults().getResults().get(0);
268     assertSame(match.getSequence(), al2.getSequenceAt(1));
269     assertEquals(match.getStart(), 5);
270     assertEquals(match.getEnd(), 7);
271     match = f.getSearchResults().getResults().get(1);
272     assertSame(match.getSequence(), al2.getSequenceAt(2));
273     assertEquals(match.getStart(), 4);
274     assertEquals(match.getEnd(), 6);
275   }
276
277   /**
278    * Test for matching within sequence ids
279    */
280   @Test(groups = "Functional")
281   public void testFindAll_sequenceIds()
282   {
283     Finder f = new Finder(av);
284
285     /*
286      * case insensitive; seq1 occurs twice in sequence id but
287      * only one match should be returned
288      */
289     f.findAll("SEQ1", false, false);
290     assertEquals(f.getIdMatches().size(), 1);
291     assertSame(f.getIdMatches().get(0), al.getSequenceAt(0));
292     SearchResultsI searchResults = f.getSearchResults();
293     assertTrue(searchResults.isEmpty());
294
295     /*
296      * case sensitive
297      */
298     f = new Finder(av);
299     f.findAll("SEQ1", true, false);
300     searchResults = f.getSearchResults();
301     assertTrue(searchResults.isEmpty());
302
303     /*
304      * match both sequence id and sequence
305      */
306     AlignmentI al2 = new Alignment(al);
307     AlignViewportI av2 = new AlignViewport(al2);
308     al2.addSequence(new Sequence("aBz", "xyzabZpqrAbZ"));
309     f = new Finder(av2);
310     f.findAll("ABZ", false, false);
311     assertEquals(f.getIdMatches().size(), 1);
312     assertSame(f.getIdMatches().get(0), al2.getSequenceAt(4));
313     searchResults = f.getSearchResults();
314     assertEquals(searchResults.getSize(), 2);
315     SearchResultMatchI match = searchResults.getResults().get(0);
316     assertSame(match.getSequence(), al2.getSequenceAt(4));
317     assertEquals(match.getStart(), 4);
318     assertEquals(match.getEnd(), 6);
319     match = searchResults.getResults().get(1);
320     assertSame(match.getSequence(), al2.getSequenceAt(4));
321     assertEquals(match.getStart(), 10);
322     assertEquals(match.getEnd(), 12);
323   }
324
325   /**
326    * Test finding next match of a sequence pattern in an alignment
327    */
328   @Test(groups = "Functional")
329   public void testFind_findNext()
330   {
331     /*
332      * efh should be matched in seq2 only
333      */
334     FinderI f = new Finder(av);
335     f.findNext("EfH", false, false);
336     SearchResultsI searchResults = f.getSearchResults();
337     assertEquals(searchResults.getSize(), 1);
338     SearchResultMatchI match = searchResults.getResults().get(0);
339     assertSame(match.getSequence(), al.getSequenceAt(1));
340     assertEquals(match.getStart(), 5);
341     assertEquals(match.getEnd(), 7);
342
343     /*
344      * I should be found in seq1 (twice) and seq2 (once)
345      */
346     f = new Finder(av);
347     f.findNext("I", false, false); // find next: seq1/16
348     searchResults = f.getSearchResults();
349     assertEquals(searchResults.getSize(), 1);
350     match = searchResults.getResults().get(0);
351     assertSame(match.getSequence(), al.getSequenceAt(0));
352     assertEquals(match.getStart(), 16);
353     assertEquals(match.getEnd(), 16);
354
355     f.findNext("I", false, false); // find next: seq1/18
356     searchResults = f.getSearchResults();
357     assertEquals(searchResults.getSize(), 1);
358     match = searchResults.getResults().get(0);
359     assertSame(match.getSequence(), al.getSequenceAt(0));
360     assertEquals(match.getStart(), 18);
361     assertEquals(match.getEnd(), 18);
362
363     f.findNext("I", false, false); // find next: seq2/8
364     searchResults = f.getSearchResults();
365     assertEquals(searchResults.getSize(), 1);
366     match = searchResults.getResults().get(0);
367     assertSame(match.getSequence(), al.getSequenceAt(1));
368     assertEquals(match.getStart(), 8);
369     assertEquals(match.getEnd(), 8);
370
371     f.findNext("I", false, false);
372     assertTrue(f.getSearchResults().isEmpty());
373
374     /*
375      * find should reset to start of alignment after a failed search
376      */
377     f.findNext("I", false, false); // find next: seq1/16
378     searchResults = f.getSearchResults();
379     assertEquals(searchResults.getSize(), 1);
380     match = searchResults.getResults().get(0);
381     assertSame(match.getSequence(), al.getSequenceAt(0));
382     assertEquals(match.getStart(), 16);
383     assertEquals(match.getEnd(), 16);
384   }
385
386   /**
387    * Test for JAL-2302 to verify that sub-matches are not included in a find all
388    * result
389    */
390   @Test(groups = "Functional")
391   public void testFind_maximalResultOnly()
392   {
393     Finder f = new Finder(av);
394     f.findAll("M+", false, false);
395     SearchResultsI searchResults = f.getSearchResults();
396     assertEquals(searchResults.getSize(), 1);
397     SearchResultMatchI match = searchResults.getResults().get(0);
398     assertSame(match.getSequence(), al.getSequenceAt(3));
399     assertEquals(match.getStart(), 4); // dataset sequence positions
400     assertEquals(match.getEnd(), 8); // base 1
401   }
402
403   /**
404    * Test finding all matches of a sequence pattern in an alignment
405    */
406   @Test(groups = "Functional")
407   public void testFind_findAll()
408   {
409     Finder f = new Finder(av);
410     f.findAll("EfH", false, false);
411     SearchResultsI searchResults = f.getSearchResults();
412     assertEquals(searchResults.getSize(), 2);
413     SearchResultMatchI match = searchResults.getResults().get(0);
414     assertSame(match.getSequence(), al.getSequenceAt(1));
415     assertEquals(match.getStart(), 5);
416     assertEquals(match.getEnd(), 7);
417     match = searchResults.getResults().get(1);
418     assertSame(match.getSequence(), al.getSequenceAt(2));
419     assertEquals(match.getStart(), 4);
420     assertEquals(match.getEnd(), 6);
421
422     /*
423      * find all I should find 2 positions in seq1, 1 in seq2
424      */
425     f.findAll("I", false, false);
426     searchResults = f.getSearchResults();
427     assertEquals(searchResults.getSize(), 3);
428     match = searchResults.getResults().get(0);
429     assertSame(match.getSequence(), al.getSequenceAt(0));
430     assertEquals(match.getStart(), 16);
431     assertEquals(match.getEnd(), 16);
432     match = searchResults.getResults().get(1);
433     assertSame(match.getSequence(), al.getSequenceAt(0));
434     assertEquals(match.getStart(), 18);
435     assertEquals(match.getEnd(), 18);
436     match = searchResults.getResults().get(2);
437     assertSame(match.getSequence(), al.getSequenceAt(1));
438     assertEquals(match.getStart(), 8);
439     assertEquals(match.getEnd(), 8);
440   }
441
442   /**
443    * Test finding all matches, case-sensitive
444    */
445   @Test(groups = "Functional")
446   public void testFind_findAllCaseSensitive()
447   {
448     Finder f = new Finder(av);
449
450     /*
451      * BC should match seq1/9-10 and seq2/2-3
452      */
453     f.findAll("BC", true, false);
454     SearchResultsI searchResults = f.getSearchResults();
455     assertEquals(searchResults.getSize(), 2);
456     SearchResultMatchI match = searchResults.getResults().get(0);
457     assertSame(match.getSequence(), al.getSequenceAt(0));
458     assertEquals(match.getStart(), 9);
459     assertEquals(match.getEnd(), 10);
460     match = searchResults.getResults().get(1);
461     assertSame(match.getSequence(), al.getSequenceAt(1));
462     assertEquals(match.getStart(), 2);
463     assertEquals(match.getEnd(), 3);
464
465     /*
466      * bc should match seq3/1-2
467      */
468     f = new Finder(av);
469     f.findAll("bc", true, false);
470     searchResults = f.getSearchResults();
471     assertEquals(searchResults.getSize(), 1);
472     match = searchResults.getResults().get(0);
473     assertSame(match.getSequence(), al.getSequenceAt(2));
474     assertEquals(match.getStart(), 1);
475     assertEquals(match.getEnd(), 2);
476
477     f.findAll("bC", true, false);
478     assertTrue(f.getSearchResults().isEmpty());
479   }
480
481   /**
482    * Test finding next match of a sequence pattern in a selection group
483    */
484   @Test(groups = "Functional")
485   public void testFind_inSelection()
486   {
487     /*
488      * select sequences 2 and 3, columns 4-6 which contains
489      * BCD
490      * cdE
491      */
492     SequenceGroup sg = new SequenceGroup();
493     sg.setStartRes(3);
494     sg.setEndRes(5);
495     sg.addSequence(al.getSequenceAt(1), false);
496     sg.addSequence(al.getSequenceAt(2), false);
497     av.setSelectionGroup(sg);
498
499     FinderI f = new Finder(av);
500     f.findNext("b", false, false);
501     assertTrue(f.getIdMatches().isEmpty());
502     SearchResultsI searchResults = f.getSearchResults();
503     assertEquals(searchResults.getSize(), 1);
504     SearchResultMatchI match = searchResults.getResults().get(0);
505     assertSame(match.getSequence(), al.getSequenceAt(1));
506     assertEquals(match.getStart(), 2);
507     assertEquals(match.getEnd(), 2);
508
509     /*
510      * a second Find should not return the 'b' in seq3 as outside the selection
511      */
512     f.findNext("b", false, false);
513     assertTrue(f.getSearchResults().isEmpty());
514     assertTrue(f.getIdMatches().isEmpty());
515
516     f = new Finder(av);
517     f.findNext("d", false, false);
518     assertTrue(f.getIdMatches().isEmpty());
519     searchResults = f.getSearchResults();
520     assertEquals(searchResults.getSize(), 1);
521     match = searchResults.getResults().get(0);
522     assertSame(match.getSequence(), al.getSequenceAt(1));
523     assertEquals(match.getStart(), 4);
524     assertEquals(match.getEnd(), 4);
525     f.findNext("d", false, false);
526     assertTrue(f.getIdMatches().isEmpty());
527     searchResults = f.getSearchResults();
528     assertEquals(searchResults.getSize(), 1);
529     match = searchResults.getResults().get(0);
530     assertSame(match.getSequence(), al.getSequenceAt(2));
531     assertEquals(match.getStart(), 3);
532     assertEquals(match.getEnd(), 3);
533   }
534
535   /**
536    * Test finding all matches of a search pattern in a selection group
537    */
538   @Test(groups = "Functional")
539   public void testFind_findAllInSelection()
540   {
541     /*
542      * select sequences 2 and 3, columns 4-6 which contains
543      * BCD
544      * cdE
545      */
546     SequenceGroup sg = new SequenceGroup();
547     sg.setStartRes(3);
548     sg.setEndRes(5);
549     sg.addSequence(al.getSequenceAt(1), false);
550     sg.addSequence(al.getSequenceAt(2), false);
551     av.setSelectionGroup(sg);
552   
553     /*
554      * search for 'e' should match two sequence ids and one residue
555      */
556     Finder f = new Finder(av);
557     f.findAll("e", false, false);
558     assertEquals(f.getIdMatches().size(), 2);
559     assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
560     assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
561     SearchResultsI searchResults = f.getSearchResults();
562     assertEquals(searchResults.getSize(), 1);
563     SearchResultMatchI match = searchResults.getResults().get(0);
564     assertSame(match.getSequence(), al.getSequenceAt(2));
565     assertEquals(match.getStart(), 4);
566     assertEquals(match.getEnd(), 4);
567
568     /*
569      * search for 'Q' should match two sequence ids only
570      */
571     f = new Finder(av);
572     f.findAll("Q", false, false);
573     assertEquals(f.getIdMatches().size(), 2);
574     assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
575     assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
576     assertTrue(f.getSearchResults().isEmpty());
577   }
578
579   /**
580    * Test finding in selection with a sequence too short to reach it
581    */
582   @Test(groups = "Functional")
583   public void testFind_findAllInSelectionWithShortSequence()
584   {
585     /*
586      * select all sequences, columns 10-12
587      * BCD
588      * cdE
589      */
590     SequenceGroup sg = new SequenceGroup();
591     sg.setStartRes(9);
592     sg.setEndRes(11);
593     sg.addSequence(al.getSequenceAt(0), false);
594     sg.addSequence(al.getSequenceAt(1), false);
595     sg.addSequence(al.getSequenceAt(2), false);
596     sg.addSequence(al.getSequenceAt(3), false);
597     av.setSelectionGroup(sg);
598
599     /*
600      * search for 'I' should match two sequence positions
601      */
602     Finder f = new Finder(av);
603     f.findAll("I", false, false);
604     assertTrue(f.getIdMatches().isEmpty());
605     SearchResultsI searchResults = f.getSearchResults();
606     assertEquals(searchResults.getSize(), 2);
607     SearchResultMatchI match = searchResults.getResults().get(0);
608     assertSame(match.getSequence(), al.getSequenceAt(0));
609     assertEquals(match.getStart(), 16);
610     assertEquals(match.getEnd(), 16);
611     match = searchResults.getResults().get(1);
612     assertSame(match.getSequence(), al.getSequenceAt(1));
613     assertEquals(match.getStart(), 8);
614     assertEquals(match.getEnd(), 8);
615   }
616
617   /**
618    * Test that find does not report hidden positions
619    */
620   @Test(groups = "Functional")
621   public void testFind_withHiddenColumns()
622   {
623     /*
624      * 0    5   9
625      * ABCD--EF-GHI
626      * A--BCDefHI
627      * --bcdEFH
628      * aa---aMMMMMaaa
629      */
630
631     /*
632      * hide 2-4 (CD- -BC bcd ---)
633      */
634     HiddenColumns hc = new HiddenColumns();
635     hc.hideColumns(2, 4);
636     al.setHiddenColumns(hc);
637
638     /*
639      * find all search for D should ignore hidden positions in seq1 and seq3,
640      * find the visible D in seq2
641      */
642     Finder f = new Finder(av);
643     f.findAll("D", false, false);
644     SearchResultsI searchResults = f.getSearchResults();
645     assertEquals(searchResults.getSize(), 1);
646     SearchResultMatchI match = searchResults.getResults().get(0);
647     assertSame(match.getSequence(), al.getSequenceAt(1));
648     assertEquals(match.getStart(), 4);
649     assertEquals(match.getEnd(), 4);
650
651     /*
652      * hide columns 2-5:
653      * find all 'aaa' should find end of seq4 only
654      */
655     hc.hideColumns(2, 5);
656     f = new Finder(av);
657     f.findAll("aaa", false, false);
658     searchResults = f.getSearchResults();
659     assertEquals(searchResults.getSize(), 1);
660     match = searchResults.getResults().get(0);
661     assertSame(match.getSequence(), al.getSequenceAt(3));
662     assertEquals(match.getStart(), 9);
663     assertEquals(match.getEnd(), 11);
664
665     /*
666      * find all 'BE' should not match across hidden columns in seq1
667      */
668     f.findAll("BE", false, false);
669     assertTrue(f.getSearchResults().isEmpty());
670
671     /*
672      * boundary case: hide columns at end of alignment
673      * search for H should match seq3/6 only
674      */
675     hc.revealAllHiddenColumns(new ColumnSelection());
676     hc.hideColumns(8, 13);
677     f = new Finder(av);
678     f.findNext("H", false, false);
679     searchResults = f.getSearchResults();
680     assertEquals(searchResults.getSize(), 1);
681     match = searchResults.getResults().get(0);
682     assertSame(match.getSequence(), al.getSequenceAt(2));
683     assertEquals(match.getStart(), 6);
684     assertEquals(match.getEnd(), 6);
685   }
686
687   @Test(groups = "Functional")
688   public void testFind_withHiddenColumnsAndSelection()
689   {
690     /*
691      * 0    5   9
692      * ABCD--EF-GHI
693      * A--BCDefHI
694      * --bcdEFH
695      * aa---aMMMMMaaa
696      */
697   
698     /*
699      * hide columns 2-4 and 6-7
700      */
701     HiddenColumns hc = new HiddenColumns();
702     hc.hideColumns(2, 4);
703     hc.hideColumns(6, 7);
704     al.setHiddenColumns(hc);
705   
706     /*
707      * select rows 2-3
708      */
709     SequenceGroup sg = new SequenceGroup();
710     sg.addSequence(al.getSequenceAt(1), false);
711     sg.addSequence(al.getSequenceAt(2), false);
712     sg.setStartRes(0);
713     sg.setEndRes(13);
714     av.setSelectionGroup(sg);
715
716     /*
717      * find all search for A or H
718      * should match seq2/1, seq2/7, not seq3/6
719      */
720     Finder f = new Finder(av);
721     f.findAll("[AH]", false, false);
722     SearchResultsI searchResults = f.getSearchResults();
723     assertEquals(searchResults.getSize(), 2);
724     SearchResultMatchI match = searchResults.getResults().get(0);
725     assertSame(match.getSequence(), al.getSequenceAt(1));
726     assertEquals(match.getStart(), 1);
727     assertEquals(match.getEnd(), 1);
728     match = searchResults.getResults().get(1);
729     assertSame(match.getSequence(), al.getSequenceAt(1));
730     assertEquals(match.getStart(), 7);
731     assertEquals(match.getEnd(), 7);
732   }
733 }