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.setPropertyNoSave("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()
91 av.setSelectionGroup(null);
96 * Test for find matches of a regular expression
98 @Test(groups = "Functional")
99 public void testFind_regex()
102 * find next match only
104 Finder f = new Finder(av);
105 f.findNext("E.H", false, false, false); // 'E, any character, H'
106 // should match seq2 efH only
107 SearchResultsI sr = f.getSearchResults();
108 assertEquals(sr.getCount(), 1);
109 List<SearchResultMatchI> matches = sr.getResults();
110 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
111 assertEquals(matches.get(0).getStart(), 5);
112 assertEquals(matches.get(0).getEnd(), 7);
115 f.findAll("E.H", false, false, false); // 'E, any character, H'
116 // should match seq2 efH and seq3 EFH
117 sr = f.getSearchResults();
118 assertEquals(sr.getCount(), 2);
119 matches = sr.getResults();
120 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
121 assertSame(matches.get(1).getSequence(), al.getSequenceAt(2));
122 assertEquals(matches.get(0).getStart(), 5);
123 assertEquals(matches.get(0).getEnd(), 7);
124 assertEquals(matches.get(1).getStart(), 4);
125 assertEquals(matches.get(1).getEnd(), 6);
128 @Test(groups = "Functional")
129 public void testFind_findAll()
132 * simple JAL-3765 test
133 * single symbol should find *all* matching symbols
135 Finder f = new Finder(av);
136 f.findAll("M", false, false, false);
137 SearchResultsI sr = f.getSearchResults();
138 assertEquals(sr.getCount(), 5);
143 * Test for (undocumented) find residue by position
145 @Test(groups = "Functional")
146 public void testFind_residueNumber()
148 Finder f = new Finder(av);
151 * find first match should return seq1 residue 9
153 f.findNext("9", false, false, false);
154 SearchResultsI sr = f.getSearchResults();
155 assertEquals(sr.getCount(), 1);
156 List<SearchResultMatchI> matches = sr.getResults();
157 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
158 assertEquals(matches.get(0).getStart(), 9);
159 assertEquals(matches.get(0).getEnd(), 9);
162 * find all matches should return seq1 and seq4 (others are too short)
163 * (and not matches in sequence ids)
166 String name = al.getSequenceAt(0).getName();
167 al.getSequenceAt(0).setName("Q9XA0");
168 f.findAll("9", false, false, false);
169 sr = f.getSearchResults();
170 assertEquals(sr.getCount(), 2);
171 matches = sr.getResults();
172 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
173 assertSame(matches.get(1).getSequence(), al.getSequenceAt(3));
174 assertEquals(matches.get(0).getStart(), 9);
175 assertEquals(matches.get(0).getEnd(), 9);
176 assertEquals(matches.get(1).getStart(), 9);
177 assertEquals(matches.get(1).getEnd(), 9);
178 al.getSequenceAt(0).setName(name);
181 * parsing of search string as integer is strict
184 f.findNext(" 9", false, false, false);
185 assertTrue(f.getSearchResults().isEmpty());
189 * Test for find next action
191 @Test(groups = "Functional")
192 public void testFindNext()
195 * start at second sequence; residueIndex of -1
196 * means sequence id / description is searched
198 Finder f = new Finder(av);
199 PA.setValue(f, "sequenceIndex", 1);
200 PA.setValue(f, "residueIndex", -1);
201 f.findNext("e", false, false, false); // matches id
203 assertTrue(f.getSearchResults().isEmpty());
204 assertEquals(f.getIdMatches().size(), 1);
205 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
207 // residueIndex is now 0 - for use in next find next
208 // searching A--BCDefHI
209 assertEquals(PA.getValue(f, "residueIndex"), 0);
211 PA.setValue(f, "sequenceIndex", 1);
212 PA.setValue(f, "residueIndex", 0);
213 f.findNext("e", false, false, false); // matches in sequence
214 assertTrue(f.getIdMatches().isEmpty());
215 assertEquals(f.getSearchResults().getCount(), 1);
216 List<SearchResultMatchI> matches = f.getSearchResults().getResults();
217 assertEquals(matches.get(0).getStart(), 5);
218 assertEquals(matches.get(0).getEnd(), 5);
219 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
220 // still in the second sequence
221 assertEquals(PA.getValue(f, "sequenceIndex"), 1);
222 // next residue offset to search from is 5
223 assertEquals(PA.getValue(f, "residueIndex"), 5);
225 // find next from end of sequence - finds next sequence id
227 PA.setValue(f, "sequenceIndex", 1);
228 PA.setValue(f, "residueIndex", 7);
229 f.findNext("e", false, false, false);
230 assertEquals(f.getIdMatches().size(), 1);
231 assertSame(f.getIdMatches().get(0), al.getSequenceAt(2));
232 assertTrue(f.getSearchResults().isEmpty());
236 * Test for matching within sequence descriptions
238 @Test(groups = "Functional")
239 public void testFind_inDescription()
241 AlignmentI al2 = new Alignment(al);
242 al2.getSequenceAt(0).setDescription("BRAF");
243 al2.getSequenceAt(1).setDescription("braf");
245 AlignViewportI av2 = new AlignViewport(al2);
248 * find first match only
250 Finder f = new Finder(av2);
251 f.findNext("rAF", false, true, false);
252 assertEquals(f.getIdMatches().size(), 1);
253 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
254 assertTrue(f.getSearchResults().isEmpty());
260 f.findAll("rAF", false, true, false);
261 assertEquals(f.getIdMatches().size(), 2);
262 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
263 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
264 assertTrue(f.getSearchResults().isEmpty());
270 f.findAll("RAF", true, true, false);
271 assertEquals(f.getIdMatches().size(), 1);
272 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
273 assertTrue(f.getSearchResults().isEmpty());
276 * match sequence id, description and sequence!
278 al2.getSequenceAt(0).setDescription("the efh sequence");
279 al2.getSequenceAt(0).setName("mouseEFHkinase");
280 al2.getSequenceAt(1).setName("humanEFHkinase");
284 * sequence matches should have no duplicates
286 f.findAll("EFH", false, true, false);
287 assertEquals(f.getIdMatches().size(), 2);
288 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
289 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
291 assertEquals(f.getSearchResults().getCount(), 2);
292 SearchResultMatchI match = f.getSearchResults().getResults().get(0);
293 assertSame(match.getSequence(), al2.getSequenceAt(1));
294 assertEquals(match.getStart(), 5);
295 assertEquals(match.getEnd(), 7);
296 match = f.getSearchResults().getResults().get(1);
297 assertSame(match.getSequence(), al2.getSequenceAt(2));
298 assertEquals(match.getStart(), 4);
299 assertEquals(match.getEnd(), 6);
303 * Test for matching within sequence ids
305 @Test(groups = "Functional")
306 public void testFindAll_sequenceIds()
308 Finder f = new Finder(av);
311 * case insensitive; seq1 occurs twice in sequence id but
312 * only one match should be returned
314 f.findAll("SEQ1", false, false, false);
315 assertEquals(f.getIdMatches().size(), 1);
316 assertSame(f.getIdMatches().get(0), al.getSequenceAt(0));
317 SearchResultsI searchResults = f.getSearchResults();
318 assertTrue(searchResults.isEmpty());
324 f.findAll("SEQ1", true, false, false);
325 searchResults = f.getSearchResults();
326 assertTrue(searchResults.isEmpty());
329 * match both sequence id and sequence
331 AlignmentI al2 = new Alignment(al);
332 AlignViewportI av2 = new AlignViewport(al2);
333 al2.addSequence(new Sequence("aBz", "xyzabZpqrAbZ"));
335 f.findAll("ABZ", false, false, false);
336 assertEquals(f.getIdMatches().size(), 1);
337 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(4));
338 searchResults = f.getSearchResults();
339 assertEquals(searchResults.getCount(), 2);
340 SearchResultMatchI match = searchResults.getResults().get(0);
341 assertSame(match.getSequence(), al2.getSequenceAt(4));
342 assertEquals(match.getStart(), 4);
343 assertEquals(match.getEnd(), 6);
344 match = searchResults.getResults().get(1);
345 assertSame(match.getSequence(), al2.getSequenceAt(4));
346 assertEquals(match.getStart(), 10);
347 assertEquals(match.getEnd(), 12);
351 * Test finding next match of a sequence pattern in an alignment
353 @Test(groups = "Functional")
354 public void testFind_findNext()
356 // "seq1/8-18 ABCD--EF-GHIJI\n" +
357 // "seq2 A--BCDefHI\n" +
358 // "seq3 --bcdEFH\n" +
359 // "seq4 aa---aMMMMMaaa\n";
361 * efh should be matched in seq2 only
363 FinderI f = new Finder(av);
364 f.findNext("EfH", false, false, false);
365 SearchResultsI searchResults = f.getSearchResults();
366 assertEquals(searchResults.getCount(), 1);
367 SearchResultMatchI match = searchResults.getResults().get(0);
368 assertSame(match.getSequence(), al.getSequenceAt(1));
369 assertEquals(match.getStart(), 5);
370 assertEquals(match.getEnd(), 7);
373 * I should be found in seq1 (twice) and seq2 (once)
376 f.findNext("I", false, false, false); // find next: seq1/16
377 searchResults = f.getSearchResults();
378 assertEquals(searchResults.getCount(), 1);
379 match = searchResults.getResults().get(0);
380 assertSame(match.getSequence(), al.getSequenceAt(0));
381 assertEquals(match.getStart(), 16);
382 assertEquals(match.getEnd(), 16);
384 f.findNext("I", false, false, false); // find next: seq1/18
385 searchResults = f.getSearchResults();
386 assertEquals(searchResults.getCount(), 1);
387 match = searchResults.getResults().get(0);
388 assertSame(match.getSequence(), al.getSequenceAt(0));
389 assertEquals(match.getStart(), 18);
390 assertEquals(match.getEnd(), 18);
392 f.findNext("I", false, false, false); // find next: seq2/8
393 searchResults = f.getSearchResults();
394 assertEquals(searchResults.getCount(), 1);
395 match = searchResults.getResults().get(0);
396 assertSame(match.getSequence(), al.getSequenceAt(1));
397 assertEquals(match.getStart(), 8);
398 assertEquals(match.getEnd(), 8);
400 f.findNext("I", false, false, false);
401 assertTrue(f.getSearchResults().isEmpty());
404 * find should reset to start of alignment after a failed search
406 f.findNext("I", false, false, false); // find next: seq1/16
407 searchResults = f.getSearchResults();
408 assertEquals(searchResults.getCount(), 1);
409 match = searchResults.getResults().get(0);
410 assertSame(match.getSequence(), al.getSequenceAt(0));
411 assertEquals(match.getStart(), 16);
412 assertEquals(match.getEnd(), 16);
416 * Test for JAL-2302 to verify that sub-matches are not included in a find all
419 @Test(groups = "Functional")
420 public void testFindAll_maximalResultOnly()
422 Finder f = new Finder(av);
423 f.findAll("M+", false, false, false);
424 SearchResultsI searchResults = f.getSearchResults();
425 assertEquals(searchResults.getCount(), 1);
426 SearchResultMatchI match = searchResults.getResults().get(0);
427 assertSame(match.getSequence(), al.getSequenceAt(3));
428 assertEquals(match.getStart(), 4); // dataset sequence positions
429 assertEquals(match.getEnd(), 8); // base 1
433 * Test finding all matches of a sequence pattern in an alignment
435 @Test(groups = "Functional")
436 public void testFindAll()
438 Finder f = new Finder(av);
439 f.findAll("EfH", false, false, false);
440 SearchResultsI searchResults = f.getSearchResults();
441 assertEquals(searchResults.getCount(), 2);
442 SearchResultMatchI match = searchResults.getResults().get(0);
443 assertSame(match.getSequence(), al.getSequenceAt(1));
444 assertEquals(match.getStart(), 5);
445 assertEquals(match.getEnd(), 7);
446 match = searchResults.getResults().get(1);
447 assertSame(match.getSequence(), al.getSequenceAt(2));
448 assertEquals(match.getStart(), 4);
449 assertEquals(match.getEnd(), 6);
452 * find all I should find 2 positions in seq1, 1 in seq2
454 f.findAll("I", false, false, false);
455 searchResults = f.getSearchResults();
456 assertEquals(searchResults.getCount(), 3);
457 match = searchResults.getResults().get(0);
458 assertSame(match.getSequence(), al.getSequenceAt(0));
459 assertEquals(match.getStart(), 16);
460 assertEquals(match.getEnd(), 16);
461 match = searchResults.getResults().get(1);
462 assertSame(match.getSequence(), al.getSequenceAt(0));
463 assertEquals(match.getStart(), 18);
464 assertEquals(match.getEnd(), 18);
465 match = searchResults.getResults().get(2);
466 assertSame(match.getSequence(), al.getSequenceAt(1));
467 assertEquals(match.getStart(), 8);
468 assertEquals(match.getEnd(), 8);
472 * Test finding all matches, case-sensitive
474 @Test(groups = "Functional")
475 public void testFindAll_caseSensitive()
477 Finder f = new Finder(av);
480 * BC should match seq1/9-10 and seq2/2-3
482 f.findAll("BC", true, false, false);
483 SearchResultsI searchResults = f.getSearchResults();
484 assertEquals(searchResults.getCount(), 2);
485 SearchResultMatchI match = searchResults.getResults().get(0);
486 assertSame(match.getSequence(), al.getSequenceAt(0));
487 assertEquals(match.getStart(), 9);
488 assertEquals(match.getEnd(), 10);
489 match = searchResults.getResults().get(1);
490 assertSame(match.getSequence(), al.getSequenceAt(1));
491 assertEquals(match.getStart(), 2);
492 assertEquals(match.getEnd(), 3);
495 * bc should match seq3/1-2
498 f.findAll("bc", true, false, false);
499 searchResults = f.getSearchResults();
500 assertEquals(searchResults.getCount(), 1);
501 match = searchResults.getResults().get(0);
502 assertSame(match.getSequence(), al.getSequenceAt(2));
503 assertEquals(match.getStart(), 1);
504 assertEquals(match.getEnd(), 2);
506 f.findAll("bC", true, false, false);
507 assertTrue(f.getSearchResults().isEmpty());
511 * Test finding next match of a sequence pattern in a selection group
513 @Test(groups = "Functional")
514 public void testFindNext_inSelection()
517 * select sequences 2 and 3, columns 4-6 which contains
521 SequenceGroup sg = new SequenceGroup();
524 sg.addSequence(al.getSequenceAt(1), false);
525 sg.addSequence(al.getSequenceAt(2), false);
526 av.setSelectionGroup(sg);
528 FinderI f = new Finder(av);
529 f.findNext("b", false, false, false);
530 assertTrue(f.getIdMatches().isEmpty());
531 SearchResultsI searchResults = f.getSearchResults();
532 assertEquals(searchResults.getCount(), 1);
533 SearchResultMatchI match = searchResults.getResults().get(0);
534 assertSame(match.getSequence(), al.getSequenceAt(1));
535 assertEquals(match.getStart(), 2);
536 assertEquals(match.getEnd(), 2);
539 * a second Find should not return the 'b' in seq3 as outside the selection
541 f.findNext("b", false, false, false);
542 assertTrue(f.getSearchResults().isEmpty());
543 assertTrue(f.getIdMatches().isEmpty());
546 f.findNext("d", false, false, false);
547 assertTrue(f.getIdMatches().isEmpty());
548 searchResults = f.getSearchResults();
549 assertEquals(searchResults.getCount(), 1);
550 match = searchResults.getResults().get(0);
551 assertSame(match.getSequence(), al.getSequenceAt(1));
552 assertEquals(match.getStart(), 4);
553 assertEquals(match.getEnd(), 4);
554 f.findNext("d", false, false, false);
555 assertTrue(f.getIdMatches().isEmpty());
556 searchResults = f.getSearchResults();
557 assertEquals(searchResults.getCount(), 1);
558 match = searchResults.getResults().get(0);
559 assertSame(match.getSequence(), al.getSequenceAt(2));
560 assertEquals(match.getStart(), 3);
561 assertEquals(match.getEnd(), 3);
565 * Test finding all matches of a search pattern in a selection group
567 @Test(groups = "Functional")
568 public void testFindAll_inSelection()
571 * select sequences 2 and 3, columns 4-6 which contains
575 SequenceGroup sg = new SequenceGroup();
578 sg.addSequence(al.getSequenceAt(1), false);
579 sg.addSequence(al.getSequenceAt(2), false);
580 av.setSelectionGroup(sg);
583 * search for 'e' should match two sequence ids and one residue
585 Finder f = new Finder(av);
586 f.findAll("e", false, false, false);
587 assertEquals(f.getIdMatches().size(), 2);
588 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
589 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
590 SearchResultsI searchResults = f.getSearchResults();
591 assertEquals(searchResults.getCount(), 1);
592 SearchResultMatchI match = searchResults.getResults().get(0);
593 assertSame(match.getSequence(), al.getSequenceAt(2));
594 assertEquals(match.getStart(), 4);
595 assertEquals(match.getEnd(), 4);
598 * search for 'Q' should match two sequence ids only
601 f.findAll("Q", false, false, false);
602 assertEquals(f.getIdMatches().size(), 2);
603 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
604 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
605 assertTrue(f.getSearchResults().isEmpty());
609 * Test finding in selection with a sequence too short to reach it
611 @Test(groups = "Functional")
612 public void testFind_findAllInSelectionWithShortSequence()
615 * select all sequences, columns 10-12
619 SequenceGroup sg = new SequenceGroup();
622 sg.addSequence(al.getSequenceAt(0), false);
623 sg.addSequence(al.getSequenceAt(1), false);
624 sg.addSequence(al.getSequenceAt(2), false);
625 sg.addSequence(al.getSequenceAt(3), false);
626 av.setSelectionGroup(sg);
629 * search for 'I' should match two sequence positions
631 Finder f = new Finder(av);
632 f.findAll("I", false, false, false);
633 assertTrue(f.getIdMatches().isEmpty());
634 SearchResultsI searchResults = f.getSearchResults();
635 assertEquals(searchResults.getCount(), 2);
636 SearchResultMatchI match = searchResults.getResults().get(0);
637 assertSame(match.getSequence(), al.getSequenceAt(0));
638 assertEquals(match.getStart(), 16);
639 assertEquals(match.getEnd(), 16);
640 match = searchResults.getResults().get(1);
641 assertSame(match.getSequence(), al.getSequenceAt(1));
642 assertEquals(match.getStart(), 8);
643 assertEquals(match.getEnd(), 8);
647 * Test that find does not report hidden positions, but does report matches
648 * that span hidden gaps
650 @Test(groups = "Functional")
651 public void testFind_withHiddenColumns()
662 * hide column 3 only, search for aaa
663 * should find two matches: aa-[-]-aa and trailing aaa
665 HiddenColumns hc = new HiddenColumns();
666 hc.hideColumns(3, 3);
667 al.setHiddenColumns(hc);
668 Finder f = new Finder(av);
669 f.findAll("aaa", false, false, false);
670 SearchResultsI searchResults = f.getSearchResults();
671 assertEquals(searchResults.getCount(), 2);
672 SearchResultMatchI match = searchResults.getResults().get(0);
673 assertSame(match.getSequence(), al.getSequenceAt(3));
674 assertEquals(match.getStart(), 1);
675 assertEquals(match.getEnd(), 3);
676 match = searchResults.getResults().get(1);
677 assertSame(match.getSequence(), al.getSequenceAt(3));
678 assertEquals(match.getStart(), 9);
679 assertEquals(match.getEnd(), 11);
682 * hide 2-4 (CD- -BC bcd ---)
684 hc.hideColumns(2, 4);
687 * find all search for D should ignore hidden positions in seq1 and seq3,
688 * find the visible D in seq2
691 f.findAll("D", false, false, false);
692 searchResults = f.getSearchResults();
693 assertEquals(searchResults.getCount(), 1);
694 match = searchResults.getResults().get(0);
695 assertSame(match.getSequence(), al.getSequenceAt(1));
696 assertEquals(match.getStart(), 4);
697 assertEquals(match.getEnd(), 4);
700 * search for AD should fail although these are now
701 * consecutive in the visible columns
704 f.findAll("AD", false, false, false);
705 searchResults = f.getSearchResults();
706 assertTrue(searchResults.isEmpty());
709 * find all 'aaa' should find both start and end of seq4
710 * (first run includes hidden gaps)
713 f.findAll("aaa", false, false, false);
714 searchResults = f.getSearchResults();
715 assertEquals(searchResults.getCount(), 2);
716 match = searchResults.getResults().get(0);
717 assertSame(match.getSequence(), al.getSequenceAt(3));
718 assertEquals(match.getStart(), 1);
719 assertEquals(match.getEnd(), 3);
720 match = searchResults.getResults().get(1);
721 assertSame(match.getSequence(), al.getSequenceAt(3));
722 assertEquals(match.getStart(), 9);
723 assertEquals(match.getEnd(), 11);
727 * find all 'aaa' should match twice in seq4
728 * (first match partly hidden, second all visible)
730 hc.hideColumns(2, 5);
732 f.findAll("aaa", false, false, false);
733 searchResults = f.getSearchResults();
734 assertEquals(searchResults.getCount(), 2);
735 match = searchResults.getResults().get(0);
736 assertSame(match.getSequence(), al.getSequenceAt(3));
737 assertEquals(match.getStart(), 1);
738 assertEquals(match.getEnd(), 3);
739 match = searchResults.getResults().get(1);
740 assertSame(match.getSequence(), al.getSequenceAt(3));
741 assertEquals(match.getStart(), 9);
742 assertEquals(match.getEnd(), 11);
745 * find all 'BE' should not match across hidden columns in seq1
747 f.findAll("BE", false, false, false);
748 assertTrue(f.getSearchResults().isEmpty());
751 * boundary case: hide columns at end of alignment
752 * search for H should match seq3/6 only
754 hc.revealAllHiddenColumns(new ColumnSelection());
755 hc.hideColumns(8, 13);
757 f.findNext("H", false, false, false);
758 searchResults = f.getSearchResults();
759 assertEquals(searchResults.getCount(), 1);
760 match = searchResults.getResults().get(0);
761 assertSame(match.getSequence(), al.getSequenceAt(2));
762 assertEquals(match.getStart(), 6);
763 assertEquals(match.getEnd(), 6);
766 @Test(groups = "Functional")
767 public void testFind_withHiddenColumnsAndSelection()
778 * hide columns 2-4 and 6-7
780 HiddenColumns hc = new HiddenColumns();
781 hc.hideColumns(2, 4);
782 hc.hideColumns(6, 7);
783 al.setHiddenColumns(hc);
788 SequenceGroup sg = new SequenceGroup();
789 sg.addSequence(al.getSequenceAt(1), false);
790 sg.addSequence(al.getSequenceAt(2), false);
793 av.setSelectionGroup(sg);
796 * find all search for A or H
797 * should match seq2/1, seq2/7, not seq3/6
799 Finder f = new Finder(av);
800 f.findAll("[AH]", false, false, false);
801 SearchResultsI searchResults = f.getSearchResults();
802 assertEquals(searchResults.getCount(), 2);
803 SearchResultMatchI match = searchResults.getResults().get(0);
804 assertSame(match.getSequence(), al.getSequenceAt(1));
805 assertEquals(match.getStart(), 1);
806 assertEquals(match.getEnd(), 1);
807 match = searchResults.getResults().get(1);
808 assertSame(match.getSequence(), al.getSequenceAt(1));
809 assertEquals(match.getStart(), 7);
810 assertEquals(match.getEnd(), 7);
813 @Test(groups = "Functional")
814 public void testFind_ignoreHiddenColumns()
823 HiddenColumns hc = new HiddenColumns();
824 hc.hideColumns(2, 4);
825 hc.hideColumns(7, 7);
826 al.setHiddenColumns(hc);
836 Finder f = new Finder(av);
837 f.findAll("abe", false, false, true); // true = ignore hidden
838 SearchResultsI searchResults = f.getSearchResults();
841 * match of seq1 ABE made up of AB and E
842 * note only one match is counted
844 assertEquals(searchResults.getCount(), 1);
845 assertEquals(searchResults.getResults().size(), 2);
846 SearchResultMatchI match = searchResults.getResults().get(0);
847 assertSame(match.getSequence(), al.getSequenceAt(0));
848 assertEquals(match.getStart(), 8); // A
849 assertEquals(match.getEnd(), 9); // B
850 match = searchResults.getResults().get(1);
851 assertSame(match.getSequence(), al.getSequenceAt(0));
852 assertEquals(match.getStart(), 12); // E
853 assertEquals(match.getEnd(), 12);
856 f.findNext("a.E", false, false, true);
857 searchResults = f.getSearchResults();
858 assertEquals(searchResults.getCount(), 1);
859 assertEquals(searchResults.getResults().size(), 2);
860 match = searchResults.getResults().get(0);
861 assertSame(match.getSequence(), al.getSequenceAt(0));
862 assertEquals(match.getStart(), 8); // A
863 assertEquals(match.getEnd(), 9); // B
864 match = searchResults.getResults().get(1);
865 assertSame(match.getSequence(), al.getSequenceAt(0));
866 assertEquals(match.getStart(), 12); // E
867 assertEquals(match.getEnd(), 12);
869 f.findNext("a.E", false, false, true);
870 searchResults = f.getSearchResults();
871 assertEquals(searchResults.getCount(), 1);
872 assertEquals(searchResults.getResults().size(), 2);
873 match = searchResults.getResults().get(0);
874 assertSame(match.getSequence(), al.getSequenceAt(1));
875 assertEquals(match.getStart(), 1); // a
876 assertEquals(match.getEnd(), 1);
877 match = searchResults.getResults().get(1);
878 assertSame(match.getSequence(), al.getSequenceAt(1));
879 assertEquals(match.getStart(), 4); // D
880 assertEquals(match.getEnd(), 5); // e
883 * find all matching across two hidden column regions
884 * note one 'match' is returned as three contiguous matches
886 f.findAll("BEG", false, false, true);
887 searchResults = f.getSearchResults();
888 assertEquals(searchResults.getCount(), 1);
889 assertEquals(searchResults.getResults().size(), 3);
890 match = searchResults.getResults().get(0);
891 assertSame(match.getSequence(), al.getSequenceAt(0));
892 assertEquals(match.getStart(), 9); // B
893 assertEquals(match.getEnd(), 9);
894 match = searchResults.getResults().get(1);
895 assertSame(match.getSequence(), al.getSequenceAt(0));
896 assertEquals(match.getStart(), 12); // E
897 assertEquals(match.getEnd(), 12);
898 match = searchResults.getResults().get(2);
899 assertSame(match.getSequence(), al.getSequenceAt(0));
900 assertEquals(match.getStart(), 14); // G
901 assertEquals(match.getEnd(), 14);
904 * now select columns 0-9 and search for A.*H
905 * this should match in the second sequence (split as 3 matches)
906 * but not the first (as H is outside the selection)
908 SequenceGroup selection = new SequenceGroup();
909 selection.setStartRes(0);
910 selection.setEndRes(9);
911 al.getSequences().forEach(seq -> selection.addSequence(seq, false));
912 av.setSelectionGroup(selection);
913 f.findAll("A.*H", false, false, true);
914 searchResults = f.getSearchResults();
915 assertEquals(searchResults.getCount(), 1);
916 assertEquals(searchResults.getResults().size(), 3);
917 // match made of contiguous matches A, DE, H
918 match = searchResults.getResults().get(0);
919 assertSame(match.getSequence(), al.getSequenceAt(1));
920 assertEquals(match.getStart(), 1); // A
921 assertEquals(match.getEnd(), 1);
922 match = searchResults.getResults().get(1);
923 assertSame(match.getSequence(), al.getSequenceAt(1));
924 assertEquals(match.getStart(), 4); // D
925 assertEquals(match.getEnd(), 5); // E
926 match = searchResults.getResults().get(2);
927 assertSame(match.getSequence(), al.getSequenceAt(1));
928 assertEquals(match.getStart(), 7); // H (there is no G)
929 assertEquals(match.getEnd(), 7);