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 java.util.List;
29 import org.testng.annotations.AfterMethod;
30 import org.testng.annotations.BeforeClass;
31 import org.testng.annotations.Test;
33 import jalview.api.AlignViewportI;
34 import jalview.api.FinderI;
35 import jalview.bin.Cache;
36 import jalview.datamodel.Alignment;
37 import jalview.datamodel.AlignmentI;
38 import jalview.datamodel.ColumnSelection;
39 import jalview.datamodel.HiddenColumns;
40 import jalview.datamodel.SearchResultMatchI;
41 import jalview.datamodel.SearchResultsI;
42 import jalview.datamodel.Sequence;
43 import jalview.datamodel.SequenceFeature;
44 import jalview.datamodel.SequenceGroup;
45 import jalview.datamodel.SequenceI;
46 import jalview.gui.AlignFrame;
47 import jalview.gui.AlignViewport;
48 import jalview.gui.JvOptionPane;
49 import jalview.io.DataSourceType;
50 import jalview.io.FileLoader;
51 import junit.extensions.PA;
53 public class FinderTest
55 @BeforeClass(alwaysRun = true)
56 public void setUpJvOptionPane()
58 JvOptionPane.setInteractiveMode(false);
59 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
62 private AlignFrame af;
64 private AlignmentI al;
66 private AlignViewportI av;
68 @BeforeClass(groups = "Functional")
71 Cache.loadProperties("test/jalview/io/testProps.jvprops");
72 Cache.applicationProperties.setProperty("PAD_GAPS",
73 Boolean.FALSE.toString());
77 "seq1/8-18 ABCD--EF-GHIJI\n" +
80 "seq4 aa---aMMMMMaaa\n";
82 af = new FileLoader().LoadFileWaitTillLoaded(seqData,
83 DataSourceType.PASTE);
84 av = af.getViewport();
85 al = av.getAlignment();
86 al.getSequenceAt(0).addSequenceFeature(
87 new SequenceFeature("BBBB", "FeatureB", 9, 11, ""));
88 al.getSequenceAt(3).addSequenceFeature(
89 new SequenceFeature("BBAB", "FeatureA", 1, 3, ""));
90 al.getSequenceAt(3).addSequenceFeature(
91 new SequenceFeature("AAAA", "FeatureA", 9, 11, ""));
94 @AfterMethod(alwaysRun = true)
95 public void tearDownAfterTest()
97 av.setSelectionGroup(null);
101 * Test for find matches of a regular expression
103 @Test(groups = "Functional")
104 public void testFind_regex()
107 * find next match only
109 Finder f = new Finder(av);
110 f.findNext("E.H", false, false, false, false); // 'E, any character, H'
111 // should match seq2 efH only
112 SearchResultsI sr = f.getSearchResults();
113 assertEquals(sr.getCount(), 1);
114 List<SearchResultMatchI> matches = sr.getResults();
115 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
116 assertEquals(matches.get(0).getStart(), 5);
117 assertEquals(matches.get(0).getEnd(), 7);
120 f.findAll("E.H", false, false, false, false); // 'E, any character, H'
121 // should match seq2 efH and seq3 EFH
122 sr = f.getSearchResults();
123 assertEquals(sr.getCount(), 2);
124 matches = sr.getResults();
125 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
126 assertSame(matches.get(1).getSequence(), al.getSequenceAt(2));
127 assertEquals(matches.get(0).getStart(), 5);
128 assertEquals(matches.get(0).getEnd(), 7);
129 assertEquals(matches.get(1).getStart(), 4);
130 assertEquals(matches.get(1).getEnd(), 6);
133 @Test(groups = "Functional")
134 public void testFind_findAll()
137 * simple JAL-3765 test
138 * single symbol should find *all* matching symbols
140 Finder f = new Finder(av);
141 f.findAll("M", false, false, false, false);
142 SearchResultsI sr = f.getSearchResults();
143 assertEquals(sr.getCount(), 5);
148 * Test for (undocumented) find residue by position
150 @Test(groups = "Functional")
151 public void testFind_residueNumber()
153 Finder f = new Finder(av);
156 * find first match should return seq1 residue 9
158 f.findNext("9", false, false, false, false);
159 SearchResultsI sr = f.getSearchResults();
160 assertEquals(sr.getCount(), 1);
161 List<SearchResultMatchI> matches = sr.getResults();
162 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
163 assertEquals(matches.get(0).getStart(), 9);
164 assertEquals(matches.get(0).getEnd(), 9);
167 * find all matches should return seq1 and seq4 (others are too short)
168 * (and not matches in sequence ids)
171 String name = al.getSequenceAt(0).getName();
172 al.getSequenceAt(0).setName("Q9XA0");
173 f.findAll("9", false, false, false, false);
174 sr = f.getSearchResults();
175 assertEquals(sr.getCount(), 2);
176 matches = sr.getResults();
177 assertSame(matches.get(0).getSequence(), al.getSequenceAt(0));
178 assertSame(matches.get(1).getSequence(), al.getSequenceAt(3));
179 assertEquals(matches.get(0).getStart(), 9);
180 assertEquals(matches.get(0).getEnd(), 9);
181 assertEquals(matches.get(1).getStart(), 9);
182 assertEquals(matches.get(1).getEnd(), 9);
183 al.getSequenceAt(0).setName(name);
186 * parsing of search string as integer is strict
189 f.findNext(" 9", false, false, false, false);
190 assertTrue(f.getSearchResults().isEmpty());
194 * Test for find next action
196 @Test(groups = "Functional")
197 public void testFindNext()
200 * start at second sequence; residueIndex of -1
201 * means sequence id / description is searched
203 Finder f = new Finder(av);
204 PA.setValue(f, "sequenceIndex", 1);
205 PA.setValue(f, "residueIndex", -1);
206 f.findNext("e", false, false, false, false); // matches id
208 assertTrue(f.getSearchResults().isEmpty());
209 assertEquals(f.getIdMatches().size(), 1);
210 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
212 // residueIndex is now 0 - for use in next find next
213 // searching A--BCDefHI
214 assertEquals(PA.getValue(f, "residueIndex"), 0);
216 PA.setValue(f, "sequenceIndex", 1);
217 PA.setValue(f, "residueIndex", 0);
218 f.findNext("e", false, false, false, false); // matches in sequence
219 assertTrue(f.getIdMatches().isEmpty());
220 assertEquals(f.getSearchResults().getCount(), 1);
221 List<SearchResultMatchI> matches = f.getSearchResults().getResults();
222 assertEquals(matches.get(0).getStart(), 5);
223 assertEquals(matches.get(0).getEnd(), 5);
224 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
225 // still in the second sequence
226 assertEquals(PA.getValue(f, "sequenceIndex"), 1);
227 // next residue offset to search from is 5
228 assertEquals(PA.getValue(f, "residueIndex"), 5);
230 // find next from end of sequence - finds next sequence id
232 PA.setValue(f, "sequenceIndex", 1);
233 PA.setValue(f, "residueIndex", 7);
234 f.findNext("e", false, false, false, false);
235 assertEquals(f.getIdMatches().size(), 1);
236 assertSame(f.getIdMatches().get(0), al.getSequenceAt(2));
237 assertTrue(f.getSearchResults().isEmpty());
241 * Test for matching within sequence descriptions
243 @Test(groups = "Functional")
244 public void testFind_inDescription()
246 AlignmentI al2 = new Alignment(al);
247 al2.getSequenceAt(0).setDescription("BRAF");
248 al2.getSequenceAt(1).setDescription("braf");
250 AlignViewportI av2 = new AlignViewport(al2);
253 * find first match only
255 Finder f = new Finder(av2);
256 f.findNext("rAF", false, true, false, false);
257 assertEquals(f.getIdMatches().size(), 1);
258 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
259 assertTrue(f.getSearchResults().isEmpty());
265 f.findAll("rAF", false, true, false, false);
266 assertEquals(f.getIdMatches().size(), 2);
267 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
268 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
269 assertTrue(f.getSearchResults().isEmpty());
275 f.findAll("RAF", true, true, false, false);
276 assertEquals(f.getIdMatches().size(), 1);
277 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
278 assertTrue(f.getSearchResults().isEmpty());
281 * match sequence id, description and sequence!
283 al2.getSequenceAt(0).setDescription("the efh sequence");
284 al2.getSequenceAt(0).setName("mouseEFHkinase");
285 al2.getSequenceAt(1).setName("humanEFHkinase");
289 * sequence matches should have no duplicates
291 f.findAll("EFH", false, true, false, false);
292 assertEquals(f.getIdMatches().size(), 2);
293 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(0));
294 assertSame(f.getIdMatches().get(1), al2.getSequenceAt(1));
296 assertEquals(f.getSearchResults().getCount(), 2);
297 SearchResultMatchI match = f.getSearchResults().getResults().get(0);
298 assertSame(match.getSequence(), al2.getSequenceAt(1));
299 assertEquals(match.getStart(), 5);
300 assertEquals(match.getEnd(), 7);
301 match = f.getSearchResults().getResults().get(1);
302 assertSame(match.getSequence(), al2.getSequenceAt(2));
303 assertEquals(match.getStart(), 4);
304 assertEquals(match.getEnd(), 6);
308 * Test for matching within sequence ids
310 @Test(groups = "Functional")
311 public void testFindAll_sequenceIds()
313 Finder f = new Finder(av);
316 * case insensitive; seq1 occurs twice in sequence id but
317 * only one match should be returned
319 f.findAll("SEQ1", false, false, false, false);
320 assertEquals(f.getIdMatches().size(), 1);
321 assertSame(f.getIdMatches().get(0), al.getSequenceAt(0));
322 SearchResultsI searchResults = f.getSearchResults();
323 assertTrue(searchResults.isEmpty());
329 f.findAll("SEQ1", true, false, false, false);
330 searchResults = f.getSearchResults();
331 assertTrue(searchResults.isEmpty());
334 * match both sequence id and sequence
336 AlignmentI al2 = new Alignment(al);
337 AlignViewportI av2 = new AlignViewport(al2);
338 al2.addSequence(new Sequence("aBz", "xyzabZpqrAbZ"));
340 f.findAll("ABZ", false, false, false, false);
341 assertEquals(f.getIdMatches().size(), 1);
342 assertSame(f.getIdMatches().get(0), al2.getSequenceAt(4));
343 searchResults = f.getSearchResults();
344 assertEquals(searchResults.getCount(), 2);
345 SearchResultMatchI match = searchResults.getResults().get(0);
346 assertSame(match.getSequence(), al2.getSequenceAt(4));
347 assertEquals(match.getStart(), 4);
348 assertEquals(match.getEnd(), 6);
349 match = searchResults.getResults().get(1);
350 assertSame(match.getSequence(), al2.getSequenceAt(4));
351 assertEquals(match.getStart(), 10);
352 assertEquals(match.getEnd(), 12);
356 * Test finding next match of a sequence pattern in an alignment
358 @Test(groups = "Functional")
359 public void testFind_findNext()
361 // "seq1/8-18 ABCD--EF-GHIJI\n" +
362 // "seq2 A--BCDefHI\n" +
363 // "seq3 --bcdEFH\n" +
364 // "seq4 aa---aMMMMMaaa\n";
366 * efh should be matched in seq2 only
368 FinderI f = new Finder(av);
369 f.findNext("EfH", false, false, false, false);
370 SearchResultsI searchResults = f.getSearchResults();
371 assertEquals(searchResults.getCount(), 1);
372 SearchResultMatchI match = searchResults.getResults().get(0);
373 assertSame(match.getSequence(), al.getSequenceAt(1));
374 assertEquals(match.getStart(), 5);
375 assertEquals(match.getEnd(), 7);
378 * I should be found in seq1 (twice) and seq2 (once)
381 f.findNext("I", false, false, false, false); // find next: seq1/16
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(), 16);
387 assertEquals(match.getEnd(), 16);
389 f.findNext("I", false, false, false, false); // find next: seq1/18
390 searchResults = f.getSearchResults();
391 assertEquals(searchResults.getCount(), 1);
392 match = searchResults.getResults().get(0);
393 assertSame(match.getSequence(), al.getSequenceAt(0));
394 assertEquals(match.getStart(), 18);
395 assertEquals(match.getEnd(), 18);
397 f.findNext("I", false, false, false, false); // find next: seq2/8
398 searchResults = f.getSearchResults();
399 assertEquals(searchResults.getCount(), 1);
400 match = searchResults.getResults().get(0);
401 assertSame(match.getSequence(), al.getSequenceAt(1));
402 assertEquals(match.getStart(), 8);
403 assertEquals(match.getEnd(), 8);
405 f.findNext("I", false, false, false, false);
406 assertTrue(f.getSearchResults().isEmpty());
409 * find should reset to start of alignment after a failed search
411 f.findNext("I", false, false, false, false); // find next: seq1/16
412 searchResults = f.getSearchResults();
413 assertEquals(searchResults.getCount(), 1);
414 match = searchResults.getResults().get(0);
415 assertSame(match.getSequence(), al.getSequenceAt(0));
416 assertEquals(match.getStart(), 16);
417 assertEquals(match.getEnd(), 16);
421 * Test for JAL-2302 to verify that sub-matches are not included in a find all
424 @Test(groups = "Functional")
425 public void testFindAll_maximalResultOnly()
427 Finder f = new Finder(av);
428 f.findAll("M+", false, false, false, false);
429 SearchResultsI searchResults = f.getSearchResults();
430 assertEquals(searchResults.getCount(), 1);
431 SearchResultMatchI match = searchResults.getResults().get(0);
432 assertSame(match.getSequence(), al.getSequenceAt(3));
433 assertEquals(match.getStart(), 4); // dataset sequence positions
434 assertEquals(match.getEnd(), 8); // base 1
438 * Test finding all matches of a sequence pattern in an alignment
440 @Test(groups = "Functional")
441 public void testFindAll()
443 Finder f = new Finder(av);
444 f.findAll("EfH", false, false, false, false);
445 SearchResultsI searchResults = f.getSearchResults();
446 assertEquals(searchResults.getCount(), 2);
447 SearchResultMatchI match = searchResults.getResults().get(0);
448 assertSame(match.getSequence(), al.getSequenceAt(1));
449 assertEquals(match.getStart(), 5);
450 assertEquals(match.getEnd(), 7);
451 match = searchResults.getResults().get(1);
452 assertSame(match.getSequence(), al.getSequenceAt(2));
453 assertEquals(match.getStart(), 4);
454 assertEquals(match.getEnd(), 6);
457 * find all I should find 2 positions in seq1, 1 in seq2
459 f.findAll("I", false, false, false, false);
460 searchResults = f.getSearchResults();
461 assertEquals(searchResults.getCount(), 3);
462 match = searchResults.getResults().get(0);
463 assertSame(match.getSequence(), al.getSequenceAt(0));
464 assertEquals(match.getStart(), 16);
465 assertEquals(match.getEnd(), 16);
466 match = searchResults.getResults().get(1);
467 assertSame(match.getSequence(), al.getSequenceAt(0));
468 assertEquals(match.getStart(), 18);
469 assertEquals(match.getEnd(), 18);
470 match = searchResults.getResults().get(2);
471 assertSame(match.getSequence(), al.getSequenceAt(1));
472 assertEquals(match.getStart(), 8);
473 assertEquals(match.getEnd(), 8);
477 * Test finding all matches, case-sensitive
479 @Test(groups = "Functional")
480 public void testFindAll_caseSensitive()
482 Finder f = new Finder(av);
485 * BC should match seq1/9-10 and seq2/2-3
487 f.findAll("BC", true, false, false, false);
488 SearchResultsI searchResults = f.getSearchResults();
489 assertEquals(searchResults.getCount(), 2);
490 SearchResultMatchI match = searchResults.getResults().get(0);
491 assertSame(match.getSequence(), al.getSequenceAt(0));
492 assertEquals(match.getStart(), 9);
493 assertEquals(match.getEnd(), 10);
494 match = searchResults.getResults().get(1);
495 assertSame(match.getSequence(), al.getSequenceAt(1));
496 assertEquals(match.getStart(), 2);
497 assertEquals(match.getEnd(), 3);
500 * bc should match seq3/1-2
503 f.findAll("bc", true, false, false, false);
504 searchResults = f.getSearchResults();
505 assertEquals(searchResults.getCount(), 1);
506 match = searchResults.getResults().get(0);
507 assertSame(match.getSequence(), al.getSequenceAt(2));
508 assertEquals(match.getStart(), 1);
509 assertEquals(match.getEnd(), 2);
511 f.findAll("bC", true, false, false, false);
512 assertTrue(f.getSearchResults().isEmpty());
516 * Test finding next match of a sequence pattern in a selection group
518 @Test(groups = "Functional")
519 public void testFindNext_inSelection()
522 * select sequences 2 and 3, columns 4-6 which contains
526 SequenceGroup sg = new SequenceGroup();
529 sg.addSequence(al.getSequenceAt(1), false);
530 sg.addSequence(al.getSequenceAt(2), false);
531 av.setSelectionGroup(sg);
533 FinderI f = new Finder(av);
534 f.findNext("b", false, false, false, false);
535 assertTrue(f.getIdMatches().isEmpty());
536 SearchResultsI searchResults = f.getSearchResults();
537 assertEquals(searchResults.getCount(), 1);
538 SearchResultMatchI match = searchResults.getResults().get(0);
539 assertSame(match.getSequence(), al.getSequenceAt(1));
540 assertEquals(match.getStart(), 2);
541 assertEquals(match.getEnd(), 2);
544 * a second Find should not return the 'b' in seq3 as outside the selection
546 f.findNext("b", false, false, false, false);
547 assertTrue(f.getSearchResults().isEmpty());
548 assertTrue(f.getIdMatches().isEmpty());
551 f.findNext("d", false, 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(1));
557 assertEquals(match.getStart(), 4);
558 assertEquals(match.getEnd(), 4);
559 f.findNext("d", false, false, false, false);
560 assertTrue(f.getIdMatches().isEmpty());
561 searchResults = f.getSearchResults();
562 assertEquals(searchResults.getCount(), 1);
563 match = searchResults.getResults().get(0);
564 assertSame(match.getSequence(), al.getSequenceAt(2));
565 assertEquals(match.getStart(), 3);
566 assertEquals(match.getEnd(), 3);
570 * Test finding all matches of a search pattern in a selection group
572 @Test(groups = "Functional")
573 public void testFindAll_inSelection()
576 * select sequences 2 and 3, columns 4-6 which contains
580 SequenceGroup sg = new SequenceGroup();
583 sg.addSequence(al.getSequenceAt(1), false);
584 sg.addSequence(al.getSequenceAt(2), false);
585 av.setSelectionGroup(sg);
588 * search for 'e' should match two sequence ids and one residue
590 Finder f = new Finder(av);
591 f.findAll("e", false, false, false, false);
592 assertEquals(f.getIdMatches().size(), 2);
593 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
594 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
595 SearchResultsI searchResults = f.getSearchResults();
596 assertEquals(searchResults.getCount(), 1);
597 SearchResultMatchI match = searchResults.getResults().get(0);
598 assertSame(match.getSequence(), al.getSequenceAt(2));
599 assertEquals(match.getStart(), 4);
600 assertEquals(match.getEnd(), 4);
603 * search for 'Q' should match two sequence ids only
606 f.findAll("Q", false, false, false, false);
607 assertEquals(f.getIdMatches().size(), 2);
608 assertSame(f.getIdMatches().get(0), al.getSequenceAt(1));
609 assertSame(f.getIdMatches().get(1), al.getSequenceAt(2));
610 assertTrue(f.getSearchResults().isEmpty());
614 * Test finding in selection with a sequence too short to reach it
616 @Test(groups = "Functional")
617 public void testFind_findAllInSelectionWithShortSequence()
620 * select all sequences, columns 10-12
624 SequenceGroup sg = new SequenceGroup();
627 sg.addSequence(al.getSequenceAt(0), false);
628 sg.addSequence(al.getSequenceAt(1), false);
629 sg.addSequence(al.getSequenceAt(2), false);
630 sg.addSequence(al.getSequenceAt(3), false);
631 av.setSelectionGroup(sg);
634 * search for 'I' should match two sequence positions
636 Finder f = new Finder(av);
637 f.findAll("I", false, false, false, false);
638 assertTrue(f.getIdMatches().isEmpty());
639 SearchResultsI searchResults = f.getSearchResults();
640 assertEquals(searchResults.getCount(), 2);
641 SearchResultMatchI match = searchResults.getResults().get(0);
642 assertSame(match.getSequence(), al.getSequenceAt(0));
643 assertEquals(match.getStart(), 16);
644 assertEquals(match.getEnd(), 16);
645 match = searchResults.getResults().get(1);
646 assertSame(match.getSequence(), al.getSequenceAt(1));
647 assertEquals(match.getStart(), 8);
648 assertEquals(match.getEnd(), 8);
652 * Test that find does not report hidden positions, but does report matches
653 * that span hidden gaps
655 @Test(groups = "Functional")
656 public void testFind_withHiddenColumns()
667 * hide column 3 only, search for aaa
668 * should find two matches: aa-[-]-aa and trailing aaa
670 HiddenColumns hc = new HiddenColumns();
671 hc.hideColumns(3, 3);
672 al.setHiddenColumns(hc);
673 Finder f = new Finder(av);
674 f.findAll("aaa", false, false, false, false);
675 SearchResultsI searchResults = f.getSearchResults();
676 assertEquals(searchResults.getCount(), 2);
677 SearchResultMatchI match = searchResults.getResults().get(0);
678 assertSame(match.getSequence(), al.getSequenceAt(3));
679 assertEquals(match.getStart(), 1);
680 assertEquals(match.getEnd(), 3);
681 match = searchResults.getResults().get(1);
682 assertSame(match.getSequence(), al.getSequenceAt(3));
683 assertEquals(match.getStart(), 9);
684 assertEquals(match.getEnd(), 11);
687 * hide 2-4 (CD- -BC bcd ---)
689 hc.hideColumns(2, 4);
692 * find all search for D should ignore hidden positions in seq1 and seq3,
693 * find the visible D in seq2
696 f.findAll("D", false, false, false, false);
697 searchResults = f.getSearchResults();
698 assertEquals(searchResults.getCount(), 1);
699 match = searchResults.getResults().get(0);
700 assertSame(match.getSequence(), al.getSequenceAt(1));
701 assertEquals(match.getStart(), 4);
702 assertEquals(match.getEnd(), 4);
705 * search for AD should fail although these are now
706 * consecutive in the visible columns
709 f.findAll("AD", false, false, false, false);
710 searchResults = f.getSearchResults();
711 assertTrue(searchResults.isEmpty());
714 * find all 'aaa' should find both start and end of seq4
715 * (first run includes hidden gaps)
718 f.findAll("aaa", false, false, false, false);
719 searchResults = f.getSearchResults();
720 assertEquals(searchResults.getCount(), 2);
721 match = searchResults.getResults().get(0);
722 assertSame(match.getSequence(), al.getSequenceAt(3));
723 assertEquals(match.getStart(), 1);
724 assertEquals(match.getEnd(), 3);
725 match = searchResults.getResults().get(1);
726 assertSame(match.getSequence(), al.getSequenceAt(3));
727 assertEquals(match.getStart(), 9);
728 assertEquals(match.getEnd(), 11);
732 * find all 'aaa' should match twice in seq4
733 * (first match partly hidden, second all visible)
735 hc.hideColumns(2, 5);
737 f.findAll("aaa", false, false, false, false);
738 searchResults = f.getSearchResults();
739 assertEquals(searchResults.getCount(), 2);
740 match = searchResults.getResults().get(0);
741 assertSame(match.getSequence(), al.getSequenceAt(3));
742 assertEquals(match.getStart(), 1);
743 assertEquals(match.getEnd(), 3);
744 match = searchResults.getResults().get(1);
745 assertSame(match.getSequence(), al.getSequenceAt(3));
746 assertEquals(match.getStart(), 9);
747 assertEquals(match.getEnd(), 11);
750 * find all 'BE' should not match across hidden columns in seq1
752 f.findAll("BE", false, false, false, false);
753 assertTrue(f.getSearchResults().isEmpty());
756 * boundary case: hide columns at end of alignment
757 * search for H should match seq3/6 only
759 hc.revealAllHiddenColumns(new ColumnSelection());
760 hc.hideColumns(8, 13);
762 f.findNext("H", false, false, false, false);
763 searchResults = f.getSearchResults();
764 assertEquals(searchResults.getCount(), 1);
765 match = searchResults.getResults().get(0);
766 assertSame(match.getSequence(), al.getSequenceAt(2));
767 assertEquals(match.getStart(), 6);
768 assertEquals(match.getEnd(), 6);
771 @Test(groups = "Functional")
772 public void testFind_withHiddenColumnsAndSelection()
783 * hide columns 2-4 and 6-7
785 HiddenColumns hc = new HiddenColumns();
786 hc.hideColumns(2, 4);
787 hc.hideColumns(6, 7);
788 al.setHiddenColumns(hc);
793 SequenceGroup sg = new SequenceGroup();
794 sg.addSequence(al.getSequenceAt(1), false);
795 sg.addSequence(al.getSequenceAt(2), false);
798 av.setSelectionGroup(sg);
801 * find all search for A or H
802 * should match seq2/1, seq2/7, not seq3/6
804 Finder f = new Finder(av);
805 f.findAll("[AH]", false, false, false, false);
806 SearchResultsI searchResults = f.getSearchResults();
807 assertEquals(searchResults.getCount(), 2);
808 SearchResultMatchI match = searchResults.getResults().get(0);
809 assertSame(match.getSequence(), al.getSequenceAt(1));
810 assertEquals(match.getStart(), 1);
811 assertEquals(match.getEnd(), 1);
812 match = searchResults.getResults().get(1);
813 assertSame(match.getSequence(), al.getSequenceAt(1));
814 assertEquals(match.getStart(), 7);
815 assertEquals(match.getEnd(), 7);
818 @Test(groups = "Functional")
819 public void testFind_ignoreHiddenColumns()
828 HiddenColumns hc = new HiddenColumns();
829 hc.hideColumns(2, 4);
830 hc.hideColumns(7, 7);
831 al.setHiddenColumns(hc);
841 Finder f = new Finder(av);
842 f.findAll("abe", false, false, false, true); // true = ignore hidden
843 SearchResultsI searchResults = f.getSearchResults();
846 * match of seq1 ABE made up of AB and E
847 * note only one match is counted
849 assertEquals(searchResults.getCount(), 1);
850 assertEquals(searchResults.getResults().size(), 2);
851 SearchResultMatchI match = searchResults.getResults().get(0);
852 assertSame(match.getSequence(), al.getSequenceAt(0));
853 assertEquals(match.getStart(), 8); // A
854 assertEquals(match.getEnd(), 9); // B
855 match = searchResults.getResults().get(1);
856 assertSame(match.getSequence(), al.getSequenceAt(0));
857 assertEquals(match.getStart(), 12); // E
858 assertEquals(match.getEnd(), 12);
861 f.findNext("a.E", false, false, false, true);
862 searchResults = f.getSearchResults();
863 assertEquals(searchResults.getCount(), 1);
864 assertEquals(searchResults.getResults().size(), 2);
865 match = searchResults.getResults().get(0);
866 assertSame(match.getSequence(), al.getSequenceAt(0));
867 assertEquals(match.getStart(), 8); // A
868 assertEquals(match.getEnd(), 9); // B
869 match = searchResults.getResults().get(1);
870 assertSame(match.getSequence(), al.getSequenceAt(0));
871 assertEquals(match.getStart(), 12); // E
872 assertEquals(match.getEnd(), 12);
874 f.findNext("a.E", false, false, false, true);
875 searchResults = f.getSearchResults();
876 assertEquals(searchResults.getCount(), 1);
877 assertEquals(searchResults.getResults().size(), 2);
878 match = searchResults.getResults().get(0);
879 assertSame(match.getSequence(), al.getSequenceAt(1));
880 assertEquals(match.getStart(), 1); // a
881 assertEquals(match.getEnd(), 1);
882 match = searchResults.getResults().get(1);
883 assertSame(match.getSequence(), al.getSequenceAt(1));
884 assertEquals(match.getStart(), 4); // D
885 assertEquals(match.getEnd(), 5); // e
888 * find all matching across two hidden column regions
889 * note one 'match' is returned as three contiguous matches
891 f.findAll("BEG", false, false, false, true);
892 searchResults = f.getSearchResults();
893 assertEquals(searchResults.getCount(), 1);
894 assertEquals(searchResults.getResults().size(), 3);
895 match = searchResults.getResults().get(0);
896 assertSame(match.getSequence(), al.getSequenceAt(0));
897 assertEquals(match.getStart(), 9); // B
898 assertEquals(match.getEnd(), 9);
899 match = searchResults.getResults().get(1);
900 assertSame(match.getSequence(), al.getSequenceAt(0));
901 assertEquals(match.getStart(), 12); // E
902 assertEquals(match.getEnd(), 12);
903 match = searchResults.getResults().get(2);
904 assertSame(match.getSequence(), al.getSequenceAt(0));
905 assertEquals(match.getStart(), 14); // G
906 assertEquals(match.getEnd(), 14);
909 * now select columns 0-9 and search for A.*H
910 * this should match in the second sequence (split as 3 matches)
911 * but not the first (as H is outside the selection)
913 SequenceGroup selection = new SequenceGroup();
914 selection.setStartRes(0);
915 selection.setEndRes(9);
916 al.getSequences().forEach(seq -> selection.addSequence(seq, false));
917 av.setSelectionGroup(selection);
918 f.findAll("A.*H", false, false, false, true);
919 searchResults = f.getSearchResults();
920 assertEquals(searchResults.getCount(), 1);
921 assertEquals(searchResults.getResults().size(), 3);
922 // match made of contiguous matches A, DE, H
923 match = searchResults.getResults().get(0);
924 assertSame(match.getSequence(), al.getSequenceAt(1));
925 assertEquals(match.getStart(), 1); // A
926 assertEquals(match.getEnd(), 1);
927 match = searchResults.getResults().get(1);
928 assertSame(match.getSequence(), al.getSequenceAt(1));
929 assertEquals(match.getStart(), 4); // D
930 assertEquals(match.getEnd(), 5); // E
931 match = searchResults.getResults().get(2);
932 assertSame(match.getSequence(), al.getSequenceAt(1));
933 assertEquals(match.getStart(), 7); // H (there is no G)
934 assertEquals(match.getEnd(), 7);
937 @Test(groups = "Functional")
938 public void testFind_featuresOnly()
940 Finder f = new Finder(av);
941 // no match when not searching feature descriptions
942 f.findAll("Feature", false, false, false, true);
943 assertEquals(f.getSearchResults().getCount(), 0);
945 // no match when case sensitive on feature descriptions
946 f.findAll("feature", true, false, true, true);
947 assertEquals(f.getSearchResults().getCount(), 0);
949 // search feature descriptions - all match
950 f.findAll("Feature", false, false, true, true);
951 assertEquals(f.getSearchResults().getCount(), 3);
953 List<SequenceI> seqs = f.getSearchResults().getMatchingSubSequences();
954 // assume order is preserved in results
955 assertEquals(al.getSequenceAt(0).getDatasetSequence(),
956 seqs.get(0).getDatasetSequence());
957 assertEquals(seqs.get(0).getStart(), 9);
958 assertEquals(seqs.get(0).getEnd(), 11);
959 assertEquals(al.getSequenceAt(3).getDatasetSequence(),
960 seqs.get(1).getDatasetSequence());
961 assertEquals(seqs.get(1).getStart(), 9);
962 assertEquals(seqs.get(1).getEnd(), 11);
963 assertEquals(al.getSequenceAt(3).getDatasetSequence(),
964 seqs.get(2).getDatasetSequence());
965 assertEquals(seqs.get(2).getStart(), 1);
966 assertEquals(seqs.get(2).getEnd(), 3);
969 // search feature descriptions incrementally
970 // assume same order as before
971 f.findNext("Feature", false, false, true, true);
972 assertEquals(f.getSearchResults().getCount(), 1);
973 sq = f.getSearchResults().getMatchingSubSequences().get(0);
974 assertEquals(sq.getSequenceAsString(),
975 seqs.get(0).getSequenceAsString());
978 f.findNext("Feature", false, false, true, true);
979 assertEquals(f.getSearchResults().getCount(), 1);
980 sq = f.getSearchResults().getMatchingSubSequences().get(0);
981 assertEquals(sq.getSequenceAsString(),
982 seqs.get(1).getSequenceAsString());
985 f.findNext("Feature", false, false, true, true);
986 assertEquals(f.getSearchResults().getCount(), 1);
987 sq = f.getSearchResults().getMatchingSubSequences().get(0);
988 assertEquals(sq.getSequenceAsString(),
989 seqs.get(2).getSequenceAsString());