2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.analysis;
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertSame;
25 import static org.testng.Assert.assertTrue;
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;
44 import java.util.List;
46 import org.testng.annotations.AfterMethod;
47 import org.testng.annotations.BeforeClass;
48 import org.testng.annotations.Test;
50 import junit.extensions.PA;
52 public class FinderTest
54 @BeforeClass(alwaysRun = true)
55 public void setUpJvOptionPane()
57 JvOptionPane.setInteractiveMode(false);
58 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
61 private AlignFrame af;
63 private AlignmentI al;
65 private AlignViewportI av;
67 @BeforeClass(groups = "Functional")
70 Cache.loadProperties("test/jalview/io/testProps.jvprops");
71 Cache.applicationProperties.setProperty("PAD_GAPS",
72 Boolean.FALSE.toString());
76 "seq1/8-18 ABCD--EF-GHIJI\n" +
79 "seq4 aa---aMMMMMaaa\n";
81 af = new FileLoader().LoadFileWaitTillLoaded(seqData,
82 DataSourceType.PASTE);
83 av = af.getViewport();
84 al = av.getAlignment();
87 @AfterMethod(alwaysRun = true)
88 public void tearDownAfterTest()
90 av.setSelectionGroup(null);
94 * Test for find matches of a regular expression
96 @Test(groups = "Functional")
97 public void testFind_regex()
100 * find next match only
102 Finder f = new Finder(av);
103 f.findNext("E.H", false, false, false); // 'E, any character, H'
104 // should match seq2 efH only
105 SearchResultsI sr = f.getSearchResults();
106 assertEquals(sr.getCount(), 1);
107 List<SearchResultMatchI> matches = sr.getResults();
108 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
109 assertEquals(matches.get(0).getStart(), 5);
110 assertEquals(matches.get(0).getEnd(), 7);
113 f.findAll("E.H", false, false, false); // 'E, any character, H'
114 // should match seq2 efH and seq3 EFH
115 sr = f.getSearchResults();
116 assertEquals(sr.getCount(), 2);
117 matches = sr.getResults();
118 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
119 assertSame(matches.get(1).getSequence(), al.getSequenceAt(2));
120 assertEquals(matches.get(0).getStart(), 5);
121 assertEquals(matches.get(0).getEnd(), 7);
122 assertEquals(matches.get(1).getStart(), 4);
123 assertEquals(matches.get(1).getEnd(), 6);
126 @Test(groups = "Functional")
127 public void testFind_findAll()
130 * simple JAL-3765 test
131 * single symbol should find *all* matching symbols
133 Finder f = new Finder(av);
134 f.findAll("M", false,false,false);
135 SearchResultsI sr = f.getSearchResults();
136 assertEquals(sr.getCount(),5);
140 * Test for (undocumented) find residue by position
142 @Test(groups = "Functional")
143 public void testFind_residueNumber()
145 Finder f = new Finder(av);
148 * find first match should return seq1 residue 9
150 f.findNext("9", false, false, false);
151 SearchResultsI sr = f.getSearchResults();
152 assertEquals(sr.getCount(), 1);
153 List<SearchResultMatchI> matches = sr.getResults();
154 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
155 assertEquals(matches.get(0).getStart(), 9);
156 assertEquals(matches.get(0).getEnd(), 9);
159 * find all matches should return seq1 and seq4 (others are too short)
160 * (and not matches in sequence ids)
163 String name = al.getSequenceAt(0).getName();
164 al.getSequenceAt(0).setName("Q9XA0");
165 f.findAll("9", false, false, false);
166 sr = f.getSearchResults();
167 assertEquals(sr.getCount(), 2);
168 matches = sr.getResults();
169 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
170 assertSame(matches.get(1).getSequence(), al.getSequenceAt(3));
171 assertEquals(matches.get(0).getStart(), 9);
172 assertEquals(matches.get(0).getEnd(), 9);
173 assertEquals(matches.get(1).getStart(), 9);
174 assertEquals(matches.get(1).getEnd(), 9);
175 al.getSequenceAt(0).setName(name);
178 * parsing of search string as integer is strict
181 f.findNext(" 9", false, false, false);
182 assertTrue(f.getSearchResults().isEmpty());
186 * Test for find next action
188 @Test(groups = "Functional")
189 public void testFindNext()
192 * start at second sequence; residueIndex of -1
193 * means sequence id / description is searched
195 Finder f = new Finder(av);
196 PA.setValue(f, "sequenceIndex", 1);
197 PA.setValue(f, "residueIndex", -1);
198 f.findNext("e", false, false, false); // matches id
200 assertTrue(f.getSearchResults().isEmpty());
201 assertEquals(f.getIdMatches().size(), 1);
202 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
204 // residueIndex is now 0 - for use in next find next
205 // searching A--BCDefHI
206 assertEquals(PA.getValue(f, "residueIndex"), 0);
208 PA.setValue(f, "sequenceIndex", 1);
209 PA.setValue(f, "residueIndex", 0);
210 f.findNext("e", false, false, false); // matches in sequence
211 assertTrue(f.getIdMatches().isEmpty());
212 assertEquals(f.getSearchResults().getCount(), 1);
213 List<SearchResultMatchI> matches = f.getSearchResults().getResults();
214 assertEquals(matches.get(0).getStart(), 5);
215 assertEquals(matches.get(0).getEnd(), 5);
216 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
217 // still in the second sequence
218 assertEquals(PA.getValue(f, "sequenceIndex"), 1);
219 // next residue offset to search from is 5
220 assertEquals(PA.getValue(f, "residueIndex"), 5);
222 // find next from end of sequence - finds next sequence id
224 PA.setValue(f, "sequenceIndex", 1);
225 PA.setValue(f, "residueIndex", 7);
226 f.findNext("e", false, false, false);
227 assertEquals(f.getIdMatches().size(), 1);
228 assertSame(f.getIdMatches().get(0), al.getSequenceAt(2));
229 assertTrue(f.getSearchResults().isEmpty());
233 * Test for matching within sequence descriptions
235 @Test(groups = "Functional")
236 public void testFind_inDescription()
238 AlignmentI al2 = new Alignment(al);
239 al2.getSequenceAt(0).setDescription("BRAF");
240 al2.getSequenceAt(1).setDescription("braf");
242 AlignViewportI av2 = new AlignViewport(al2);
245 * find first match only
247 Finder f = new Finder(av2);
248 f.findNext("rAF", false, true, false);
249 assertEquals(f.getIdMatches().size(), 1);
250 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
251 assertTrue(f.getSearchResults().isEmpty());
257 f.findAll("rAF", false, true, false);
258 assertEquals(f.getIdMatches().size(), 2);
259 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
260 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
261 assertTrue(f.getSearchResults().isEmpty());
267 f.findAll("RAF", true, true, false);
268 assertEquals(f.getIdMatches().size(), 1);
269 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
270 assertTrue(f.getSearchResults().isEmpty());
273 * match sequence id, description and sequence!
275 al2.getSequenceAt(0).setDescription("the efh sequence");
276 al2.getSequenceAt(0).setName("mouseEFHkinase");
277 al2.getSequenceAt(1).setName("humanEFHkinase");
281 * sequence matches should have no duplicates
283 f.findAll("EFH", false, true, false);
284 assertEquals(f.getIdMatches().size(), 2);
285 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
286 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
288 assertEquals(f.getSearchResults().getCount(), 2);
289 SearchResultMatchI match = f.getSearchResults().getResults().get(0);
290 assertSame(match.getSequence(), al2.getSequenceAt(1));
291 assertEquals(match.getStart(), 5);
292 assertEquals(match.getEnd(), 7);
293 match = f.getSearchResults().getResults().get(1);
294 assertSame(match.getSequence(), al2.getSequenceAt(2));
295 assertEquals(match.getStart(), 4);
296 assertEquals(match.getEnd(), 6);
300 * Test for matching within sequence ids
302 @Test(groups = "Functional")
303 public void testFindAll_sequenceIds()
305 Finder f = new Finder(av);
308 * case insensitive; seq1 occurs twice in sequence id but
309 * only one match should be returned
311 f.findAll("SEQ1", false, false, false);
312 assertEquals(f.getIdMatches().size(), 1);
313 assertSame(f.getIdMatches().get(0), al.getSequenceAt(0));
314 SearchResultsI searchResults = f.getSearchResults();
315 assertTrue(searchResults.isEmpty());
321 f.findAll("SEQ1", true, false, false);
322 searchResults = f.getSearchResults();
323 assertTrue(searchResults.isEmpty());
326 * match both sequence id and sequence
328 AlignmentI al2 = new Alignment(al);
329 AlignViewportI av2 = new AlignViewport(al2);
330 al2.addSequence(new Sequence("aBz", "xyzabZpqrAbZ"));
332 f.findAll("ABZ", false, false, false);
333 assertEquals(f.getIdMatches().size(), 1);
334 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(4));
335 searchResults = f.getSearchResults();
336 assertEquals(searchResults.getCount(), 2);
337 SearchResultMatchI match = searchResults.getResults().get(0);
338 assertSame(match.getSequence(), al2.getSequenceAt(4));
339 assertEquals(match.getStart(), 4);
340 assertEquals(match.getEnd(), 6);
341 match = searchResults.getResults().get(1);
342 assertSame(match.getSequence(), al2.getSequenceAt(4));
343 assertEquals(match.getStart(), 10);
344 assertEquals(match.getEnd(), 12);
348 * Test finding next match of a sequence pattern in an alignment
350 @Test(groups = "Functional")
351 public void testFind_findNext()
353 // "seq1/8-18 ABCD--EF-GHIJI\n" +
354 // "seq2 A--BCDefHI\n" +
355 // "seq3 --bcdEFH\n" +
356 // "seq4 aa---aMMMMMaaa\n";
358 * efh should be matched in seq2 only
360 FinderI f = new Finder(av);
361 f.findNext("EfH", false, false, false);
362 SearchResultsI searchResults = f.getSearchResults();
363 assertEquals(searchResults.getCount(), 1);
364 SearchResultMatchI match = searchResults.getResults().get(0);
365 assertSame(match.getSequence(), al.getSequenceAt(1));
366 assertEquals(match.getStart(), 5);
367 assertEquals(match.getEnd(), 7);
370 * I should be found in seq1 (twice) and seq2 (once)
373 f.findNext("I", false, false, false); // find next: seq1/16
374 searchResults = f.getSearchResults();
375 assertEquals(searchResults.getCount(), 1);
376 match = searchResults.getResults().get(0);
377 assertSame(match.getSequence(), al.getSequenceAt(0));
378 assertEquals(match.getStart(), 16);
379 assertEquals(match.getEnd(), 16);
381 f.findNext("I", false, false, false); // find next: seq1/18
382 searchResults = f.getSearchResults();
383 assertEquals(searchResults.getCount(), 1);
384 match = searchResults.getResults().get(0);
385 assertSame(match.getSequence(), al.getSequenceAt(0));
386 assertEquals(match.getStart(), 18);
387 assertEquals(match.getEnd(), 18);
389 f.findNext("I", false, false, false); // find next: seq2/8
390 searchResults = f.getSearchResults();
391 assertEquals(searchResults.getCount(), 1);
392 match = searchResults.getResults().get(0);
393 assertSame(match.getSequence(), al.getSequenceAt(1));
394 assertEquals(match.getStart(), 8);
395 assertEquals(match.getEnd(), 8);
397 f.findNext("I", false, false, false);
398 assertTrue(f.getSearchResults().isEmpty());
401 * find should reset to start of alignment after a failed search
403 f.findNext("I", false, false, false); // find next: seq1/16
404 searchResults = f.getSearchResults();
405 assertEquals(searchResults.getCount(), 1);
406 match = searchResults.getResults().get(0);
407 assertSame(match.getSequence(), al.getSequenceAt(0));
408 assertEquals(match.getStart(), 16);
409 assertEquals(match.getEnd(), 16);
413 * Test for JAL-2302 to verify that sub-matches are not included in a find all
416 @Test(groups = "Functional")
417 public void testFindAll_maximalResultOnly()
419 Finder f = new Finder(av);
420 f.findAll("M+", false, false, false);
421 SearchResultsI searchResults = f.getSearchResults();
422 assertEquals(searchResults.getCount(), 1);
423 SearchResultMatchI match = searchResults.getResults().get(0);
424 assertSame(match.getSequence(), al.getSequenceAt(3));
425 assertEquals(match.getStart(), 4); // dataset sequence positions
426 assertEquals(match.getEnd(), 8); // base 1
430 * Test finding all matches of a sequence pattern in an alignment
432 @Test(groups = "Functional")
433 public void testFindAll()
435 Finder f = new Finder(av);
436 f.findAll("EfH", false, false, false);
437 SearchResultsI searchResults = f.getSearchResults();
438 assertEquals(searchResults.getCount(), 2);
439 SearchResultMatchI match = searchResults.getResults().get(0);
440 assertSame(match.getSequence(), al.getSequenceAt(1));
441 assertEquals(match.getStart(), 5);
442 assertEquals(match.getEnd(), 7);
443 match = searchResults.getResults().get(1);
444 assertSame(match.getSequence(), al.getSequenceAt(2));
445 assertEquals(match.getStart(), 4);
446 assertEquals(match.getEnd(), 6);
449 * find all I should find 2 positions in seq1, 1 in seq2
451 f.findAll("I", false, false, false);
452 searchResults = f.getSearchResults();
453 assertEquals(searchResults.getCount(), 3);
454 match = searchResults.getResults().get(0);
455 assertSame(match.getSequence(), al.getSequenceAt(0));
456 assertEquals(match.getStart(), 16);
457 assertEquals(match.getEnd(), 16);
458 match = searchResults.getResults().get(1);
459 assertSame(match.getSequence(), al.getSequenceAt(0));
460 assertEquals(match.getStart(), 18);
461 assertEquals(match.getEnd(), 18);
462 match = searchResults.getResults().get(2);
463 assertSame(match.getSequence(), al.getSequenceAt(1));
464 assertEquals(match.getStart(), 8);
465 assertEquals(match.getEnd(), 8);
469 * Test finding all matches, case-sensitive
471 @Test(groups = "Functional")
472 public void testFindAll_caseSensitive()
474 Finder f = new Finder(av);
477 * BC should match seq1/9-10 and seq2/2-3
479 f.findAll("BC", true, false, false);
480 SearchResultsI searchResults = f.getSearchResults();
481 assertEquals(searchResults.getCount(), 2);
482 SearchResultMatchI match = searchResults.getResults().get(0);
483 assertSame(match.getSequence(), al.getSequenceAt(0));
484 assertEquals(match.getStart(), 9);
485 assertEquals(match.getEnd(), 10);
486 match = searchResults.getResults().get(1);
487 assertSame(match.getSequence(), al.getSequenceAt(1));
488 assertEquals(match.getStart(), 2);
489 assertEquals(match.getEnd(), 3);
492 * bc should match seq3/1-2
495 f.findAll("bc", true, false, false);
496 searchResults = f.getSearchResults();
497 assertEquals(searchResults.getCount(), 1);
498 match = searchResults.getResults().get(0);
499 assertSame(match.getSequence(), al.getSequenceAt(2));
500 assertEquals(match.getStart(), 1);
501 assertEquals(match.getEnd(), 2);
503 f.findAll("bC", true, false, false);
504 assertTrue(f.getSearchResults().isEmpty());
508 * Test finding next match of a sequence pattern in a selection group
510 @Test(groups = "Functional")
511 public void testFindNext_inSelection()
514 * select sequences 2 and 3, columns 4-6 which contains
518 SequenceGroup sg = new SequenceGroup();
521 sg.addSequence(al.getSequenceAt(1), false);
522 sg.addSequence(al.getSequenceAt(2), false);
523 av.setSelectionGroup(sg);
525 FinderI f = new Finder(av);
526 f.findNext("b", false, false, false);
527 assertTrue(f.getIdMatches().isEmpty());
528 SearchResultsI searchResults = f.getSearchResults();
529 assertEquals(searchResults.getCount(), 1);
530 SearchResultMatchI match = searchResults.getResults().get(0);
531 assertSame(match.getSequence(), al.getSequenceAt(1));
532 assertEquals(match.getStart(), 2);
533 assertEquals(match.getEnd(), 2);
536 * a second Find should not return the 'b' in seq3 as outside the selection
538 f.findNext("b", false, false, false);
539 assertTrue(f.getSearchResults().isEmpty());
540 assertTrue(f.getIdMatches().isEmpty());
543 f.findNext("d", false, false, false);
544 assertTrue(f.getIdMatches().isEmpty());
545 searchResults = f.getSearchResults();
546 assertEquals(searchResults.getCount(), 1);
547 match = searchResults.getResults().get(0);
548 assertSame(match.getSequence(), al.getSequenceAt(1));
549 assertEquals(match.getStart(), 4);
550 assertEquals(match.getEnd(), 4);
551 f.findNext("d", false, false, false);
552 assertTrue(f.getIdMatches().isEmpty());
553 searchResults = f.getSearchResults();
554 assertEquals(searchResults.getCount(), 1);
555 match = searchResults.getResults().get(0);
556 assertSame(match.getSequence(), al.getSequenceAt(2));
557 assertEquals(match.getStart(), 3);
558 assertEquals(match.getEnd(), 3);
562 * Test finding all matches of a search pattern in a selection group
564 @Test(groups = "Functional")
565 public void testFindAll_inSelection()
568 * select sequences 2 and 3, columns 4-6 which contains
572 SequenceGroup sg = new SequenceGroup();
575 sg.addSequence(al.getSequenceAt(1), false);
576 sg.addSequence(al.getSequenceAt(2), false);
577 av.setSelectionGroup(sg);
580 * search for 'e' should match two sequence ids and one residue
582 Finder f = new Finder(av);
583 f.findAll("e", false, false, false);
584 assertEquals(f.getIdMatches().size(), 2);
585 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
586 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
587 SearchResultsI searchResults = f.getSearchResults();
588 assertEquals(searchResults.getCount(), 1);
589 SearchResultMatchI match = searchResults.getResults().get(0);
590 assertSame(match.getSequence(), al.getSequenceAt(2));
591 assertEquals(match.getStart(), 4);
592 assertEquals(match.getEnd(), 4);
595 * search for 'Q' should match two sequence ids only
598 f.findAll("Q", false, false, false);
599 assertEquals(f.getIdMatches().size(), 2);
600 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
601 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
602 assertTrue(f.getSearchResults().isEmpty());
606 * Test finding in selection with a sequence too short to reach it
608 @Test(groups = "Functional")
609 public void testFind_findAllInSelectionWithShortSequence()
612 * select all sequences, columns 10-12
616 SequenceGroup sg = new SequenceGroup();
619 sg.addSequence(al.getSequenceAt(0), false);
620 sg.addSequence(al.getSequenceAt(1), false);
621 sg.addSequence(al.getSequenceAt(2), false);
622 sg.addSequence(al.getSequenceAt(3), false);
623 av.setSelectionGroup(sg);
626 * search for 'I' should match two sequence positions
628 Finder f = new Finder(av);
629 f.findAll("I", false, false, false);
630 assertTrue(f.getIdMatches().isEmpty());
631 SearchResultsI searchResults = f.getSearchResults();
632 assertEquals(searchResults.getCount(), 2);
633 SearchResultMatchI match = searchResults.getResults().get(0);
634 assertSame(match.getSequence(), al.getSequenceAt(0));
635 assertEquals(match.getStart(), 16);
636 assertEquals(match.getEnd(), 16);
637 match = searchResults.getResults().get(1);
638 assertSame(match.getSequence(), al.getSequenceAt(1));
639 assertEquals(match.getStart(), 8);
640 assertEquals(match.getEnd(), 8);
644 * Test that find does not report hidden positions, but does report matches that
647 @Test(groups = "Functional")
648 public void testFind_withHiddenColumns()
659 * hide column 3 only, search for aaa
660 * should find two matches: aa-[-]-aa and trailing aaa
662 HiddenColumns hc = new HiddenColumns();
663 hc.hideColumns(3, 3);
664 al.setHiddenColumns(hc);
665 Finder f = new Finder(av);
666 f.findAll("aaa", false, false, false);
667 SearchResultsI searchResults = f.getSearchResults();
668 assertEquals(searchResults.getCount(), 2);
669 SearchResultMatchI match = searchResults.getResults().get(0);
670 assertSame(match.getSequence(), al.getSequenceAt(3));
671 assertEquals(match.getStart(), 1);
672 assertEquals(match.getEnd(), 3);
673 match = searchResults.getResults().get(1);
674 assertSame(match.getSequence(), al.getSequenceAt(3));
675 assertEquals(match.getStart(), 9);
676 assertEquals(match.getEnd(), 11);
679 * hide 2-4 (CD- -BC bcd ---)
681 hc.hideColumns(2, 4);
684 * find all search for D should ignore hidden positions in seq1 and seq3,
685 * find the visible D in seq2
688 f.findAll("D", false, false, false);
689 searchResults = f.getSearchResults();
690 assertEquals(searchResults.getCount(), 1);
691 match = searchResults.getResults().get(0);
692 assertSame(match.getSequence(), al.getSequenceAt(1));
693 assertEquals(match.getStart(), 4);
694 assertEquals(match.getEnd(), 4);
697 * search for AD should fail although these are now
698 * consecutive in the visible columns
701 f.findAll("AD", false, false, false);
702 searchResults = f.getSearchResults();
703 assertTrue(searchResults.isEmpty());
706 * find all 'aaa' should find both start and end of seq4
707 * (first run includes hidden gaps)
710 f.findAll("aaa", false, false, false);
711 searchResults = f.getSearchResults();
712 assertEquals(searchResults.getCount(), 2);
713 match = searchResults.getResults().get(0);
714 assertSame(match.getSequence(), al.getSequenceAt(3));
715 assertEquals(match.getStart(), 1);
716 assertEquals(match.getEnd(), 3);
717 match = searchResults.getResults().get(1);
718 assertSame(match.getSequence(), al.getSequenceAt(3));
719 assertEquals(match.getStart(), 9);
720 assertEquals(match.getEnd(), 11);
724 * find all 'aaa' should match twice in seq4
725 * (first match partly hidden, second all visible)
727 hc.hideColumns(2, 5);
729 f.findAll("aaa", false, false, false);
730 searchResults = f.getSearchResults();
731 assertEquals(searchResults.getCount(), 2);
732 match = searchResults.getResults().get(0);
733 assertSame(match.getSequence(), al.getSequenceAt(3));
734 assertEquals(match.getStart(), 1);
735 assertEquals(match.getEnd(), 3);
736 match = searchResults.getResults().get(1);
737 assertSame(match.getSequence(), al.getSequenceAt(3));
738 assertEquals(match.getStart(), 9);
739 assertEquals(match.getEnd(), 11);
742 * find all 'BE' should not match across hidden columns in seq1
744 f.findAll("BE", false, false, false);
745 assertTrue(f.getSearchResults().isEmpty());
748 * boundary case: hide columns at end of alignment
749 * search for H should match seq3/6 only
751 hc.revealAllHiddenColumns(new ColumnSelection());
752 hc.hideColumns(8, 13);
754 f.findNext("H", false, false, false);
755 searchResults = f.getSearchResults();
756 assertEquals(searchResults.getCount(), 1);
757 match = searchResults.getResults().get(0);
758 assertSame(match.getSequence(), al.getSequenceAt(2));
759 assertEquals(match.getStart(), 6);
760 assertEquals(match.getEnd(), 6);
763 @Test(groups = "Functional")
764 public void testFind_withHiddenColumnsAndSelection()
775 * hide columns 2-4 and 6-7
777 HiddenColumns hc = new HiddenColumns();
778 hc.hideColumns(2, 4);
779 hc.hideColumns(6, 7);
780 al.setHiddenColumns(hc);
785 SequenceGroup sg = new SequenceGroup();
786 sg.addSequence(al.getSequenceAt(1), false);
787 sg.addSequence(al.getSequenceAt(2), false);
790 av.setSelectionGroup(sg);
793 * find all search for A or H
794 * should match seq2/1, seq2/7, not seq3/6
796 Finder f = new Finder(av);
797 f.findAll("[AH]", false, false, false);
798 SearchResultsI searchResults = f.getSearchResults();
799 assertEquals(searchResults.getCount(), 2);
800 SearchResultMatchI match = searchResults.getResults().get(0);
801 assertSame(match.getSequence(), al.getSequenceAt(1));
802 assertEquals(match.getStart(), 1);
803 assertEquals(match.getEnd(), 1);
804 match = searchResults.getResults().get(1);
805 assertSame(match.getSequence(), al.getSequenceAt(1));
806 assertEquals(match.getStart(), 7);
807 assertEquals(match.getEnd(), 7);
810 @Test(groups = "Functional")
811 public void testFind_ignoreHiddenColumns()
820 HiddenColumns hc = new HiddenColumns();
821 hc.hideColumns(2, 4);
822 hc.hideColumns(7, 7);
823 al.setHiddenColumns(hc);
833 Finder f = new Finder(av);
834 f.findAll("abe", false, false, true); // true = ignore hidden
835 SearchResultsI searchResults = f.getSearchResults();
838 * match of seq1 ABE made up of AB and E
839 * note only one match is counted
841 assertEquals(searchResults.getCount(), 1);
842 assertEquals(searchResults.getResults().size(), 2);
843 SearchResultMatchI match = searchResults.getResults().get(0);
844 assertSame(match.getSequence(), al.getSequenceAt(0));
845 assertEquals(match.getStart(), 8); // A
846 assertEquals(match.getEnd(), 9); // B
847 match = searchResults.getResults().get(1);
848 assertSame(match.getSequence(), al.getSequenceAt(0));
849 assertEquals(match.getStart(), 12); // E
850 assertEquals(match.getEnd(), 12);
853 f.findNext("a.E", false, false, true);
854 searchResults = f.getSearchResults();
855 assertEquals(searchResults.getCount(), 1);
856 assertEquals(searchResults.getResults().size(), 2);
857 match = searchResults.getResults().get(0);
858 assertSame(match.getSequence(), al.getSequenceAt(0));
859 assertEquals(match.getStart(), 8); // A
860 assertEquals(match.getEnd(), 9); // B
861 match = searchResults.getResults().get(1);
862 assertSame(match.getSequence(), al.getSequenceAt(0));
863 assertEquals(match.getStart(), 12); // E
864 assertEquals(match.getEnd(), 12);
866 f.findNext("a.E", false, false, true);
867 searchResults = f.getSearchResults();
868 assertEquals(searchResults.getCount(), 1);
869 assertEquals(searchResults.getResults().size(), 2);
870 match = searchResults.getResults().get(0);
871 assertSame(match.getSequence(), al.getSequenceAt(1));
872 assertEquals(match.getStart(), 1); // a
873 assertEquals(match.getEnd(), 1);
874 match = searchResults.getResults().get(1);
875 assertSame(match.getSequence(), al.getSequenceAt(1));
876 assertEquals(match.getStart(), 4); // D
877 assertEquals(match.getEnd(), 5); // e
880 * find all matching across two hidden column regions
881 * note one 'match' is returned as three contiguous matches
883 f.findAll("BEG", false, false, true);
884 searchResults = f.getSearchResults();
885 assertEquals(searchResults.getCount(), 1);
886 assertEquals(searchResults.getResults().size(), 3);
887 match = searchResults.getResults().get(0);
888 assertSame(match.getSequence(), al.getSequenceAt(0));
889 assertEquals(match.getStart(), 9); // B
890 assertEquals(match.getEnd(), 9);
891 match = searchResults.getResults().get(1);
892 assertSame(match.getSequence(), al.getSequenceAt(0));
893 assertEquals(match.getStart(), 12); // E
894 assertEquals(match.getEnd(), 12);
895 match = searchResults.getResults().get(2);
896 assertSame(match.getSequence(), al.getSequenceAt(0));
897 assertEquals(match.getStart(), 14); // G
898 assertEquals(match.getEnd(), 14);
901 * now select columns 0-9 and search for A.*H
902 * this should match in the second sequence (split as 3 matches)
903 * but not the first (as H is outside the selection)
905 SequenceGroup selection = new SequenceGroup();
906 selection.setStartRes(0);
907 selection.setEndRes(9);
908 al.getSequences().forEach(seq -> selection.addSequence(seq, false));
909 av.setSelectionGroup(selection);
910 f.findAll("A.*H", false, false, true);
911 searchResults = f.getSearchResults();
912 assertEquals(searchResults.getCount(), 1);
913 assertEquals(searchResults.getResults().size(), 3);
914 // match made of contiguous matches A, DE, H
915 match = searchResults.getResults().get(0);
916 assertSame(match.getSequence(), al.getSequenceAt(1));
917 assertEquals(match.getStart(), 1); // A
918 assertEquals(match.getEnd(), 1);
919 match = searchResults.getResults().get(1);
920 assertSame(match.getSequence(), al.getSequenceAt(1));
921 assertEquals(match.getStart(), 4); // D
922 assertEquals(match.getEnd(), 5); // E
923 match = searchResults.getResults().get(2);
924 assertSame(match.getSequence(), al.getSequenceAt(1));
925 assertEquals(match.getStart(), 7); // H (there is no G)
926 assertEquals(match.getEnd(), 7);