Merge remote-tracking branch 'origin/tasks/JAL-3035_remove_dasobert_dependency' into...
[jalview.git] / test / jalview / datamodel / SequenceTest.java
index 5a14514..c344645 100644 (file)
@@ -52,7 +52,6 @@ import junit.extensions.PA;
 
 public class SequenceTest
 {
-
   @BeforeClass(alwaysRun = true)
   public void setUpJvOptionPane()
   {
@@ -247,7 +246,9 @@ public class SequenceTest
     sq.sequenceChanged();
     assertEquals(6, sq.findIndex(9));
 
-    sq = new Sequence("test/8-13", "-A--B-C-D-E-F--");
+    final String aligned = "-A--B-C-D-E-F--";
+    assertEquals(15, aligned.length());
+    sq = new Sequence("test/8-13", aligned);
     assertEquals(2, sq.findIndex(8));
     sq.sequenceChanged();
     assertEquals(5, sq.findIndex(9));
@@ -263,6 +264,84 @@ public class SequenceTest
     // beyond end returns last residue column
     sq.sequenceChanged();
     assertEquals(13, sq.findIndex(99));
+
+    /*
+     * residue before sequence 'end' but beyond end of sequence returns 
+     * length of sequence (last column) (rightly or wrongly!)
+     */
+    sq = new Sequence("test/8-15", "A-B-C-"); // trailing gap case
+    assertEquals(6, sq.getLength());
+    sq.sequenceChanged();
+    assertEquals(sq.getLength(), sq.findIndex(14));
+    sq = new Sequence("test/8-99", "-A--B-C-D"); // trailing residue case
+    sq.sequenceChanged();
+    assertEquals(sq.getLength(), sq.findIndex(65));
+
+    /*
+     * residue after sequence 'start' but before first residue returns 
+     * zero (before first column) (rightly or wrongly!)
+     */
+    sq = new Sequence("test/8-15", "-A-B-C-"); // leading gap case
+    sq.sequenceChanged();
+    assertEquals(0, sq.findIndex(3));
+    sq = new Sequence("test/8-15", "A-B-C-"); // leading residue case
+    sq.sequenceChanged();
+    assertEquals(0, sq.findIndex(2));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testFindPositions()
+  {
+    SequenceI sq = new Sequence("test/8-13", "-ABC---DE-F--");
+
+    /*
+     * invalid inputs
+     */
+    assertNull(sq.findPositions(6, 5));
+    assertNull(sq.findPositions(0, 5));
+    assertNull(sq.findPositions(-1, 5));
+
+    /*
+     * all gapped ranges
+     */
+    assertNull(sq.findPositions(1, 1)); // 1-based columns
+    assertNull(sq.findPositions(5, 5));
+    assertNull(sq.findPositions(5, 6));
+    assertNull(sq.findPositions(5, 7));
+
+    /*
+     * all ungapped ranges
+     */
+    assertEquals(new Range(8, 8), sq.findPositions(2, 2)); // A
+    assertEquals(new Range(8, 9), sq.findPositions(2, 3)); // AB
+    assertEquals(new Range(8, 10), sq.findPositions(2, 4)); // ABC
+    assertEquals(new Range(9, 10), sq.findPositions(3, 4)); // BC
+
+    /*
+     * gap to ungapped range
+     */
+    assertEquals(new Range(8, 10), sq.findPositions(1, 4)); // ABC
+    assertEquals(new Range(11, 12), sq.findPositions(6, 9)); // DE
+
+    /*
+     * ungapped to gapped range
+     */
+    assertEquals(new Range(10, 10), sq.findPositions(4, 5)); // C
+    assertEquals(new Range(9, 13), sq.findPositions(3, 11)); // BCDEF
+
+    /*
+     * ungapped to ungapped enclosing gaps
+     */
+    assertEquals(new Range(10, 11), sq.findPositions(4, 8)); // CD
+    assertEquals(new Range(8, 13), sq.findPositions(2, 11)); // ABCDEF
+
+    /*
+     * gapped to gapped enclosing ungapped
+     */
+    assertEquals(new Range(8, 10), sq.findPositions(1, 5)); // ABC
+    assertEquals(new Range(11, 12), sq.findPositions(5, 10)); // DE
+    assertEquals(new Range(8, 13), sq.findPositions(1, 13)); // the lot
+    assertEquals(new Range(8, 13), sq.findPositions(1, 99));
   }
 
   /**
@@ -440,8 +519,7 @@ public class SequenceTest
     assertEquals("test:Pos13:Col10:startCol3:endCol10:tok0",
             PA.getValue(sq, "cursor").toString());
     sq.sequenceChanged();
-    assertEquals(12, sq.findPosition(8));
-    cursor = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertEquals(12, sq.findPosition(8)); // E12
     // sequenceChanged() invalidates cursor.lastResidueColumn
     cursor = (SequenceCursor) PA.getValue(sq, "cursor");
     assertEquals("test:Pos12:Col9:startCol3:endCol0:tok1",
@@ -480,6 +558,13 @@ public class SequenceTest
     assertEquals(6, sq.getEnd());
     assertNull(PA.getValue(sq, "datasetSequence"));
 
+    sq = new Sequence("test", "ABCDE");
+    sq.deleteChars(0, 3);
+    assertEquals("DE", sq.getSequenceAsString());
+    assertEquals(4, sq.getStart());
+    assertEquals(5, sq.getEnd());
+    assertNull(PA.getValue(sq, "datasetSequence"));
+
     /*
      * delete at end
      */
@@ -489,6 +574,21 @@ public class SequenceTest
     assertEquals(1, sq.getStart());
     assertEquals(4, sq.getEnd());
     assertNull(PA.getValue(sq, "datasetSequence"));
+
+    /*
+     * delete more positions than there are
+     */
+    sq = new Sequence("test/8-11", "ABCD");
+    sq.deleteChars(0, 99);
+    assertEquals("", sq.getSequenceAsString());
+    assertEquals(12, sq.getStart()); // = findPosition(99) ?!?
+    assertEquals(11, sq.getEnd());
+
+    sq = new Sequence("test/8-11", "----");
+    sq.deleteChars(0, 99); // ArrayIndexOutOfBoundsException <= 2.10.2
+    assertEquals("", sq.getSequenceAsString());
+    assertEquals(8, sq.getStart());
+    assertEquals(11, sq.getEnd());
   }
 
   @Test(groups = { "Functional" })
@@ -1402,14 +1502,61 @@ public class SequenceTest
   {
     Sequence sq = new Sequence("test/8-13", "-A--BCD-EF--");
 
-    // find F given A
+    // find F given A, check cursor is now at the found position
     assertEquals(10, sq.findIndex(13, new SequenceCursor(sq, 8, 2, 0)));
+    SequenceCursor cursor = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertEquals(13, cursor.residuePosition);
+    assertEquals(10, cursor.columnPosition);
 
     // find A given F
     assertEquals(2, sq.findIndex(8, new SequenceCursor(sq, 13, 10, 0)));
+    cursor = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertEquals(8, cursor.residuePosition);
+    assertEquals(2, cursor.columnPosition);
 
-    // find C given C
+    // find C given C (no cursor update is done for this case)
     assertEquals(6, sq.findIndex(10, new SequenceCursor(sq, 10, 6, 0)));
+    SequenceCursor cursor2 = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertSame(cursor2, cursor);
+
+    /*
+     * sequence 'end' beyond end of sequence returns length of sequence 
+     *  (for compatibility with pre-cursor code)
+     *  - also verify the cursor is left in a valid state
+     */
+    sq = new Sequence("test/8-99", "-A--B-C-D-E-F--"); // trailing gap case
+    assertEquals(7, sq.findIndex(10)); // establishes a cursor
+    cursor = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertEquals(10, cursor.residuePosition);
+    assertEquals(7, cursor.columnPosition);
+    assertEquals(sq.getLength(), sq.findIndex(65));
+    cursor2 = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertSame(cursor, cursor2); // not updated for this case!
+
+    sq = new Sequence("test/8-99", "-A--B-C-D-E-F"); // trailing residue case
+    sq.findIndex(10); // establishes a cursor
+    cursor = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertEquals(sq.getLength(), sq.findIndex(65));
+    cursor2 = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertSame(cursor, cursor2); // not updated for this case!
+
+    /*
+     * residue after sequence 'start' but before first residue should return 
+     * zero (for compatibility with pre-cursor code)
+     */
+    sq = new Sequence("test/8-15", "-A-B-C-"); // leading gap case
+    sq.findIndex(10); // establishes a cursor
+    cursor = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertEquals(0, sq.findIndex(3));
+    cursor2 = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertSame(cursor, cursor2); // not updated for this case!
+
+    sq = new Sequence("test/8-15", "A-B-C-"); // leading residue case
+    sq.findIndex(10); // establishes a cursor
+    cursor = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertEquals(0, sq.findIndex(2));
+    cursor2 = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertSame(cursor, cursor2); // not updated for this case!
   }
 
   @Test(groups = { "Functional" })
@@ -1542,6 +1689,10 @@ public class SequenceTest
     // cursor should now be at [D 6]
     cursor = (SequenceCursor) PA.getValue(sq, "cursor");
     assertEquals(new SequenceCursor(sq, 11, 6, ++token), cursor);
+    assertEquals(0, cursor.lastColumnPosition); // not yet found
+    assertEquals(13, sq.findPosition(8)); // E13
+    cursor = (SequenceCursor) PA.getValue(sq, "cursor");
+    assertEquals(9, cursor.lastColumnPosition); // found
 
     /*
      * deleteChars should invalidate the cached cursor
@@ -1621,61 +1772,6 @@ public class SequenceTest
   }
 
   @Test(groups = { "Functional" })
-  public void testFindPositions()
-  {
-    SequenceI sq = new Sequence("test/8-13", "-ABC---DE-F--");
-
-    /*
-     * invalid inputs
-     */
-    assertNull(sq.findPositions(6, 5));
-    assertNull(sq.findPositions(0, 5));
-    assertNull(sq.findPositions(-1, 5));
-
-    /*
-     * all gapped ranges
-     */
-    assertNull(sq.findPositions(1, 1)); // 1-based columns
-    assertNull(sq.findPositions(5, 5));
-    assertNull(sq.findPositions(5, 6));
-    assertNull(sq.findPositions(5, 7));
-
-    /*
-     * all ungapped ranges
-     */
-    assertEquals(new Range(8, 8), sq.findPositions(2, 2)); // A
-    assertEquals(new Range(8, 9), sq.findPositions(2, 3)); // AB
-    assertEquals(new Range(8, 10), sq.findPositions(2, 4)); // ABC
-    assertEquals(new Range(9, 10), sq.findPositions(3, 4)); // BC
-
-    /*
-     * gap to ungapped range
-     */
-    assertEquals(new Range(8, 10), sq.findPositions(1, 4)); // ABC
-    assertEquals(new Range(11, 12), sq.findPositions(6, 9)); // DE
-
-    /*
-     * ungapped to gapped range
-     */
-    assertEquals(new Range(10, 10), sq.findPositions(4, 5)); // C
-    assertEquals(new Range(9, 13), sq.findPositions(3, 11)); // BCDEF
-
-    /*
-     * ungapped to ungapped enclosing gaps
-     */
-    assertEquals(new Range(10, 11), sq.findPositions(4, 8)); // CD
-    assertEquals(new Range(8, 13), sq.findPositions(2, 11)); // ABCDEF
-
-    /*
-     * gapped to gapped enclosing ungapped
-     */
-    assertEquals(new Range(8, 10), sq.findPositions(1, 5)); // ABC
-    assertEquals(new Range(11, 12), sq.findPositions(5, 10)); // DE
-    assertEquals(new Range(8, 13), sq.findPositions(1, 13)); // the lot
-    assertEquals(new Range(8, 13), sq.findPositions(1, 99));
-  }
-
-  @Test(groups = { "Functional" })
   public void testGapBitset()
   {
     SequenceI sq = new Sequence("test/8-13", "-ABC---DE-F--");