JAL-1645 source formatting and organise imports
[jalview.git] / test / jalview / commands / EditCommandTest.java
1 package jalview.commands;
2
3 import static org.testng.AssertJUnit.assertEquals;
4 import static org.testng.AssertJUnit.assertSame;
5
6 import jalview.commands.EditCommand.Action;
7 import jalview.commands.EditCommand.Edit;
8 import jalview.datamodel.Alignment;
9 import jalview.datamodel.AlignmentI;
10 import jalview.datamodel.Sequence;
11 import jalview.datamodel.SequenceI;
12
13 import java.util.Map;
14
15 import org.testng.annotations.BeforeMethod;
16 import org.testng.annotations.Test;
17
18 /**
19  * Unit tests for EditCommand
20  * 
21  * @author gmcarstairs
22  *
23  */
24 public class EditCommandTest
25 {
26
27   private EditCommand testee;
28
29   private SequenceI[] seqs;
30
31   private Alignment al;
32
33   @BeforeMethod(alwaysRun = true)
34   public void setUp()
35   {
36     testee = new EditCommand();
37     seqs = new SequenceI[4];
38     seqs[0] = new Sequence("seq0", "abcdefghjk");
39     seqs[0].setDatasetSequence(new Sequence("seq0ds", "abcdefghjk"));
40     seqs[1] = new Sequence("seq1", "fghjklmnopq");
41     seqs[1].setDatasetSequence(new Sequence("seq1ds", "fghjklmnopq"));
42     seqs[2] = new Sequence("seq2", "qrstuvwxyz");
43     seqs[2].setDatasetSequence(new Sequence("seq2ds", "qrstuvwxyz"));
44     seqs[3] = new Sequence("seq3", "1234567890");
45     seqs[3].setDatasetSequence(new Sequence("seq3ds", "1234567890"));
46     al = new Alignment(seqs);
47     al.setGapCharacter('?');
48   }
49
50   /**
51    * Test inserting gap characters
52    */
53   @Test(groups = { "Functional" })
54   public void testAppendEdit_insertGap()
55   {
56     // set a non-standard gap character to prove it is actually used
57     testee.appendEdit(Action.INSERT_GAP, seqs, 4, 3, al, true);
58     assertEquals("abcd???efghjk", seqs[0].getSequenceAsString());
59     assertEquals("fghj???klmnopq", seqs[1].getSequenceAsString());
60     assertEquals("qrst???uvwxyz", seqs[2].getSequenceAsString());
61     assertEquals("1234???567890", seqs[3].getSequenceAsString());
62
63     // todo: test for handling out of range positions?
64   }
65
66   /**
67    * Test deleting characters from sequences. Note the deleteGap() action does
68    * not check that only gap characters are being removed.
69    */
70   @Test(groups = { "Functional" })
71   public void testAppendEdit_deleteGap()
72   {
73     testee.appendEdit(Action.DELETE_GAP, seqs, 4, 3, al, true);
74     assertEquals("abcdhjk", seqs[0].getSequenceAsString());
75     assertEquals("fghjnopq", seqs[1].getSequenceAsString());
76     assertEquals("qrstxyz", seqs[2].getSequenceAsString());
77     assertEquals("1234890", seqs[3].getSequenceAsString());
78   }
79
80   /**
81    * Test a cut action. The command should store the cut characters to support
82    * undo.
83    */
84   @Test(groups = { "Functional" })
85   public void testCut()
86   {
87     Edit ec = testee.new Edit(Action.CUT, seqs, 4, 3, al);
88     testee.cut(ec, new AlignmentI[] { al });
89     assertEquals("abcdhjk", seqs[0].getSequenceAsString());
90     assertEquals("fghjnopq", seqs[1].getSequenceAsString());
91     assertEquals("qrstxyz", seqs[2].getSequenceAsString());
92     assertEquals("1234890", seqs[3].getSequenceAsString());
93
94     assertEquals("efg", new String(ec.string[0]));
95     assertEquals("klm", new String(ec.string[1]));
96     assertEquals("uvw", new String(ec.string[2]));
97     assertEquals("567", new String(ec.string[3]));
98     // TODO: case where whole sequence is deleted as nothing left; etc
99   }
100
101   /**
102    * Test a Paste action, where this adds sequences to an alignment.
103    */
104   @Test(groups = { "Functional" }, enabled = false)
105   // TODO fix so it works
106   public void testPaste_addToAlignment()
107   {
108     SequenceI[] newSeqs = new SequenceI[2];
109     newSeqs[0] = new Sequence("newseq0", "ACEFKL");
110     newSeqs[1] = new Sequence("newseq1", "JWMPDH");
111
112     Edit ec = testee.new Edit(Action.PASTE, newSeqs, 0, al.getWidth(), al);
113     testee.paste(ec, new AlignmentI[] { al });
114     assertEquals(6, al.getSequences().size());
115     assertEquals("1234567890", seqs[3].getSequenceAsString());
116     assertEquals("ACEFKL", seqs[4].getSequenceAsString());
117     assertEquals("JWMPDH", seqs[5].getSequenceAsString());
118   }
119
120   /**
121    * Test insertGap followed by undo command
122    */
123   @Test(groups = { "Functional" })
124   public void testUndo_insertGap()
125   {
126     // Edit ec = testee.new Edit(Action.INSERT_GAP, seqs, 4, 3, '?');
127     testee.appendEdit(Action.INSERT_GAP, seqs, 4, 3, al, true);
128     // check something changed
129     assertEquals("abcd???efghjk", seqs[0].getSequenceAsString());
130     testee.undoCommand(new AlignmentI[] { al });
131     assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
132     assertEquals("fghjklmnopq", seqs[1].getSequenceAsString());
133     assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString());
134     assertEquals("1234567890", seqs[3].getSequenceAsString());
135   }
136
137   /**
138    * Test deleteGap followed by undo command
139    */
140   @Test(groups = { "Functional" })
141   public void testUndo_deleteGap()
142   {
143     testee.appendEdit(Action.DELETE_GAP, seqs, 4, 3, al, true);
144     // check something changed
145     assertEquals("abcdhjk", seqs[0].getSequenceAsString());
146     testee.undoCommand(new AlignmentI[] { al });
147     // deleteGap doesn't 'remember' deleted characters, only gaps get put back
148     assertEquals("abcd???hjk", seqs[0].getSequenceAsString());
149     assertEquals("fghj???nopq", seqs[1].getSequenceAsString());
150     assertEquals("qrst???xyz", seqs[2].getSequenceAsString());
151     assertEquals("1234???890", seqs[3].getSequenceAsString());
152   }
153
154   /**
155    * Test several commands followed by an undo command
156    */
157   @Test(groups = { "Functional" })
158   public void testUndo_multipleCommands()
159   {
160     // delete positions 3/4/5 (counting from 1)
161     testee.appendEdit(Action.DELETE_GAP, seqs, 2, 3, al, true);
162     assertEquals("abfghjk", seqs[0].getSequenceAsString());
163     assertEquals("1267890", seqs[3].getSequenceAsString());
164
165     // insert 2 gaps after the second residue
166     testee.appendEdit(Action.INSERT_GAP, seqs, 2, 2, al, true);
167     assertEquals("ab??fghjk", seqs[0].getSequenceAsString());
168     assertEquals("12??67890", seqs[3].getSequenceAsString());
169
170     // delete positions 4/5/6
171     testee.appendEdit(Action.DELETE_GAP, seqs, 3, 3, al, true);
172     assertEquals("ab?hjk", seqs[0].getSequenceAsString());
173     assertEquals("12?890", seqs[3].getSequenceAsString());
174
175     // undo edit commands
176     testee.undoCommand(new AlignmentI[] { al });
177     assertEquals("ab?????hjk", seqs[0].getSequenceAsString());
178     assertEquals("12?????890", seqs[3].getSequenceAsString());
179   }
180
181   /**
182    * Unit test for JAL-1594 bug: click and drag sequence right to insert gaps -
183    * undo did not remove them all.
184    */
185   @Test(groups = { "Functional" })
186   public void testUndo_multipleInsertGaps()
187   {
188     testee.appendEdit(Action.INSERT_GAP, seqs, 4, 1, al, true);
189     testee.appendEdit(Action.INSERT_GAP, seqs, 5, 1, al, true);
190     testee.appendEdit(Action.INSERT_GAP, seqs, 6, 1, al, true);
191
192     // undo edit commands
193     testee.undoCommand(new AlignmentI[] { al });
194     assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
195     assertEquals("1234567890", seqs[3].getSequenceAsString());
196
197   }
198
199   /**
200    * Test cut followed by undo command
201    */
202   @Test(groups = { "Functional" })
203   public void testUndo_cut()
204   {
205     testee.appendEdit(Action.CUT, seqs, 4, 3, al, true);
206     // check something changed
207     assertEquals("abcdhjk", seqs[0].getSequenceAsString());
208     testee.undoCommand(new AlignmentI[] { al });
209     assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
210     assertEquals("fghjklmnopq", seqs[1].getSequenceAsString());
211     assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString());
212     assertEquals("1234567890", seqs[3].getSequenceAsString());
213   }
214
215   /**
216    * Test the replace command (used to manually edit a sequence)
217    */
218   @Test(groups = { "Functional" })
219   public void testReplace()
220   {
221     // seem to need a dataset sequence on the edited sequence here
222     seqs[1].setDatasetSequence(seqs[1]);
223     new EditCommand("", Action.REPLACE, "ZXY", new SequenceI[] { seqs[1] },
224             4, 8, al);
225     assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
226     assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString());
227     assertEquals("1234567890", seqs[3].getSequenceAsString());
228     seqs[1] = new Sequence("seq1", "fghjZXYnopq");
229   }
230
231   /**
232    * Test that the addEdit command correctly merges insert gap commands when
233    * possible.
234    */
235   @Test(groups = { "Functional" })
236   public void testAddEdit_multipleInsertGap()
237   {
238     /*
239      * 3 insert gap in a row (aka mouse drag right):
240      */
241     Edit e = new EditCommand().new Edit(Action.INSERT_GAP,
242             new SequenceI[] { seqs[0] }, 1, 1, al);
243     testee.addEdit(e);
244     SequenceI edited = new Sequence("seq0", "a?bcdefghjk");
245     edited.setDatasetSequence(seqs[0].getDatasetSequence());
246     e = new EditCommand().new Edit(Action.INSERT_GAP,
247             new SequenceI[] { edited }, 2, 1, al);
248     testee.addEdit(e);
249     edited = new Sequence("seq0", "a??bcdefghjk");
250     edited.setDatasetSequence(seqs[0].getDatasetSequence());
251     e = new EditCommand().new Edit(Action.INSERT_GAP,
252             new SequenceI[] { edited }, 3, 1, al);
253     testee.addEdit(e);
254     assertEquals(1, testee.getSize());
255     assertEquals(Action.INSERT_GAP, testee.getEdit(0).getAction());
256     assertEquals(1, testee.getEdit(0).getPosition());
257     assertEquals(3, testee.getEdit(0).getNumber());
258
259     /*
260      * Add a non-contiguous edit - should not be merged.
261      */
262     e = new EditCommand().new Edit(Action.INSERT_GAP,
263             new SequenceI[] { edited }, 5, 2, al);
264     testee.addEdit(e);
265     assertEquals(2, testee.getSize());
266     assertEquals(5, testee.getEdit(1).getPosition());
267     assertEquals(2, testee.getEdit(1).getNumber());
268
269     /*
270      * Add a Delete after the Insert - should not be merged.
271      */
272     e = new EditCommand().new Edit(Action.DELETE_GAP,
273             new SequenceI[] { edited }, 6, 2, al);
274     testee.addEdit(e);
275     assertEquals(3, testee.getSize());
276     assertEquals(Action.DELETE_GAP, testee.getEdit(2).getAction());
277     assertEquals(6, testee.getEdit(2).getPosition());
278     assertEquals(2, testee.getEdit(2).getNumber());
279   }
280
281   /**
282    * Test that the addEdit command correctly merges delete gap commands when
283    * possible.
284    */
285   @Test(groups = { "Functional" })
286   public void testAddEdit_multipleDeleteGap()
287   {
288     /*
289      * 3 delete gap in a row (aka mouse drag left):
290      */
291     seqs[0].setSequence("a???bcdefghjk");
292     Edit e = new EditCommand().new Edit(Action.DELETE_GAP,
293             new SequenceI[] { seqs[0] }, 4, 1, al);
294     testee.addEdit(e);
295     assertEquals(1, testee.getSize());
296
297     SequenceI edited = new Sequence("seq0", "a??bcdefghjk");
298     edited.setDatasetSequence(seqs[0].getDatasetSequence());
299     e = new EditCommand().new Edit(Action.DELETE_GAP,
300             new SequenceI[] { edited }, 3, 1, al);
301     testee.addEdit(e);
302     assertEquals(1, testee.getSize());
303
304     edited = new Sequence("seq0", "a?bcdefghjk");
305     edited.setDatasetSequence(seqs[0].getDatasetSequence());
306     e = new EditCommand().new Edit(Action.DELETE_GAP,
307             new SequenceI[] { edited }, 2, 1, al);
308     testee.addEdit(e);
309     assertEquals(1, testee.getSize());
310     assertEquals(Action.DELETE_GAP, testee.getEdit(0).getAction());
311     assertEquals(2, testee.getEdit(0).getPosition());
312     assertEquals(3, testee.getEdit(0).getNumber());
313
314     /*
315      * Add a non-contiguous edit - should not be merged.
316      */
317     e = new EditCommand().new Edit(Action.DELETE_GAP,
318             new SequenceI[] { edited }, 2, 1, al);
319     testee.addEdit(e);
320     assertEquals(2, testee.getSize());
321     assertEquals(Action.DELETE_GAP, testee.getEdit(0).getAction());
322     assertEquals(2, testee.getEdit(1).getPosition());
323     assertEquals(1, testee.getEdit(1).getNumber());
324
325     /*
326      * Add an Insert after the Delete - should not be merged.
327      */
328     e = new EditCommand().new Edit(Action.INSERT_GAP,
329             new SequenceI[] { edited }, 1, 1, al);
330     testee.addEdit(e);
331     assertEquals(3, testee.getSize());
332     assertEquals(Action.INSERT_GAP, testee.getEdit(2).getAction());
333     assertEquals(1, testee.getEdit(2).getPosition());
334     assertEquals(1, testee.getEdit(2).getNumber());
335   }
336
337   /**
338    * Test that the addEdit command correctly handles 'remove gaps' edits for the
339    * case when they appear contiguous but are acting on different sequences.
340    * They should not be merged.
341    */
342   @Test(groups = { "Functional" })
343   public void testAddEdit_removeAllGaps()
344   {
345     seqs[0].setSequence("a???bcdefghjk");
346     Edit e = new EditCommand().new Edit(Action.DELETE_GAP,
347             new SequenceI[] { seqs[0] }, 4, 1, al);
348     testee.addEdit(e);
349
350     seqs[1].setSequence("f??ghjklmnopq");
351     Edit e2 = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[]
352     { seqs[1] }, 3, 1, al);
353     testee.addEdit(e2);
354     assertEquals(2, testee.getSize());
355     assertSame(e, testee.getEdit(0));
356     assertSame(e2, testee.getEdit(1));
357   }
358
359   /**
360    * Test that the addEdit command correctly merges insert gap commands acting
361    * on a multi-sequence selection.
362    */
363   @Test(groups = { "Functional" })
364   public void testAddEdit_groupInsertGaps()
365   {
366     /*
367      * 2 insert gap in a row (aka mouse drag right), on two sequences:
368      */
369     Edit e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] {
370         seqs[0], seqs[1] }, 1, 1, al);
371     testee.addEdit(e);
372     SequenceI seq1edited = new Sequence("seq0", "a?bcdefghjk");
373     seq1edited.setDatasetSequence(seqs[0].getDatasetSequence());
374     SequenceI seq2edited = new Sequence("seq1", "f?ghjklmnopq");
375     seq2edited.setDatasetSequence(seqs[1].getDatasetSequence());
376     e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] {
377         seq1edited, seq2edited }, 2, 1, al);
378     testee.addEdit(e);
379
380     assertEquals(1, testee.getSize());
381     assertEquals(Action.INSERT_GAP, testee.getEdit(0).getAction());
382     assertEquals(1, testee.getEdit(0).getPosition());
383     assertEquals(2, testee.getEdit(0).getNumber());
384     assertEquals(seqs[0].getDatasetSequence(), testee.getEdit(0)
385             .getSequences()[0].getDatasetSequence());
386     assertEquals(seqs[1].getDatasetSequence(), testee.getEdit(0)
387             .getSequences()[1].getDatasetSequence());
388   }
389
390   /**
391    * Test for 'undoing' a series of gap insertions.
392    * <ul>
393    * <li>Start: ABCDEF insert 2 at pos 1</li>
394    * <li>next: A--BCDEF insert 1 at pos 4</li>
395    * <li>next: A--B-CDEF insert 2 at pos 0</li>
396    * <li>last: --A--B-CDEF</li>
397    * </ul>
398    */
399   @Test(groups = { "Functional" })
400   public void testPriorState_multipleInserts()
401   {
402     EditCommand command = new EditCommand();
403     SequenceI seq = new Sequence("", "--A--B-CDEF");
404     SequenceI ds = new Sequence("", "ABCDEF");
405     seq.setDatasetSequence(ds);
406     SequenceI[] seqs = new SequenceI[] { seq };
407     Edit e = command.new Edit(Action.INSERT_GAP, seqs, 1, 2, '-');
408     command.addEdit(e);
409     e = command.new Edit(Action.INSERT_GAP, seqs, 4, 1, '-');
410     command.addEdit(e);
411     e = command.new Edit(Action.INSERT_GAP, seqs, 0, 2, '-');
412     command.addEdit(e);
413
414     Map<SequenceI, SequenceI> unwound = command.priorState(false);
415     assertEquals("ABCDEF", unwound.get(ds).getSequenceAsString());
416   }
417
418   /**
419    * Test for 'undoing' a series of gap deletions.
420    * <ul>
421    * <li>Start: A-B-C delete 1 at pos 1</li>
422    * <li>Next: AB-C delete 1 at pos 2</li>
423    * <li>End: ABC</li>
424    * </ul>
425    */
426   @Test(groups = { "Functional" })
427   public void testPriorState_removeAllGaps()
428   {
429     EditCommand command = new EditCommand();
430     SequenceI seq = new Sequence("", "ABC");
431     SequenceI ds = new Sequence("", "ABC");
432     seq.setDatasetSequence(ds);
433     SequenceI[] seqs = new SequenceI[] { seq };
434     Edit e = command.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
435     command.addEdit(e);
436     e = command.new Edit(Action.DELETE_GAP, seqs, 2, 1, '-');
437     command.addEdit(e);
438
439     Map<SequenceI, SequenceI> unwound = command.priorState(false);
440     assertEquals("A-B-C", unwound.get(ds).getSequenceAsString());
441   }
442
443   /**
444    * Test for 'undoing' a single delete edit.
445    */
446   @Test(groups = { "Functional" })
447   public void testPriorState_singleDelete()
448   {
449     EditCommand command = new EditCommand();
450     SequenceI seq = new Sequence("", "ABCDEF");
451     SequenceI ds = new Sequence("", "ABCDEF");
452     seq.setDatasetSequence(ds);
453     SequenceI[] seqs = new SequenceI[] { seq };
454     Edit e = command.new Edit(Action.DELETE_GAP, seqs, 2, 2, '-');
455     command.addEdit(e);
456
457     Map<SequenceI, SequenceI> unwound = command.priorState(false);
458     assertEquals("AB--CDEF", unwound.get(ds).getSequenceAsString());
459   }
460
461   /**
462    * Test 'undoing' a single gap insertion edit command.
463    */
464   @Test(groups = { "Functional" })
465   public void testPriorState_singleInsert()
466   {
467     EditCommand command = new EditCommand();
468     SequenceI seq = new Sequence("", "AB---CDEF");
469     SequenceI ds = new Sequence("", "ABCDEF");
470     seq.setDatasetSequence(ds);
471     SequenceI[] seqs = new SequenceI[] { seq };
472     Edit e = command.new Edit(Action.INSERT_GAP, seqs, 2, 3, '-');
473     command.addEdit(e);
474
475     Map<SequenceI, SequenceI> unwound = command.priorState(false);
476     assertEquals("ABCDEF", unwound.get(ds).getSequenceAsString());
477   }
478
479   /**
480    * Test that mimics 'remove all gaps' action. This generates delete gap edits
481    * for contiguous gaps in each sequence separately.
482    */
483   @Test(groups = { "Functional" })
484   public void testPriorState_removeGapsMultipleSeqs()
485   {
486     EditCommand command = new EditCommand();
487     String original1 = "--ABC-DEF";
488     String original2 = "FG-HI--J";
489     String original3 = "M-NOPQ";
490
491     /*
492      * Two edits for the first sequence
493      */
494     SequenceI seq = new Sequence("", "ABC-DEF");
495     SequenceI ds1 = new Sequence("", "ABCDEF");
496     seq.setDatasetSequence(ds1);
497     SequenceI[] seqs = new SequenceI[] { seq };
498     Edit e = command.new Edit(Action.DELETE_GAP, seqs, 0, 2, '-');
499     command.addEdit(e);
500     seq = new Sequence("", "ABCDEF");
501     seq.setDatasetSequence(ds1);
502     seqs = new SequenceI[] { seq };
503     e = command.new Edit(Action.DELETE_GAP, seqs, 3, 1, '-');
504     command.addEdit(e);
505
506     /*
507      * Two edits for the second sequence
508      */
509     seq = new Sequence("", "FGHI--J");
510     SequenceI ds2 = new Sequence("", "FGHIJ");
511     seq.setDatasetSequence(ds2);
512     seqs = new SequenceI[] { seq };
513     e = command.new Edit(Action.DELETE_GAP, seqs, 2, 1, '-');
514     command.addEdit(e);
515     seq = new Sequence("", "FGHIJ");
516     seq.setDatasetSequence(ds2);
517     seqs = new SequenceI[] { seq };
518     e = command.new Edit(Action.DELETE_GAP, seqs, 4, 2, '-');
519     command.addEdit(e);
520
521     /*
522      * One edit for the third sequence.
523      */
524     seq = new Sequence("", "MNOPQ");
525     SequenceI ds3 = new Sequence("", "MNOPQ");
526     seq.setDatasetSequence(ds3);
527     seqs = new SequenceI[] { seq };
528     e = command.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
529     command.addEdit(e);
530
531     Map<SequenceI, SequenceI> unwound = command.priorState(false);
532     assertEquals(original1, unwound.get(ds1).getSequenceAsString());
533     assertEquals(original2, unwound.get(ds2).getSequenceAsString());
534     assertEquals(original3, unwound.get(ds3).getSequenceAsString());
535   }
536
537   /**
538    * Test that mimics 'remove all gapped columns' action. This generates a
539    * series Delete Gap edits that each act on all sequences that share a gapped
540    * column region.
541    */
542   @Test(groups = { "Functional" })
543   public void testPriorState_removeGappedCols()
544   {
545     EditCommand command = new EditCommand();
546     String original1 = "--ABC--DEF";
547     String original2 = "-G-HI--J";
548     String original3 = "-M-NO--PQ";
549
550     /*
551      * First edit deletes the first column.
552      */
553     SequenceI seq1 = new Sequence("", "-ABC--DEF");
554     SequenceI ds1 = new Sequence("", "ABCDEF");
555     seq1.setDatasetSequence(ds1);
556     SequenceI seq2 = new Sequence("", "G-HI--J");
557     SequenceI ds2 = new Sequence("", "GHIJ");
558     seq2.setDatasetSequence(ds2);
559     SequenceI seq3 = new Sequence("", "M-NO--PQ");
560     SequenceI ds3 = new Sequence("", "MNOPQ");
561     seq3.setDatasetSequence(ds3);
562     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3 };
563     Edit e = command.new Edit(Action.DELETE_GAP, seqs, 0, 1, '-');
564     command.addEdit(e);
565
566     /*
567      * Second edit deletes what is now columns 4 and 5.
568      */
569     seq1 = new Sequence("", "-ABCDEF");
570     seq1.setDatasetSequence(ds1);
571     seq2 = new Sequence("", "G-HIJ");
572     seq2.setDatasetSequence(ds2);
573     seq3 = new Sequence("", "M-NOPQ");
574     seq3.setDatasetSequence(ds3);
575     seqs = new SequenceI[] { seq1, seq2, seq3 };
576     e = command.new Edit(Action.DELETE_GAP, seqs, 4, 2, '-');
577     command.addEdit(e);
578
579     Map<SequenceI, SequenceI> unwound = command.priorState(false);
580     assertEquals(original1, unwound.get(ds1).getSequenceAsString());
581     assertEquals(original2, unwound.get(ds2).getSequenceAsString());
582     assertEquals(original3, unwound.get(ds3).getSequenceAsString());
583     assertEquals(ds1, unwound.get(ds1).getDatasetSequence());
584     assertEquals(ds2, unwound.get(ds2).getDatasetSequence());
585     assertEquals(ds3, unwound.get(ds3).getDatasetSequence());
586   }
587 }