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