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