Merge branch 'features/JAL-2326_JOptionPane-refactoring' into develop
[jalview.git] / test / jalview / analysis / FinderTest.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
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.
11  *  
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.
16  * 
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.
20  */
21 package jalview.analysis;
22
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertSame;
25 import static org.testng.Assert.assertTrue;
26
27 import jalview.datamodel.Alignment;
28 import jalview.datamodel.AlignmentI;
29 import jalview.datamodel.SearchResultMatchI;
30 import jalview.datamodel.SearchResultsI;
31 import jalview.datamodel.Sequence;
32 import jalview.gui.AlignFrame;
33 import jalview.gui.JvOptionPane;
34 import jalview.io.FileLoader;
35 import jalview.io.FormatAdapter;
36
37 import java.util.List;
38
39 import org.testng.annotations.BeforeClass;
40 import org.testng.annotations.Test;
41
42 public class FinderTest
43 {
44   @BeforeClass(alwaysRun = true)
45   public void setUpJvOptionPane()
46   {
47     JvOptionPane.setInteractiveMode(false);
48     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
49   }
50
51   private AlignFrame af;
52
53   private AlignmentI al;
54
55   @BeforeClass(groups = "Functional")
56   public void setUp()
57   {
58     String seqData = "seq1 ABCD--EF-GHI\n" + "seq2 A--BCDefHI\n"
59             + "seq3 --bcdEFH\n" + "seq4 aa---aMMMMMaaa\n";
60     af = new FileLoader().LoadFileWaitTillLoaded(seqData,
61             FormatAdapter.PASTE);
62     al = af.getViewport().getAlignment();
63   }
64
65   /**
66    * Test for find all matches of a regular expression
67    */
68   @Test(groups = "Functional")
69   public void testFindAll_regex()
70   {
71     Finder f = new Finder(al, null);
72     f.setFindAll(true);
73     f.find("E.H"); // 'E, any character, H'
74
75     // should match seq2 efH and seq3 EFH
76     SearchResultsI sr = f.getSearchResults();
77     assertEquals(sr.getSize(), 2);
78     List<SearchResultMatchI> matches = sr.getResults();
79     assertSame(al.getSequenceAt(1), matches.get(0).getSequence());
80     assertSame(al.getSequenceAt(2), matches.get(1).getSequence());
81     assertEquals(matches.get(0).getStart(), 5);
82     assertEquals(matches.get(0).getEnd(), 7);
83     assertEquals(matches.get(1).getStart(), 4);
84     assertEquals(matches.get(1).getEnd(), 6);
85   }
86
87   /**
88    * Test for (undocumented) find residue by position
89    */
90   @Test(groups = "Functional")
91   public void testFind_residueNumber()
92   {
93     Finder f = new Finder(al, null);
94     f.setFindAll(true);
95     f.find("9");
96
97     // seq1 and seq4 have 9 residues; no match in other sequences
98     SearchResultsI sr = f.getSearchResults();
99     assertEquals(sr.getSize(), 2);
100     List<SearchResultMatchI> matches = sr.getResults();
101     assertSame(al.getSequenceAt(0), matches.get(0).getSequence());
102     assertSame(al.getSequenceAt(3), matches.get(1).getSequence());
103     assertEquals(matches.get(0).getStart(), 9);
104     assertEquals(matches.get(0).getEnd(), 9);
105     assertEquals(matches.get(1).getStart(), 9);
106     assertEquals(matches.get(1).getEnd(), 9);
107   }
108
109   /**
110    * Test for find next action
111    */
112   @Test(groups = "Functional")
113   public void testFindNext()
114   {
115     /*
116      * start at second sequence; resIndex of -1
117      * means sequence id / description is searched
118      */
119     Finder f = new Finder(al, null, 1, -1);
120     f.find("e"); // matches id
121
122     assertTrue(f.getSearchResults().isEmpty());
123     assertEquals(f.getIdMatch().size(), 1);
124     assertSame(f.getIdMatch().get(0), al.getSequenceAt(1));
125
126     // resIndex is now 0 - for use in next find next
127     assertEquals(f.getResIndex(), 0);
128     f = new Finder(al, null, 1, 0);
129     f.find("e"); // matches in sequence
130     assertTrue(f.getIdMatch().isEmpty());
131     assertEquals(f.getSearchResults().getSize(), 1);
132     List<SearchResultMatchI> matches = f.getSearchResults().getResults();
133     assertEquals(matches.get(0).getStart(), 5);
134     assertEquals(matches.get(0).getEnd(), 5);
135     assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
136     // still in the second sequence
137     assertEquals(f.getSeqIndex(), 1);
138     // next residue position to search from is 5
139     // (used as base 0 by RegEx so the same as 6 if base 1)
140     assertEquals(f.getResIndex(), 5);
141
142     // find next from end of sequence - finds next sequence id
143     f = new Finder(al, null, 1, 5);
144     f.find("e");
145     assertEquals(f.getIdMatch().size(), 1);
146     assertSame(f.getIdMatch().get(0), al.getSequenceAt(2));
147   }
148
149   /**
150    * Test for matching within sequence descriptions
151    */
152   @Test(groups = "Functional")
153   public void testFindAll_inDescription()
154   {
155     AlignmentI al2 = new Alignment(al);
156     al2.getSequenceAt(0).setDescription("BRAF");
157     al2.getSequenceAt(1).setDescription("braf");
158     Finder f = new Finder(al2, null);
159     f.setFindAll(true);
160     f.setIncludeDescription(true);
161
162     f.find("rAF");
163     assertEquals(f.getIdMatch().size(), 2);
164     assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
165     assertSame(f.getIdMatch().get(1), al2.getSequenceAt(1));
166     assertTrue(f.getSearchResults().isEmpty());
167
168     /*
169      * case sensitive
170      */
171     f = new Finder(al2, null);
172     f.setFindAll(true);
173     f.setCaseSensitive(true);
174     f.setIncludeDescription(true);
175
176     f.find("RAF");
177     assertEquals(f.getIdMatch().size(), 1);
178     assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
179     assertTrue(f.getSearchResults().isEmpty());
180
181     /*
182      * match sequence id, description and sequence!
183      */
184     al2.getSequenceAt(0).setDescription("the efh sequence");
185     al2.getSequenceAt(0).setName("mouseEFHkinase");
186     al2.getSequenceAt(1).setName("humanEFHkinase");
187     f = new Finder(al2, null);
188     f.setFindAll(true);
189     f.setIncludeDescription(true);
190
191     /*
192      * sequence matches should have no duplicates
193      */
194     f.find("EFH");
195     assertEquals(f.getIdMatch().size(), 2);
196     assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
197     assertSame(f.getIdMatch().get(1), al2.getSequenceAt(1));
198
199     assertEquals(f.getSearchResults().getSize(), 2);
200     SearchResultMatchI match = f.getSearchResults().getResults().get(0);
201     assertSame(al2.getSequenceAt(1), match.getSequence());
202     assertEquals(5, match.getStart());
203     assertEquals(7, match.getEnd());
204     match = f.getSearchResults().getResults().get(1);
205     assertSame(al2.getSequenceAt(2), match.getSequence());
206     assertEquals(4, match.getStart());
207     assertEquals(6, match.getEnd());
208   }
209
210   /**
211    * Test for matching within sequence ids
212    */
213   @Test(groups = "Functional")
214   public void testFindAll_sequenceIds()
215   {
216     Finder f = new Finder(al, null);
217     f.setFindAll(true);
218
219     /*
220      * case insensitive
221      */
222     f.find("SEQ1");
223     assertEquals(f.getIdMatch().size(), 1);
224     assertSame(f.getIdMatch().get(0), al.getSequenceAt(0));
225     assertTrue(f.getSearchResults().isEmpty());
226
227     /*
228      * case sensitive
229      */
230     f = new Finder(al, null);
231     f.setFindAll(true);
232     f.setCaseSensitive(true);
233     f.find("SEQ1");
234     assertTrue(f.getSearchResults().isEmpty());
235
236     /*
237      * match both sequence id and sequence
238      */
239     AlignmentI al2 = new Alignment(al);
240     al2.addSequence(new Sequence("aBz", "xyzabZpqrAbZ"));
241     f = new Finder(al2, null);
242     f.setFindAll(true);
243     f.find("ABZ");
244     assertEquals(f.getIdMatch().size(), 1);
245     assertSame(f.getIdMatch().get(0), al2.getSequenceAt(4));
246     assertEquals(f.getSearchResults().getSize(), 2);
247     SearchResultMatchI match = f.getSearchResults().getResults().get(0);
248     assertSame(al2.getSequenceAt(4), match.getSequence());
249     assertEquals(4, match.getStart());
250     assertEquals(6, match.getEnd());
251     match = f.getSearchResults().getResults().get(1);
252     assertSame(al2.getSequenceAt(4), match.getSequence());
253     assertEquals(10, match.getStart());
254     assertEquals(12, match.getEnd());
255   }
256
257   /**
258    * Test finding all matches of a sequence pattern in an alignment
259    */
260   @Test(groups = "Functional")
261   public void testFindAll_simpleMatch()
262   {
263     Finder f = new Finder(al, null);
264     f.setFindAll(true);
265
266     /*
267      * case insensitive first
268      */
269     f.find("EfH");
270     SearchResultsI searchResults = f.getSearchResults();
271     assertEquals(searchResults.getSize(), 2);
272     SearchResultMatchI match = searchResults.getResults().get(0);
273     assertSame(al.getSequenceAt(1), match.getSequence());
274     assertEquals(5, match.getStart());
275     assertEquals(7, match.getEnd());
276     match = searchResults.getResults().get(1);
277     assertSame(al.getSequenceAt(2), match.getSequence());
278     assertEquals(4, match.getStart());
279     assertEquals(6, match.getEnd());
280
281     /*
282      * case sensitive
283      */
284     f = new Finder(al, null);
285     f.setFindAll(true);
286     f.setCaseSensitive(true);
287     f.find("BC");
288     searchResults = f.getSearchResults();
289     assertEquals(searchResults.getSize(), 2);
290     match = searchResults.getResults().get(0);
291     assertSame(al.getSequenceAt(0), match.getSequence());
292     assertEquals(2, match.getStart());
293     assertEquals(3, match.getEnd());
294     match = searchResults.getResults().get(1);
295     assertSame(al.getSequenceAt(1), match.getSequence());
296     assertEquals(2, match.getStart());
297     assertEquals(3, match.getEnd());
298   }
299
300   /**
301    * Test for JAL-2302 to verify that sub-matches are not included in a find all
302    * result
303    */
304   @Test(groups = "Functional")
305   public void testFind_maximalResultOnly()
306   {
307     Finder f = new Finder(al, null);
308     f.setFindAll(true);
309     f.find("M+");
310     SearchResultsI searchResults = f.getSearchResults();
311     assertEquals(searchResults.getSize(), 1);
312     SearchResultMatchI match = searchResults.getResults().get(0);
313     assertSame(al.getSequenceAt(3), match.getSequence());
314     assertEquals(4, match.getStart()); // dataset sequence positions
315     assertEquals(8, match.getEnd()); // base 1
316   }
317 }