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.
21 package jalview.commands;
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertSame;
26 import jalview.commands.EditCommand.Action;
27 import jalview.commands.EditCommand.Edit;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentI;
30 import jalview.datamodel.Sequence;
31 import jalview.datamodel.SequenceI;
32 import jalview.gui.JvOptionPane;
36 import org.testng.annotations.BeforeClass;
37 import org.testng.annotations.BeforeMethod;
38 import org.testng.annotations.Test;
41 * Unit tests for EditCommand
46 public class EditCommandTest
49 @BeforeClass(alwaysRun = true)
50 public void setUpJvOptionPane()
52 JvOptionPane.setInteractiveMode(false);
53 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
56 private EditCommand testee;
58 private SequenceI[] seqs;
62 @BeforeMethod(alwaysRun = true)
65 testee = new EditCommand();
66 seqs = new SequenceI[4];
67 seqs[0] = new Sequence("seq0", "abcdefghjk");
68 seqs[0].setDatasetSequence(new Sequence("seq0ds", "abcdefghjk"));
69 seqs[1] = new Sequence("seq1", "fghjklmnopq");
70 seqs[1].setDatasetSequence(new Sequence("seq1ds", "fghjklmnopq"));
71 seqs[2] = new Sequence("seq2", "qrstuvwxyz");
72 seqs[2].setDatasetSequence(new Sequence("seq2ds", "qrstuvwxyz"));
73 seqs[3] = new Sequence("seq3", "1234567890");
74 seqs[3].setDatasetSequence(new Sequence("seq3ds", "1234567890"));
75 al = new Alignment(seqs);
76 al.setGapCharacter('?');
80 * Test inserting gap characters
82 @Test(groups = { "Functional" })
83 public void testAppendEdit_insertGap()
85 // set a non-standard gap character to prove it is actually used
86 testee.appendEdit(Action.INSERT_GAP, seqs, 4, 3, al, true);
87 assertEquals("abcd???efghjk", seqs[0].getSequenceAsString());
88 assertEquals("fghj???klmnopq", seqs[1].getSequenceAsString());
89 assertEquals("qrst???uvwxyz", seqs[2].getSequenceAsString());
90 assertEquals("1234???567890", seqs[3].getSequenceAsString());
92 // todo: test for handling out of range positions?
96 * Test deleting characters from sequences. Note the deleteGap() action does
97 * not check that only gap characters are being removed.
99 @Test(groups = { "Functional" })
100 public void testAppendEdit_deleteGap()
102 testee.appendEdit(Action.DELETE_GAP, seqs, 4, 3, al, true);
103 assertEquals("abcdhjk", seqs[0].getSequenceAsString());
104 assertEquals("fghjnopq", seqs[1].getSequenceAsString());
105 assertEquals("qrstxyz", seqs[2].getSequenceAsString());
106 assertEquals("1234890", seqs[3].getSequenceAsString());
110 * Test a cut action. The command should store the cut characters to support
113 @Test(groups = { "Functional" })
114 public void testCut()
116 Edit ec = testee.new Edit(Action.CUT, seqs, 4, 3, al);
117 EditCommand.cut(ec, new AlignmentI[] { al });
118 assertEquals("abcdhjk", seqs[0].getSequenceAsString());
119 assertEquals("fghjnopq", seqs[1].getSequenceAsString());
120 assertEquals("qrstxyz", seqs[2].getSequenceAsString());
121 assertEquals("1234890", seqs[3].getSequenceAsString());
123 assertEquals("efg", new String(ec.string[0]));
124 assertEquals("klm", new String(ec.string[1]));
125 assertEquals("uvw", new String(ec.string[2]));
126 assertEquals("567", new String(ec.string[3]));
127 // TODO: case where whole sequence is deleted as nothing left; etc
131 * Test a Paste action, where this adds sequences to an alignment.
133 @Test(groups = { "Functional" }, enabled = false)
134 // TODO fix so it works
135 public void testPaste_addToAlignment()
137 SequenceI[] newSeqs = new SequenceI[2];
138 newSeqs[0] = new Sequence("newseq0", "ACEFKL");
139 newSeqs[1] = new Sequence("newseq1", "JWMPDH");
141 Edit ec = testee.new Edit(Action.PASTE, newSeqs, 0, al.getWidth(), al);
142 EditCommand.paste(ec, new AlignmentI[] { al });
143 assertEquals(6, al.getSequences().size());
144 assertEquals("1234567890", seqs[3].getSequenceAsString());
145 assertEquals("ACEFKL", seqs[4].getSequenceAsString());
146 assertEquals("JWMPDH", seqs[5].getSequenceAsString());
150 * Test insertGap followed by undo command
152 @Test(groups = { "Functional" })
153 public void testUndo_insertGap()
155 // Edit ec = testee.new Edit(Action.INSERT_GAP, seqs, 4, 3, '?');
156 testee.appendEdit(Action.INSERT_GAP, seqs, 4, 3, al, true);
157 // check something changed
158 assertEquals("abcd???efghjk", seqs[0].getSequenceAsString());
159 testee.undoCommand(new AlignmentI[] { al });
160 assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
161 assertEquals("fghjklmnopq", seqs[1].getSequenceAsString());
162 assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString());
163 assertEquals("1234567890", seqs[3].getSequenceAsString());
167 * Test deleteGap followed by undo command
169 @Test(groups = { "Functional" })
170 public void testUndo_deleteGap()
172 testee.appendEdit(Action.DELETE_GAP, seqs, 4, 3, al, true);
173 // check something changed
174 assertEquals("abcdhjk", seqs[0].getSequenceAsString());
175 testee.undoCommand(new AlignmentI[] { al });
176 // deleteGap doesn't 'remember' deleted characters, only gaps get put back
177 assertEquals("abcd???hjk", seqs[0].getSequenceAsString());
178 assertEquals("fghj???nopq", seqs[1].getSequenceAsString());
179 assertEquals("qrst???xyz", seqs[2].getSequenceAsString());
180 assertEquals("1234???890", seqs[3].getSequenceAsString());
184 * Test several commands followed by an undo command
186 @Test(groups = { "Functional" })
187 public void testUndo_multipleCommands()
189 // delete positions 3/4/5 (counting from 1)
190 testee.appendEdit(Action.DELETE_GAP, seqs, 2, 3, al, true);
191 assertEquals("abfghjk", seqs[0].getSequenceAsString());
192 assertEquals("1267890", seqs[3].getSequenceAsString());
194 // insert 2 gaps after the second residue
195 testee.appendEdit(Action.INSERT_GAP, seqs, 2, 2, al, true);
196 assertEquals("ab??fghjk", seqs[0].getSequenceAsString());
197 assertEquals("12??67890", seqs[3].getSequenceAsString());
199 // delete positions 4/5/6
200 testee.appendEdit(Action.DELETE_GAP, seqs, 3, 3, al, true);
201 assertEquals("ab?hjk", seqs[0].getSequenceAsString());
202 assertEquals("12?890", seqs[3].getSequenceAsString());
204 // undo edit commands
205 testee.undoCommand(new AlignmentI[] { al });
206 assertEquals("ab?????hjk", seqs[0].getSequenceAsString());
207 assertEquals("12?????890", seqs[3].getSequenceAsString());
211 * Unit test for JAL-1594 bug: click and drag sequence right to insert gaps -
212 * undo did not remove them all.
214 @Test(groups = { "Functional" })
215 public void testUndo_multipleInsertGaps()
217 testee.appendEdit(Action.INSERT_GAP, seqs, 4, 1, al, true);
218 testee.appendEdit(Action.INSERT_GAP, seqs, 5, 1, al, true);
219 testee.appendEdit(Action.INSERT_GAP, seqs, 6, 1, al, true);
221 // undo edit commands
222 testee.undoCommand(new AlignmentI[] { al });
223 assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
224 assertEquals("1234567890", seqs[3].getSequenceAsString());
229 * Test cut followed by undo command
231 @Test(groups = { "Functional" })
232 public void testUndo_cut()
234 testee.appendEdit(Action.CUT, seqs, 4, 3, al, true);
235 // check something changed
236 assertEquals("abcdhjk", seqs[0].getSequenceAsString());
237 testee.undoCommand(new AlignmentI[] { al });
238 assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
239 assertEquals("fghjklmnopq", seqs[1].getSequenceAsString());
240 assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString());
241 assertEquals("1234567890", seqs[3].getSequenceAsString());
245 * Test the replace command (used to manually edit a sequence)
247 @Test(groups = { "Functional" })
248 public void testReplace()
250 // seem to need a dataset sequence on the edited sequence here
251 seqs[1].createDatasetSequence();
252 new EditCommand("", Action.REPLACE, "ZXY", new SequenceI[] { seqs[1] },
254 assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
255 assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString());
256 assertEquals("1234567890", seqs[3].getSequenceAsString());
257 seqs[1] = new Sequence("seq1", "fghjZXYnopq");
261 * Test that the addEdit command correctly merges insert gap commands when
264 @Test(groups = { "Functional" })
265 public void testAddEdit_multipleInsertGap()
268 * 3 insert gap in a row (aka mouse drag right):
270 Edit e = new EditCommand().new Edit(Action.INSERT_GAP,
271 new SequenceI[] { seqs[0] }, 1, 1, al);
273 SequenceI edited = new Sequence("seq0", "a?bcdefghjk");
274 edited.setDatasetSequence(seqs[0].getDatasetSequence());
275 e = new EditCommand().new Edit(Action.INSERT_GAP,
276 new SequenceI[] { edited }, 2, 1, al);
278 edited = new Sequence("seq0", "a??bcdefghjk");
279 edited.setDatasetSequence(seqs[0].getDatasetSequence());
280 e = new EditCommand().new Edit(Action.INSERT_GAP,
281 new SequenceI[] { edited }, 3, 1, al);
283 assertEquals(1, testee.getSize());
284 assertEquals(Action.INSERT_GAP, testee.getEdit(0).getAction());
285 assertEquals(1, testee.getEdit(0).getPosition());
286 assertEquals(3, testee.getEdit(0).getNumber());
289 * Add a non-contiguous edit - should not be merged.
291 e = new EditCommand().new Edit(Action.INSERT_GAP,
292 new SequenceI[] { edited }, 5, 2, al);
294 assertEquals(2, testee.getSize());
295 assertEquals(5, testee.getEdit(1).getPosition());
296 assertEquals(2, testee.getEdit(1).getNumber());
299 * Add a Delete after the Insert - should not be merged.
301 e = new EditCommand().new Edit(Action.DELETE_GAP,
302 new SequenceI[] { edited }, 6, 2, al);
304 assertEquals(3, testee.getSize());
305 assertEquals(Action.DELETE_GAP, testee.getEdit(2).getAction());
306 assertEquals(6, testee.getEdit(2).getPosition());
307 assertEquals(2, testee.getEdit(2).getNumber());
311 * Test that the addEdit command correctly merges delete gap commands when
314 @Test(groups = { "Functional" })
315 public void testAddEdit_multipleDeleteGap()
318 * 3 delete gap in a row (aka mouse drag left):
320 seqs[0].setSequence("a???bcdefghjk");
321 Edit e = new EditCommand().new Edit(Action.DELETE_GAP,
322 new SequenceI[] { seqs[0] }, 4, 1, al);
324 assertEquals(1, testee.getSize());
326 SequenceI edited = new Sequence("seq0", "a??bcdefghjk");
327 edited.setDatasetSequence(seqs[0].getDatasetSequence());
328 e = new EditCommand().new Edit(Action.DELETE_GAP,
329 new SequenceI[] { edited }, 3, 1, al);
331 assertEquals(1, testee.getSize());
333 edited = new Sequence("seq0", "a?bcdefghjk");
334 edited.setDatasetSequence(seqs[0].getDatasetSequence());
335 e = new EditCommand().new Edit(Action.DELETE_GAP,
336 new SequenceI[] { edited }, 2, 1, al);
338 assertEquals(1, testee.getSize());
339 assertEquals(Action.DELETE_GAP, testee.getEdit(0).getAction());
340 assertEquals(2, testee.getEdit(0).getPosition());
341 assertEquals(3, testee.getEdit(0).getNumber());
344 * Add a non-contiguous edit - should not be merged.
346 e = new EditCommand().new Edit(Action.DELETE_GAP,
347 new SequenceI[] { edited }, 2, 1, al);
349 assertEquals(2, testee.getSize());
350 assertEquals(Action.DELETE_GAP, testee.getEdit(0).getAction());
351 assertEquals(2, testee.getEdit(1).getPosition());
352 assertEquals(1, testee.getEdit(1).getNumber());
355 * Add an Insert after the Delete - should not be merged.
357 e = new EditCommand().new Edit(Action.INSERT_GAP,
358 new SequenceI[] { edited }, 1, 1, al);
360 assertEquals(3, testee.getSize());
361 assertEquals(Action.INSERT_GAP, testee.getEdit(2).getAction());
362 assertEquals(1, testee.getEdit(2).getPosition());
363 assertEquals(1, testee.getEdit(2).getNumber());
367 * Test that the addEdit command correctly handles 'remove gaps' edits for the
368 * case when they appear contiguous but are acting on different sequences.
369 * They should not be merged.
371 @Test(groups = { "Functional" })
372 public void testAddEdit_removeAllGaps()
374 seqs[0].setSequence("a???bcdefghjk");
375 Edit e = new EditCommand().new Edit(Action.DELETE_GAP,
376 new SequenceI[] { seqs[0] }, 4, 1, al);
379 seqs[1].setSequence("f??ghjklmnopq");
380 Edit e2 = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[]
381 { seqs[1] }, 3, 1, al);
383 assertEquals(2, testee.getSize());
384 assertSame(e, testee.getEdit(0));
385 assertSame(e2, testee.getEdit(1));
389 * Test that the addEdit command correctly merges insert gap commands acting
390 * on a multi-sequence selection.
392 @Test(groups = { "Functional" })
393 public void testAddEdit_groupInsertGaps()
396 * 2 insert gap in a row (aka mouse drag right), on two sequences:
398 Edit e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] {
399 seqs[0], seqs[1] }, 1, 1, al);
401 SequenceI seq1edited = new Sequence("seq0", "a?bcdefghjk");
402 seq1edited.setDatasetSequence(seqs[0].getDatasetSequence());
403 SequenceI seq2edited = new Sequence("seq1", "f?ghjklmnopq");
404 seq2edited.setDatasetSequence(seqs[1].getDatasetSequence());
405 e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] {
406 seq1edited, seq2edited }, 2, 1, al);
409 assertEquals(1, testee.getSize());
410 assertEquals(Action.INSERT_GAP, testee.getEdit(0).getAction());
411 assertEquals(1, testee.getEdit(0).getPosition());
412 assertEquals(2, testee.getEdit(0).getNumber());
413 assertEquals(seqs[0].getDatasetSequence(), testee.getEdit(0)
414 .getSequences()[0].getDatasetSequence());
415 assertEquals(seqs[1].getDatasetSequence(), testee.getEdit(0)
416 .getSequences()[1].getDatasetSequence());
420 * Test for 'undoing' a series of gap insertions.
422 * <li>Start: ABCDEF insert 2 at pos 1</li>
423 * <li>next: A--BCDEF insert 1 at pos 4</li>
424 * <li>next: A--B-CDEF insert 2 at pos 0</li>
425 * <li>last: --A--B-CDEF</li>
428 @Test(groups = { "Functional" })
429 public void testPriorState_multipleInserts()
431 EditCommand command = new EditCommand();
432 SequenceI seq = new Sequence("", "--A--B-CDEF");
433 SequenceI ds = new Sequence("", "ABCDEF");
434 seq.setDatasetSequence(ds);
435 SequenceI[] sqs = new SequenceI[] { seq };
436 Edit e = command.new Edit(Action.INSERT_GAP, sqs, 1, 2, '-');
438 e = command.new Edit(Action.INSERT_GAP, sqs, 4, 1, '-');
440 e = command.new Edit(Action.INSERT_GAP, sqs, 0, 2, '-');
443 Map<SequenceI, SequenceI> unwound = command.priorState(false);
444 assertEquals("ABCDEF", unwound.get(ds).getSequenceAsString());
448 * Test for 'undoing' a series of gap deletions.
450 * <li>Start: A-B-C delete 1 at pos 1</li>
451 * <li>Next: AB-C delete 1 at pos 2</li>
455 @Test(groups = { "Functional" })
456 public void testPriorState_removeAllGaps()
458 EditCommand command = new EditCommand();
459 SequenceI seq = new Sequence("", "ABC");
460 SequenceI ds = new Sequence("", "ABC");
461 seq.setDatasetSequence(ds);
462 SequenceI[] sqs = new SequenceI[] { seq };
463 Edit e = command.new Edit(Action.DELETE_GAP, sqs, 1, 1, '-');
465 e = command.new Edit(Action.DELETE_GAP, sqs, 2, 1, '-');
468 Map<SequenceI, SequenceI> unwound = command.priorState(false);
469 assertEquals("A-B-C", unwound.get(ds).getSequenceAsString());
473 * Test for 'undoing' a single delete edit.
475 @Test(groups = { "Functional" })
476 public void testPriorState_singleDelete()
478 EditCommand command = new EditCommand();
479 SequenceI seq = new Sequence("", "ABCDEF");
480 SequenceI ds = new Sequence("", "ABCDEF");
481 seq.setDatasetSequence(ds);
482 SequenceI[] sqs = new SequenceI[] { seq };
483 Edit e = command.new Edit(Action.DELETE_GAP, sqs, 2, 2, '-');
486 Map<SequenceI, SequenceI> unwound = command.priorState(false);
487 assertEquals("AB--CDEF", unwound.get(ds).getSequenceAsString());
491 * Test 'undoing' a single gap insertion edit command.
493 @Test(groups = { "Functional" })
494 public void testPriorState_singleInsert()
496 EditCommand command = new EditCommand();
497 SequenceI seq = new Sequence("", "AB---CDEF");
498 SequenceI ds = new Sequence("", "ABCDEF");
499 seq.setDatasetSequence(ds);
500 SequenceI[] sqs = new SequenceI[] { seq };
501 Edit e = command.new Edit(Action.INSERT_GAP, sqs, 2, 3, '-');
504 Map<SequenceI, SequenceI> unwound = command.priorState(false);
505 SequenceI prior = unwound.get(ds);
506 assertEquals("ABCDEF", prior.getSequenceAsString());
507 assertEquals(1, prior.getStart());
508 assertEquals(6, prior.getEnd());
512 * Test 'undoing' a single gap insertion edit command, on a sequence whose
513 * start residue is other than 1
515 @Test(groups = { "Functional" })
516 public void testPriorState_singleInsertWithOffset()
518 EditCommand command = new EditCommand();
519 SequenceI seq = new Sequence("", "AB---CDEF", 8, 13);
520 // SequenceI ds = new Sequence("", "ABCDEF", 8, 13);
521 // seq.setDatasetSequence(ds);
522 seq.createDatasetSequence();
523 SequenceI[] sqs = new SequenceI[] { seq };
524 Edit e = command.new Edit(Action.INSERT_GAP, sqs, 2, 3, '-');
527 Map<SequenceI, SequenceI> unwound = command.priorState(false);
528 SequenceI prior = unwound.get(seq.getDatasetSequence());
529 assertEquals("ABCDEF", prior.getSequenceAsString());
530 assertEquals(8, prior.getStart());
531 assertEquals(13, prior.getEnd());
535 * Test that mimics 'remove all gaps' action. This generates delete gap edits
536 * for contiguous gaps in each sequence separately.
538 @Test(groups = { "Functional" })
539 public void testPriorState_removeGapsMultipleSeqs()
541 EditCommand command = new EditCommand();
542 String original1 = "--ABC-DEF";
543 String original2 = "FG-HI--J";
544 String original3 = "M-NOPQ";
547 * Two edits for the first sequence
549 SequenceI seq = new Sequence("", "ABC-DEF");
550 SequenceI ds1 = new Sequence("", "ABCDEF");
551 seq.setDatasetSequence(ds1);
552 SequenceI[] sqs = new SequenceI[] { seq };
553 Edit e = command.new Edit(Action.DELETE_GAP, sqs, 0, 2, '-');
555 seq = new Sequence("", "ABCDEF");
556 seq.setDatasetSequence(ds1);
557 sqs = new SequenceI[] { seq };
558 e = command.new Edit(Action.DELETE_GAP, sqs, 3, 1, '-');
562 * Two edits for the second sequence
564 seq = new Sequence("", "FGHI--J");
565 SequenceI ds2 = new Sequence("", "FGHIJ");
566 seq.setDatasetSequence(ds2);
567 sqs = new SequenceI[] { seq };
568 e = command.new Edit(Action.DELETE_GAP, sqs, 2, 1, '-');
570 seq = new Sequence("", "FGHIJ");
571 seq.setDatasetSequence(ds2);
572 sqs = new SequenceI[] { seq };
573 e = command.new Edit(Action.DELETE_GAP, sqs, 4, 2, '-');
577 * One edit for the third sequence.
579 seq = new Sequence("", "MNOPQ");
580 SequenceI ds3 = new Sequence("", "MNOPQ");
581 seq.setDatasetSequence(ds3);
582 sqs = new SequenceI[] { seq };
583 e = command.new Edit(Action.DELETE_GAP, sqs, 1, 1, '-');
586 Map<SequenceI, SequenceI> unwound = command.priorState(false);
587 assertEquals(original1, unwound.get(ds1).getSequenceAsString());
588 assertEquals(original2, unwound.get(ds2).getSequenceAsString());
589 assertEquals(original3, unwound.get(ds3).getSequenceAsString());
593 * Test that mimics 'remove all gapped columns' action. This generates a
594 * series Delete Gap edits that each act on all sequences that share a gapped
597 @Test(groups = { "Functional" })
598 public void testPriorState_removeGappedCols()
600 EditCommand command = new EditCommand();
601 String original1 = "--ABC--DEF";
602 String original2 = "-G-HI--J";
603 String original3 = "-M-NO--PQ";
606 * First edit deletes the first column.
608 SequenceI seq1 = new Sequence("", "-ABC--DEF");
609 SequenceI ds1 = new Sequence("", "ABCDEF");
610 seq1.setDatasetSequence(ds1);
611 SequenceI seq2 = new Sequence("", "G-HI--J");
612 SequenceI ds2 = new Sequence("", "GHIJ");
613 seq2.setDatasetSequence(ds2);
614 SequenceI seq3 = new Sequence("", "M-NO--PQ");
615 SequenceI ds3 = new Sequence("", "MNOPQ");
616 seq3.setDatasetSequence(ds3);
617 SequenceI[] sqs = new SequenceI[] { seq1, seq2, seq3 };
618 Edit e = command.new Edit(Action.DELETE_GAP, sqs, 0, 1, '-');
622 * Second edit deletes what is now columns 4 and 5.
624 seq1 = new Sequence("", "-ABCDEF");
625 seq1.setDatasetSequence(ds1);
626 seq2 = new Sequence("", "G-HIJ");
627 seq2.setDatasetSequence(ds2);
628 seq3 = new Sequence("", "M-NOPQ");
629 seq3.setDatasetSequence(ds3);
630 sqs = new SequenceI[] { seq1, seq2, seq3 };
631 e = command.new Edit(Action.DELETE_GAP, sqs, 4, 2, '-');
634 Map<SequenceI, SequenceI> unwound = command.priorState(false);
635 assertEquals(original1, unwound.get(ds1).getSequenceAsString());
636 assertEquals(original2, unwound.get(ds2).getSequenceAsString());
637 assertEquals(original3, unwound.get(ds3).getSequenceAsString());
638 assertEquals(ds1, unwound.get(ds1).getDatasetSequence());
639 assertEquals(ds2, unwound.get(ds2).getDatasetSequence());
640 assertEquals(ds3, unwound.get(ds3).getDatasetSequence());