2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
23 import static org.testng.AssertJUnit.assertNotNull;
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.gui.AlignFrame;
36 import jalview.gui.JvOptionPane;
37 import jalview.json.binding.biojson.v1.ColourSchemeMapper;
38 import jalview.schemes.ColourSchemeI;
39 import jalview.schemes.ResidueColourScheme;
41 import java.io.IOException;
42 import java.util.ArrayList;
43 import java.util.HashMap;
44 import java.util.List;
46 import org.testng.Assert;
47 import org.testng.AssertJUnit;
48 import org.testng.annotations.AfterTest;
49 import org.testng.annotations.BeforeClass;
50 import org.testng.annotations.BeforeMethod;
51 import org.testng.annotations.BeforeTest;
52 import org.testng.annotations.Test;
54 public class JSONFileTest
57 @BeforeClass(alwaysRun = true)
58 public void setUpJvOptionPane()
60 JvOptionPane.setInteractiveMode(false);
61 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
64 private int TEST_SEQ_HEIGHT = 0;
66 private int TEST_GRP_HEIGHT = 0;
68 private int TEST_ANOT_HEIGHT = 0;
70 private int TEST_CS_HEIGHT = 0;
72 private String TEST_JSON_FILE = "examples/example.json";
74 private Alignment alignment;
76 private HashMap<String, SequenceI> expectedSeqs = new HashMap<>();
78 private HashMap<String, AlignmentAnnotation> expectedAnnots = new HashMap<>();
80 private HashMap<String, SequenceGroup> expectedGrps = new HashMap<>();
82 private HiddenColumns expectedColSel = new HiddenColumns();
84 private SequenceI[] expectedHiddenSeqs = new SequenceI[1];
86 private AlignmentI testAlignment;
88 private int passedCount;
90 private JSONFile testJsonFile;
94 private AlignExportSettingI exportSettings;
96 @BeforeTest(alwaysRun = true)
97 public void setup() throws Exception
99 // create and add sequences
100 Sequence[] seqs = new Sequence[5];
101 seqs[0] = new Sequence("FER_CAPAN",
102 "SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALF", 3, 34);
103 seqs[1] = new Sequence("FER1_SOLLC",
104 "SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALF", 3, 34);
105 seqs[2] = new Sequence("Q93XJ9_SOLTU",
106 "SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALF", 3, 34);
107 seqs[3] = new Sequence("FER1_PEA",
108 "ALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFL", 6, 37);
109 seqs[4] = new Sequence("Q7XA98_TRIPR",
110 "ALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGF", 6, 39);
112 SequenceI hiddenSeq = new Sequence("FER_TOCH",
113 "FILGTMISKSFLFRKPAVTSL-KAISNVGE--ALF", 3, 34);
114 expectedHiddenSeqs[0] = hiddenSeq;
116 // create and add sequence features
117 SequenceFeature seqFeature2 = new SequenceFeature("feature_x",
118 "desciption", "status", 6, 15, "Jalview");
119 SequenceFeature seqFeature3 = new SequenceFeature("feature_x",
120 "desciption", "status", 9, 18, "Jalview");
121 SequenceFeature seqFeature4 = new SequenceFeature("feature_x",
122 "desciption", "status", 9, 18, "Jalview");
123 seqs[2].addSequenceFeature(seqFeature2);
124 seqs[3].addSequenceFeature(seqFeature3);
125 seqs[4].addSequenceFeature(seqFeature4);
127 for (Sequence seq : seqs)
129 seq.createDatasetSequence();
130 expectedSeqs.put(seq.getName(), seq);
133 // create and add a sequence group
134 List<SequenceI> grpSeqs = new ArrayList<>();
135 grpSeqs.add(seqs[1]);
136 grpSeqs.add(seqs[2]);
137 grpSeqs.add(seqs[3]);
138 grpSeqs.add(seqs[4]);
139 SequenceGroup seqGrp = new SequenceGroup(grpSeqs,
141 null, true, true, false, 21, 29);
142 ColourSchemeI scheme = ColourSchemeMapper.getJalviewColourScheme(
144 seqGrp.cs.setColourScheme(scheme);
145 seqGrp.setShowNonconserved(false);
146 seqGrp.setDescription(null);
148 expectedGrps.put(seqGrp.getName(), seqGrp);
150 // create and add annotation
151 Annotation[] annot = new Annotation[35];
152 annot[0] = new Annotation("", "", '\u0000', 0);
153 annot[1] = new Annotation("", "", '\u0000', 0);
154 annot[2] = new Annotation("α", "", 'H', 0);
155 annot[3] = new Annotation("α", "", 'H', 0);
156 annot[4] = new Annotation("α", "", 'H', 0);
157 annot[5] = new Annotation("", "", '\u0000', 0);
158 annot[6] = new Annotation("", "", '\u0000', 0);
159 annot[7] = new Annotation("", "", '\u0000', 0);
160 annot[8] = new Annotation("β", "", 'E', 0);
161 annot[9] = new Annotation("β", "", 'E', 0);
162 annot[10] = new Annotation("β", "", 'E', 0);
163 annot[11] = new Annotation("β", "", 'E', 0);
164 annot[12] = new Annotation("β", "", 'E', 0);
165 annot[13] = new Annotation("β", "", 'E', 0);
166 annot[14] = new Annotation("β", "", 'E', 0);
167 annot[15] = new Annotation("β", "", 'E', 0);
168 annot[16] = new Annotation("", "", '\u0000', 0);
169 annot[17] = new Annotation("", "", '\u0000', 0);
170 annot[18] = new Annotation("", "", '\u0000', 0);
171 annot[19] = new Annotation("", "", '\u0000', 0);
172 annot[20] = new Annotation("", "", '\u0000', 0);
173 annot[21] = new Annotation("", "", '\u0000', 0);
174 annot[22] = new Annotation("", "", '\u0000', 0);
175 annot[23] = new Annotation("", "", '\u0000', 0);
176 annot[24] = new Annotation("", "", '\u0000', 0);
177 annot[25] = new Annotation("", "", '\u0000', 0);
178 annot[26] = new Annotation("α", "", 'H', 0);
179 annot[27] = new Annotation("α", "", 'H', 0);
180 annot[28] = new Annotation("α", "", 'H', 0);
181 annot[29] = new Annotation("α", "", 'H', 0);
182 annot[30] = new Annotation("α", "", 'H', 0);
183 annot[31] = new Annotation("", "", '\u0000', 0);
184 annot[32] = new Annotation("", "", '\u0000', 0);
185 annot[33] = new Annotation("", "", '\u0000', 0);
186 annot[34] = new Annotation("", "", '\u0000', 0);
188 AlignmentAnnotation alignAnnot = new AlignmentAnnotation(
189 "Secondary Structure", "New description", annot);
190 expectedAnnots.put(alignAnnot.label, alignAnnot);
192 expectedColSel.hideColumns(32, 33);
193 expectedColSel.hideColumns(34, 34);
195 TEST_SEQ_HEIGHT = expectedSeqs.size();
196 TEST_GRP_HEIGHT = expectedGrps.size();
197 TEST_ANOT_HEIGHT = expectedAnnots.size();
198 TEST_CS_HEIGHT = expectedColSel.getHiddenColumnsCopy().size();
200 exportSettings = new AlignExportSettingI()
203 public boolean isExportHiddenSequences()
209 public boolean isExportHiddenColumns()
215 public boolean isExportGroups()
221 public boolean isExportFeatures()
227 public boolean isExportAnnotations()
233 public boolean isCancelled()
239 AppletFormatAdapter formatAdapter = new AppletFormatAdapter();
242 alignment = (Alignment) formatAdapter.readFile(TEST_JSON_FILE,
243 DataSourceType.FILE, FileFormat.Json);
244 jf = (JSONFile) formatAdapter.getAlignFile();
246 AlignFrame af = new AlignFrame(alignment, jf.getHiddenSequences(),
247 jf.getHiddenColumns(), AlignFrame.DEFAULT_WIDTH,
248 AlignFrame.DEFAULT_HEIGHT);
249 af.getViewport().setShowSequenceFeatures(jf.isShowSeqFeatures());
250 String colourSchemeName = jf.getGlobalColourScheme();
251 ColourSchemeI cs = ColourSchemeMapper.getJalviewColourScheme(
252 colourSchemeName, alignment);
254 af.getViewport().setFeaturesDisplayed(jf.getDisplayedFeatures());
256 formatAdapter = new AppletFormatAdapter(af.alignPanel, exportSettings);
257 String jsonOutput = formatAdapter.formatSequences(FileFormat.Json,
258 af.alignPanel.getAlignment(), false);
260 formatAdapter = new AppletFormatAdapter();
261 testAlignment = formatAdapter.readFile(jsonOutput,
262 DataSourceType.PASTE, FileFormat.Json);
263 testJsonFile = (JSONFile) formatAdapter.getAlignFile();
264 // System.out.println(jsonOutput);
265 } catch (IOException e)
272 @BeforeMethod(alwaysRun = true)
273 public void methodSetup()
278 @AfterTest(alwaysRun = true)
279 public void tearDown() throws Exception
284 expectedAnnots = null;
286 testAlignment = null;
290 @Test(groups = { "Functional" })
291 public void roundTripTest()
293 assertNotNull("JSON roundtrip test failed!", testJsonFile);
296 @Test(groups = { "Functional" })
297 public void testSeqParsed()
299 assertNotNull("Couldn't read supplied alignment data.", testAlignment);
300 Assert.assertNotNull(testAlignment.getSequences());
301 for (SequenceI seq : testAlignment.getSequences())
303 SequenceI expectedSeq = expectedSeqs.get(seq.getName());
304 AssertJUnit.assertTrue(
305 "Failed Sequence Test for >>> " + seq.getName(),
306 isSeqMatched(expectedSeq, seq));
309 AssertJUnit.assertEquals("Some Sequences did not pass the test",
310 TEST_SEQ_HEIGHT, passedCount);
313 @Test(groups = { "Functional" })
314 public void hiddenColsTest()
316 HiddenColumns cs = testJsonFile.getHiddenColumns();
317 Assert.assertNotNull(cs);
318 Assert.assertNotNull(cs.getHiddenColumnsCopy());
319 List<int[]> hiddenCols = cs.getHiddenColumnsCopy();
320 Assert.assertEquals(hiddenCols.size(), TEST_CS_HEIGHT);
321 Assert.assertEquals(hiddenCols.get(0), expectedColSel
322 .getHiddenColumnsCopy().get(0),
323 "Mismatched hidden columns!");
326 @Test(groups = { "Functional" })
327 public void hiddenSeqsTest()
329 Assert.assertNotNull(testJsonFile.getHiddenSequences(),
330 "Hidden sequence Expected but found Null");
331 Assert.assertEquals(jf.getHiddenSequences().length, 1,
335 @Test(groups = { "Functional" })
336 public void colorSchemeTest()
338 Assert.assertNotNull(testJsonFile.getGlobalColourScheme(),
339 "Colourscheme is null, parsing failed!");
340 Assert.assertEquals(testJsonFile.getGlobalColourScheme(), "Zappo",
341 "Zappo colour scheme expected!");
345 * Test for bug JAL-2489, NPE when exporting BioJSON with global colour
346 * scheme, and a group colour scheme, set as 'None'
348 @Test(groups = { "Functional" })
349 public void testBioJSONRoundTripWithColourSchemeNone()
351 AppletFormatAdapter formatAdapter = new AppletFormatAdapter();
353 Alignment _alignment;
356 // load example BioJSON file
357 _alignment = (Alignment) formatAdapter.readFile(TEST_JSON_FILE,
358 DataSourceType.FILE, FileFormat.Json);
359 JSONFile bioJsonFile = (JSONFile) formatAdapter.getAlignFile();
360 AlignFrame alignFrame = new AlignFrame(_alignment,
361 bioJsonFile.getHiddenSequences(),
362 bioJsonFile.getHiddenColumns(), AlignFrame.DEFAULT_WIDTH,
363 AlignFrame.DEFAULT_HEIGHT);
366 * Create a group on the alignment;
367 * Change global and group colour scheme to 'None' and perform round trip
369 SequenceGroup sg = new SequenceGroup();
370 sg.addSequence(_alignment.getSequenceAt(0), false);
371 sg.setColourScheme(null);
372 ColourSchemeI cs = ColourSchemeMapper.getJalviewColourScheme(
373 ResidueColourScheme.NONE, _alignment);
374 alignFrame.changeColour(cs);
375 alignFrame.getViewport().setFeaturesDisplayed(
376 bioJsonFile.getDisplayedFeatures());
377 formatAdapter = new AppletFormatAdapter(alignFrame.alignPanel,
379 // export BioJSON string
380 String jsonOutput = formatAdapter.formatSequences(FileFormat.Json,
381 alignFrame.alignPanel.getAlignment(), false);
382 // read back Alignment from BioJSON string
383 formatAdapter = new AppletFormatAdapter();
384 formatAdapter.readFile(jsonOutput, DataSourceType.PASTE,
386 // assert 'None' colour scheme is retained after round trip
387 JSONFile _bioJsonFile = (JSONFile) formatAdapter.getAlignFile();
388 Assert.assertEquals(_bioJsonFile.getGlobalColourScheme(),
389 ResidueColourScheme.NONE);
390 } catch (IOException e)
396 @Test(groups = { "Functional" })
397 public void isShowSeqFeaturesSet()
399 Assert.assertTrue(testJsonFile.isShowSeqFeatures(),
400 "Sequence feature isDisplayed setting expected to be true");
403 @Test(groups = { "Functional" })
404 public void testGrpParsed()
406 Assert.assertNotNull(testAlignment.getGroups());
407 for (SequenceGroup seqGrp : testAlignment.getGroups())
409 SequenceGroup expectedGrp = expectedGrps.get(seqGrp.getName());
410 AssertJUnit.assertTrue(
411 "Failed SequenceGroup Test for >>> " + seqGrp.getName(),
412 isGroupMatched(expectedGrp, seqGrp));
415 AssertJUnit.assertEquals("Some SequenceGroups did not pass the test",
416 TEST_GRP_HEIGHT, passedCount);
419 @Test(groups = { "Functional" })
420 public void testAnnotationParsed()
422 Assert.assertNotNull(testAlignment.getAlignmentAnnotation());
423 for (AlignmentAnnotation annot : testAlignment.getAlignmentAnnotation())
425 AlignmentAnnotation expectedAnnot = expectedAnnots.get(annot.label);
426 AssertJUnit.assertTrue("Failed AlignmentAnnotation Test for >>> "
427 + annot.label, isAnnotationMatched(expectedAnnot, annot));
430 AssertJUnit.assertEquals("Some Sequences did not pass the test",
431 TEST_ANOT_HEIGHT, passedCount);
434 public boolean isAnnotationMatched(AlignmentAnnotation eAnnot,
435 AlignmentAnnotation annot)
437 if (!eAnnot.label.equals(annot.label)
438 || !eAnnot.description.equals(annot.description)
439 || eAnnot.annotations.length != annot.annotations.length)
444 for (int x = 0; x < annot.annotations.length; x++)
446 Annotation y = annot.annotations[x];
447 Annotation z = annot.annotations[x];
449 if (!y.displayCharacter.equals(z.displayCharacter)
450 || y.value != z.value
451 || y.secondaryStructure != z.secondaryStructure)
459 public boolean isSeqMatched(SequenceI expectedSeq, SequenceI actualSeq)
461 System.out.println("Testing >>> " + actualSeq.getName());
463 if (expectedSeq.getName().equals(actualSeq.getName())
464 && expectedSeq.getSequenceAsString().equals(
465 actualSeq.getSequenceAsString())
466 && expectedSeq.getStart() == actualSeq.getStart()
467 && expectedSeq.getEnd() == actualSeq.getEnd()
468 && featuresMatched(expectedSeq, actualSeq))
475 public boolean isGroupMatched(SequenceGroup expectedGrp,
476 SequenceGroup actualGrp)
479 System.out.println("Testing >>> " + actualGrp.getName());
480 System.out.println(expectedGrp.getName() + " | " + actualGrp.getName());
481 System.out.println(expectedGrp.getColourText() + " | "
482 + actualGrp.getColourText());
483 System.out.println(expectedGrp.getDisplayBoxes() + " | "
484 + actualGrp.getDisplayBoxes());
485 System.out.println(expectedGrp.getIgnoreGapsConsensus() + " | "
486 + actualGrp.getIgnoreGapsConsensus());
487 System.out.println(expectedGrp.getSequences().size() + " | "
488 + actualGrp.getSequences().size());
489 System.out.println(expectedGrp.getStartRes() + " | "
490 + actualGrp.getStartRes());
491 System.out.println(expectedGrp.getEndRes() + " | "
492 + actualGrp.getEndRes());
493 System.out.println(expectedGrp.cs + " | " + actualGrp.cs);
495 if (expectedGrp.getName().equals(actualGrp.getName())
496 && expectedGrp.getColourText() == actualGrp.getColourText()
497 && expectedGrp.getDisplayBoxes() == actualGrp.getDisplayBoxes()
498 && expectedGrp.getIgnoreGapsConsensus() == actualGrp
499 .getIgnoreGapsConsensus()
500 && (expectedGrp.cs.getClass().equals(actualGrp.cs.getClass()))
501 && expectedGrp.getSequences().size() == actualGrp
502 .getSequences().size()
503 && expectedGrp.getStartRes() == actualGrp.getStartRes()
504 && expectedGrp.getEndRes() == actualGrp.getEndRes())
511 private boolean featuresMatched(SequenceI seq1, SequenceI seq2)
513 boolean matched = false;
516 if (seq1 == null && seq2 == null)
521 SequenceFeature[] inFeature = seq1.getSequenceFeatures();
522 SequenceFeature[] outFeature = seq2.getSequenceFeatures();
524 if (inFeature == null && outFeature == null)
528 else if ((inFeature == null && outFeature != null)
529 || (inFeature != null && outFeature == null))
534 int testSize = inFeature.length;
535 int matchedCount = 0;
536 for (SequenceFeature in : inFeature)
538 for (SequenceFeature out : outFeature)
540 System.out.println(out.getType() + " | " + in.getType());
541 System.out.println(out.getBegin() + " | " + in.getBegin());
542 System.out.println(out.getEnd() + " | " + in.getEnd());
544 if (inFeature.length == outFeature.length
545 && in.getBegin() == out.getBegin()
546 && in.getEnd() == out.getEnd()
547 && in.getScore() == out.getScore()
548 && in.getFeatureGroup().equals(out.getFeatureGroup())
549 && in.getType().equals(out.getType()))
556 System.out.println("matched count >>>>>> " + matchedCount);
557 if (testSize == matchedCount)
561 } catch (Exception e)
565 // System.out.println(">>>>>>>>>>>>>> features matched : " + matched);
570 * Test group roundtrip with null (None) group colour scheme
572 * @throws IOException
574 @Test(groups = { "Functional" })
575 public void testGrpParsed_colourNone() throws IOException
577 AlignmentI copy = new Alignment(testAlignment);
578 SequenceGroup sg = testAlignment.getGroups().get(0);
579 SequenceGroup copySg = new SequenceGroup(new ArrayList<SequenceI>(),
581 null, sg.getDisplayBoxes(), sg.getDisplayText(),
582 sg.getColourText(), sg.getStartRes(), sg.getEndRes());
583 for (SequenceI seq : sg.getSequences())
585 int seqIndex = testAlignment.findIndex(seq);
586 copySg.addSequence(copy.getSequenceAt(seqIndex), false);
588 copy.addGroup(copySg);
590 AlignFrame af = new AlignFrame(copy, copy.getWidth(), copy.getHeight());
591 AppletFormatAdapter formatAdapter = new AppletFormatAdapter(
593 String jsonOutput = formatAdapter.formatSequences(FileFormat.Json,
595 formatAdapter = new AppletFormatAdapter();
596 AlignmentI newAlignment = formatAdapter.readFile(jsonOutput,
597 DataSourceType.PASTE, FileFormat.Json);
599 Assert.assertNotNull(newAlignment.getGroups());
600 for (SequenceGroup seqGrp : newAlignment.getGroups())
602 SequenceGroup expectedGrp = expectedGrps.get(seqGrp.getName());
603 AssertJUnit.assertTrue(
604 "Failed SequenceGroup Test for >>> " + seqGrp.getName(),
605 isGroupMatched(expectedGrp, seqGrp));
608 AssertJUnit.assertEquals("Some SequenceGroups did not pass the test",
609 TEST_GRP_HEIGHT, passedCount);