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