b43f3aaf4031e8e8f62da2d98b21d5e3321ec271
[jalview.git] / test / jalview / io / JSONFileTest.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
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.
11  *  
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.
16  * 
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.
20  */
21 package jalview.io;
22
23 import static org.testng.AssertJUnit.assertNotNull;
24
25 import jalview.api.AlignExportSettingsI;
26 import jalview.datamodel.AlignExportSettingsAdapter;
27 import jalview.datamodel.Alignment;
28 import jalview.datamodel.AlignmentAnnotation;
29 import jalview.datamodel.AlignmentI;
30 import jalview.datamodel.Annotation;
31 import jalview.datamodel.HiddenColumns;
32 import jalview.datamodel.Sequence;
33 import jalview.datamodel.SequenceFeature;
34 import jalview.datamodel.SequenceGroup;
35 import jalview.datamodel.SequenceI;
36 import jalview.datamodel.features.SequenceFeatures;
37 import jalview.gui.AlignFrame;
38 import jalview.gui.Desktop;
39 import jalview.gui.JvOptionPane;
40 import jalview.json.binding.biojson.v1.ColourSchemeMapper;
41 import jalview.schemes.ColourSchemeI;
42 import jalview.schemes.ResidueColourScheme;
43
44 import java.io.IOException;
45 import java.util.ArrayList;
46 import java.util.HashMap;
47 import java.util.Iterator;
48 import java.util.List;
49 import java.util.Map;
50
51 import org.testng.Assert;
52 import org.testng.AssertJUnit;
53 import org.testng.annotations.AfterTest;
54 import org.testng.annotations.BeforeClass;
55 import org.testng.annotations.BeforeMethod;
56 import org.testng.annotations.BeforeTest;
57 import org.testng.annotations.Test;
58
59 public class JSONFileTest
60 {
61
62   @BeforeClass(alwaysRun = true)
63   public void setUpJvOptionPane()
64   {
65     JvOptionPane.setInteractiveMode(false);
66     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
67   }
68
69   private int TEST_SEQ_HEIGHT = 0;
70
71   private int TEST_GRP_HEIGHT = 0;
72
73   private int TEST_ANOT_HEIGHT = 0;
74
75   private int TEST_CS_HEIGHT = 0;
76
77   private String TEST_JSON_FILE = "examples/example.json";
78
79   private Alignment alignment;
80
81   private HashMap<String, SequenceI> expectedSeqs = new HashMap<>();
82
83   private HashMap<String, AlignmentAnnotation> expectedAnnots = new HashMap<>();
84
85   private HashMap<String, SequenceGroup> expectedGrps = new HashMap<>();
86
87   private HiddenColumns expectedColSel = new HiddenColumns();
88
89   private SequenceI[] expectedHiddenSeqs = new SequenceI[1];
90
91   private AlignmentI testAlignment;
92
93   private int passedCount;
94
95   private JSONFile testJsonFile;
96
97   private JSONFile jf;
98
99   private AlignExportSettingsI exportSettings;
100
101   @BeforeTest(alwaysRun = true)
102   public void setup() throws Exception
103   {
104
105     Desktop.getInstanceOnly(); // Prevents Desktop.checkURLLinks();
106     /*
107      * construct expected values
108      * nb this have to match the data in examples/example.json
109      */
110     // create and add sequences
111     Sequence[] seqs = new Sequence[5];
112     seqs[0] = new Sequence("FER_CAPAN",
113             "SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALF", 3, 34);
114     seqs[1] = new Sequence("FER1_SOLLC",
115             "SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALF", 3, 34);
116     seqs[2] = new Sequence("Q93XJ9_SOLTU",
117             "SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALF", 3, 34);
118     seqs[3] = new Sequence("FER1_PEA",
119             "ALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFL", 6, 37);
120     seqs[4] = new Sequence("Q7XA98_TRIPR",
121             "ALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGF", 6, 39);
122
123     SequenceI hiddenSeq = new Sequence("FER_TOCH",
124             "FILGTMISKSFLFRKPAVTSL-KAISNVGE--ALF", 3, 34);
125     expectedHiddenSeqs[0] = hiddenSeq;
126
127     // create and add sequence features
128     SequenceFeature seqFeature2 = new SequenceFeature("feature_x",
129             "theDesc", 6, 15, "Jalview");
130     SequenceFeature seqFeature3 = new SequenceFeature("feature_x",
131             "theDesc", 9, 18, "Jalview");
132     SequenceFeature seqFeature4 = new SequenceFeature("feature_x",
133             "theDesc", 9, 18, "Jalview");
134     // non-positional feature:
135     SequenceFeature seqFeature5 = new SequenceFeature("Domain",
136             "My description", 0, 0, "Pfam");
137     seqs[2].addSequenceFeature(seqFeature2);
138     seqs[3].addSequenceFeature(seqFeature3);
139     seqs[4].addSequenceFeature(seqFeature4);
140     seqs[2].addSequenceFeature(seqFeature5);
141
142     for (Sequence seq : seqs)
143     {
144       seq.createDatasetSequence();
145       expectedSeqs.put(seq.getName(), seq);
146     }
147
148     // create and add a sequence group
149     List<SequenceI> grpSeqs = new ArrayList<>();
150     grpSeqs.add(seqs[1]);
151     grpSeqs.add(seqs[2]);
152     grpSeqs.add(seqs[3]);
153     grpSeqs.add(seqs[4]);
154     SequenceGroup seqGrp = new SequenceGroup(grpSeqs,
155             "JGroup:1883305585",
156             null, true, true, false, 21, 29);
157     ColourSchemeI scheme = ColourSchemeMapper.getJalviewColourScheme(
158             "zappo", seqGrp);
159     seqGrp.cs.setColourScheme(scheme);
160     seqGrp.setShowNonconserved(false);
161     seqGrp.setDescription(null);
162
163     expectedGrps.put(seqGrp.getName(), seqGrp);
164
165     // create and add annotation
166     Annotation[] annot = new Annotation[35];
167     annot[0] = new Annotation("", "", '\u0000', 0);
168     annot[1] = new Annotation("", "", '\u0000', 0);
169     annot[2] = new Annotation("α", "", 'H', 0);
170     annot[3] = new Annotation("α", "", 'H', 0);
171     annot[4] = new Annotation("α", "", 'H', 0);
172     annot[5] = new Annotation("", "", '\u0000', 0);
173     annot[6] = new Annotation("", "", '\u0000', 0);
174     annot[7] = new Annotation("", "", '\u0000', 0);
175     annot[8] = new Annotation("β", "", 'E', 0);
176     annot[9] = new Annotation("β", "", 'E', 0);
177     annot[10] = new Annotation("β", "", 'E', 0);
178     annot[11] = new Annotation("β", "", 'E', 0);
179     annot[12] = new Annotation("β", "", 'E', 0);
180     annot[13] = new Annotation("β", "", 'E', 0);
181     annot[14] = new Annotation("β", "", 'E', 0);
182     annot[15] = new Annotation("β", "", 'E', 0);
183     annot[16] = new Annotation("", "", '\u0000', 0);
184     annot[17] = new Annotation("", "", '\u0000', 0);
185     annot[18] = new Annotation("", "", '\u0000', 0);
186     annot[19] = new Annotation("", "", '\u0000', 0);
187     annot[20] = new Annotation("", "", '\u0000', 0);
188     annot[21] = new Annotation("", "", '\u0000', 0);
189     annot[22] = new Annotation("", "", '\u0000', 0);
190     annot[23] = new Annotation("", "", '\u0000', 0);
191     annot[24] = new Annotation("", "", '\u0000', 0);
192     annot[25] = new Annotation("", "", '\u0000', 0);
193     annot[26] = new Annotation("α", "", 'H', 0);
194     annot[27] = new Annotation("α", "", 'H', 0);
195     annot[28] = new Annotation("α", "", 'H', 0);
196     annot[29] = new Annotation("α", "", 'H', 0);
197     annot[30] = new Annotation("α", "", 'H', 0);
198     annot[31] = new Annotation("", "", '\u0000', 0);
199     annot[32] = new Annotation("", "", '\u0000', 0);
200     annot[33] = new Annotation("", "", '\u0000', 0);
201     annot[34] = new Annotation("", "", '\u0000', 0);
202
203     AlignmentAnnotation alignAnnot = new AlignmentAnnotation(
204             "Secondary Structure", "New description", annot);
205     expectedAnnots.put(alignAnnot.label, alignAnnot);
206
207     expectedColSel.hideColumns(32, 33);
208     expectedColSel.hideColumns(34, 34);
209
210     TEST_SEQ_HEIGHT = expectedSeqs.size();
211     TEST_GRP_HEIGHT = expectedGrps.size();
212     TEST_ANOT_HEIGHT = expectedAnnots.size();
213     TEST_CS_HEIGHT = expectedColSel.getNumberOfRegions();
214
215     exportSettings = new AlignExportSettingsAdapter(true);
216
217     AppletFormatAdapter formatAdapter = new AppletFormatAdapter();
218     try
219     {
220       alignment = (Alignment) formatAdapter.readFile(TEST_JSON_FILE,
221               DataSourceType.FILE, FileFormat.Json);
222       jf = (JSONFile) formatAdapter.getAlignFile();
223
224       AlignFrame af = new AlignFrame(alignment, jf.getHiddenSequences(),
225               jf.getHiddenColumns(), AlignFrame.DEFAULT_WIDTH,
226               AlignFrame.DEFAULT_HEIGHT);
227       af.getViewport().setShowSequenceFeatures(jf.isShowSeqFeatures());
228       String colourSchemeName = jf.getGlobalColourScheme();
229       ColourSchemeI cs = ColourSchemeMapper.getJalviewColourScheme(
230               colourSchemeName, alignment);
231       af.changeColour(cs);
232       af.getViewport().setFeaturesDisplayed(jf.getDisplayedFeatures());
233
234       formatAdapter = new AppletFormatAdapter(af.alignPanel, exportSettings);
235       String jsonOutput = formatAdapter.formatSequences(FileFormat.Json,
236               af.alignPanel.getAlignment(), false);
237
238       formatAdapter = new AppletFormatAdapter();
239       testAlignment = formatAdapter.readFile(jsonOutput,
240               DataSourceType.PASTE, FileFormat.Json);
241       testJsonFile = (JSONFile) formatAdapter.getAlignFile();
242       System.out.println(jsonOutput);
243     } catch (IOException e)
244     {
245       e.printStackTrace();
246     }
247
248   }
249
250   @BeforeMethod(alwaysRun = true)
251   public void methodSetup()
252   {
253     passedCount = 0;
254   }
255
256   @AfterTest(alwaysRun = true)
257   public void tearDown() throws Exception
258   {
259     testJsonFile = null;
260     alignment = null;
261     expectedSeqs = null;
262     expectedAnnots = null;
263     expectedGrps = null;
264     testAlignment = null;
265     jf = null;
266   }
267
268   @Test(groups = { "Functional" })
269   public void roundTripTest()
270   {
271     assertNotNull("JSON roundtrip test failed!", testJsonFile);
272   }
273
274   @Test(groups = { "Functional" })
275   public void testSeqParsed()
276   {
277     assertNotNull("Couldn't read supplied alignment data.", testAlignment);
278     Assert.assertNotNull(testAlignment.getSequences());
279     for (SequenceI seq : testAlignment.getSequences())
280     {
281       SequenceI expectedSeq = expectedSeqs.get(seq.getName());
282       AssertJUnit.assertTrue(
283               "Failed Sequence Test  for >>> " + seq.getName(),
284               isSeqMatched(expectedSeq, seq));
285       passedCount++;
286     }
287     AssertJUnit.assertEquals("Some Sequences did not pass the test",
288             TEST_SEQ_HEIGHT, passedCount);
289   }
290
291   @Test(groups = { "Functional" })
292   public void hiddenColsTest()
293   {
294     HiddenColumns cs = testJsonFile.getHiddenColumns();
295     Assert.assertNotNull(cs);
296
297     Iterator<int[]> it = cs.iterator();
298     Iterator<int[]> colselit = expectedColSel.iterator();
299     Assert.assertTrue(it.hasNext());
300     Assert.assertEquals(cs.getNumberOfRegions(), TEST_CS_HEIGHT);
301     Assert.assertEquals(it.next(), colselit.next(),
302             "Mismatched hidden columns!");
303   }
304
305   @Test(groups = { "Functional" })
306   public void hiddenSeqsTest()
307   {
308     Assert.assertNotNull(testJsonFile.getHiddenSequences(),
309             "Hidden sequence Expected but found Null");
310     Assert.assertEquals(jf.getHiddenSequences().length, 1,
311             "Hidden sequence");
312   }
313
314   @Test(groups = { "Functional" })
315   public void colorSchemeTest()
316   {
317     Assert.assertNotNull(testJsonFile.getGlobalColourScheme(),
318             "Colourscheme is null, parsing failed!");
319     Assert.assertEquals(testJsonFile.getGlobalColourScheme(), "Zappo",
320             "Zappo colour scheme expected!");
321   }
322
323   /**
324    * Test for bug JAL-2489, NPE when exporting BioJSON with global colour
325    * scheme, and a group colour scheme, set as 'None'
326    */
327   @Test(groups = { "Functional" })
328   public void testBioJSONRoundTripWithColourSchemeNone()
329   {
330     AppletFormatAdapter formatAdapter = new AppletFormatAdapter();
331
332     Alignment _alignment;
333     try
334     {
335       // load example BioJSON file
336       _alignment = (Alignment) formatAdapter.readFile(TEST_JSON_FILE,
337               DataSourceType.FILE, FileFormat.Json);
338       JSONFile bioJsonFile = (JSONFile) formatAdapter.getAlignFile();
339       AlignFrame alignFrame = new AlignFrame(_alignment,
340               bioJsonFile.getHiddenSequences(),
341               bioJsonFile.getHiddenColumns(), AlignFrame.DEFAULT_WIDTH,
342               AlignFrame.DEFAULT_HEIGHT);
343
344       /*
345        * Create a group on the alignment;
346        * Change global and group colour scheme to 'None' and perform round trip
347        */
348       SequenceGroup sg = new SequenceGroup();
349       sg.addSequence(_alignment.getSequenceAt(0), false);
350       sg.setColourScheme(null);
351       ColourSchemeI cs = ColourSchemeMapper.getJalviewColourScheme(
352               ResidueColourScheme.NONE, _alignment);
353       alignFrame.changeColour(cs);
354       alignFrame.getViewport().setFeaturesDisplayed(
355               bioJsonFile.getDisplayedFeatures());
356       formatAdapter = new AppletFormatAdapter(alignFrame.alignPanel,
357               exportSettings);
358       // export BioJSON string
359       String jsonOutput = formatAdapter.formatSequences(FileFormat.Json,
360               alignFrame.alignPanel.getAlignment(), false);
361       // read back Alignment from BioJSON string
362       formatAdapter = new AppletFormatAdapter();
363       formatAdapter.readFile(jsonOutput, DataSourceType.PASTE,
364               FileFormat.Json);
365       // assert 'None' colour scheme is retained after round trip
366       JSONFile _bioJsonFile = (JSONFile) formatAdapter.getAlignFile();
367       Assert.assertEquals(_bioJsonFile.getGlobalColourScheme(),
368               ResidueColourScheme.NONE);
369     } catch (IOException e)
370     {
371       e.printStackTrace();
372     }
373   }
374
375   @Test(groups = { "Functional" })
376   public void isShowSeqFeaturesSet()
377   {
378     Assert.assertTrue(testJsonFile.isShowSeqFeatures(),
379             "Sequence feature isDisplayed setting expected to be true");
380   }
381
382   @Test(groups = { "Functional" })
383   public void testGrpParsed()
384   {
385     Assert.assertNotNull(testAlignment.getGroups());
386     for (SequenceGroup seqGrp : testAlignment.getGroups())
387     {
388       SequenceGroup expectedGrp = expectedGrps.get(seqGrp.getName());
389       AssertJUnit.assertTrue(
390               "Failed SequenceGroup Test for >>> " + seqGrp.getName(),
391               isGroupMatched(expectedGrp, seqGrp));
392       passedCount++;
393     }
394     AssertJUnit.assertEquals("Some SequenceGroups did not pass the test",
395             TEST_GRP_HEIGHT, passedCount);
396   }
397
398   @Test(groups = { "Functional" })
399   public void testAnnotationParsed()
400   {
401     Assert.assertNotNull(testAlignment.getAlignmentAnnotation());
402     for (AlignmentAnnotation annot : testAlignment.getAlignmentAnnotation())
403     {
404       AlignmentAnnotation expectedAnnot = expectedAnnots.get(annot.label);
405       AssertJUnit.assertTrue("Failed AlignmentAnnotation Test for >>> "
406               + annot.label, isAnnotationMatched(expectedAnnot, annot));
407       passedCount++;
408     }
409     AssertJUnit.assertEquals("Some Sequences did not pass the test",
410             TEST_ANOT_HEIGHT, passedCount);
411   }
412
413   public boolean isAnnotationMatched(AlignmentAnnotation eAnnot,
414           AlignmentAnnotation annot)
415   {
416     if (!eAnnot.label.equals(annot.label)
417             || !eAnnot.description.equals(annot.description)
418             || eAnnot.annotations.length != annot.annotations.length)
419     {
420       return false;
421     }
422
423     for (int x = 0; x < annot.annotations.length; x++)
424     {
425       Annotation y = annot.annotations[x];
426       Annotation z = annot.annotations[x];
427
428       if (!y.displayCharacter.equals(z.displayCharacter)
429               || y.value != z.value
430               || y.secondaryStructure != z.secondaryStructure)
431       {
432         return false;
433       }
434     }
435     return true;
436   }
437
438   boolean isSeqMatched(SequenceI expectedSeq, SequenceI actualSeq)
439   {
440     System.out.println("Testing >>> " + actualSeq.getName());
441
442     if (expectedSeq.getName().equals(actualSeq.getName())
443             && expectedSeq.getSequenceAsString().equals(
444                     actualSeq.getSequenceAsString())
445             && expectedSeq.getStart() == actualSeq.getStart()
446             && expectedSeq.getEnd() == actualSeq.getEnd()
447             && featuresMatched(expectedSeq, actualSeq))
448     {
449       return true;
450     }
451     return false;
452   }
453
454   public boolean isGroupMatched(SequenceGroup expectedGrp,
455           SequenceGroup actualGrp)
456   {
457
458     System.out.println("Testing >>> " + actualGrp.getName());
459     System.out.println(expectedGrp.getName() + " | " + actualGrp.getName());
460     System.out.println(expectedGrp.getColourText() + " | "
461             + actualGrp.getColourText());
462     System.out.println(expectedGrp.getDisplayBoxes() + " | "
463             + actualGrp.getDisplayBoxes());
464     System.out.println(expectedGrp.getIgnoreGapsConsensus() + " | "
465             + actualGrp.getIgnoreGapsConsensus());
466     System.out.println(expectedGrp.getSequences().size() + " | "
467             + actualGrp.getSequences().size());
468     System.out.println(expectedGrp.getStartRes() + " | "
469             + actualGrp.getStartRes());
470     System.out.println(expectedGrp.getEndRes() + " | "
471             + actualGrp.getEndRes());
472     System.out.println(expectedGrp.cs.getColourScheme() + " | "
473             + actualGrp.cs.getColourScheme());
474
475     boolean colourSchemeMatches = (expectedGrp.cs.getColourScheme() == null && actualGrp.cs
476             .getColourScheme() == null)
477             || expectedGrp.cs.getColourScheme().getClass()
478                     .equals(actualGrp.cs.getColourScheme().getClass());
479     if (expectedGrp.getName().equals(actualGrp.getName())
480             && expectedGrp.getColourText() == actualGrp.getColourText()
481             && expectedGrp.getDisplayBoxes() == actualGrp.getDisplayBoxes()
482             && expectedGrp.getIgnoreGapsConsensus() == actualGrp
483                     .getIgnoreGapsConsensus()
484             && colourSchemeMatches
485             && expectedGrp.getSequences().size() == actualGrp
486                     .getSequences().size()
487             && expectedGrp.getStartRes() == actualGrp.getStartRes()
488             && expectedGrp.getEndRes() == actualGrp.getEndRes())
489     {
490       return true;
491     }
492     return false;
493   }
494
495   private boolean featuresMatched(SequenceI seq1, SequenceI seq2)
496   {
497     try
498     {
499       if (seq1 == null && seq2 == null)
500       {
501         return true;
502       }
503
504       List<SequenceFeature> inFeature = seq1.getFeatures().getAllFeatures();
505       List<SequenceFeature> outFeature = seq2.getFeatures()
506               .getAllFeatures();
507
508       if (inFeature.size() != outFeature.size())
509       {
510         System.err.println("Feature count in: " + inFeature.size()
511                 + ", out: " + outFeature.size());
512         return false;
513       }
514
515       SequenceFeatures.sortFeatures(inFeature, true);
516       SequenceFeatures.sortFeatures(outFeature, true);
517       int i = 0;
518       for (SequenceFeature in : inFeature)
519       {
520         SequenceFeature out = outFeature.get(i);
521         /*
522         System.out.println(out.getType() + " | " + in.getType());
523         System.out.println(out.getBegin() + " | " + in.getBegin());
524         System.out.println(out.getEnd() + " | " + in.getEnd());
525         */
526         if (!in.equals(out))
527         {
528           System.err.println("Mismatch of " + in.toString() + " "
529                   + out.toString());
530           return false;
531         }
532         /*
533                 if (in.getBegin() == out.getBegin() && in.getEnd() == out.getEnd()
534                         && in.getScore() == out.getScore()
535                         && in.getFeatureGroup().equals(out.getFeatureGroup())
536                         && in.getType().equals(out.getType())
537                         && mapsMatch(in.otherDetails, out.otherDetails))
538                 {
539                 }
540                 else
541                 {
542                   System.err.println("Feature[" + i + "] mismatch, in: "
543                           + in.toString() + ", out: "
544                           + outFeature.get(i).toString());
545                   return false;
546                 }
547                 */
548         i++;
549       }
550     } catch (Exception e)
551     {
552       e.printStackTrace();
553     }
554     // System.out.println(">>>>>>>>>>>>>> features matched : " + matched);
555     return true;
556   }
557
558   boolean mapsMatch(Map<String, Object> m1, Map<String, Object> m2)
559   {
560     if (m1 == null || m2 == null)
561     {
562       if (m1 != null || m2 != null)
563       {
564         System.err
565                 .println("only one SequenceFeature.otherDetails is not null");
566         return false;
567       }
568       else
569       {
570         return true;
571       }
572     }
573     if (m1.size() != m2.size())
574     {
575       System.err.println("otherDetails map different sizes");
576       return false;
577     }
578     for (String key : m1.keySet())
579     {
580       if (!m2.containsKey(key))
581       {
582         System.err.println(key + " in only one otherDetails");
583         return false;
584       }
585       if (m1.get(key) == null && m2.get(key) != null || m1.get(key) != null
586               && m2.get(key) == null || !m1.get(key).equals(m2.get(key)))
587       {
588         System.err.println(key + " values in otherDetails don't match");
589         return false;
590       }
591     }
592     return true;
593   }
594
595   /**
596    * Test group roundtrip with null (None) group colour scheme
597    * 
598    * @throws IOException
599    */
600   @Test(groups = { "Functional" })
601   public void testGrpParsed_colourNone() throws IOException
602   {
603     AlignmentI copy = new Alignment(testAlignment);
604     SequenceGroup sg = testAlignment.getGroups().get(0);
605     SequenceGroup copySg = new SequenceGroup(new ArrayList<SequenceI>(),
606             sg.getName(),
607             null, sg.getDisplayBoxes(), sg.getDisplayText(),
608             sg.getColourText(), sg.getStartRes(), sg.getEndRes());
609     for (SequenceI seq : sg.getSequences())
610     {
611       int seqIndex = testAlignment.findIndex(seq);
612       copySg.addSequence(copy.getSequenceAt(seqIndex), false);
613     }
614     copy.addGroup(copySg);
615
616     AlignFrame af = new AlignFrame(copy, copy.getWidth(), copy.getHeight());
617     AppletFormatAdapter formatAdapter = new AppletFormatAdapter(
618             af.alignPanel);
619     String jsonOutput = formatAdapter.formatSequences(FileFormat.Json,
620             copy, false);
621     formatAdapter = new AppletFormatAdapter();
622     AlignmentI newAlignment = formatAdapter.readFile(jsonOutput,
623             DataSourceType.PASTE, FileFormat.Json);
624
625     Assert.assertNotNull(newAlignment.getGroups());
626     for (SequenceGroup seqGrp : newAlignment.getGroups())
627     {
628       SequenceGroup expectedGrp = copySg;
629       AssertJUnit.assertTrue(
630               "Failed SequenceGroup Test for >>> " + seqGrp.getName(),
631               isGroupMatched(expectedGrp, seqGrp));
632       passedCount++;
633     }
634     AssertJUnit.assertEquals("Some SequenceGroups did not pass the test",
635             TEST_GRP_HEIGHT, passedCount);
636   }
637 }