*/
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 = true)
- // TODO fix so it works
- public void testPaste_addToAlignment()
+ @Test(groups = { "Functional" }, enabled = false)
+ 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());
}
/**
+ * 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" })
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
- assertEquals("fghjklmnopq", dsseq.getSequenceAsString());
+ // 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);
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());
}
* 3 insert gap in a row (aka mouse drag right):
*/
Edit e = new EditCommand().new Edit(Action.INSERT_GAP,
- new SequenceI[] { seqs[0] }, 1, 1, al);
+ new SequenceI[]
+ { seqs[0] }, 1, 1, al);
testee.addEdit(e);
SequenceI edited = new Sequence("seq0", "a?bcdefghjk");
edited.setDatasetSequence(seqs[0].getDatasetSequence());
e = new EditCommand().new Edit(Action.INSERT_GAP,
- new SequenceI[] { edited }, 2, 1, al);
+ new SequenceI[]
+ { edited }, 2, 1, al);
testee.addEdit(e);
edited = new Sequence("seq0", "a??bcdefghjk");
edited.setDatasetSequence(seqs[0].getDatasetSequence());
e = new EditCommand().new Edit(Action.INSERT_GAP,
- new SequenceI[] { edited }, 3, 1, al);
+ new SequenceI[]
+ { edited }, 3, 1, al);
testee.addEdit(e);
assertEquals(1, testee.getSize());
assertEquals(Action.INSERT_GAP, testee.getEdit(0).getAction());
* Add a non-contiguous edit - should not be merged.
*/
e = new EditCommand().new Edit(Action.INSERT_GAP,
- new SequenceI[] { edited }, 5, 2, al);
+ new SequenceI[]
+ { edited }, 5, 2, al);
testee.addEdit(e);
assertEquals(2, testee.getSize());
assertEquals(5, testee.getEdit(1).getPosition());
* Add a Delete after the Insert - should not be merged.
*/
e = new EditCommand().new Edit(Action.DELETE_GAP,
- new SequenceI[] { edited }, 6, 2, al);
+ new SequenceI[]
+ { edited }, 6, 2, al);
testee.addEdit(e);
assertEquals(3, testee.getSize());
assertEquals(Action.DELETE_GAP, testee.getEdit(2).getAction());
*/
seqs[0].setSequence("a???bcdefghjk");
Edit e = new EditCommand().new Edit(Action.DELETE_GAP,
- new SequenceI[] { seqs[0] }, 4, 1, al);
+ new SequenceI[]
+ { seqs[0] }, 4, 1, al);
testee.addEdit(e);
assertEquals(1, testee.getSize());
SequenceI edited = new Sequence("seq0", "a??bcdefghjk");
edited.setDatasetSequence(seqs[0].getDatasetSequence());
e = new EditCommand().new Edit(Action.DELETE_GAP,
- new SequenceI[] { edited }, 3, 1, al);
+ new SequenceI[]
+ { edited }, 3, 1, al);
testee.addEdit(e);
assertEquals(1, testee.getSize());
edited = new Sequence("seq0", "a?bcdefghjk");
edited.setDatasetSequence(seqs[0].getDatasetSequence());
e = new EditCommand().new Edit(Action.DELETE_GAP,
- new SequenceI[] { edited }, 2, 1, al);
+ new SequenceI[]
+ { edited }, 2, 1, al);
testee.addEdit(e);
assertEquals(1, testee.getSize());
assertEquals(Action.DELETE_GAP, testee.getEdit(0).getAction());
* Add a non-contiguous edit - should not be merged.
*/
e = new EditCommand().new Edit(Action.DELETE_GAP,
- new SequenceI[] { edited }, 2, 1, al);
+ new SequenceI[]
+ { edited }, 2, 1, al);
testee.addEdit(e);
assertEquals(2, testee.getSize());
assertEquals(Action.DELETE_GAP, testee.getEdit(0).getAction());
* Add an Insert after the Delete - should not be merged.
*/
e = new EditCommand().new Edit(Action.INSERT_GAP,
- new SequenceI[] { edited }, 1, 1, al);
+ new SequenceI[]
+ { edited }, 1, 1, al);
testee.addEdit(e);
assertEquals(3, testee.getSize());
assertEquals(Action.INSERT_GAP, testee.getEdit(2).getAction());
{
seqs[0].setSequence("a???bcdefghjk");
Edit e = new EditCommand().new Edit(Action.DELETE_GAP,
- new SequenceI[] { seqs[0] }, 4, 1, al);
+ new SequenceI[]
+ { seqs[0] }, 4, 1, al);
testee.addEdit(e);
seqs[1].setSequence("f??ghjklmnopq");
- Edit e2 = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[]
- { seqs[1] }, 3, 1, al);
+ Edit e2 = new EditCommand().new Edit(Action.DELETE_GAP,
+ new SequenceI[]
+ { seqs[1] }, 3, 1, al);
testee.addEdit(e2);
assertEquals(2, testee.getSize());
assertSame(e, testee.getEdit(0));
/*
* 2 insert gap in a row (aka mouse drag right), on two sequences:
*/
- Edit e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] {
- seqs[0], seqs[1] }, 1, 1, al);
+ Edit e = new EditCommand().new Edit(Action.INSERT_GAP,
+ new SequenceI[]
+ { seqs[0], seqs[1] }, 1, 1, al);
testee.addEdit(e);
SequenceI seq1edited = new Sequence("seq0", "a?bcdefghjk");
seq1edited.setDatasetSequence(seqs[0].getDatasetSequence());
SequenceI seq2edited = new Sequence("seq1", "f?ghjklmnopq");
seq2edited.setDatasetSequence(seqs[1].getDatasetSequence());
- e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] {
- seq1edited, seq2edited }, 2, 1, al);
+ e = new EditCommand().new Edit(Action.INSERT_GAP,
+ new SequenceI[]
+ { seq1edited, seq2edited }, 2, 1, al);
testee.addEdit(e);
assertEquals(1, testee.getSize());
assertEquals(Action.INSERT_GAP, testee.getEdit(0).getAction());
assertEquals(1, testee.getEdit(0).getPosition());
assertEquals(2, testee.getEdit(0).getNumber());
- assertEquals(seqs[0].getDatasetSequence(), testee.getEdit(0)
- .getSequences()[0].getDatasetSequence());
- assertEquals(seqs[1].getDatasetSequence(), testee.getEdit(0)
- .getSequences()[1].getDatasetSequence());
+ assertEquals(seqs[0].getDatasetSequence(),
+ testee.getEdit(0).getSequences()[0].getDatasetSequence());
+ assertEquals(seqs[1].getDatasetSequence(),
+ testee.getEdit(0).getSequences()[1].getDatasetSequence());
}
/**
* a cut of columns/residues 4-7
*/
SequenceI seq0 = seqs[0]; // abcdefghjk/1-10
- seq0.addSequenceFeature(new SequenceFeature("before", "", 1, 3, 0f,
- null));
- seq0.addSequenceFeature(new SequenceFeature("overlap left", "", 2, 6,
- 0f, null));
- seq0.addSequenceFeature(new SequenceFeature("internal", "", 5, 6, 0f,
- null));
- seq0.addSequenceFeature(new SequenceFeature("overlap right", "", 7, 8,
- 0f, null));
- seq0.addSequenceFeature(new SequenceFeature("after", "", 8, 10, 0f,
- null));
+ seq0.addSequenceFeature(
+ new SequenceFeature("before", "", 1, 3, 0f, null));
+ seq0.addSequenceFeature(
+ new SequenceFeature("overlap left", "", 2, 6, 0f, null));
+ seq0.addSequenceFeature(
+ new SequenceFeature("internal", "", 5, 6, 0f, null));
+ seq0.addSequenceFeature(
+ new SequenceFeature("overlap right", "", 7, 8, 0f, null));
+ seq0.addSequenceFeature(
+ new SequenceFeature("after", "", 8, 10, 0f, null));
/*
* add some contact features
*/
- SequenceFeature internalContact = new SequenceFeature("disulphide bond", "", 5,
- 6, 0f, null);
+ SequenceFeature internalContact = new SequenceFeature("disulphide bond",
+ "", 5, 6, 0f, null);
seq0.addSequenceFeature(internalContact); // should get deleted
SequenceFeature overlapLeftContact = new SequenceFeature(
"disulphide bond", "", 2, 6, 0f, null);
SequenceFeature overlapRightContact = new SequenceFeature(
"disulphide bond", "", 5, 8, 0f, null);
seq0.addSequenceFeature(overlapRightContact); // should get deleted
- SequenceFeature spanningContact = new SequenceFeature(
- "disulphide bond", "", 2, 9, 0f, null);
+ SequenceFeature spanningContact = new SequenceFeature("disulphide bond",
+ "", 2, 9, 0f, null);
seq0.addSequenceFeature(spanningContact); // should get shortened 3'
/*
for (int to = from; to <= end; to++)
{
String desc = String.format("%d-%d", from, to);
- SequenceFeature sf = new SequenceFeature("test", desc, from, to,
- 0f, null);
+ SequenceFeature sf = new SequenceFeature("test", desc, from, to, 0f,
+ null);
sf.setValue("from", Integer.valueOf(from));
sf.setValue("to", Integer.valueOf(to));
seq0.addSequenceFeature(sf);
* and validate the resulting remaining sequence features!
*/
SequenceI[] sqs = new SequenceI[] { seq0 };
- boolean checkDsSize = true;
for (int from = 0; from < seq0.getLength(); from++)
{
for (int to = from; to < seq0.getLength(); to++)
{
- EditCommand ec = new EditCommand("Cut", Action.CUT, sqs, from, (to
- - from + 1), alignment);
+ 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();
copySequenceFeatures,
copySeq0.getSequenceFeatures().toString());
- if (checkDsSize)
- {
- /*
- * verify a new dataset sequence has appeared
- */
- assertEquals("Wrong Dataset size after cut",
- newDatasetSequence ? 2 : 1, alignment.getDataset()
- .getHeight());
- }
+ /*
+ * 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
*/
/*
* 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());
-
- if (checkDsSize)
- {
- /*
- * verify dataset sequence has shrunk
- */
- assertEquals("Wrong Dataset size after cut", 1,
- alignment.getDataset().getHeight());
- }
+ assertEquals("Wrong Dataset size after Undo of " + msg, 1,
+ alignment.getDataset().getHeight());
/*
* redo and verify
/*
* 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());
-
- if (checkDsSize)
- {
- /*
- * verify a new dataset sequence has appeared again
- */
- assertEquals("Wrong Dataset size after cut",
- newDatasetSequence ? 2 : 1, alignment.getDataset()
- .getHeight());
- }
+ assertEquals("Wrong Dataset size after Redo of " + msg,
+ newDatasetSequence ? 2 : 1,
+ alignment.getDataset().getHeight());
/*
* undo ready for next cut
/*
* 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());
- if (checkDsSize)
- {
- /*
- * and that dataset sequence has shrunk
- */
- assertEquals("Wrong Dataset size after cut", 1,
- alignment.getDataset().getHeight());
- }
+ assertEquals("Wrong Dataset size after final Undo of " + msg, 1,
+ alignment.getDataset().getHeight());
}
}
}
else
{
// failure in checkFeatureRelocation is more informative!
- assertEquals(msg + "wrong number of features left", func(5)
- - func(to - from + 1), sfs.size());
+ assertEquals(msg + "wrong number of features left",
+ func(5) - func(to - from + 1), sfs.size());
}
/*
{
final int oldFrom = ((Integer) sf.getValue("from")).intValue();
final int oldTo = ((Integer) sf.getValue("to")).intValue();
- String msg = String.format(
- "Undo cut of [%d-%d], feature at [%d-%d] ", from + 1, to + 1,
- oldFrom, oldTo);
+ String msg = String.format("Undo cut of [%d-%d], feature at [%d-%d] ",
+ from + 1, to + 1, oldFrom, oldTo);
assertEquals(msg + "start", oldFrom, sf.getBegin());
assertEquals(msg + "end", oldTo, sf.getEnd());
}
* @param seqStart
*/
private void verifyFeatureRelocation(SequenceFeature sf, int from, int to,
- boolean newDataset, int seqStart)
+ boolean newDataset, int seqStart)
{
// TODO handle the gapped sequence case as well
int cutSize = to - from + 1;
SequenceI seq0 = new Sequence("seq/8-11", "A-BCC");
seq0.createDatasetSequence();
assertEquals(8, seq0.getStart());
- seq0.addSequenceFeature(new SequenceFeature("", "", 10, 11, 0f,
- null));
+ seq0.addSequenceFeature(new SequenceFeature("", "", 10, 11, 0f, null));
SequenceI[] seqsArray = new SequenceI[] { seq0 };
AlignmentI alignment = new Alignment(seqsArray);
*/
Edit ec = testee.new Edit(Action.CUT, seqsArray, 0, 3, alignment);
EditCommand.cut(ec, new AlignmentI[] { alignment });
-
+
/*
* feature on CC(10-11) should still be on CC(10-11)
*/