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);
127 * Test for (undocumented) find residue by position
129 @Test(groups = "Functional")
130 public void testFind_residueNumber()
132 Finder f = new Finder(av);
135 * find first match should return seq1 residue 9
137 f.findNext("9", false, false, false);
138 SearchResultsI sr = f.getSearchResults();
139 assertEquals(sr.getCount(), 1);
140 List<SearchResultMatchI> matches = sr.getResults();
141 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
142 assertEquals(matches.get(0).getStart(), 9);
143 assertEquals(matches.get(0).getEnd(), 9);
146 * find all matches should return seq1 and seq4 (others are too short)
147 * (and not matches in sequence ids)
150 String name = al.getSequenceAt(0).getName();
151 al.getSequenceAt(0).setName("Q9XA0");
152 f.findAll("9", false, false, false);
153 sr = f.getSearchResults();
154 assertEquals(sr.getCount(), 2);
155 matches = sr.getResults();
156 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
157 assertSame(matches.get(1).getSequence(), al.getSequenceAt(3));
158 assertEquals(matches.get(0).getStart(), 9);
159 assertEquals(matches.get(0).getEnd(), 9);
160 assertEquals(matches.get(1).getStart(), 9);
161 assertEquals(matches.get(1).getEnd(), 9);
162 al.getSequenceAt(0).setName(name);
165 * parsing of search string as integer is strict
168 f.findNext(" 9", false, false, false);
169 assertTrue(f.getSearchResults().isEmpty());
173 * Test for find next action
175 @Test(groups = "Functional")
176 public void testFindNext()
179 * start at second sequence; residueIndex of -1
180 * means sequence id / description is searched
182 Finder f = new Finder(av);
183 PA.setValue(f, "sequenceIndex", 1);
184 PA.setValue(f, "residueIndex", -1);
185 f.findNext("e", false, false, false); // matches id
187 assertTrue(f.getSearchResults().isEmpty());
188 assertEquals(f.getIdMatches().size(), 1);
189 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
191 // residueIndex is now 0 - for use in next find next
192 // searching A--BCDefHI
193 assertEquals(PA.getValue(f, "residueIndex"), 0);
195 PA.setValue(f, "sequenceIndex", 1);
196 PA.setValue(f, "residueIndex", 0);
197 f.findNext("e", false, false, false); // matches in sequence
198 assertTrue(f.getIdMatches().isEmpty());
199 assertEquals(f.getSearchResults().getCount(), 1);
200 List<SearchResultMatchI> matches = f.getSearchResults().getResults();
201 assertEquals(matches.get(0).getStart(), 5);
202 assertEquals(matches.get(0).getEnd(), 5);
203 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
204 // still in the second sequence
205 assertEquals(PA.getValue(f, "sequenceIndex"), 1);
206 // next residue offset to search from is 5
207 assertEquals(PA.getValue(f, "residueIndex"), 5);
209 // find next from end of sequence - finds next sequence id
211 PA.setValue(f, "sequenceIndex", 1);
212 PA.setValue(f, "residueIndex", 7);
213 f.findNext("e", false, false, false);
214 assertEquals(f.getIdMatches().size(), 1);
215 assertSame(f.getIdMatches().get(0), al.getSequenceAt(2));
216 assertTrue(f.getSearchResults().isEmpty());
220 * Test for matching within sequence descriptions
222 @Test(groups = "Functional")
223 public void testFind_inDescription()
225 AlignmentI al2 = new Alignment(al);
226 al2.getSequenceAt(0).setDescription("BRAF");
227 al2.getSequenceAt(1).setDescription("braf");
229 AlignViewportI av2 = new AlignViewport(al2);
232 * find first match only
234 Finder f = new Finder(av2);
235 f.findNext("rAF", false, true, false);
236 assertEquals(f.getIdMatches().size(), 1);
237 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
238 assertTrue(f.getSearchResults().isEmpty());
244 f.findAll("rAF", false, true, false);
245 assertEquals(f.getIdMatches().size(), 2);
246 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
247 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
248 assertTrue(f.getSearchResults().isEmpty());
254 f.findAll("RAF", true, true, false);
255 assertEquals(f.getIdMatches().size(), 1);
256 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
257 assertTrue(f.getSearchResults().isEmpty());
260 * match sequence id, description and sequence!
262 al2.getSequenceAt(0).setDescription("the efh sequence");
263 al2.getSequenceAt(0).setName("mouseEFHkinase");
264 al2.getSequenceAt(1).setName("humanEFHkinase");
268 * sequence matches should have no duplicates
270 f.findAll("EFH", false, true, false);
271 assertEquals(f.getIdMatches().size(), 2);
272 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
273 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
275 assertEquals(f.getSearchResults().getCount(), 2);
276 SearchResultMatchI match = f.getSearchResults().getResults().get(0);
277 assertSame(match.getSequence(), al2.getSequenceAt(1));
278 assertEquals(match.getStart(), 5);
279 assertEquals(match.getEnd(), 7);
280 match = f.getSearchResults().getResults().get(1);
281 assertSame(match.getSequence(), al2.getSequenceAt(2));
282 assertEquals(match.getStart(), 4);
283 assertEquals(match.getEnd(), 6);
287 * Test for matching within sequence ids
289 @Test(groups = "Functional")
290 public void testFindAll_sequenceIds()
292 Finder f = new Finder(av);
295 * case insensitive; seq1 occurs twice in sequence id but
296 * only one match should be returned
298 f.findAll("SEQ1", false, false, false);
299 assertEquals(f.getIdMatches().size(), 1);
300 assertSame(f.getIdMatches().get(0), al.getSequenceAt(0));
301 SearchResultsI searchResults = f.getSearchResults();
302 assertTrue(searchResults.isEmpty());
308 f.findAll("SEQ1", true, false, false);
309 searchResults = f.getSearchResults();
310 assertTrue(searchResults.isEmpty());
313 * match both sequence id and sequence
315 AlignmentI al2 = new Alignment(al);
316 AlignViewportI av2 = new AlignViewport(al2);
317 al2.addSequence(new Sequence("aBz", "xyzabZpqrAbZ"));
319 f.findAll("ABZ", false, false, false);
320 assertEquals(f.getIdMatches().size(), 1);
321 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(4));
322 searchResults = f.getSearchResults();
323 assertEquals(searchResults.getCount(), 2);
324 SearchResultMatchI match = searchResults.getResults().get(0);
325 assertSame(match.getSequence(), al2.getSequenceAt(4));
326 assertEquals(match.getStart(), 4);
327 assertEquals(match.getEnd(), 6);
328 match = searchResults.getResults().get(1);
329 assertSame(match.getSequence(), al2.getSequenceAt(4));
330 assertEquals(match.getStart(), 10);
331 assertEquals(match.getEnd(), 12);
335 * Test finding next match of a sequence pattern in an alignment
337 @Test(groups = "Functional")
338 public void testFind_findNext()
340 // "seq1/8-18 ABCD--EF-GHIJI\n" +
341 // "seq2 A--BCDefHI\n" +
342 // "seq3 --bcdEFH\n" +
343 // "seq4 aa---aMMMMMaaa\n";
345 * efh should be matched in seq2 only
347 FinderI f = new Finder(av);
348 f.findNext("EfH", false, false, false);
349 SearchResultsI searchResults = f.getSearchResults();
350 assertEquals(searchResults.getCount(), 1);
351 SearchResultMatchI match = searchResults.getResults().get(0);
352 assertSame(match.getSequence(), al.getSequenceAt(1));
353 assertEquals(match.getStart(), 5);
354 assertEquals(match.getEnd(), 7);
357 * I should be found in seq1 (twice) and seq2 (once)
360 f.findNext("I", false, false, false); // find next: seq1/16
361 searchResults = f.getSearchResults();
362 assertEquals(searchResults.getCount(), 1);
363 match = searchResults.getResults().get(0);
364 assertSame(match.getSequence(), al.getSequenceAt(0));
365 assertEquals(match.getStart(), 16);
366 assertEquals(match.getEnd(), 16);
368 f.findNext("I", false, false, false); // find next: seq1/18
369 searchResults = f.getSearchResults();
370 assertEquals(searchResults.getCount(), 1);
371 match = searchResults.getResults().get(0);
372 assertSame(match.getSequence(), al.getSequenceAt(0));
373 assertEquals(match.getStart(), 18);
374 assertEquals(match.getEnd(), 18);
376 f.findNext("I", false, false, false); // find next: seq2/8
377 searchResults = f.getSearchResults();
378 assertEquals(searchResults.getCount(), 1);
379 match = searchResults.getResults().get(0);
380 assertSame(match.getSequence(), al.getSequenceAt(1));
381 assertEquals(match.getStart(), 8);
382 assertEquals(match.getEnd(), 8);
384 f.findNext("I", false, false, false);
385 assertTrue(f.getSearchResults().isEmpty());
388 * find should reset to start of alignment after a failed search
390 f.findNext("I", false, false, false); // find next: seq1/16
391 searchResults = f.getSearchResults();
392 assertEquals(searchResults.getCount(), 1);
393 match = searchResults.getResults().get(0);
394 assertSame(match.getSequence(), al.getSequenceAt(0));
395 assertEquals(match.getStart(), 16);
396 assertEquals(match.getEnd(), 16);
400 * Test for JAL-2302 to verify that sub-matches are not included in a find all
403 @Test(groups = "Functional")
404 public void testFindAll_maximalResultOnly()
406 Finder f = new Finder(av);
407 f.findAll("M+", false, false, false);
408 SearchResultsI searchResults = f.getSearchResults();
409 assertEquals(searchResults.getCount(), 1);
410 SearchResultMatchI match = searchResults.getResults().get(0);
411 assertSame(match.getSequence(), al.getSequenceAt(3));
412 assertEquals(match.getStart(), 4); // dataset sequence positions
413 assertEquals(match.getEnd(), 8); // base 1
417 * Test finding all matches of a sequence pattern in an alignment
419 @Test(groups = "Functional")
420 public void testFindAll()
422 Finder f = new Finder(av);
423 f.findAll("EfH", false, false, false);
424 SearchResultsI searchResults = f.getSearchResults();
425 assertEquals(searchResults.getCount(), 2);
426 SearchResultMatchI match = searchResults.getResults().get(0);
427 assertSame(match.getSequence(), al.getSequenceAt(1));
428 assertEquals(match.getStart(), 5);
429 assertEquals(match.getEnd(), 7);
430 match = searchResults.getResults().get(1);
431 assertSame(match.getSequence(), al.getSequenceAt(2));
432 assertEquals(match.getStart(), 4);
433 assertEquals(match.getEnd(), 6);
436 * find all I should find 2 positions in seq1, 1 in seq2
438 f.findAll("I", false, false, false);
439 searchResults = f.getSearchResults();
440 assertEquals(searchResults.getCount(), 3);
441 match = searchResults.getResults().get(0);
442 assertSame(match.getSequence(), al.getSequenceAt(0));
443 assertEquals(match.getStart(), 16);
444 assertEquals(match.getEnd(), 16);
445 match = searchResults.getResults().get(1);
446 assertSame(match.getSequence(), al.getSequenceAt(0));
447 assertEquals(match.getStart(), 18);
448 assertEquals(match.getEnd(), 18);
449 match = searchResults.getResults().get(2);
450 assertSame(match.getSequence(), al.getSequenceAt(1));
451 assertEquals(match.getStart(), 8);
452 assertEquals(match.getEnd(), 8);
456 * Test finding all matches, case-sensitive
458 @Test(groups = "Functional")
459 public void testFindAll_caseSensitive()
461 Finder f = new Finder(av);
464 * BC should match seq1/9-10 and seq2/2-3
466 f.findAll("BC", true, false, false);
467 SearchResultsI searchResults = f.getSearchResults();
468 assertEquals(searchResults.getCount(), 2);
469 SearchResultMatchI match = searchResults.getResults().get(0);
470 assertSame(match.getSequence(), al.getSequenceAt(0));
471 assertEquals(match.getStart(), 9);
472 assertEquals(match.getEnd(), 10);
473 match = searchResults.getResults().get(1);
474 assertSame(match.getSequence(), al.getSequenceAt(1));
475 assertEquals(match.getStart(), 2);
476 assertEquals(match.getEnd(), 3);
479 * bc should match seq3/1-2
482 f.findAll("bc", true, false, false);
483 searchResults = f.getSearchResults();
484 assertEquals(searchResults.getCount(), 1);
485 match = searchResults.getResults().get(0);
486 assertSame(match.getSequence(), al.getSequenceAt(2));
487 assertEquals(match.getStart(), 1);
488 assertEquals(match.getEnd(), 2);
490 f.findAll("bC", true, false, false);
491 assertTrue(f.getSearchResults().isEmpty());
495 * Test finding next match of a sequence pattern in a selection group
497 @Test(groups = "Functional")
498 public void testFindNext_inSelection()
501 * select sequences 2 and 3, columns 4-6 which contains
505 SequenceGroup sg = new SequenceGroup();
508 sg.addSequence(al.getSequenceAt(1), false);
509 sg.addSequence(al.getSequenceAt(2), false);
510 av.setSelectionGroup(sg);
512 FinderI f = new Finder(av);
513 f.findNext("b", false, false, false);
514 assertTrue(f.getIdMatches().isEmpty());
515 SearchResultsI searchResults = f.getSearchResults();
516 assertEquals(searchResults.getCount(), 1);
517 SearchResultMatchI match = searchResults.getResults().get(0);
518 assertSame(match.getSequence(), al.getSequenceAt(1));
519 assertEquals(match.getStart(), 2);
520 assertEquals(match.getEnd(), 2);
523 * a second Find should not return the 'b' in seq3 as outside the selection
525 f.findNext("b", false, false, false);
526 assertTrue(f.getSearchResults().isEmpty());
527 assertTrue(f.getIdMatches().isEmpty());
530 f.findNext("d", false, false, false);
531 assertTrue(f.getIdMatches().isEmpty());
532 searchResults = f.getSearchResults();
533 assertEquals(searchResults.getCount(), 1);
534 match = searchResults.getResults().get(0);
535 assertSame(match.getSequence(), al.getSequenceAt(1));
536 assertEquals(match.getStart(), 4);
537 assertEquals(match.getEnd(), 4);
538 f.findNext("d", false, false, false);
539 assertTrue(f.getIdMatches().isEmpty());
540 searchResults = f.getSearchResults();
541 assertEquals(searchResults.getCount(), 1);
542 match = searchResults.getResults().get(0);
543 assertSame(match.getSequence(), al.getSequenceAt(2));
544 assertEquals(match.getStart(), 3);
545 assertEquals(match.getEnd(), 3);
549 * Test finding all matches of a search pattern in a selection group
551 @Test(groups = "Functional")
552 public void testFindAll_inSelection()
555 * select sequences 2 and 3, columns 4-6 which contains
559 SequenceGroup sg = new SequenceGroup();
562 sg.addSequence(al.getSequenceAt(1), false);
563 sg.addSequence(al.getSequenceAt(2), false);
564 av.setSelectionGroup(sg);
567 * search for 'e' should match two sequence ids and one residue
569 Finder f = new Finder(av);
570 f.findAll("e", false, false, false);
571 assertEquals(f.getIdMatches().size(), 2);
572 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
573 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
574 SearchResultsI searchResults = f.getSearchResults();
575 assertEquals(searchResults.getCount(), 1);
576 SearchResultMatchI match = searchResults.getResults().get(0);
577 assertSame(match.getSequence(), al.getSequenceAt(2));
578 assertEquals(match.getStart(), 4);
579 assertEquals(match.getEnd(), 4);
582 * search for 'Q' should match two sequence ids only
585 f.findAll("Q", false, false, false);
586 assertEquals(f.getIdMatches().size(), 2);
587 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
588 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
589 assertTrue(f.getSearchResults().isEmpty());
593 * Test finding in selection with a sequence too short to reach it
595 @Test(groups = "Functional")
596 public void testFind_findAllInSelectionWithShortSequence()
599 * select all sequences, columns 10-12
603 SequenceGroup sg = new SequenceGroup();
606 sg.addSequence(al.getSequenceAt(0), false);
607 sg.addSequence(al.getSequenceAt(1), false);
608 sg.addSequence(al.getSequenceAt(2), false);
609 sg.addSequence(al.getSequenceAt(3), false);
610 av.setSelectionGroup(sg);
613 * search for 'I' should match two sequence positions
615 Finder f = new Finder(av);
616 f.findAll("I", false, false, false);
617 assertTrue(f.getIdMatches().isEmpty());
618 SearchResultsI searchResults = f.getSearchResults();
619 assertEquals(searchResults.getCount(), 2);
620 SearchResultMatchI match = searchResults.getResults().get(0);
621 assertSame(match.getSequence(), al.getSequenceAt(0));
622 assertEquals(match.getStart(), 16);
623 assertEquals(match.getEnd(), 16);
624 match = searchResults.getResults().get(1);
625 assertSame(match.getSequence(), al.getSequenceAt(1));
626 assertEquals(match.getStart(), 8);
627 assertEquals(match.getEnd(), 8);
631 * Test that find does not report hidden positions, but does report matches that
634 @Test(groups = "Functional")
635 public void testFind_withHiddenColumns()
646 * hide column 3 only, search for aaa
647 * should find two matches: aa-[-]-aa and trailing aaa
649 HiddenColumns hc = new HiddenColumns();
650 hc.hideColumns(3, 3);
651 al.setHiddenColumns(hc);
652 Finder f = new Finder(av);
653 f.findAll("aaa", false, false, false);
654 SearchResultsI searchResults = f.getSearchResults();
655 assertEquals(searchResults.getCount(), 2);
656 SearchResultMatchI match = searchResults.getResults().get(0);
657 assertSame(match.getSequence(), al.getSequenceAt(3));
658 assertEquals(match.getStart(), 1);
659 assertEquals(match.getEnd(), 3);
660 match = searchResults.getResults().get(1);
661 assertSame(match.getSequence(), al.getSequenceAt(3));
662 assertEquals(match.getStart(), 9);
663 assertEquals(match.getEnd(), 11);
666 * hide 2-4 (CD- -BC bcd ---)
668 hc.hideColumns(2, 4);
671 * find all search for D should ignore hidden positions in seq1 and seq3,
672 * find the visible D in seq2
675 f.findAll("D", false, false, false);
676 searchResults = f.getSearchResults();
677 assertEquals(searchResults.getCount(), 1);
678 match = searchResults.getResults().get(0);
679 assertSame(match.getSequence(), al.getSequenceAt(1));
680 assertEquals(match.getStart(), 4);
681 assertEquals(match.getEnd(), 4);
684 * search for AD should fail although these are now
685 * consecutive in the visible columns
688 f.findAll("AD", false, false, false);
689 searchResults = f.getSearchResults();
690 assertTrue(searchResults.isEmpty());
693 * find all 'aaa' should find both start and end of seq4
694 * (first run includes hidden gaps)
697 f.findAll("aaa", false, false, false);
698 searchResults = f.getSearchResults();
699 assertEquals(searchResults.getCount(), 2);
700 match = searchResults.getResults().get(0);
701 assertSame(match.getSequence(), al.getSequenceAt(3));
702 assertEquals(match.getStart(), 1);
703 assertEquals(match.getEnd(), 3);
704 match = searchResults.getResults().get(1);
705 assertSame(match.getSequence(), al.getSequenceAt(3));
706 assertEquals(match.getStart(), 9);
707 assertEquals(match.getEnd(), 11);
711 * find all 'aaa' should match twice in seq4
712 * (first match partly hidden, second all visible)
714 hc.hideColumns(2, 5);
716 f.findAll("aaa", false, false, false);
717 searchResults = f.getSearchResults();
718 assertEquals(searchResults.getCount(), 2);
719 match = searchResults.getResults().get(0);
720 assertSame(match.getSequence(), al.getSequenceAt(3));
721 assertEquals(match.getStart(), 1);
722 assertEquals(match.getEnd(), 3);
723 match = searchResults.getResults().get(1);
724 assertSame(match.getSequence(), al.getSequenceAt(3));
725 assertEquals(match.getStart(), 9);
726 assertEquals(match.getEnd(), 11);
729 * find all 'BE' should not match across hidden columns in seq1
731 f.findAll("BE", false, false, false);
732 assertTrue(f.getSearchResults().isEmpty());
735 * boundary case: hide columns at end of alignment
736 * search for H should match seq3/6 only
738 hc.revealAllHiddenColumns(new ColumnSelection());
739 hc.hideColumns(8, 13);
741 f.findNext("H", false, false, false);
742 searchResults = f.getSearchResults();
743 assertEquals(searchResults.getCount(), 1);
744 match = searchResults.getResults().get(0);
745 assertSame(match.getSequence(), al.getSequenceAt(2));
746 assertEquals(match.getStart(), 6);
747 assertEquals(match.getEnd(), 6);
750 @Test(groups = "Functional")
751 public void testFind_withHiddenColumnsAndSelection()
762 * hide columns 2-4 and 6-7
764 HiddenColumns hc = new HiddenColumns();
765 hc.hideColumns(2, 4);
766 hc.hideColumns(6, 7);
767 al.setHiddenColumns(hc);
772 SequenceGroup sg = new SequenceGroup();
773 sg.addSequence(al.getSequenceAt(1), false);
774 sg.addSequence(al.getSequenceAt(2), false);
777 av.setSelectionGroup(sg);
780 * find all search for A or H
781 * should match seq2/1, seq2/7, not seq3/6
783 Finder f = new Finder(av);
784 f.findAll("[AH]", false, false, false);
785 SearchResultsI searchResults = f.getSearchResults();
786 assertEquals(searchResults.getCount(), 2);
787 SearchResultMatchI match = searchResults.getResults().get(0);
788 assertSame(match.getSequence(), al.getSequenceAt(1));
789 assertEquals(match.getStart(), 1);
790 assertEquals(match.getEnd(), 1);
791 match = searchResults.getResults().get(1);
792 assertSame(match.getSequence(), al.getSequenceAt(1));
793 assertEquals(match.getStart(), 7);
794 assertEquals(match.getEnd(), 7);
797 @Test(groups = "Functional")
798 public void testFind_ignoreHiddenColumns()
807 HiddenColumns hc = new HiddenColumns();
808 hc.hideColumns(2, 4);
809 hc.hideColumns(7, 7);
810 al.setHiddenColumns(hc);
820 Finder f = new Finder(av);
821 f.findAll("abe", false, false, true); // true = ignore hidden
822 SearchResultsI searchResults = f.getSearchResults();
825 * match of seq1 ABE made up of AB and E
826 * note only one match is counted
828 assertEquals(searchResults.getCount(), 1);
829 assertEquals(searchResults.getResults().size(), 2);
830 SearchResultMatchI match = searchResults.getResults().get(0);
831 assertSame(match.getSequence(), al.getSequenceAt(0));
832 assertEquals(match.getStart(), 8); // A
833 assertEquals(match.getEnd(), 9); // B
834 match = searchResults.getResults().get(1);
835 assertSame(match.getSequence(), al.getSequenceAt(0));
836 assertEquals(match.getStart(), 12); // E
837 assertEquals(match.getEnd(), 12);
840 f.findNext("a.E", false, false, true);
841 searchResults = f.getSearchResults();
842 assertEquals(searchResults.getCount(), 1);
843 assertEquals(searchResults.getResults().size(), 2);
844 match = searchResults.getResults().get(0);
845 assertSame(match.getSequence(), al.getSequenceAt(0));
846 assertEquals(match.getStart(), 8); // A
847 assertEquals(match.getEnd(), 9); // B
848 match = searchResults.getResults().get(1);
849 assertSame(match.getSequence(), al.getSequenceAt(0));
850 assertEquals(match.getStart(), 12); // E
851 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(1));
859 assertEquals(match.getStart(), 1); // a
860 assertEquals(match.getEnd(), 1);
861 match = searchResults.getResults().get(1);
862 assertSame(match.getSequence(), al.getSequenceAt(1));
863 assertEquals(match.getStart(), 4); // D
864 assertEquals(match.getEnd(), 5); // e
867 * find all matching across two hidden column regions
868 * note one 'match' is returned as three contiguous matches
870 f.findAll("BEG", false, false, true);
871 searchResults = f.getSearchResults();
872 assertEquals(searchResults.getCount(), 1);
873 assertEquals(searchResults.getResults().size(), 3);
874 match = searchResults.getResults().get(0);
875 assertSame(match.getSequence(), al.getSequenceAt(0));
876 assertEquals(match.getStart(), 9); // B
877 assertEquals(match.getEnd(), 9);
878 match = searchResults.getResults().get(1);
879 assertSame(match.getSequence(), al.getSequenceAt(0));
880 assertEquals(match.getStart(), 12); // E
881 assertEquals(match.getEnd(), 12);
882 match = searchResults.getResults().get(2);
883 assertSame(match.getSequence(), al.getSequenceAt(0));
884 assertEquals(match.getStart(), 14); // G
885 assertEquals(match.getEnd(), 14);
888 * now select columns 0-9 and search for A.*H
889 * this should match in the second sequence (split as 3 matches)
890 * but not the first (as H is outside the selection)
892 SequenceGroup selection = new SequenceGroup();
893 selection.setStartRes(0);
894 selection.setEndRes(9);
895 al.getSequences().forEach(seq -> selection.addSequence(seq, false));
896 av.setSelectionGroup(selection);
897 f.findAll("A.*H", false, false, true);
898 searchResults = f.getSearchResults();
899 assertEquals(searchResults.getCount(), 1);
900 assertEquals(searchResults.getResults().size(), 3);
901 // match made of contiguous matches A, DE, H
902 match = searchResults.getResults().get(0);
903 assertSame(match.getSequence(), al.getSequenceAt(1));
904 assertEquals(match.getStart(), 1); // A
905 assertEquals(match.getEnd(), 1);
906 match = searchResults.getResults().get(1);
907 assertSame(match.getSequence(), al.getSequenceAt(1));
908 assertEquals(match.getStart(), 4); // D
909 assertEquals(match.getEnd(), 5); // E
910 match = searchResults.getResults().get(2);
911 assertSame(match.getSequence(), al.getSequenceAt(1));
912 assertEquals(match.getStart(), 7); // H (there is no G)
913 assertEquals(match.getEnd(), 7);