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