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.datamodel;
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertNull;
25 import static org.testng.AssertJUnit.assertSame;
26 import static org.testng.AssertJUnit.assertTrue;
28 import java.util.Arrays;
29 import java.util.List;
31 import org.testng.annotations.BeforeMethod;
32 import org.testng.annotations.Test;
34 public class SequenceTest
38 @BeforeMethod(alwaysRun = true)
41 seq = new Sequence("FER1", "AKPNGVL");
44 @Test(groups = { "Functional" })
45 public void testInsertGapsAndGapmaps()
47 SequenceI aseq = seq.deriveSequence();
48 aseq.insertCharAt(2, 3, '-');
49 aseq.insertCharAt(6, 3, '-');
50 assertEquals("Gap insertions not correct", "AK---P---NGVL",
51 aseq.getSequenceAsString());
52 List<int[]> gapInt = aseq.getInsertions();
53 assertEquals("Gap interval 1 start wrong", 2, gapInt.get(0)[0]);
54 assertEquals("Gap interval 1 end wrong", 4, gapInt.get(0)[1]);
55 assertEquals("Gap interval 2 start wrong", 6, gapInt.get(1)[0]);
56 assertEquals("Gap interval 2 end wrong", 8, gapInt.get(1)[1]);
59 @Test(groups = { "Functional" })
60 public void testGetAnnotation()
62 // initial state returns null not an empty array
63 assertNull(seq.getAnnotation());
64 AlignmentAnnotation ann = addAnnotation("label1", "desc1", "calcId1",
66 AlignmentAnnotation[] anns = seq.getAnnotation();
67 assertEquals(1, anns.length);
68 assertSame(ann, anns[0]);
70 // removing all annotations reverts array to null
71 seq.removeAlignmentAnnotation(ann);
72 assertNull(seq.getAnnotation());
75 @Test(groups = { "Functional" })
76 public void testGetAnnotation_forLabel()
78 AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1",
80 AlignmentAnnotation ann2 = addAnnotation("label2", "desc2", "calcId2",
82 AlignmentAnnotation ann3 = addAnnotation("label1", "desc3", "calcId3",
84 AlignmentAnnotation[] anns = seq.getAnnotation("label1");
85 assertEquals(2, anns.length);
86 assertSame(ann1, anns[0]);
87 assertSame(ann3, anns[1]);
90 private AlignmentAnnotation addAnnotation(String label,
91 String description, String calcId, float value)
93 final AlignmentAnnotation annotation = new AlignmentAnnotation(label,
95 annotation.setCalcId(calcId);
96 seq.addAlignmentAnnotation(annotation);
100 @Test(groups = { "Functional" })
101 public void testGetAlignmentAnnotations_forCalcIdAndLabel()
103 AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1",
105 AlignmentAnnotation ann2 = addAnnotation("label2", "desc2", "calcId2",
107 AlignmentAnnotation ann3 = addAnnotation("label2", "desc3", "calcId3",
109 AlignmentAnnotation ann4 = addAnnotation("label2", "desc3", "calcId2",
111 AlignmentAnnotation ann5 = addAnnotation("label5", "desc3", null, 1f);
112 AlignmentAnnotation ann6 = addAnnotation(null, "desc3", "calcId3", 1f);
113 List<AlignmentAnnotation> anns = seq.getAlignmentAnnotations("calcId2",
115 assertEquals(2, anns.size());
116 assertSame(ann2, anns.get(0));
117 assertSame(ann4, anns.get(1));
119 assertTrue(seq.getAlignmentAnnotations("calcId2", "label3").isEmpty());
120 assertTrue(seq.getAlignmentAnnotations("calcId3", "label5").isEmpty());
121 assertTrue(seq.getAlignmentAnnotations("calcId2", null).isEmpty());
122 assertTrue(seq.getAlignmentAnnotations(null, "label3").isEmpty());
123 assertTrue(seq.getAlignmentAnnotations(null, null).isEmpty());
127 * Tests for addAlignmentAnnotation. Note this method has the side-effect of
128 * setting the sequenceRef on the annotation. Adding the same annotation twice
131 @Test(groups = { "Functional" })
132 public void testAddAlignmentAnnotation()
134 assertNull(seq.getAnnotation());
135 final AlignmentAnnotation annotation = new AlignmentAnnotation("a",
137 assertNull(annotation.sequenceRef);
138 seq.addAlignmentAnnotation(annotation);
139 assertSame(seq, annotation.sequenceRef);
140 AlignmentAnnotation[] anns = seq.getAnnotation();
141 assertEquals(1, anns.length);
142 assertSame(annotation, anns[0]);
144 // re-adding does nothing
145 seq.addAlignmentAnnotation(annotation);
146 anns = seq.getAnnotation();
147 assertEquals(1, anns.length);
148 assertSame(annotation, anns[0]);
150 // an identical but different annotation can be added
151 final AlignmentAnnotation annotation2 = new AlignmentAnnotation("a",
153 seq.addAlignmentAnnotation(annotation2);
154 anns = seq.getAnnotation();
155 assertEquals(2, anns.length);
156 assertSame(annotation, anns[0]);
157 assertSame(annotation2, anns[1]);
161 @Test(groups = { "Functional" })
162 public void testGetStartGetEnd()
164 SequenceI seq = new Sequence("test", "ABCDEF");
165 assertEquals(1, seq.getStart());
166 assertEquals(6, seq.getEnd());
168 seq = new Sequence("test", "--AB-C-DEF--");
169 assertEquals(1, seq.getStart());
170 assertEquals(6, seq.getEnd());
172 seq = new Sequence("test", "----");
173 assertEquals(1, seq.getStart());
174 assertEquals(0, seq.getEnd()); // ??
178 * Tests for the method that returns an alignment column position (base 1) for
179 * a given sequence position (base 1).
181 @Test(groups = { "Functional" })
182 public void testFindIndex()
184 SequenceI seq = new Sequence("test", "ABCDEF");
185 assertEquals(0, seq.findIndex(0));
186 assertEquals(1, seq.findIndex(1));
187 assertEquals(5, seq.findIndex(5));
188 assertEquals(6, seq.findIndex(6));
189 assertEquals(6, seq.findIndex(9));
191 seq = new Sequence("test", "-A--B-C-D-E-F--");
192 assertEquals(2, seq.findIndex(1));
193 assertEquals(5, seq.findIndex(2));
194 assertEquals(7, seq.findIndex(3));
196 // before start returns 0
197 assertEquals(0, seq.findIndex(0));
198 assertEquals(0, seq.findIndex(-1));
200 // beyond end returns last residue column
201 assertEquals(13, seq.findIndex(99));
206 * Tests for the method that returns a dataset sequence position (base 1) for
207 * an aligned column position (base 0).
209 @Test(groups = { "Functional" })
210 public void testFindPosition()
212 SequenceI seq = new Sequence("test", "ABCDEF");
213 assertEquals(1, seq.findPosition(0));
214 assertEquals(6, seq.findPosition(5));
215 // assertEquals(-1, seq.findPosition(6)); // fails
217 seq = new Sequence("test", "AB-C-D--");
218 assertEquals(1, seq.findPosition(0));
219 assertEquals(2, seq.findPosition(1));
220 // gap position 'finds' residue to the right (not the left as per javadoc)
221 assertEquals(3, seq.findPosition(2));
222 assertEquals(3, seq.findPosition(3));
223 assertEquals(4, seq.findPosition(4));
224 assertEquals(4, seq.findPosition(5));
225 // returns 1 more than sequence length if off the end ?!?
226 assertEquals(5, seq.findPosition(6));
227 assertEquals(5, seq.findPosition(7));
229 seq = new Sequence("test", "--AB-C-DEF--");
230 assertEquals(1, seq.findPosition(0));
231 assertEquals(1, seq.findPosition(1));
232 assertEquals(1, seq.findPosition(2));
233 assertEquals(2, seq.findPosition(3));
234 assertEquals(3, seq.findPosition(4));
235 assertEquals(3, seq.findPosition(5));
236 assertEquals(4, seq.findPosition(6));
237 assertEquals(4, seq.findPosition(7));
238 assertEquals(5, seq.findPosition(8));
239 assertEquals(6, seq.findPosition(9));
240 assertEquals(7, seq.findPosition(10));
241 assertEquals(7, seq.findPosition(11));
244 @Test(groups = { "Functional" })
245 public void testDeleteChars()
247 SequenceI seq = new Sequence("test", "ABCDEF");
248 assertEquals(1, seq.getStart());
249 assertEquals(6, seq.getEnd());
250 seq.deleteChars(2, 3);
251 assertEquals("ABDEF", seq.getSequenceAsString());
252 assertEquals(1, seq.getStart());
253 assertEquals(5, seq.getEnd());
255 seq = new Sequence("test", "ABCDEF");
256 seq.deleteChars(0, 2);
257 assertEquals("CDEF", seq.getSequenceAsString());
258 assertEquals(3, seq.getStart());
259 assertEquals(6, seq.getEnd());
262 @Test(groups = { "Functional" })
263 public void testInsertCharAt()
265 // non-static methods:
266 SequenceI seq = new Sequence("test", "ABCDEF");
267 seq.insertCharAt(0, 'z');
268 assertEquals("zABCDEF", seq.getSequenceAsString());
269 seq.insertCharAt(2, 2, 'x');
270 assertEquals("zAxxBCDEF", seq.getSequenceAsString());
272 // for static method see StringUtilsTest
276 * Test the method that returns an array of aligned sequence positions where
277 * the array index is the data sequence position (both base 0).
279 @Test(groups = { "Functional" })
280 public void testGapMap()
282 SequenceI seq = new Sequence("test", "-A--B-CD-E--F-");
283 seq.createDatasetSequence();
284 assertEquals("[1, 4, 6, 7, 9, 12]", Arrays.toString(seq.gapMap()));
288 * Test the method that gets sequence features, either from the sequence or
291 @Test(groups = { "Functional" })
292 public void testGetSequenceFeatures()
294 SequenceI seq = new Sequence("test", "GATCAT");
295 seq.createDatasetSequence();
297 assertNull(seq.getSequenceFeatures());
300 * SequenceFeature on sequence
302 SequenceFeature sf = new SequenceFeature();
303 seq.addSequenceFeature(sf);
304 SequenceFeature[] sfs = seq.getSequenceFeatures();
305 assertEquals(1, sfs.length);
306 assertSame(sf, sfs[0]);
309 * SequenceFeature on sequence and dataset sequence; returns that on
312 SequenceFeature sf2 = new SequenceFeature();
313 seq.getDatasetSequence().addSequenceFeature(sf2);
314 sfs = seq.getSequenceFeatures();
315 assertEquals(1, sfs.length);
316 assertSame(sf, sfs[0]);
319 * SequenceFeature on dataset sequence only
321 seq.setSequenceFeatures(null);
322 sfs = seq.getSequenceFeatures();
323 assertEquals(1, sfs.length);
324 assertSame(sf2, sfs[0]);
327 * Corrupt case - no SequenceFeature, dataset's dataset is the original
328 * sequence. Test shows no infinite loop results.
330 seq.getDatasetSequence().setSequenceFeatures(null);
331 seq.getDatasetSequence().setDatasetSequence(seq); // loop!
332 assertNull(seq.getSequenceFeatures());
336 * Test the method that returns an array, indexed by sequence position, whose
337 * entries are the residue positions at the sequence position (or to the right
340 @Test(groups = { "Functional" })
341 public void testFindPositionMap()
344 * Note: Javadoc for findPosition says it returns the residue position to
345 * the left of a gapped position; in fact it returns the position to the
346 * right. Also it returns a non-existent residue position for a gap beyond
349 Sequence seq = new Sequence("TestSeq", "AB.C-D E.");
350 int[] map = seq.findPositionMap();
351 assertEquals(Arrays.toString(new int[] { 1, 2, 3, 3, 4, 4, 5, 5, 6 }),
352 Arrays.toString(map));
356 * Test for getSubsequence
358 @Test(groups = { "Functional" })
359 public void testGetSubsequence()
361 SequenceI seq = new Sequence("TestSeq", "ABCDEFG");
362 seq.createDatasetSequence();
364 // positions are base 0, end position is exclusive
365 SequenceI subseq = seq.getSubSequence(2, 4);
367 assertEquals("CD", subseq.getSequenceAsString());
368 // start/end are base 1 positions
369 assertEquals(3, subseq.getStart());
370 assertEquals(4, subseq.getEnd());
371 // subsequence shares the full dataset sequence
372 assertSame(seq.getDatasetSequence(), subseq.getDatasetSequence());
376 * Test for deriveSequence applied to a sequence with a dataset
378 @Test(groups = { "Functional" })
379 public void testDeriveSequence_existingDataset()
381 SequenceI seq = new Sequence("Seq1", "CD");
382 seq.setDatasetSequence(new Sequence("Seq1", "ABCDEF"));
385 SequenceI derived = seq.deriveSequence();
386 assertEquals("CD", derived.getSequenceAsString());
387 assertSame(seq.getDatasetSequence(), derived.getDatasetSequence());
391 * Test for deriveSequence applied to an ungapped sequence with no dataset
393 @Test(groups = { "Functional" })
394 public void testDeriveSequence_noDatasetUngapped()
396 SequenceI seq = new Sequence("Seq1", "ABCDEF");
397 assertEquals(1, seq.getStart());
398 assertEquals(6, seq.getEnd());
399 SequenceI derived = seq.deriveSequence();
400 assertEquals("ABCDEF", derived.getSequenceAsString());
401 assertEquals("ABCDEF", derived.getDatasetSequence()
402 .getSequenceAsString());
406 * Test for deriveSequence applied to a gapped sequence with no dataset
408 @Test(groups = { "Functional" })
409 public void testDeriveSequence_noDatasetGapped()
411 SequenceI seq = new Sequence("Seq1", "AB-C.D EF");
412 assertEquals(1, seq.getStart());
413 assertEquals(6, seq.getEnd());
414 assertNull(seq.getDatasetSequence());
415 SequenceI derived = seq.deriveSequence();
416 assertEquals("AB-C.D EF", derived.getSequenceAsString());
417 assertEquals("ABCDEF", derived.getDatasetSequence()
418 .getSequenceAsString());