*/
package jalview.commands;
+import java.util.Locale;
+
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
testee = new EditCommand();
seqs = new SequenceI[4];
seqs[0] = new Sequence("seq0", "abcdefghjk");
- seqs[0].setDatasetSequence(new Sequence("seq0ds", "abcdefghjk"));
+ seqs[0].setDatasetSequence(new Sequence("seq0ds", "ABCDEFGHJK"));
seqs[1] = new Sequence("seq1", "fghjklmnopq");
- seqs[1].setDatasetSequence(new Sequence("seq1ds", "fghjklmnopq"));
+ seqs[1].setDatasetSequence(new Sequence("seq1ds", "FGHJKLMNOPQ"));
seqs[2] = new Sequence("seq2", "qrstuvwxyz");
- seqs[2].setDatasetSequence(new Sequence("seq2ds", "qrstuvwxyz"));
+ seqs[2].setDatasetSequence(new Sequence("seq2ds", "QRSTUVWXYZ"));
seqs[3] = new Sequence("seq3", "1234567890");
seqs[3].setDatasetSequence(new Sequence("seq3ds", "1234567890"));
al = new Alignment(seqs);
}
/**
- * Test a Paste action, where this adds sequences to an alignment.
+ * Test a Paste action, followed by Undo and Redo
*/
@Test(groups = { "Functional" }, enabled = false)
- // TODO fix so it works
- public void testPaste_addToAlignment()
+ public void testPaste_undo_redo()
{
+ // TODO code this test properly, bearing in mind that:
+ // Paste action requires something on the clipboard (Cut/Copy)
+ // - EditCommand.paste doesn't add sequences to the alignment
+ // ... that is done in AlignFrame.paste()
+ // ... unless as a Redo
+ // ...
+
SequenceI[] newSeqs = new SequenceI[2];
newSeqs[0] = new Sequence("newseq0", "ACEFKL");
newSeqs[1] = new Sequence("newseq1", "JWMPDH");
- Edit ec = testee.new Edit(Action.PASTE, newSeqs, 0, al.getWidth(), al);
- EditCommand.paste(ec, new AlignmentI[] { al });
+ new EditCommand("Paste", Action.PASTE, newSeqs, 0, al.getWidth(), al);
assertEquals(6, al.getSequences().size());
assertEquals("1234567890", seqs[3].getSequenceAsString());
assertEquals("ACEFKL", seqs[4].getSequenceAsString());
{
// seem to need a dataset sequence on the edited sequence here
seqs[1].createDatasetSequence();
- new EditCommand("", Action.REPLACE, "ZXY", new SequenceI[] { seqs[1] },
+ assertEquals("fghjklmnopq", seqs[1].getSequenceAsString());
+ // NB command.number holds end position for a Replace command
+ new EditCommand("", Action.REPLACE, "Z-xY", new SequenceI[] { seqs[1] },
4, 8, al);
assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
+ assertEquals("fghjZ-xYopq", seqs[1].getSequenceAsString());
+ // Dataset Sequence should always be uppercase
+ assertEquals("fghjZxYopq".toUpperCase(Locale.ROOT),
+ seqs[1].getDatasetSequence().getSequenceAsString());
assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString());
assertEquals("1234567890", seqs[3].getSequenceAsString());
- seqs[1] = new Sequence("seq1", "fghjZXYnopq");
+ }
+
+ /**
+ * Test the replace command (used to manually edit a sequence)
+ */
+ @Test(groups = { "Functional" })
+ public void testReplace_withGaps()
+ {
+ SequenceI seq = new Sequence("seq", "ABC--DEF");
+ seq.createDatasetSequence();
+ assertEquals("ABCDEF", seq.getDatasetSequence().getSequenceAsString());
+ assertEquals(1, seq.getStart());
+ assertEquals(6, seq.getEnd());
+
+ /*
+ * replace C- with XYZ
+ * NB arg4 = start column of selection for edit (base 0)
+ * arg5 = column after end of selection for edit
+ */
+ EditCommand edit = new EditCommand("", Action.REPLACE, "xyZ",
+ new SequenceI[]
+ { seq }, 2,
+ 4, al);
+ assertEquals("ABxyZ-DEF", seq.getSequenceAsString());
+ assertEquals(1, seq.getStart());
+ assertEquals(8, seq.getEnd());
+ // Dataset sequence always uppercase
+ assertEquals("ABxyZDEF".toUpperCase(Locale.ROOT),
+ seq.getDatasetSequence().getSequenceAsString());
+ assertEquals(8, seq.getDatasetSequence().getEnd());
+
+ /*
+ * undo the edit
+ */
+ AlignmentI[] views = new AlignmentI[]
+ { new Alignment(new SequenceI[] { seq }) };
+ edit.undoCommand(views);
+
+ assertEquals("ABC--DEF", seq.getSequenceAsString());
+ assertEquals("ABCDEF", seq.getDatasetSequence().getSequenceAsString());
+ assertEquals(1, seq.getStart());
+ assertEquals(6, seq.getEnd());
+ assertEquals(6, seq.getDatasetSequence().getEnd());
+
+ /*
+ * redo the edit
+ */
+ edit.doCommand(views);
+
+ assertEquals("ABxyZ-DEF", seq.getSequenceAsString());
+ assertEquals(1, seq.getStart());
+ assertEquals(8, seq.getEnd());
+ // dataset sequence should be Uppercase
+ assertEquals("ABxyZDEF".toUpperCase(Locale.ROOT),
+ seq.getDatasetSequence().getSequenceAsString());
+ assertEquals(8, seq.getDatasetSequence().getEnd());
+
+ }
+
+ /**
+ * Test replace command when it doesn't cause a sequence edit (see comment in
+ */
+ @Test(groups = { "Functional" })
+ public void testReplaceFirstResiduesWithGaps()
+ {
+ // test replace when gaps are inserted at start. Start/end should change
+ // w.r.t. original edited sequence.
+ SequenceI dsseq = seqs[1].getDatasetSequence();
+ EditCommand edit = new EditCommand("", Action.REPLACE, "----",
+ new SequenceI[]
+ { seqs[1] }, 0, 4, al);
+
+ // trimmed start
+ assertEquals("----klmnopq", seqs[1].getSequenceAsString());
+ // and ds is preserved
+ assertTrue(dsseq == seqs[1].getDatasetSequence());
+ // and it is unchanged and UPPERCASE !
+ assertEquals("fghjklmnopq".toUpperCase(Locale.ROOT), dsseq.getSequenceAsString());
+ // and that alignment sequence start has been adjusted
+ assertEquals(5, seqs[1].getStart());
+ assertEquals(11, seqs[1].getEnd());
+
+ AlignmentI[] views = new AlignmentI[] { new Alignment(seqs) };
+ // and undo
+ edit.undoCommand(views);
+
+ // dataset sequence unchanged
+ assertTrue(dsseq == seqs[1].getDatasetSequence());
+ // restore sequence
+ assertEquals("fghjklmnopq", seqs[1].getSequenceAsString());
+ // and start/end numbering also restored
+ assertEquals(1, seqs[1].getStart());
+ assertEquals(11, seqs[1].getEnd());
+
+ // now redo
+ edit.undoCommand(views);
+
+ // and repeat asserts for the original edit
+
+ // trimmed start
+ assertEquals("----klmnopq", seqs[1].getSequenceAsString());
+ // and ds is preserved
+ assertTrue(dsseq == seqs[1].getDatasetSequence());
+ // and it is unchanged AND UPPERCASE !
+ assertEquals("fghjklmnopq".toUpperCase(Locale.ROOT), dsseq.getSequenceAsString());
+ // and that alignment sequence start has been adjusted
+ assertEquals(5, seqs[1].getStart());
+ assertEquals(11, seqs[1].getEnd());
+
}
/**
seq0.setEnd(end);
AlignmentI alignment = new Alignment(new SequenceI[] { seq0 });
alignment.setDataset(null);
+
+ /*
+ * create a new alignment with shared dataset sequence
+ */
+ AlignmentI copy = new Alignment(
+ new SequenceI[]
+ { alignment.getDataset().getSequenceAt(0).deriveSequence() });
+ SequenceI copySeq0 = copy.getSequenceAt(0);
+
for (int from = start; from <= end; from++)
{
for (int to = from; to <= end; to++)
// sanity check
List<SequenceFeature> sfs = seq0.getSequenceFeatures();
assertEquals(func(5), sfs.size());
+ assertEquals(sfs, copySeq0.getSequenceFeatures());
+ String copySequenceFeatures = copySeq0.getSequenceFeatures().toString();
/*
* now perform all possible cuts of subranges of columns 1-5
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();
verifyCut(seq0, from, to, msg, start);
/*
+ * verify copy alignment dataset sequence unaffected
+ */
+ assertEquals("Original dataset sequence was modified",
+ copySequenceFeatures,
+ copySeq0.getSequenceFeatures().toString());
+
+ /*
+ * verify any new dataset sequence was added to the
+ * alignment dataset
+ */
+ assertEquals("Wrong Dataset size after " + msg,
+ newDatasetSequence ? 2 : 1,
+ alignment.getDataset().getHeight());
+
+ /*
* undo and verify all restored
*/
AlignmentI[] views = new AlignmentI[] { alignment };
verifyUndo(from, to, sfs);
/*
+ * verify copy alignment dataset sequence still unaffected
+ * and alignment dataset has shrunk (if it was added to)
+ */
+ assertEquals("Original dataset sequence was modified",
+ copySequenceFeatures,
+ copySeq0.getSequenceFeatures().toString());
+ assertEquals("Wrong Dataset size after Undo of " + msg, 1,
+ alignment.getDataset().getHeight());
+
+ /*
* redo and verify
*/
ec.doCommand(views);
verifyCut(seq0, from, to, msg, start);
/*
+ * verify copy alignment dataset sequence unaffected
+ * and any new dataset sequence readded to alignment dataset
+ */
+ assertEquals("Original dataset sequence was modified",
+ copySequenceFeatures,
+ copySeq0.getSequenceFeatures().toString());
+ assertEquals("Wrong Dataset size after Redo of " + msg,
+ newDatasetSequence ? 2 : 1,
+ alignment.getDataset().getHeight());
+
+ /*
* undo ready for next cut
*/
ec.undoCommand(views);
+
+ /*
+ * final verify that copy alignment dataset sequence is still unaffected
+ * and that alignment dataset has shrunk
+ */
+ assertEquals("Original dataset sequence was modified",
+ copySequenceFeatures,
+ copySeq0.getSequenceFeatures().toString());
+ assertEquals("Wrong Dataset size after final Undo of " + msg, 1,
+ alignment.getDataset().getHeight());
}
}
}