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