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