Merge branch 'bug/JAL-2829deleteCharsWithGaps' into
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 13 Nov 2017 11:59:46 +0000 (11:59 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 13 Nov 2017 11:59:46 +0000 (11:59 +0000)
bug/JAL-2541cutRelocateFeatures

Conflicts:
src/jalview/datamodel/Sequence.java

1  2 
src/jalview/commands/EditCommand.java
src/jalview/datamodel/Sequence.java
src/jalview/datamodel/SequenceI.java
test/jalview/commands/EditCommandTest.java
test/jalview/datamodel/SequenceTest.java

@@@ -1415,43 -1315,29 +1415,45 @@@ public class EditCommand implements Com
  
    public class Edit
    {
--    public SequenceI[] oldds;
++    private SequenceI[] oldds;
  
 -    boolean fullAlignmentHeight = false;
 +    /**
 +     * start and end of sequence prior to edit
 +     */
-     public Range[] oldStartEnd;
++    private Range[] oldStartEnd;
 +
-     boolean fullAlignmentHeight = false;
++    private boolean fullAlignmentHeight = false;
  
-     Map<SequenceI, AlignmentAnnotation[]> deletedAnnotationRows;
 -    Hashtable<SequenceI, AlignmentAnnotation[]> deletedAnnotationRows;
++    private Map<SequenceI, AlignmentAnnotation[]> deletedAnnotationRows;
  
-     Map<String, Annotation[]> deletedAnnotations;
 -    Hashtable<String, Annotation[]> deletedAnnotations;
++    private Map<String, Annotation[]> deletedAnnotations;
 +
 +    /*
 +     * features deleted by the cut (re-add on Undo)
 +     * (including the original of any shortened features)
 +     */
-     Map<SequenceI, List<SequenceFeature>> deletedFeatures;
++    private Map<SequenceI, List<SequenceFeature>> deletedFeatures;
  
 -    Hashtable<SequenceI, List<SequenceFeature>> editedFeatures;
 +    /*
 +     * shortened features added by the cut (delete on Undo)
 +     */
-     Map<SequenceI, List<SequenceFeature>> truncatedFeatures;
++    private Map<SequenceI, List<SequenceFeature>> truncatedFeatures;
  
--    AlignmentI al;
++    private AlignmentI al;
  
--    Action command;
++    final private Action command;
  
      char[][] string;
  
      SequenceI[] seqs;
  
--    int[] alIndex;
++    private int[] alIndex;
  
--    int position, number;
++    private int position;
  
--    char gapChar;
++    private int number;
++
++    private char gapChar;
  
      public Edit(Action cmd, SequenceI[] sqs, int pos, int count,
              char gap)
        fullAlignmentHeight = (align.getHeight() == sqs.length);
      }
  
++    /**
++     * Constructor given a REPLACE command and the replacement string
++     * 
++     * @param cmd
++     * @param sqs
++     * @param pos
++     * @param count
++     * @param align
++     * @param replace
++     */
      Edit(Action cmd, SequenceI[] sqs, int pos, int count,
              AlignmentI align, String replace)
      {
@@@ -1174,15 -1177,37 +1174,38 @@@ public class Sequence extends ASequenc
      boolean createNewDs = false;
      // TODO: take a (second look) at the dataset creation validation method for
      // the very large sequence case
-     int eindex = -1, sindex = -1;
-     boolean ecalc = false, scalc = false;
++
+     int startIndex = findIndex(start) - 1;
+     int endIndex = findIndex(end) - 1;
+     int startDeleteColumn = -1; // for dataset sequence deletions
+     int deleteCount = 0;
 -    for (int s = i; s < j; s++)
 +    for (int s = i; s < j && s < sequence.length; s++)
      {
-       if (!Comparison.isGap(sequence[s]))
+       if (Comparison.isGap(sequence[s]))
+       {
+         continue;
+       }
+       deleteCount++;
+       if (startDeleteColumn == -1)
+       {
+         startDeleteColumn = findPosition(s) - start;
+       }
+       if (createNewDs)
        {
-         if (createNewDs)
+         newend--;
+       }
+       else
+       {
+         if (startIndex == s)
          {
-           newend--;
+           /*
+            * deleting characters from start of sequence; new start is the
+            * sequence position of the next column (position to the right
+            * if the column position is gapped)
+            */
+           newstart = findPosition(j);
+           break;
          }
          else
          {
    }
  
    /**
--   * @return The index (zero-based) on this sequence in the MSA. It returns
++   * @return The index (zero-based) of this sequence in the MSA. It returns
     *         {@code -1} if this information is not available.
     */
    @Override
    }
  
    /**
--   * Defines the position of this sequence in the MSA. Use the value {@code -1}
--   * if this information is undefined.
++   * Defines the (zero-based) position of this sequence in the MSA. Use the
++   * value {@code -1} if this information is undefined.
     * 
--   * @param The
--   *          position for this sequence. This value is zero-based (zero for
--   *          this first sequence)
++   * @param value
     */
    @Override
    public void setIndex(int value)
Simple merge
@@@ -155,7 -143,7 +155,7 @@@ public class EditCommandTes
    /**
     * Test a Paste action, where this adds sequences to an alignment.
     */
--  @Test(groups = { "Functional" }, enabled = false)
++  @Test(groups = { "Functional" }, enabled = true)
    // TODO fix so it works
    public void testPaste_addToAlignment()
    {
       * and validate the resulting remaining sequence features!
       */
      SequenceI[] sqs = new SequenceI[] { seq0 };
 +    boolean checkDsSize = true;
  
 -    // goal is to have this passing for all from/to values!!
 -    // for (int from = 0; from < seq0.getLength(); from++)
 -    // {
 -    // for (int to = from; to < seq0.getLength(); to++)
 -    for (int from = 1; from < 3; from++)
 +    for (int from = 0; from < seq0.getLength(); from++)
      {
 -      for (int to = 2; to < 3; to++)
 +      for (int to = from; to < seq0.getLength(); to++)
        {
 -        testee.appendEdit(Action.CUT, sqs, from, (to - from + 1),
 -                alignment, true);
 +        EditCommand ec = new EditCommand("Cut", Action.CUT, sqs, from, (to
 +                - from + 1), alignment);
 +        final String msg = String.format("Cut %d-%d ", from + 1, to + 1);
 +        boolean newDatasetSequence = copySeq0.getDatasetSequence() != seq0
 +                .getDatasetSequence();
  
 -        sfs = seq0.getSequenceFeatures();
 +        verifyCut(seq0, from, to, msg, start);
  
          /*
 -         * confirm the number of features has reduced by the
 -         * number of features within the cut region i.e. by
 -         * func(length of cut)
 +         * verify copy alignment dataset sequence unaffected
           */
 -        String msg = String.format("Cut %d-%d ", from, to);
 -        if (to - from == 4)
 +        assertEquals("Original dataset sequence was modified",
 +                copySequenceFeatures,
 +                copySeq0.getSequenceFeatures().toString());
 +
 +        if (checkDsSize)
          {
 -          // all columns cut
 -          assertNull(sfs);
 +          /*
 +           * verify a new dataset sequence has appeared
 +           */
 +          assertEquals("Wrong Dataset size after cut",
 +                  newDatasetSequence ? 2 : 1, alignment.getDataset()
 +                          .getHeight());
          }
 -        else
 +        /*
 +         * undo and verify all restored
 +         */
 +        AlignmentI[] views = new AlignmentI[] { alignment };
 +        ec.undoCommand(views);
 +        sfs = seq0.getSequenceFeatures();
 +        assertEquals("After undo of " + msg, func(5), sfs.size());
 +        verifyUndo(from, to, sfs);
 +
 +        /*
 +         * verify copy alignment dataset sequence still unaffected
 +         */
 +        assertEquals("Original dataset sequence was modified",
 +                copySequenceFeatures,
 +                copySeq0.getSequenceFeatures().toString());
 +
 +        if (checkDsSize)
          {
 -          assertEquals(msg + "wrong number of features left", func(5)
 -                  - func(to - from + 1), sfs.size());
 +          /*
 +           * verify dataset sequence has shrunk
 +           */
 +          assertEquals("Wrong Dataset size after cut", 1,
 +                  alignment.getDataset().getHeight());
          }
          /*
 -         * inspect individual features
 +         * redo and verify
 +         */
 +        ec.doCommand(views);
 +        verifyCut(seq0, from, to, msg, start);
 +
 +        /*
 +         * verify copy alignment dataset sequence unaffected
           */
 -        if (sfs != null)
 +        assertEquals("Original dataset sequence was modified",
 +                copySequenceFeatures,
 +                copySeq0.getSequenceFeatures().toString());
 +
 +        if (checkDsSize)
          {
 -          for (SequenceFeature sf : sfs)
 -          {
 -            checkFeatureRelocation(sf, from + 1, to + 1);
 -          }
 +          /*
 +           * verify a new dataset sequence has appeared again
 +           */
 +          assertEquals("Wrong Dataset size after cut",
 +                  newDatasetSequence ? 2 : 1, alignment.getDataset()
 +                          .getHeight());
          }
++
          /*
           * undo ready for next cut
           */