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.bin.Cache;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentI;
30 import jalview.datamodel.SearchResultMatchI;
31 import jalview.datamodel.SearchResultsI;
32 import jalview.datamodel.Sequence;
33 import jalview.datamodel.SequenceGroup;
34 import jalview.gui.AlignFrame;
35 import jalview.gui.JvOptionPane;
36 import jalview.io.DataSourceType;
37 import jalview.io.FileLoader;
39 import java.util.List;
41 import org.testng.annotations.BeforeClass;
42 import org.testng.annotations.Test;
44 public class FinderTest
46 @BeforeClass(alwaysRun = true)
47 public void setUpJvOptionPane()
49 JvOptionPane.setInteractiveMode(false);
50 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
53 private AlignFrame af;
55 private AlignmentI al;
57 @BeforeClass(groups = "Functional")
60 Cache.loadProperties("test/jalview/io/testProps.jvprops");
61 Cache.applicationProperties.setProperty("PAD_GAPS",
62 Boolean.FALSE.toString());
64 String seqData = "seq1seq1/8-16 ABCD--EF-GHI\n" + "seq2 A--BCDefHI\n"
65 + "seq3 --bcdEFH\n" + "seq4 aa---aMMMMMaaa\n";
66 af = new FileLoader().LoadFileWaitTillLoaded(seqData,
67 DataSourceType.PASTE);
68 al = af.getViewport().getAlignment();
72 * Test for find matches of a regular expression
74 @Test(groups = "Functional")
75 public void testFind_regex()
78 * find next match only
80 Finder f = new Finder(al, null);
81 f.find("E.H"); // 'E, any character, H'
82 // should match seq2 efH only
83 SearchResultsI sr = f.getSearchResults();
84 assertEquals(sr.getSize(), 1);
85 List<SearchResultMatchI> matches = sr.getResults();
86 assertSame(al.getSequenceAt(1), matches.get(0).getSequence());
87 assertEquals(matches.get(0).getStart(), 5);
88 assertEquals(matches.get(0).getEnd(), 7);
90 f = new Finder(al, null);
92 f.find("E.H"); // 'E, any character, H'
93 // should match seq2 efH and seq3 EFH
94 sr = f.getSearchResults();
95 assertEquals(sr.getSize(), 2);
96 matches = sr.getResults();
97 assertSame(al.getSequenceAt(1), matches.get(0).getSequence());
98 assertSame(al.getSequenceAt(2), matches.get(1).getSequence());
99 assertEquals(matches.get(0).getStart(), 5);
100 assertEquals(matches.get(0).getEnd(), 7);
101 assertEquals(matches.get(1).getStart(), 4);
102 assertEquals(matches.get(1).getEnd(), 6);
106 * Test for (undocumented) find residue by position
108 @Test(groups = "Functional")
109 public void testFind_residueNumber()
111 Finder f = new Finder(al, null);
114 * find first match should return seq1 residue 9
117 SearchResultsI sr = f.getSearchResults();
118 assertEquals(sr.getSize(), 1);
119 List<SearchResultMatchI> matches = sr.getResults();
120 assertSame(al.getSequenceAt(0), matches.get(0).getSequence());
121 assertEquals(matches.get(0).getStart(), 9);
122 assertEquals(matches.get(0).getEnd(), 9);
125 * find all matches should return seq1 and seq4 (others are too short)
127 f = new Finder(al, null);
130 sr = f.getSearchResults();
131 assertEquals(sr.getSize(), 2);
132 matches = sr.getResults();
133 assertSame(al.getSequenceAt(0), matches.get(0).getSequence());
134 assertSame(al.getSequenceAt(3), matches.get(1).getSequence());
135 assertEquals(matches.get(0).getStart(), 9);
136 assertEquals(matches.get(0).getEnd(), 9);
137 assertEquals(matches.get(1).getStart(), 9);
138 assertEquals(matches.get(1).getEnd(), 9);
141 * parsing of search string as integer is strict
143 f = new Finder(al, null);
145 assertTrue(f.getSearchResults().isEmpty());
149 * Test for find next action
151 @Test(groups = "Functional")
152 public void testFindNext()
155 * start at second sequence; resIndex of -1
156 * means sequence id / description is searched
158 Finder f = new Finder(al, null, 1, -1);
159 f.find("e"); // matches id
161 assertTrue(f.getSearchResults().isEmpty());
162 assertEquals(f.getIdMatch().size(), 1);
163 assertSame(f.getIdMatch().get(0), al.getSequenceAt(1));
165 // resIndex is now 0 - for use in next find next
166 assertEquals(f.getResIndex(), 0);
167 f = new Finder(al, null, 1, 0);
168 f.find("e"); // matches in sequence
169 assertTrue(f.getIdMatch().isEmpty());
170 assertEquals(f.getSearchResults().getSize(), 1);
171 List<SearchResultMatchI> matches = f.getSearchResults().getResults();
172 assertEquals(matches.get(0).getStart(), 5);
173 assertEquals(matches.get(0).getEnd(), 5);
174 assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
175 // still in the second sequence
176 assertEquals(f.getSeqIndex(), 1);
177 // next residue position to search from is 5
178 // (used as base 0 by RegEx so the same as 6 if base 1)
179 assertEquals(f.getResIndex(), 5);
181 // find next from end of sequence - finds next sequence id
182 f = new Finder(al, null, 1, 5);
184 assertEquals(f.getIdMatch().size(), 1);
185 assertSame(f.getIdMatch().get(0), al.getSequenceAt(2));
189 * Test for matching within sequence descriptions
191 @Test(groups = "Functional")
192 public void testFind_inDescription()
194 AlignmentI al2 = new Alignment(al);
195 al2.getSequenceAt(0).setDescription("BRAF");
196 al2.getSequenceAt(1).setDescription("braf");
199 * find first match only
201 Finder f = new Finder(al2, null);
202 f.setIncludeDescription(true);
204 assertEquals(f.getIdMatch().size(), 1);
205 assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
206 assertTrue(f.getSearchResults().isEmpty());
211 f = new Finder(al2, null);
213 f.setIncludeDescription(true);
215 assertEquals(f.getIdMatch().size(), 2);
216 assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
217 assertSame(f.getIdMatch().get(1), al2.getSequenceAt(1));
218 assertTrue(f.getSearchResults().isEmpty());
223 f = new Finder(al2, null);
225 f.setCaseSensitive(true);
226 f.setIncludeDescription(true);
229 assertEquals(f.getIdMatch().size(), 1);
230 assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
231 assertTrue(f.getSearchResults().isEmpty());
234 * match sequence id, description and sequence!
236 al2.getSequenceAt(0).setDescription("the efh sequence");
237 al2.getSequenceAt(0).setName("mouseEFHkinase");
238 al2.getSequenceAt(1).setName("humanEFHkinase");
239 f = new Finder(al2, null);
241 f.setIncludeDescription(true);
244 * sequence matches should have no duplicates
247 assertEquals(f.getIdMatch().size(), 2);
248 assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
249 assertSame(f.getIdMatch().get(1), al2.getSequenceAt(1));
251 assertEquals(f.getSearchResults().getSize(), 2);
252 SearchResultMatchI match = f.getSearchResults().getResults().get(0);
253 assertSame(al2.getSequenceAt(1), match.getSequence());
254 assertEquals(5, match.getStart());
255 assertEquals(7, match.getEnd());
256 match = f.getSearchResults().getResults().get(1);
257 assertSame(al2.getSequenceAt(2), match.getSequence());
258 assertEquals(4, match.getStart());
259 assertEquals(6, match.getEnd());
263 * Test for matching within sequence ids
265 @Test(groups = "Functional")
266 public void testFindAll_sequenceIds()
268 Finder f = new Finder(al, null);
272 * case insensitive; seq1 occurs twice in sequence id but
273 * only one match should be returned
276 assertEquals(f.getIdMatch().size(), 1);
277 assertSame(f.getIdMatch().get(0), al.getSequenceAt(0));
278 assertTrue(f.getSearchResults().isEmpty());
283 f = new Finder(al, null);
285 f.setCaseSensitive(true);
287 assertTrue(f.getSearchResults().isEmpty());
290 * match both sequence id and sequence
292 AlignmentI al2 = new Alignment(al);
293 al2.addSequence(new Sequence("aBz", "xyzabZpqrAbZ"));
294 f = new Finder(al2, null);
297 assertEquals(f.getIdMatch().size(), 1);
298 assertSame(f.getIdMatch().get(0), al2.getSequenceAt(4));
299 assertEquals(f.getSearchResults().getSize(), 2);
300 SearchResultMatchI match = f.getSearchResults().getResults().get(0);
301 assertSame(al2.getSequenceAt(4), match.getSequence());
302 assertEquals(4, match.getStart());
303 assertEquals(6, match.getEnd());
304 match = f.getSearchResults().getResults().get(1);
305 assertSame(al2.getSequenceAt(4), match.getSequence());
306 assertEquals(10, match.getStart());
307 assertEquals(12, match.getEnd());
311 * Test finding next match of a sequence pattern in an alignment
313 @Test(groups = "Functional")
314 public void testFind()
316 Finder f = new Finder(al, null);
318 SearchResultsI searchResults = f.getSearchResults();
319 assertEquals(searchResults.getSize(), 1);
320 SearchResultMatchI match = searchResults.getResults().get(0);
321 assertSame(al.getSequenceAt(1), match.getSequence());
322 assertEquals(5, match.getStart());
323 assertEquals(7, match.getEnd());
327 * Test for JAL-2302 to verify that sub-matches are not included in a find all
330 @Test(groups = "Functional")
331 public void testFind_maximalResultOnly()
333 Finder f = new Finder(al, null);
336 SearchResultsI searchResults = f.getSearchResults();
337 assertEquals(searchResults.getSize(), 1);
338 SearchResultMatchI match = searchResults.getResults().get(0);
339 assertSame(al.getSequenceAt(3), match.getSequence());
340 assertEquals(4, match.getStart()); // dataset sequence positions
341 assertEquals(8, match.getEnd()); // base 1
345 * Test finding all matches of a sequence pattern in an alignment
347 @Test(groups = "Functional")
348 public void testFind_findAll()
350 Finder f = new Finder(al, null);
353 SearchResultsI searchResults = f.getSearchResults();
354 assertEquals(searchResults.getSize(), 2);
355 SearchResultMatchI match = searchResults.getResults().get(0);
356 assertSame(al.getSequenceAt(1), match.getSequence());
357 assertEquals(5, match.getStart());
358 assertEquals(7, match.getEnd());
359 match = searchResults.getResults().get(1);
360 assertSame(al.getSequenceAt(2), match.getSequence());
361 assertEquals(4, match.getStart());
362 assertEquals(6, match.getEnd());
366 * Test finding all matches, case-sensitive
368 @Test(groups = "Functional")
369 public void testFind_findAllCaseSensitive()
371 Finder f = new Finder(al, null);
372 f.setCaseSensitive(true);
375 SearchResultsI searchResults = f.getSearchResults();
376 assertEquals(searchResults.getSize(), 2);
377 SearchResultMatchI match = searchResults.getResults().get(0);
378 assertSame(al.getSequenceAt(0), match.getSequence());
379 assertEquals(match.getStart(), 9);
380 assertEquals(match.getEnd(), 10);
381 match = searchResults.getResults().get(1);
382 assertSame(al.getSequenceAt(1), match.getSequence());
383 assertEquals(match.getStart(), 2);
384 assertEquals(match.getEnd(), 3);
388 * Test finding next match of a sequence pattern in a selection group
390 @Test(groups = "Functional")
391 public void testFind_inSelection()
394 * select sequences 2 and 3, columns 4-6 which contains
398 SequenceGroup sg = new SequenceGroup();
401 sg.addSequence(al.getSequenceAt(1), false);
402 sg.addSequence(al.getSequenceAt(2), false);
404 Finder f = new Finder(al, sg);
406 assertTrue(f.getIdMatch().isEmpty());
407 SearchResultsI searchResults = f.getSearchResults();
408 assertEquals(searchResults.getSize(), 1);
409 SearchResultMatchI match = searchResults.getResults().get(0);
410 assertSame(al.getSequenceAt(1), match.getSequence());
411 assertEquals(2, match.getStart());
412 assertEquals(2, match.getEnd());
415 * a second Find should not return the 'b' in seq3 as outside the selection
418 assertTrue(f.getSearchResults().isEmpty());
419 assertTrue(f.getIdMatch().isEmpty());
421 f = new Finder(al, sg);
423 assertTrue(f.getIdMatch().isEmpty());
424 searchResults = f.getSearchResults();
425 assertEquals(searchResults.getSize(), 1);
426 match = searchResults.getResults().get(0);
427 assertSame(al.getSequenceAt(1), match.getSequence());
428 assertEquals(4, match.getStart());
429 assertEquals(4, match.getEnd());
431 assertTrue(f.getIdMatch().isEmpty());
432 searchResults = f.getSearchResults();
433 assertEquals(searchResults.getSize(), 1);
434 match = searchResults.getResults().get(0);
435 assertSame(al.getSequenceAt(2), match.getSequence());
436 assertEquals(3, match.getStart());
437 assertEquals(3, match.getEnd());
441 * Test finding all matches of a search pattern in a selection group
443 @Test(groups = "Functional")
444 public void testFind_findAllInSelection()
447 * select sequences 2 and 3, columns 4-6 which contains
451 SequenceGroup sg = new SequenceGroup();
454 sg.addSequence(al.getSequenceAt(1), false);
455 sg.addSequence(al.getSequenceAt(2), false);
458 * search for 'e' should match two sequence ids and one residue
460 Finder f = new Finder(al, sg);
463 assertEquals(f.getIdMatch().size(), 2);
464 assertSame(f.getIdMatch().get(0), al.getSequenceAt(1));
465 assertSame(f.getIdMatch().get(1), al.getSequenceAt(2));
466 SearchResultsI searchResults = f.getSearchResults();
467 assertEquals(searchResults.getSize(), 1);
468 SearchResultMatchI match = searchResults.getResults().get(0);
469 assertSame(al.getSequenceAt(2), match.getSequence());
470 assertEquals(4, match.getStart());
471 assertEquals(4, match.getEnd());
474 * search for 'Q' should match two sequence ids only
476 f = new Finder(al, sg);
479 assertEquals(f.getIdMatch().size(), 2);
480 assertSame(f.getIdMatch().get(0), al.getSequenceAt(1));
481 assertSame(f.getIdMatch().get(1), al.getSequenceAt(2));
482 assertTrue(f.getSearchResults().isEmpty());
486 * Test finding in selection with a sequence too short to reach it
488 @Test(groups = "Functional")
489 public void testFind_findAllInSelectionWithShortSequence()
492 * select all sequences, columns 10-12
496 SequenceGroup sg = new SequenceGroup();
499 sg.addSequence(al.getSequenceAt(0), false);
500 sg.addSequence(al.getSequenceAt(1), false);
501 sg.addSequence(al.getSequenceAt(2), false);
502 sg.addSequence(al.getSequenceAt(3), false);
505 * search for 'I' should match two sequence positions
507 Finder f = new Finder(al, sg);
510 assertTrue(f.getIdMatch().isEmpty());
511 SearchResultsI searchResults = f.getSearchResults();
512 assertEquals(searchResults.getSize(), 2);
513 SearchResultMatchI match = searchResults.getResults().get(0);
514 assertSame(al.getSequenceAt(0), match.getSequence());
515 assertEquals(16, match.getStart());
516 assertEquals(16, match.getEnd());
517 match = searchResults.getResults().get(1);
518 assertSame(al.getSequenceAt(1), match.getSequence());
519 assertEquals(8, match.getStart());
520 assertEquals(8, match.getEnd());