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