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