JAL-1896 bugfix to enabled Jalview restore clustal, RNA Helices and T-Coffee colour...
[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.ColumnSelection;
31 import jalview.datamodel.Sequence;
32 import jalview.datamodel.SequenceFeature;
33 import jalview.datamodel.SequenceGroup;
34 import jalview.datamodel.SequenceI;
35 import jalview.gui.AlignFrame;
36 import jalview.json.binding.biojson.v1.ColourSchemeMapper;
37 import jalview.schemes.ColourSchemeI;
38 import jalview.schemes.ZappoColourScheme;
39
40 import java.io.IOException;
41 import java.util.ArrayList;
42 import java.util.HashMap;
43 import java.util.List;
44
45 import org.testng.Assert;
46 import org.testng.AssertJUnit;
47 import org.testng.annotations.AfterTest;
48 import org.testng.annotations.BeforeMethod;
49 import org.testng.annotations.BeforeTest;
50 import org.testng.annotations.Test;
51
52 public class JSONFileTest
53 {
54
55   private int TEST_SEQ_HEIGHT = 0;
56
57   private int TEST_GRP_HEIGHT = 0;
58
59   private int TEST_ANOT_HEIGHT = 0;
60
61   private int TEST_CS_HEIGHT = 0;
62
63   private String TEST_JSON_FILE = "examples/example.json";
64
65   private Alignment alignment;
66
67   private HashMap<String, SequenceI> expectedSeqs = new HashMap<String, SequenceI>();
68
69   private HashMap<String, AlignmentAnnotation> expectedAnnots = new HashMap<String, AlignmentAnnotation>();
70
71   private HashMap<String, SequenceGroup> expectedGrps = new HashMap<String, SequenceGroup>();
72
73   private ColumnSelection expectedColSel = new ColumnSelection();
74
75   private SequenceI[] expectedHiddenSeqs = new SequenceI[1];
76
77   private AlignmentI testAlignment;
78
79   private int passedCount;
80
81   private JSONFile testJsonFile;
82
83   private JSONFile jf;
84
85   @BeforeTest(alwaysRun = true)
86   public void setup() throws Exception
87   {
88     // create and add sequences
89     Sequence[] seqs = new Sequence[5];
90     seqs[0] = new Sequence("FER_CAPAN",
91             "SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALF", 3, 34);
92     seqs[1] = new Sequence("FER1_SOLLC",
93             "SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALF", 3, 34);
94     seqs[2] = new Sequence("Q93XJ9_SOLTU",
95             "SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALF", 3, 34);
96     seqs[3] = new Sequence("FER1_PEA",
97             "ALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFL", 6, 37);
98     seqs[4] = new Sequence("Q7XA98_TRIPR",
99             "ALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGF", 6, 39);
100
101     SequenceI hiddenSeq = new Sequence("FER_TOCH",
102             "FILGTMISKSFLFRKPAVTSL-KAISNVGE--ALF", 3, 34);
103     expectedHiddenSeqs[0] = hiddenSeq;
104
105     // create and add sequence features
106     SequenceFeature seqFeature2 = new SequenceFeature("feature_x",
107             "desciption", "status", 6, 15, "Jalview");
108     SequenceFeature seqFeature3 = new SequenceFeature("feature_x",
109             "desciption", "status", 9, 18, "Jalview");
110     SequenceFeature seqFeature4 = new SequenceFeature("feature_x",
111             "desciption", "status", 9, 18, "Jalview");
112     seqs[2].addSequenceFeature(seqFeature2);
113     seqs[3].addSequenceFeature(seqFeature3);
114     seqs[4].addSequenceFeature(seqFeature4);
115
116     for (Sequence seq : seqs)
117     {
118       seq.setDatasetSequence(seq);
119       expectedSeqs.put(seq.getName(), seq);
120     }
121
122     // create and add sequence groups
123     ArrayList<SequenceI> grpSeqs = new ArrayList<SequenceI>();
124     grpSeqs.add(seqs[1]);
125     grpSeqs.add(seqs[2]);
126     grpSeqs.add(seqs[3]);
127     grpSeqs.add(seqs[4]);
128     SequenceGroup seqGrp = new SequenceGroup(grpSeqs, "JGroup:1883305585",
129             null, true, true, false, 21, 29);
130     ColourSchemeI scheme = ColourSchemeMapper.getJalviewColourScheme(
131             "zappo", seqGrp);
132     seqGrp.cs = scheme;
133     seqGrp.setShowNonconserved(false);
134     seqGrp.setDescription(null);
135
136     expectedGrps.put(seqGrp.getName(), seqGrp);
137
138     // create and add annotation
139     Annotation[] annot = new Annotation[35];
140     annot[0] = new Annotation("", "", '\u0000', 0);
141     annot[1] = new Annotation("", "", '\u0000', 0);
142     annot[2] = new Annotation("α", "", 'H', 0);
143     annot[3] = new Annotation("α", "", 'H', 0);
144     annot[4] = new Annotation("α", "", 'H', 0);
145     annot[5] = new Annotation("", "", '\u0000', 0);
146     annot[6] = new Annotation("", "", '\u0000', 0);
147     annot[7] = new Annotation("", "", '\u0000', 0);
148     annot[8] = new Annotation("β", "", 'E', 0);
149     annot[9] = new Annotation("β", "", 'E', 0);
150     annot[10] = new Annotation("β", "", 'E', 0);
151     annot[11] = new Annotation("β", "", 'E', 0);
152     annot[12] = new Annotation("β", "", 'E', 0);
153     annot[13] = new Annotation("β", "", 'E', 0);
154     annot[14] = new Annotation("β", "", 'E', 0);
155     annot[15] = new Annotation("β", "", 'E', 0);
156     annot[16] = new Annotation("", "", '\u0000', 0);
157     annot[17] = new Annotation("", "", '\u0000', 0);
158     annot[18] = new Annotation("", "", '\u0000', 0);
159     annot[19] = new Annotation("", "", '\u0000', 0);
160     annot[20] = new Annotation("", "", '\u0000', 0);
161     annot[21] = new Annotation("", "", '\u0000', 0);
162     annot[22] = new Annotation("", "", '\u0000', 0);
163     annot[23] = new Annotation("", "", '\u0000', 0);
164     annot[24] = new Annotation("", "", '\u0000', 0);
165     annot[25] = new Annotation("", "", '\u0000', 0);
166     annot[26] = new Annotation("α", "", 'H', 0);
167     annot[27] = new Annotation("α", "", 'H', 0);
168     annot[28] = new Annotation("α", "", 'H', 0);
169     annot[29] = new Annotation("α", "", 'H', 0);
170     annot[30] = new Annotation("α", "", 'H', 0);
171     annot[31] = new Annotation("", "", '\u0000', 0);
172     annot[32] = new Annotation("", "", '\u0000', 0);
173     annot[33] = new Annotation("", "", '\u0000', 0);
174     annot[34] = new Annotation("", "", '\u0000', 0);
175
176     AlignmentAnnotation alignAnnot = new AlignmentAnnotation(
177             "Secondary Structure", "New description", annot);
178     expectedAnnots.put(alignAnnot.label, alignAnnot);
179
180     expectedColSel.hideColumns(32, 33);
181     expectedColSel.hideColumns(34, 34);
182
183     TEST_SEQ_HEIGHT = expectedSeqs.size();
184     TEST_GRP_HEIGHT = expectedGrps.size();
185     TEST_ANOT_HEIGHT = expectedAnnots.size();
186     TEST_CS_HEIGHT = expectedColSel.getHiddenColumns().size();
187
188     AlignExportSettingI exportSettings = new AlignExportSettingI()
189     {
190       @Override
191       public boolean isExportHiddenSequences()
192       {
193         return true;
194       }
195
196       @Override
197       public boolean isExportHiddenColumns()
198       {
199         return true;
200       }
201
202       @Override
203       public boolean isExportGroups()
204       {
205         return true;
206       }
207
208       @Override
209       public boolean isExportFeatures()
210       {
211         return true;
212       }
213
214       @Override
215       public boolean isExportAnnotations()
216       {
217         return true;
218       }
219
220       @Override
221       public boolean isCancelled()
222       {
223         return false;
224       }
225     };
226
227     AppletFormatAdapter formatAdapter = new AppletFormatAdapter();
228     try
229     {
230       alignment = (Alignment) formatAdapter.readFile(TEST_JSON_FILE,
231               AppletFormatAdapter.FILE, JSONFile.FILE_DESC);
232       jf = (JSONFile) formatAdapter.getAlignFile();
233
234       AlignFrame af = new AlignFrame(alignment, jf.getHiddenSequences(),
235               jf.getColumnSelection(), AlignFrame.DEFAULT_WIDTH,
236               AlignFrame.DEFAULT_HEIGHT);
237       af.getViewport().setShowSequenceFeatures(jf.isShowSeqFeatures());
238       af.changeColour(jf.getColourScheme());
239       af.getViewport().setFeaturesDisplayed(jf.getDisplayedFeatures());
240
241       formatAdapter = new AppletFormatAdapter(af.alignPanel, exportSettings);
242       String jsonOutput = formatAdapter.formatSequences(JSONFile.FILE_DESC,
243               af.alignPanel.getAlignment(), false);
244
245       formatAdapter = new AppletFormatAdapter();
246       testAlignment = formatAdapter.readFile(jsonOutput,
247               AppletFormatAdapter.PASTE, JSONFile.FILE_DESC);
248       testJsonFile = (JSONFile) formatAdapter.getAlignFile();
249       // System.out.println(jsonOutput);
250     } catch (IOException e)
251     {
252       e.printStackTrace();
253     }
254
255   }
256
257   @BeforeMethod(alwaysRun = true)
258   public void methodSetup()
259   {
260     passedCount = 0;
261   }
262
263   @AfterTest
264   public void tearDown() throws Exception
265   {
266     testJsonFile = null;
267     alignment = null;
268     expectedSeqs = null;
269     expectedAnnots = null;
270     expectedGrps = null;
271     testAlignment = null;
272     jf = null;
273   }
274
275   @Test(groups = { "Functional" })
276   public void roundTripTest()
277   {
278     assertNotNull("JSON roundtrip test failed!", testJsonFile);
279   }
280
281   @Test(groups = { "Functional" })
282   public void testSeqParsed()
283   {
284     assertNotNull("Couldn't read supplied alignment data.", testAlignment);
285     Assert.assertNotNull(testAlignment.getSequences());
286     for (SequenceI seq : testAlignment.getSequences())
287     {
288       SequenceI expectedSeq = expectedSeqs.get(seq.getName());
289       AssertJUnit.assertTrue(
290               "Failed Sequence Test  for >>> " + seq.getName(),
291               isSeqMatched(expectedSeq, seq));
292       passedCount++;
293     }
294     AssertJUnit.assertEquals("Some Sequences did not pass the test",
295             TEST_SEQ_HEIGHT, passedCount);
296   }
297
298   @Test(groups = { "Functional" })
299   public void hiddenColsTest()
300   {
301     ColumnSelection cs = testJsonFile.getColumnSelection();
302     Assert.assertNotNull(cs);
303     Assert.assertNotNull(cs.getHiddenColumns());
304     List<int[]> hiddenCols = cs.getHiddenColumns();
305     Assert.assertEquals(hiddenCols.size(), TEST_CS_HEIGHT);
306     Assert.assertEquals(hiddenCols, expectedColSel.getHiddenColumns(),
307             "Mismatched hidden columns!");
308   }
309
310   @Test(groups = { "Functional" })
311   public void hiddenSeqsTest()
312   {
313     Assert.assertNotNull(testJsonFile.getHiddenSequences(),
314             "Hidden sequence Expected but found Null");
315     Assert.assertEquals(jf.getHiddenSequences().length, 1, "Hidden sequece");
316   }
317
318   @Test(groups = { "Functional" })
319   public void colorSchemeTest()
320   {
321     Assert.assertNotNull(testJsonFile.getColourScheme(),
322             "Colourscheme is null, parsing failed!");
323     Assert.assertTrue(
324             testJsonFile.getColourScheme() instanceof ZappoColourScheme,
325             "Zappo colour scheme expected!");
326   }
327
328   @Test(groups = { "Functional" })
329   public void isShowSeqFeaturesSet()
330   {
331     Assert.assertTrue(testJsonFile.isShowSeqFeatures(),
332             "Sequence feature isDisplayed setting expected to be true");
333   }
334
335   @Test(groups = { "Functional" })
336   public void testGrpParsed()
337   {
338     Assert.assertNotNull(testAlignment.getGroups());
339     for (SequenceGroup seqGrp : testAlignment.getGroups())
340     {
341       SequenceGroup expectedGrp = expectedGrps.get(seqGrp.getName());
342       AssertJUnit.assertTrue(
343               "Failed SequenceGroup Test for >>> " + seqGrp.getName(),
344               isGroupMatched(expectedGrp, seqGrp));
345       passedCount++;
346     }
347     AssertJUnit.assertEquals("Some SequenceGroups did not pass the test",
348             TEST_GRP_HEIGHT, passedCount);
349   }
350
351   @Test(groups = { "Functional" })
352   public void testAnnotationParsed()
353   {
354     Assert.assertNotNull(testAlignment.getAlignmentAnnotation());
355     for (AlignmentAnnotation annot : testAlignment.getAlignmentAnnotation())
356     {
357       AlignmentAnnotation expectedAnnot = expectedAnnots.get(annot.label);
358       AssertJUnit.assertTrue("Failed AlignmentAnnotation Test for >>> "
359               + annot.label, isAnnotationMatched(expectedAnnot, annot));
360       passedCount++;
361     }
362     AssertJUnit.assertEquals("Some Sequences did not pass the test",
363             TEST_ANOT_HEIGHT, passedCount);
364   }
365
366   public boolean isAnnotationMatched(AlignmentAnnotation eAnnot,
367           AlignmentAnnotation annot)
368   {
369     if (!eAnnot.label.equals(annot.label)
370             || !eAnnot.description.equals(annot.description)
371             || eAnnot.annotations.length != annot.annotations.length)
372     {
373       return false;
374     }
375
376     for (int x = 0; x < annot.annotations.length; x++)
377     {
378       Annotation y = annot.annotations[x];
379       Annotation z = annot.annotations[x];
380
381       if (!y.displayCharacter.equals(z.displayCharacter)
382               || y.value != z.value
383               || y.secondaryStructure != z.secondaryStructure)
384       {
385         return false;
386       }
387     }
388     return true;
389   }
390
391   public boolean isSeqMatched(SequenceI expectedSeq, SequenceI actualSeq)
392   {
393     System.out.println("Testing >>> " + actualSeq.getName());
394
395     if (expectedSeq.getName().equals(actualSeq.getName())
396             && expectedSeq.getSequenceAsString().equals(
397                     actualSeq.getSequenceAsString())
398             && expectedSeq.getStart() == actualSeq.getStart()
399             && expectedSeq.getEnd() == actualSeq.getEnd()
400             && featuresMatched(expectedSeq, actualSeq))
401     {
402       return true;
403     }
404     return false;
405   }
406
407   public boolean isGroupMatched(SequenceGroup expectedGrp,
408           SequenceGroup actualGrp)
409   {
410
411     System.out.println("Testing >>> " + actualGrp.getName());
412     System.out.println(expectedGrp.getName() + " | " + actualGrp.getName());
413     System.out.println(expectedGrp.getColourText() + " | "
414             + actualGrp.getColourText());
415     System.out.println(expectedGrp.getDisplayBoxes() + " | "
416             + actualGrp.getDisplayBoxes());
417     System.out.println(expectedGrp.getIgnoreGapsConsensus() + " | "
418             + actualGrp.getIgnoreGapsConsensus());
419     System.out.println(expectedGrp.getSequences().size() + " | "
420             + actualGrp.getSequences().size());
421     System.out.println(expectedGrp.getStartRes() + " | "
422             + actualGrp.getStartRes());
423     System.out.println(expectedGrp.getEndRes() + " | "
424             + actualGrp.getEndRes());
425     System.out.println(expectedGrp.cs + " | " + actualGrp.cs);
426
427     if (expectedGrp.getName().equals(actualGrp.getName())
428             && expectedGrp.getColourText() == actualGrp.getColourText()
429             && expectedGrp.getDisplayBoxes() == actualGrp.getDisplayBoxes()
430             && expectedGrp.getIgnoreGapsConsensus() == actualGrp
431                     .getIgnoreGapsConsensus()
432             && (expectedGrp.cs.getClass().equals(actualGrp.cs.getClass()))
433             && expectedGrp.getSequences().size() == actualGrp
434                     .getSequences().size()
435             && expectedGrp.getStartRes() == actualGrp.getStartRes()
436             && expectedGrp.getEndRes() == actualGrp.getEndRes())
437     {
438       return true;
439     }
440     return false;
441   }
442
443   private boolean featuresMatched(SequenceI seq1, SequenceI seq2)
444   {
445     boolean matched = false;
446     try
447     {
448       if (seq1 == null && seq2 == null)
449       {
450         return true;
451       }
452
453       SequenceFeature[] inFeature = seq1.getSequenceFeatures();
454       SequenceFeature[] outFeature = seq2.getSequenceFeatures();
455
456       if (inFeature == null && outFeature == null)
457       {
458         return true;
459       }
460       else if ((inFeature == null && outFeature != null)
461               || (inFeature != null && outFeature == null))
462       {
463         return false;
464       }
465
466       int testSize = inFeature.length;
467       int matchedCount = 0;
468       for (SequenceFeature in : inFeature)
469       {
470         for (SequenceFeature out : outFeature)
471         {
472           System.out.println(out.getType() + " | " + in.getType());
473           System.out.println(out.getBegin() + " | " + in.getBegin());
474           System.out.println(out.getEnd() + " | " + in.getEnd());
475
476           if (inFeature.length == outFeature.length
477                   && in.getBegin() == out.getBegin()
478                   && in.getEnd() == out.getEnd()
479                   && in.getScore() == out.getScore()
480                   && in.getFeatureGroup().equals(out.getFeatureGroup())
481                   && in.getType().equals(out.getType()))
482           {
483
484             ++matchedCount;
485           }
486         }
487       }
488       System.out.println("matched count >>>>>> " + matchedCount);
489       if (testSize == matchedCount)
490       {
491         matched = true;
492       }
493     } catch (Exception e)
494     {
495       e.printStackTrace();
496     }
497     // System.out.println(">>>>>>>>>>>>>> features matched : " + matched);
498     return matched;
499   }
500 }