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();
86 // JAL-3765 bug test data
88 ">O80429_MAIZE/2-140 Ferredoxin\n" +
89 "AAT---------ALSMSILR---APPPCFSSPLRLRV--AVAKPLA-APMRRQLLRAQATYNVKLITPEGEV\n" +
90 "ELQVPDDVYILDFAEEEGIDLPFSCRAGSCSSCAGKVVSGSVDQSDQSFLNDNQVADGWVLTCAAYPTSDVV\n" +
92 af_oneseq=new FileLoader().LoadFileWaitTillLoaded(longSeqData, DataSourceType.PASTE);
93 av_oneseq = af_oneseq.getViewport();
94 al_oneseq = av_oneseq.getAlignment();
97 @AfterMethod(alwaysRun = true)
98 public void tearDownAfterTest()
100 av.setSelectionGroup(null);
104 * Test for find matches of a regular expression
106 @Test(groups = "Functional")
107 public void testFind_regex()
110 * find next match only
112 Finder f = new Finder(av);
113 f.findNext("E.H", false, false, false); // 'E, any character, H'
114 // should match seq2 efH only
115 SearchResultsI sr = f.getSearchResults();
116 assertEquals(sr.getCount(), 1);
117 List<SearchResultMatchI> matches = sr.getResults();
118 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
119 assertEquals(matches.get(0).getStart(), 5);
120 assertEquals(matches.get(0).getEnd(), 7);
123 f.findAll("E.H", false, false, false); // 'E, any character, H'
124 // should match seq2 efH and seq3 EFH
125 sr = f.getSearchResults();
126 assertEquals(sr.getCount(), 2);
127 matches = sr.getResults();
128 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
129 assertSame(matches.get(1).getSequence(), al.getSequenceAt(2));
130 assertEquals(matches.get(0).getStart(), 5);
131 assertEquals(matches.get(0).getEnd(), 7);
132 assertEquals(matches.get(1).getStart(), 4);
133 assertEquals(matches.get(1).getEnd(), 6);
137 * Test for (undocumented) find residue by position
139 @Test(groups = "Functional")
140 public void testFind_residueNumber()
142 Finder f = new Finder(av);
145 * find first match should return seq1 residue 9
147 f.findNext("9", false, false, false);
148 SearchResultsI sr = f.getSearchResults();
149 assertEquals(sr.getCount(), 1);
150 List<SearchResultMatchI> matches = sr.getResults();
151 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
152 assertEquals(matches.get(0).getStart(), 9);
153 assertEquals(matches.get(0).getEnd(), 9);
156 * find all matches should return seq1 and seq4 (others are too short)
157 * (and not matches in sequence ids)
160 String name = al.getSequenceAt(0).getName();
161 al.getSequenceAt(0).setName("Q9XA0");
162 f.findAll("9", false, false, false);
163 sr = f.getSearchResults();
164 assertEquals(sr.getCount(), 2);
165 matches = sr.getResults();
166 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
167 assertSame(matches.get(1).getSequence(), al.getSequenceAt(3));
168 assertEquals(matches.get(0).getStart(), 9);
169 assertEquals(matches.get(0).getEnd(), 9);
170 assertEquals(matches.get(1).getStart(), 9);
171 assertEquals(matches.get(1).getEnd(), 9);
172 al.getSequenceAt(0).setName(name);
175 * parsing of search string as integer is strict
178 f.findNext(" 9", false, false, false);
179 assertTrue(f.getSearchResults().isEmpty());
183 * Test for find next action
185 @Test(groups = "Functional")
186 public void testFindNext()
189 * start at second sequence; residueIndex of -1
190 * means sequence id / description is searched
192 Finder f = new Finder(av);
193 PA.setValue(f, "sequenceIndex", 1);
194 PA.setValue(f, "residueIndex", -1);
195 f.findNext("e", false, false, false); // matches id
197 assertTrue(f.getSearchResults().isEmpty());
198 assertEquals(f.getIdMatches().size(), 1);
199 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
201 // residueIndex is now 0 - for use in next find next
202 // searching A--BCDefHI
203 assertEquals(PA.getValue(f, "residueIndex"), 0);
205 PA.setValue(f, "sequenceIndex", 1);
206 PA.setValue(f, "residueIndex", 0);
207 f.findNext("e", false, false, false); // matches in sequence
208 assertTrue(f.getIdMatches().isEmpty());
209 assertEquals(f.getSearchResults().getCount(), 1);
210 List<SearchResultMatchI> matches = f.getSearchResults().getResults();
211 assertEquals(matches.get(0).getStart(), 5);
212 assertEquals(matches.get(0).getEnd(), 5);
213 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
214 // still in the second sequence
215 assertEquals(PA.getValue(f, "sequenceIndex"), 1);
216 // next residue offset to search from is 5
217 assertEquals(PA.getValue(f, "residueIndex"), 5);
219 // find next from end of sequence - finds next sequence id
221 PA.setValue(f, "sequenceIndex", 1);
222 PA.setValue(f, "residueIndex", 7);
223 f.findNext("e", false, false, false);
224 assertEquals(f.getIdMatches().size(), 1);
225 assertSame(f.getIdMatches().get(0), al.getSequenceAt(2));
226 assertTrue(f.getSearchResults().isEmpty());
230 * Test for matching within sequence descriptions
232 @Test(groups = "Functional")
233 public void testFind_inDescription()
235 AlignmentI al2 = new Alignment(al);
236 al2.getSequenceAt(0).setDescription("BRAF");
237 al2.getSequenceAt(1).setDescription("braf");
239 AlignViewportI av2 = new AlignViewport(al2);
242 * find first match only
244 Finder f = new Finder(av2);
245 f.findNext("rAF", false, true, false);
246 assertEquals(f.getIdMatches().size(), 1);
247 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
248 assertTrue(f.getSearchResults().isEmpty());
254 f.findAll("rAF", false, true, false);
255 assertEquals(f.getIdMatches().size(), 2);
256 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
257 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
258 assertTrue(f.getSearchResults().isEmpty());
264 f.findAll("RAF", true, true, false);
265 assertEquals(f.getIdMatches().size(), 1);
266 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
267 assertTrue(f.getSearchResults().isEmpty());
270 * match sequence id, description and sequence!
272 al2.getSequenceAt(0).setDescription("the efh sequence");
273 al2.getSequenceAt(0).setName("mouseEFHkinase");
274 al2.getSequenceAt(1).setName("humanEFHkinase");
278 * sequence matches should have no duplicates
280 f.findAll("EFH", false, true, false);
281 assertEquals(f.getIdMatches().size(), 2);
282 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
283 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
285 assertEquals(f.getSearchResults().getCount(), 2);
286 SearchResultMatchI match = f.getSearchResults().getResults().get(0);
287 assertSame(match.getSequence(), al2.getSequenceAt(1));
288 assertEquals(match.getStart(), 5);
289 assertEquals(match.getEnd(), 7);
290 match = f.getSearchResults().getResults().get(1);
291 assertSame(match.getSequence(), al2.getSequenceAt(2));
292 assertEquals(match.getStart(), 4);
293 assertEquals(match.getEnd(), 6);
297 * Test for matching within sequence ids
299 @Test(groups = "Functional")
300 public void testFindAll_sequenceIds()
302 Finder f = new Finder(av);
305 * case insensitive; seq1 occurs twice in sequence id but
306 * only one match should be returned
308 f.findAll("SEQ1", false, false, false);
309 assertEquals(f.getIdMatches().size(), 1);
310 assertSame(f.getIdMatches().get(0), al.getSequenceAt(0));
311 SearchResultsI searchResults = f.getSearchResults();
312 assertTrue(searchResults.isEmpty());
318 f.findAll("SEQ1", true, false, false);
319 searchResults = f.getSearchResults();
320 assertTrue(searchResults.isEmpty());
323 * match both sequence id and sequence
325 AlignmentI al2 = new Alignment(al);
326 AlignViewportI av2 = new AlignViewport(al2);
327 al2.addSequence(new Sequence("aBz", "xyzabZpqrAbZ"));
329 f.findAll("ABZ", false, false, false);
330 assertEquals(f.getIdMatches().size(), 1);
331 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(4));
332 searchResults = f.getSearchResults();
333 assertEquals(searchResults.getCount(), 2);
334 SearchResultMatchI match = searchResults.getResults().get(0);
335 assertSame(match.getSequence(), al2.getSequenceAt(4));
336 assertEquals(match.getStart(), 4);
337 assertEquals(match.getEnd(), 6);
338 match = searchResults.getResults().get(1);
339 assertSame(match.getSequence(), al2.getSequenceAt(4));
340 assertEquals(match.getStart(), 10);
341 assertEquals(match.getEnd(), 12);
345 * Test finding next match of a sequence pattern in an alignment
347 @Test(groups = "Functional")
348 public void testFind_findNext()
350 // "seq1/8-18 ABCD--EF-GHIJI\n" +
351 // "seq2 A--BCDefHI\n" +
352 // "seq3 --bcdEFH\n" +
353 // "seq4 aa---aMMMMMaaa\n";
355 * efh should be matched in seq2 only
357 FinderI f = new Finder(av);
358 f.findNext("EfH", false, false, false);
359 SearchResultsI searchResults = f.getSearchResults();
360 assertEquals(searchResults.getCount(), 1);
361 SearchResultMatchI match = searchResults.getResults().get(0);
362 assertSame(match.getSequence(), al.getSequenceAt(1));
363 assertEquals(match.getStart(), 5);
364 assertEquals(match.getEnd(), 7);
367 * I should be found in seq1 (twice) and seq2 (once)
370 f.findNext("I", false, false, false); // find next: seq1/16
371 searchResults = f.getSearchResults();
372 assertEquals(searchResults.getCount(), 1);
373 match = searchResults.getResults().get(0);
374 assertSame(match.getSequence(), al.getSequenceAt(0));
375 assertEquals(match.getStart(), 16);
376 assertEquals(match.getEnd(), 16);
378 f.findNext("I", false, false, false); // find next: seq1/18
379 searchResults = f.getSearchResults();
380 assertEquals(searchResults.getCount(), 1);
381 match = searchResults.getResults().get(0);
382 assertSame(match.getSequence(), al.getSequenceAt(0));
383 assertEquals(match.getStart(), 18);
384 assertEquals(match.getEnd(), 18);
386 f.findNext("I", false, false, false); // find next: seq2/8
387 searchResults = f.getSearchResults();
388 assertEquals(searchResults.getCount(), 1);
389 match = searchResults.getResults().get(0);
390 assertSame(match.getSequence(), al.getSequenceAt(1));
391 assertEquals(match.getStart(), 8);
392 assertEquals(match.getEnd(), 8);
394 f.findNext("I", false, false, false);
395 assertTrue(f.getSearchResults().isEmpty());
398 * find should reset to start of alignment after a failed search
400 f.findNext("I", false, false, false); // find next: seq1/16
401 searchResults = f.getSearchResults();
402 assertEquals(searchResults.getCount(), 1);
403 match = searchResults.getResults().get(0);
404 assertSame(match.getSequence(), al.getSequenceAt(0));
405 assertEquals(match.getStart(), 16);
406 assertEquals(match.getEnd(), 16);
410 * Test for JAL-2302 to verify that sub-matches are not included in a find all
413 @Test(groups = "Functional")
414 public void testFindAll_maximalResultOnly()
416 Finder f = new Finder(av);
417 f.findAll("M+", false, false, false);
418 SearchResultsI searchResults = f.getSearchResults();
419 assertEquals(searchResults.getCount(), 1);
420 SearchResultMatchI match = searchResults.getResults().get(0);
421 assertSame(match.getSequence(), al.getSequenceAt(3));
422 assertEquals(match.getStart(), 4); // dataset sequence positions
423 assertEquals(match.getEnd(), 8); // base 1
427 * Test finding all matches of a sequence pattern in an alignment
429 @Test(groups = "Functional")
430 public void testFindAll()
432 Finder f = new Finder(av);
433 f.findAll("EfH", false, false, false);
434 SearchResultsI searchResults = f.getSearchResults();
435 assertEquals(searchResults.getCount(), 2);
436 SearchResultMatchI match = searchResults.getResults().get(0);
437 assertSame(match.getSequence(), al.getSequenceAt(1));
438 assertEquals(match.getStart(), 5);
439 assertEquals(match.getEnd(), 7);
440 match = searchResults.getResults().get(1);
441 assertSame(match.getSequence(), al.getSequenceAt(2));
442 assertEquals(match.getStart(), 4);
443 assertEquals(match.getEnd(), 6);
446 * find all I should find 2 positions in seq1, 1 in seq2
448 f.findAll("I", false, false, false);
449 searchResults = f.getSearchResults();
450 assertEquals(searchResults.getCount(), 3);
451 match = searchResults.getResults().get(0);
452 assertSame(match.getSequence(), al.getSequenceAt(0));
453 assertEquals(match.getStart(), 16);
454 assertEquals(match.getEnd(), 16);
455 match = searchResults.getResults().get(1);
456 assertSame(match.getSequence(), al.getSequenceAt(0));
457 assertEquals(match.getStart(), 18);
458 assertEquals(match.getEnd(), 18);
459 match = searchResults.getResults().get(2);
460 assertSame(match.getSequence(), al.getSequenceAt(1));
461 assertEquals(match.getStart(), 8);
462 assertEquals(match.getEnd(), 8);
466 * Test finding all matches, case-sensitive
468 @Test(groups = "Functional")
469 public void testFindAll_caseSensitive()
471 Finder f = new Finder(av);
474 * BC should match seq1/9-10 and seq2/2-3
476 f.findAll("BC", true, false, false);
477 SearchResultsI searchResults = f.getSearchResults();
478 assertEquals(searchResults.getCount(), 2);
479 SearchResultMatchI match = searchResults.getResults().get(0);
480 assertSame(match.getSequence(), al.getSequenceAt(0));
481 assertEquals(match.getStart(), 9);
482 assertEquals(match.getEnd(), 10);
483 match = searchResults.getResults().get(1);
484 assertSame(match.getSequence(), al.getSequenceAt(1));
485 assertEquals(match.getStart(), 2);
486 assertEquals(match.getEnd(), 3);
489 * bc should match seq3/1-2
492 f.findAll("bc", true, false, false);
493 searchResults = f.getSearchResults();
494 assertEquals(searchResults.getCount(), 1);
495 match = searchResults.getResults().get(0);
496 assertSame(match.getSequence(), al.getSequenceAt(2));
497 assertEquals(match.getStart(), 1);
498 assertEquals(match.getEnd(), 2);
500 f.findAll("bC", true, false, false);
501 assertTrue(f.getSearchResults().isEmpty());
505 * Test finding next match of a sequence pattern in a selection group
507 @Test(groups = "Functional")
508 public void testFindNext_inSelection()
511 * select sequences 2 and 3, columns 4-6 which contains
515 SequenceGroup sg = new SequenceGroup();
518 sg.addSequence(al.getSequenceAt(1), false);
519 sg.addSequence(al.getSequenceAt(2), false);
520 av.setSelectionGroup(sg);
522 FinderI f = new Finder(av);
523 f.findNext("b", false, false, false);
524 assertTrue(f.getIdMatches().isEmpty());
525 SearchResultsI searchResults = f.getSearchResults();
526 assertEquals(searchResults.getCount(), 1);
527 SearchResultMatchI match = searchResults.getResults().get(0);
528 assertSame(match.getSequence(), al.getSequenceAt(1));
529 assertEquals(match.getStart(), 2);
530 assertEquals(match.getEnd(), 2);
533 * a second Find should not return the 'b' in seq3 as outside the selection
535 f.findNext("b", false, false, false);
536 assertTrue(f.getSearchResults().isEmpty());
537 assertTrue(f.getIdMatches().isEmpty());
540 f.findNext("d", false, false, false);
541 assertTrue(f.getIdMatches().isEmpty());
542 searchResults = f.getSearchResults();
543 assertEquals(searchResults.getCount(), 1);
544 match = searchResults.getResults().get(0);
545 assertSame(match.getSequence(), al.getSequenceAt(1));
546 assertEquals(match.getStart(), 4);
547 assertEquals(match.getEnd(), 4);
548 f.findNext("d", false, false, false);
549 assertTrue(f.getIdMatches().isEmpty());
550 searchResults = f.getSearchResults();
551 assertEquals(searchResults.getCount(), 1);
552 match = searchResults.getResults().get(0);
553 assertSame(match.getSequence(), al.getSequenceAt(2));
554 assertEquals(match.getStart(), 3);
555 assertEquals(match.getEnd(), 3);
559 * Test finding all matches of a search pattern in a selection group
561 @Test(groups = "Functional")
562 public void testFindAll_inSelection()
565 * select sequences 2 and 3, columns 4-6 which contains
569 SequenceGroup sg = new SequenceGroup();
572 sg.addSequence(al.getSequenceAt(1), false);
573 sg.addSequence(al.getSequenceAt(2), false);
574 av.setSelectionGroup(sg);
577 * search for 'e' should match two sequence ids and one residue
579 Finder f = new Finder(av);
580 f.findAll("e", false, false, false);
581 assertEquals(f.getIdMatches().size(), 2);
582 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
583 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
584 SearchResultsI searchResults = f.getSearchResults();
585 assertEquals(searchResults.getCount(), 1);
586 SearchResultMatchI match = searchResults.getResults().get(0);
587 assertSame(match.getSequence(), al.getSequenceAt(2));
588 assertEquals(match.getStart(), 4);
589 assertEquals(match.getEnd(), 4);
592 * search for 'Q' should match two sequence ids only
595 f.findAll("Q", false, false, false);
596 assertEquals(f.getIdMatches().size(), 2);
597 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
598 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
599 assertTrue(f.getSearchResults().isEmpty());
603 * Test finding in selection with a sequence too short to reach it
605 @Test(groups = "Functional")
606 public void testFind_findAllInSelectionWithShortSequence()
609 * select all sequences, columns 10-12
613 SequenceGroup sg = new SequenceGroup();
616 sg.addSequence(al.getSequenceAt(0), false);
617 sg.addSequence(al.getSequenceAt(1), false);
618 sg.addSequence(al.getSequenceAt(2), false);
619 sg.addSequence(al.getSequenceAt(3), false);
620 av.setSelectionGroup(sg);
623 * search for 'I' should match two sequence positions
625 Finder f = new Finder(av);
626 f.findAll("I", false, false, false);
627 assertTrue(f.getIdMatches().isEmpty());
628 SearchResultsI searchResults = f.getSearchResults();
629 assertEquals(searchResults.getCount(), 2);
630 SearchResultMatchI match = searchResults.getResults().get(0);
631 assertSame(match.getSequence(), al.getSequenceAt(0));
632 assertEquals(match.getStart(), 16);
633 assertEquals(match.getEnd(), 16);
634 match = searchResults.getResults().get(1);
635 assertSame(match.getSequence(), al.getSequenceAt(1));
636 assertEquals(match.getStart(), 8);
637 assertEquals(match.getEnd(), 8);
641 * Test that find does not report hidden positions, but does report matches that
644 @Test(groups = "Functional")
645 public void testFind_withHiddenColumns()
656 * hide column 3 only, search for aaa
657 * should find two matches: aa-[-]-aa and trailing aaa
659 HiddenColumns hc = new HiddenColumns();
660 hc.hideColumns(3, 3);
661 al.setHiddenColumns(hc);
662 Finder f = new Finder(av);
663 f.findAll("aaa", false, false, false);
664 SearchResultsI searchResults = f.getSearchResults();
665 assertEquals(searchResults.getCount(), 2);
666 SearchResultMatchI match = searchResults.getResults().get(0);
667 assertSame(match.getSequence(), al.getSequenceAt(3));
668 assertEquals(match.getStart(), 1);
669 assertEquals(match.getEnd(), 3);
670 match = searchResults.getResults().get(1);
671 assertSame(match.getSequence(), al.getSequenceAt(3));
672 assertEquals(match.getStart(), 9);
673 assertEquals(match.getEnd(), 11);
676 * hide 2-4 (CD- -BC bcd ---)
678 hc.hideColumns(2, 4);
681 * find all search for D should ignore hidden positions in seq1 and seq3,
682 * find the visible D in seq2
685 f.findAll("D", false, false, false);
686 searchResults = f.getSearchResults();
687 assertEquals(searchResults.getCount(), 1);
688 match = searchResults.getResults().get(0);
689 assertSame(match.getSequence(), al.getSequenceAt(1));
690 assertEquals(match.getStart(), 4);
691 assertEquals(match.getEnd(), 4);
694 * search for AD should fail although these are now
695 * consecutive in the visible columns
698 f.findAll("AD", false, false, false);
699 searchResults = f.getSearchResults();
700 assertTrue(searchResults.isEmpty());
703 * find all 'aaa' should find both start and end of seq4
704 * (first run includes hidden gaps)
707 f.findAll("aaa", false, false, false);
708 searchResults = f.getSearchResults();
709 assertEquals(searchResults.getCount(), 2);
710 match = searchResults.getResults().get(0);
711 assertSame(match.getSequence(), al.getSequenceAt(3));
712 assertEquals(match.getStart(), 1);
713 assertEquals(match.getEnd(), 3);
714 match = searchResults.getResults().get(1);
715 assertSame(match.getSequence(), al.getSequenceAt(3));
716 assertEquals(match.getStart(), 9);
717 assertEquals(match.getEnd(), 11);
721 * find all 'aaa' should match twice in seq4
722 * (first match partly hidden, second all visible)
724 hc.hideColumns(2, 5);
726 f.findAll("aaa", false, false, false);
727 searchResults = f.getSearchResults();
728 assertEquals(searchResults.getCount(), 2);
729 match = searchResults.getResults().get(0);
730 assertSame(match.getSequence(), al.getSequenceAt(3));
731 assertEquals(match.getStart(), 1);
732 assertEquals(match.getEnd(), 3);
733 match = searchResults.getResults().get(1);
734 assertSame(match.getSequence(), al.getSequenceAt(3));
735 assertEquals(match.getStart(), 9);
736 assertEquals(match.getEnd(), 11);
739 * find all 'BE' should not match across hidden columns in seq1
741 f.findAll("BE", false, false, false);
742 assertTrue(f.getSearchResults().isEmpty());
745 * boundary case: hide columns at end of alignment
746 * search for H should match seq3/6 only
748 hc.revealAllHiddenColumns(new ColumnSelection());
749 hc.hideColumns(8, 13);
751 f.findNext("H", false, false, false);
752 searchResults = f.getSearchResults();
753 assertEquals(searchResults.getCount(), 1);
754 match = searchResults.getResults().get(0);
755 assertSame(match.getSequence(), al.getSequenceAt(2));
756 assertEquals(match.getStart(), 6);
757 assertEquals(match.getEnd(), 6);
760 @Test(groups = "Functional")
761 public void testFind_withHiddenColumnsAndSelection()
772 * hide columns 2-4 and 6-7
774 HiddenColumns hc = new HiddenColumns();
775 hc.hideColumns(2, 4);
776 hc.hideColumns(6, 7);
777 al.setHiddenColumns(hc);
782 SequenceGroup sg = new SequenceGroup();
783 sg.addSequence(al.getSequenceAt(1), false);
784 sg.addSequence(al.getSequenceAt(2), false);
787 av.setSelectionGroup(sg);
790 * find all search for A or H
791 * should match seq2/1, seq2/7, not seq3/6
793 Finder f = new Finder(av);
794 f.findAll("[AH]", false, false, false);
795 SearchResultsI searchResults = f.getSearchResults();
796 assertEquals(searchResults.getCount(), 2);
797 SearchResultMatchI match = searchResults.getResults().get(0);
798 assertSame(match.getSequence(), al.getSequenceAt(1));
799 assertEquals(match.getStart(), 1);
800 assertEquals(match.getEnd(), 1);
801 match = searchResults.getResults().get(1);
802 assertSame(match.getSequence(), al.getSequenceAt(1));
803 assertEquals(match.getStart(), 7);
804 assertEquals(match.getEnd(), 7);
807 @Test(groups = "Functional")
808 public void testFind_ignoreHiddenColumns()
817 HiddenColumns hc = new HiddenColumns();
818 hc.hideColumns(2, 4);
819 hc.hideColumns(7, 7);
820 al.setHiddenColumns(hc);
830 Finder f = new Finder(av);
831 f.findAll("abe", false, false, true); // true = ignore hidden
832 SearchResultsI searchResults = f.getSearchResults();
835 * match of seq1 ABE made up of AB and E
836 * note only one match is counted
838 assertEquals(searchResults.getCount(), 1);
839 assertEquals(searchResults.getResults().size(), 2);
840 SearchResultMatchI match = searchResults.getResults().get(0);
841 assertSame(match.getSequence(), al.getSequenceAt(0));
842 assertEquals(match.getStart(), 8); // A
843 assertEquals(match.getEnd(), 9); // B
844 match = searchResults.getResults().get(1);
845 assertSame(match.getSequence(), al.getSequenceAt(0));
846 assertEquals(match.getStart(), 12); // E
847 assertEquals(match.getEnd(), 12);
850 f.findNext("a.E", false, false, true);
851 searchResults = f.getSearchResults();
852 assertEquals(searchResults.getCount(), 1);
853 assertEquals(searchResults.getResults().size(), 2);
854 match = searchResults.getResults().get(0);
855 assertSame(match.getSequence(), al.getSequenceAt(0));
856 assertEquals(match.getStart(), 8); // A
857 assertEquals(match.getEnd(), 9); // B
858 match = searchResults.getResults().get(1);
859 assertSame(match.getSequence(), al.getSequenceAt(0));
860 assertEquals(match.getStart(), 12); // E
861 assertEquals(match.getEnd(), 12);
863 f.findNext("a.E", false, false, true);
864 searchResults = f.getSearchResults();
865 assertEquals(searchResults.getCount(), 1);
866 assertEquals(searchResults.getResults().size(), 2);
867 match = searchResults.getResults().get(0);
868 assertSame(match.getSequence(), al.getSequenceAt(1));
869 assertEquals(match.getStart(), 1); // a
870 assertEquals(match.getEnd(), 1);
871 match = searchResults.getResults().get(1);
872 assertSame(match.getSequence(), al.getSequenceAt(1));
873 assertEquals(match.getStart(), 4); // D
874 assertEquals(match.getEnd(), 5); // e
877 * find all matching across two hidden column regions
878 * note one 'match' is returned as three contiguous matches
880 f.findAll("BEG", false, false, true);
881 searchResults = f.getSearchResults();
882 assertEquals(searchResults.getCount(), 1);
883 assertEquals(searchResults.getResults().size(), 3);
884 match = searchResults.getResults().get(0);
885 assertSame(match.getSequence(), al.getSequenceAt(0));
886 assertEquals(match.getStart(), 9); // B
887 assertEquals(match.getEnd(), 9);
888 match = searchResults.getResults().get(1);
889 assertSame(match.getSequence(), al.getSequenceAt(0));
890 assertEquals(match.getStart(), 12); // E
891 assertEquals(match.getEnd(), 12);
892 match = searchResults.getResults().get(2);
893 assertSame(match.getSequence(), al.getSequenceAt(0));
894 assertEquals(match.getStart(), 14); // G
895 assertEquals(match.getEnd(), 14);
898 * now select columns 0-9 and search for A.*H
899 * this should match in the second sequence (split as 3 matches)
900 * but not the first (as H is outside the selection)
902 SequenceGroup selection = new SequenceGroup();
903 selection.setStartRes(0);
904 selection.setEndRes(9);
905 al.getSequences().forEach(seq -> selection.addSequence(seq, false));
906 av.setSelectionGroup(selection);
907 f.findAll("A.*H", false, false, true);
908 searchResults = f.getSearchResults();
909 assertEquals(searchResults.getCount(), 1);
910 assertEquals(searchResults.getResults().size(), 3);
911 // match made of contiguous matches A, DE, H
912 match = searchResults.getResults().get(0);
913 assertSame(match.getSequence(), al.getSequenceAt(1));
914 assertEquals(match.getStart(), 1); // A
915 assertEquals(match.getEnd(), 1);
916 match = searchResults.getResults().get(1);
917 assertSame(match.getSequence(), al.getSequenceAt(1));
918 assertEquals(match.getStart(), 4); // D
919 assertEquals(match.getEnd(), 5); // E
920 match = searchResults.getResults().get(2);
921 assertSame(match.getSequence(), al.getSequenceAt(1));
922 assertEquals(match.getStart(), 7); // H (there is no G)
923 assertEquals(match.getEnd(), 7);