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