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.
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertFalse;
25 import static org.testng.AssertJUnit.assertNull;
26 import static org.testng.AssertJUnit.assertSame;
27 import static org.testng.AssertJUnit.assertTrue;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.List;
33 import org.testng.annotations.Test;
35 public class MapListTest
38 @Test(groups = { "Functional" })
39 public void testSomething()
41 MapList ml = new MapList(new int[] { 1, 5, 10, 15, 25, 20 }, new int[] {
43 MapList ml1 = new MapList(new int[] { 1, 3, 17, 4 },
44 new int[] { 51, 1 }, 1, 3);
45 MapList ml2 = new MapList(new int[] { 1, 60 }, new int[] { 1, 20 }, 3,
47 // test internal consistency
48 int to[] = new int[51];
50 MapList mldna = new MapList(new int[] { 2, 2, 6, 8, 12, 16 }, new int[]
52 int[] frm = mldna.locateInFrom(1, 1);
53 testLocateFrom(mldna, 1, 1, new int[] { 2, 2, 6, 7 });
56 * for (int from=1; from<=51; from++) { int[] too=ml.shiftTo(from); int[]
57 * toofrom=ml.shiftFrom(too[0]);
58 * System.out.println("ShiftFrom("+from+")=="+too[0]+" %
59 * "+too[1]+"\t+-+\tShiftTo("+too[0]+")=="+toofrom[0]+" % "+toofrom[1]); }
63 private static void testLocateFrom(MapList mldna, int i, int j, int[] ks)
65 int[] frm = mldna.locateInFrom(i, j);
66 assertEquals("Failed test locate from " + i + " to " + j,
67 Arrays.toString(frm), Arrays.toString(ks));
71 * test routine. not incremental.
77 private void testMap(MapList ml, int fromS, int fromE)
79 // todo convert to JUnit style tests
80 for (int from = 1; from <= 25; from++)
82 int[] too = ml.shiftFrom(from);
83 System.out.print("ShiftFrom(" + from + ")==");
86 System.out.print("NaN\n");
90 System.out.print(too[0] + " % " + too[1] + " (" + too[2] + ")");
91 System.out.print("\t+--+\t");
92 int[] toofrom = ml.shiftTo(too[0]);
95 if (toofrom[0] != from)
97 System.err.println("Mapping not reflexive:" + from + " "
98 + too[0] + "->" + toofrom[0]);
100 System.out.println("ShiftTo(" + too[0] + ")==" + toofrom[0]
101 + " % " + toofrom[1] + " (" + toofrom[2] + ")");
105 System.out.println("ShiftTo(" + too[0] + ")=="
106 + "NaN! - not Bijective Mapping!");
110 int mmap[][] = ml.makeFromMap();
111 System.out.println("FromMap : (" + mmap[0][0] + " " + mmap[0][1] + " "
112 + mmap[0][2] + " " + mmap[0][3] + " ");
113 for (int i = 1; i <= mmap[1].length; i++)
115 if (mmap[1][i - 1] == -1)
117 System.out.print(i + "=XXX");
122 System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1]));
126 System.out.print("\n");
130 System.out.print(",");
133 // test range function
134 System.out.print("\nTest locateInFrom\n");
136 int f = mmap[0][2], t = mmap[0][3];
139 System.out.println("Range " + f + " to " + t);
140 int rng[] = ml.locateInFrom(f, t);
143 for (int i = 0; i < rng.length; i++)
145 System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";"));
150 System.out.println("No range!");
152 System.out.print("\nReversed\n");
153 rng = ml.locateInFrom(t, f);
156 for (int i = 0; i < rng.length; i++)
158 System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";"));
163 System.out.println("No range!");
165 System.out.print("\n");
170 System.out.print("\n");
171 mmap = ml.makeToMap();
172 System.out.println("ToMap : (" + mmap[0][0] + " " + mmap[0][1] + " "
173 + mmap[0][2] + " " + mmap[0][3] + " ");
174 for (int i = 1; i <= mmap[1].length; i++)
176 if (mmap[1][i - 1] == -1)
178 System.out.print(i + "=XXX");
183 System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1]));
187 System.out.print("\n");
191 System.out.print(",");
194 System.out.print("\n");
195 // test range function
196 System.out.print("\nTest locateInTo\n");
198 int f = mmap[0][2], t = mmap[0][3];
201 System.out.println("Range " + f + " to " + t);
202 int rng[] = ml.locateInTo(f, t);
205 for (int i = 0; i < rng.length; i++)
207 System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";"));
212 System.out.println("No range!");
214 System.out.print("\nReversed\n");
215 rng = ml.locateInTo(t, f);
218 for (int i = 0; i < rng.length; i++)
220 System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";"));
225 System.out.println("No range!");
229 System.out.print("\n");
235 * Tests for method that locates ranges in the 'from' map for given range in
238 @Test(groups = { "Functional" })
239 public void testLocateInFrom_noIntrons()
242 * Simple mapping with no introns
244 int[] codons = new int[] { 1, 12 };
245 int[] protein = new int[] { 1, 4 };
246 MapList ml = new MapList(codons, protein, 3, 1);
247 assertEquals("[1, 3]", Arrays.toString(ml.locateInFrom(1, 1)));
248 assertEquals("[4, 6]", Arrays.toString(ml.locateInFrom(2, 2)));
249 assertEquals("[7, 9]", Arrays.toString(ml.locateInFrom(3, 3)));
250 assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4)));
251 assertEquals("[1, 6]", Arrays.toString(ml.locateInFrom(1, 2)));
252 assertEquals("[1, 9]", Arrays.toString(ml.locateInFrom(1, 3)));
253 assertEquals("[1, 12]", Arrays.toString(ml.locateInFrom(1, 4)));
254 assertEquals("[4, 9]", Arrays.toString(ml.locateInFrom(2, 3)));
255 assertEquals("[4, 12]", Arrays.toString(ml.locateInFrom(2, 4)));
256 assertEquals("[7, 12]", Arrays.toString(ml.locateInFrom(3, 4)));
257 assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4)));
259 assertNull(ml.locateInFrom(0, 0));
260 assertNull(ml.locateInFrom(1, 5));
261 assertNull(ml.locateInFrom(-1, 1));
265 * Tests for method that locates ranges in the 'from' map for given range in
268 @Test(groups = { "Functional" })
269 public void testLocateInFrom_withIntrons()
272 * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e.
273 * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18
275 int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 };
276 int[] protein = { 1, 4 };
277 MapList ml = new MapList(codons, protein, 3, 1);
278 assertEquals("[2, 3, 5, 5]", Arrays.toString(ml.locateInFrom(1, 1)));
279 assertEquals("[6, 7, 9, 9]", Arrays.toString(ml.locateInFrom(2, 2)));
280 assertEquals("[10, 10, 12, 12, 14, 14]",
281 Arrays.toString(ml.locateInFrom(3, 3)));
282 assertEquals("[16, 18]", Arrays.toString(ml.locateInFrom(4, 4)));
286 * Tests for method that locates ranges in the 'to' map for given range in the
289 @Test(groups = { "Functional" })
290 public void testLocateInTo_noIntrons()
293 * Simple mapping with no introns
295 int[] codons = new int[] { 1, 12 };
296 int[] protein = new int[] { 1, 4 };
297 MapList ml = new MapList(codons, protein, 3, 1);
298 assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 3)));
299 assertEquals("[2, 2]", Arrays.toString(ml.locateInTo(4, 6)));
300 assertEquals("[3, 3]", Arrays.toString(ml.locateInTo(7, 9)));
301 assertEquals("[4, 4]", Arrays.toString(ml.locateInTo(10, 12)));
302 assertEquals("[1, 2]", Arrays.toString(ml.locateInTo(1, 6)));
303 assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(1, 9)));
304 assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(1, 12)));
305 assertEquals("[2, 2]", Arrays.toString(ml.locateInTo(4, 6)));
306 assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(4, 12)));
309 * A part codon is treated as if a whole one.
311 assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 1)));
312 assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 2)));
313 assertEquals("[1, 2]", Arrays.toString(ml.locateInTo(1, 4)));
314 assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(2, 8)));
315 assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(3, 11)));
316 assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(5, 11)));
318 assertNull(ml.locateInTo(0, 0));
319 assertNull(ml.locateInTo(1, 13));
320 assertNull(ml.locateInTo(-1, 1));
324 * Tests for method that locates ranges in the 'to' map for given range in the
327 @Test(groups = { "Functional" })
328 public void testLocateInTo_withIntrons()
331 * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e.
332 * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18
334 int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 };
336 * Mapped proteins at positions 1, 3, 4, 6 in the sequence
338 int[] protein = { 1, 1, 3, 4, 6, 6 };
339 MapList ml = new MapList(codons, protein, 3, 1);
342 * Can't map from an unmapped position
344 assertNull(ml.locateInTo(1, 2));
345 assertNull(ml.locateInTo(2, 4));
346 assertNull(ml.locateInTo(4, 4));
349 * Valid range or subrange of codon1 maps to protein1.
351 assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 2)));
352 assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(3, 3)));
353 assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(3, 5)));
354 assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 3)));
355 assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 5)));
357 // codon position 6 starts the next protein:
358 assertEquals("[1, 1, 3, 3]", Arrays.toString(ml.locateInTo(3, 6)));
360 // codon positions 7 to 17 (part) cover proteins 2/3/4 at positions 3/4/6
361 assertEquals("[3, 4, 6, 6]", Arrays.toString(ml.locateInTo(7, 17)));
366 * Test equals method.
368 @Test(groups = { "Functional" })
369 public void testEquals()
371 int[] codons = new int[] { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 };
372 int[] protein = new int[] { 1, 4 };
373 MapList ml = new MapList(codons, protein, 3, 1);
374 MapList ml1 = new MapList(codons, protein, 3, 1); // same values
375 MapList ml2 = new MapList(codons, protein, 2, 1); // fromRatio differs
376 MapList ml3 = new MapList(codons, protein, 3, 2); // toRatio differs
378 MapList ml6 = new MapList(codons, protein, 3, 1); // fromShifts differ
380 MapList ml7 = new MapList(codons, protein, 3, 1); // toShifts differ
382 assertTrue(ml.equals(ml));
383 assertTrue(ml.equals(ml1));
384 assertTrue(ml1.equals(ml));
386 assertFalse(ml.equals(null));
387 assertFalse(ml.equals("hello"));
388 assertFalse(ml.equals(ml2));
389 assertFalse(ml.equals(ml3));
390 assertFalse(ml.equals(ml6));
391 assertFalse(ml.equals(ml7));
392 assertFalse(ml6.equals(ml7));
396 MapList ml4 = new MapList(codons, null, 3, 1); // toShifts null
397 assertFalse(ml.equals(ml4));
398 } catch (NullPointerException e)
400 // actually thrown by constructor before equals can be called
404 MapList ml5 = new MapList(null, protein, 3, 1); // fromShifts null
405 assertFalse(ml.equals(ml5));
406 } catch (NullPointerException e)
408 // actually thrown by constructor before equals can be called
413 * Test for the method that flattens a list of ranges into a single array.
415 @Test(groups = { "Functional" })
416 public void testGetRanges()
418 List<int[]> ranges = new ArrayList<int[]>();
419 ranges.add(new int[] { 2, 3 });
420 ranges.add(new int[] { 5, 6 });
421 assertEquals("[2, 3, 5, 6]", Arrays.toString(MapList.getRanges(ranges)));
425 * Check state after construction
427 @Test(groups = { "Functional" })
428 public void testConstructor()
430 int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 };
431 int[] protein = { 1, 1, 3, 4, 6, 6 };
432 MapList ml = new MapList(codons, protein, 3, 1);
433 assertEquals(3, ml.getFromRatio());
434 assertEquals(2, ml.getFromLowest());
435 assertEquals(18, ml.getFromHighest());
436 assertEquals(1, ml.getToLowest());
437 assertEquals(6, ml.getToHighest());
438 assertEquals("{[2, 3], [5, 7], [9, 10], [12, 12], [14, 14], [16, 18]}",
439 prettyPrint(ml.getFromRanges()));
440 assertEquals("{[1, 1], [3, 4], [6, 6]}", prettyPrint(ml.getToRanges()));
443 * Also copy constructor
445 MapList ml2 = new MapList(ml);
446 assertEquals(3, ml2.getFromRatio());
447 assertEquals(2, ml2.getFromLowest());
448 assertEquals(18, ml2.getFromHighest());
449 assertEquals(1, ml2.getToLowest());
450 assertEquals(6, ml2.getToHighest());
451 assertEquals("{[2, 3], [5, 7], [9, 10], [12, 12], [14, 14], [16, 18]}",
452 prettyPrint(ml2.getFromRanges()));
453 assertEquals("{[1, 1], [3, 4], [6, 6]}", prettyPrint(ml2.getToRanges()));
458 codons = new int[] { 9, 6 };
459 protein = new int[] { 100, 91, 80, 79 };
460 ml = new MapList(codons, protein, 3, 1);
461 assertEquals(6, ml.getFromLowest());
462 assertEquals(9, ml.getFromHighest());
463 assertEquals(79, ml.getToLowest());
464 assertEquals(100, ml.getToHighest());
468 * Test constructor can merge consecutive ranges
470 @Test(groups = { "Functional" })
471 public void testConstructor_mergeRanges()
473 int[] codons = { 2, 3, 3, 7, 9, 10, 12, 12, 14, 14, 16, 17 };
474 int[] protein = { 1, 1, 1, 3, 6, 6 };
475 MapList ml = new MapList(codons, protein, 3, 1);
476 assertEquals(3, ml.getFromRatio());
477 assertEquals(2, ml.getFromLowest());
478 assertEquals(17, ml.getFromHighest());
479 assertEquals(1, ml.getToLowest());
480 assertEquals(6, ml.getToHighest());
481 assertEquals("{[2, 7], [9, 10], [12, 12], [14, 14], [16, 17]}",
482 prettyPrint(ml.getFromRanges()));
483 assertEquals("{[1, 3], [6, 6]}", prettyPrint(ml.getToRanges()));
487 * Convert a List of {[i, j], [k, l], ...} to "[[i, j], [k, l], ...]"
492 private String prettyPrint(List<int[]> ranges)
494 StringBuilder sb = new StringBuilder(ranges.size() * 5);
495 boolean first = true;
497 for (int[] range : ranges)
503 sb.append(Arrays.toString(range));
507 return sb.toString();
511 * Test the method that creates an inverse mapping
513 @Test(groups = { "Functional" })
514 public void testGetInverse()
516 int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 };
517 int[] protein = { 1, 1, 3, 4, 6, 6 };
519 MapList ml = new MapList(codons, protein, 3, 1);
520 MapList ml2 = ml.getInverse();
521 assertEquals(ml.getFromRatio(), ml2.getToRatio());
522 assertEquals(ml.getFromRatio(), ml2.getToRatio());
523 assertEquals(ml.getToHighest(), ml2.getFromHighest());
524 assertEquals(ml.getFromHighest(), ml2.getToHighest());
525 assertEquals(prettyPrint(ml.getFromRanges()),
526 prettyPrint(ml2.getToRanges()));
527 assertEquals(prettyPrint(ml.getToRanges()),
528 prettyPrint(ml2.getFromRanges()));
531 @Test(groups = { "Functional" })
532 public void testToString()
534 MapList ml = new MapList(new int[] { 1, 5, 10, 15, 25, 20 }, new int[] {
536 String s = ml.toString();
537 assertEquals("[ [1, 5] [10, 15] [25, 20] ] To [ [51, 1] ]",
541 @Test(groups = { "Functional" })
542 public void testAddMapList()
544 MapList ml = new MapList(new int[] { 11, 15, 20, 25, 35, 30 },
545 new int[] { 72, 22 }, 1, 3);
546 assertEquals(11, ml.getFromLowest());
547 assertEquals(35, ml.getFromHighest());
548 assertEquals(22, ml.getToLowest());
549 assertEquals(72, ml.getToHighest());
551 MapList ml2 = new MapList(new int[] { 2, 4, 37, 40 }, new int[] { 12,
552 17, 78, 83, 88, 96 }, 1, 3);
554 assertEquals(2, ml.getFromLowest());
555 assertEquals(40, ml.getFromHighest());
556 assertEquals(12, ml.getToLowest());
557 assertEquals(96, ml.getToHighest());
559 String s = ml.toString();
561 "[ [11, 15] [20, 25] [35, 30] [2, 4] [37, 40] ] To [ [72, 22] [12, 17] [78, 83] [88, 96] ]",
565 @Test(groups = { "Functional" })
566 public void testAddMapList_contiguous()
568 MapList ml = new MapList(new int[] { 11, 15 }, new int[] { 72, 58 }, 1,
571 MapList ml2 = new MapList(new int[] { 15, 16 }, new int[] { 58, 53 },
574 assertEquals("[ [11, 16] ] To [ [72, 53] ]", ml.toString());
577 @Test(groups = "Functional")
578 public void testAddRange()
580 int[] range = { 1, 5 };
581 List<int[]> ranges = new ArrayList<int[]>();
583 // add to empty list:
584 MapList.addRange(range, ranges);
585 assertEquals(1, ranges.size());
586 assertSame(range, ranges.get(0));
588 // extend contiguous (same position):
589 MapList.addRange(new int[] { 5, 10 }, ranges);
590 assertEquals(1, ranges.size());
591 assertEquals(1, ranges.get(0)[0]);
592 assertEquals(10, ranges.get(0)[1]);
594 // extend contiguous (next position):
595 MapList.addRange(new int[] { 11, 15 }, ranges);
596 assertEquals(1, ranges.size());
597 assertEquals(1, ranges.get(0)[0]);
598 assertEquals(15, ranges.get(0)[1]);
600 // change direction: range is not merged:
601 MapList.addRange(new int[] { 16, 10 }, ranges);
602 assertEquals(2, ranges.size());
603 assertEquals(16, ranges.get(1)[0]);
604 assertEquals(10, ranges.get(1)[1]);
606 // extend reverse contiguous (same position):
607 MapList.addRange(new int[] { 10, 8 }, ranges);
608 assertEquals(2, ranges.size());
609 assertEquals(16, ranges.get(1)[0]);
610 assertEquals(8, ranges.get(1)[1]);
612 // extend reverse contiguous (next position):
613 MapList.addRange(new int[] { 7, 6 }, ranges);
614 assertEquals(2, ranges.size());
615 assertEquals(16, ranges.get(1)[0]);
616 assertEquals(6, ranges.get(1)[1]);
618 // change direction: range is not merged:
619 MapList.addRange(new int[] { 6, 9 }, ranges);
620 assertEquals(3, ranges.size());
621 assertEquals(6, ranges.get(2)[0]);
622 assertEquals(9, ranges.get(2)[1]);
624 // not contiguous: not merged
625 MapList.addRange(new int[] { 11, 12 }, ranges);
626 assertEquals(4, ranges.size());
627 assertEquals(11, ranges.get(3)[0]);
628 assertEquals(12, ranges.get(3)[1]);
632 * Check state after construction
634 @Test(groups = { "Functional" })
635 public void testConstructor_withLists()
640 int[][] codons = new int[][] { { 9, 6 } };
641 int[][] protein = new int[][] { { 100, 91 }, { 80, 79 } };
642 MapList ml = new MapList(Arrays.asList(codons), Arrays.asList(protein),
644 assertEquals(6, ml.getFromLowest());
645 assertEquals(9, ml.getFromHighest());
646 assertEquals(79, ml.getToLowest());
647 assertEquals(100, ml.getToHighest());
651 * Test that method that inspects for the (first) forward or reverse from
652 * range. Single position ranges are ignored.
654 @Test(groups = { "Functional" })
655 public void testIsFromForwardStrand()
657 MapList ml = new MapList(new int[] { 2, 2, 3, 9, 12, 11 },
658 new int[] { 20, 11 }, 1, 1);
659 assertTrue(ml.isFromForwardStrand());
661 ml = new MapList(new int[] { 2, 2, 11, 5, 13, 14 },
662 new int[] { 20, 11 }, 1, 1);
663 assertFalse(ml.isFromForwardStrand());
665 ml = new MapList(new int[] { 2, 2, 4, 4, 6, 6 }, new int[] { 3, 1 }, 1,
667 assertTrue(ml.isFromForwardStrand());