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.datamodel.features.SequenceFeatures;
36 import jalview.gui.AlignFrame;
37 import jalview.gui.JvOptionPane;
38 import jalview.json.binding.biojson.v1.ColourSchemeMapper;
39 import jalview.schemes.ColourSchemeI;
40 import jalview.schemes.ResidueColourScheme;
42 import java.io.IOException;
43 import java.util.ArrayList;
44 import java.util.HashMap;
45 import java.util.List;
47 import org.testng.Assert;
48 import org.testng.AssertJUnit;
49 import org.testng.annotations.AfterTest;
50 import org.testng.annotations.BeforeClass;
51 import org.testng.annotations.BeforeMethod;
52 import org.testng.annotations.BeforeTest;
53 import org.testng.annotations.Test;
55 public class JSONFileTest
58 @BeforeClass(alwaysRun = true)
59 public void setUpJvOptionPane()
61 JvOptionPane.setInteractiveMode(false);
62 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
65 private int TEST_SEQ_HEIGHT = 0;
67 private int TEST_GRP_HEIGHT = 0;
69 private int TEST_ANOT_HEIGHT = 0;
71 private int TEST_CS_HEIGHT = 0;
73 private String TEST_JSON_FILE = "examples/example.json";
75 private Alignment alignment;
77 private HashMap<String, SequenceI> expectedSeqs = new HashMap<String, SequenceI>();
79 private HashMap<String, AlignmentAnnotation> expectedAnnots = new HashMap<String, AlignmentAnnotation>();
81 private HashMap<String, SequenceGroup> expectedGrps = new HashMap<String, SequenceGroup>();
83 private HiddenColumns expectedColSel = new HiddenColumns();
85 private SequenceI[] expectedHiddenSeqs = new SequenceI[1];
87 private AlignmentI testAlignment;
89 private int passedCount;
91 private JSONFile testJsonFile;
95 private AlignExportSettingI exportSettings;
97 @BeforeTest(alwaysRun = true)
98 public void setup() throws Exception
101 * construct expected values
102 * nb this have to match the data in examples/example.json
104 // create and add sequences
105 Sequence[] seqs = new Sequence[5];
106 seqs[0] = new Sequence("FER_CAPAN",
107 "SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALF", 3, 34);
108 seqs[1] = new Sequence("FER1_SOLLC",
109 "SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALF", 3, 34);
110 seqs[2] = new Sequence("Q93XJ9_SOLTU",
111 "SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALF", 3, 34);
112 seqs[3] = new Sequence("FER1_PEA",
113 "ALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFL", 6, 37);
114 seqs[4] = new Sequence("Q7XA98_TRIPR",
115 "ALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGF", 6, 39);
117 SequenceI hiddenSeq = new Sequence("FER_TOCH",
118 "FILGTMISKSFLFRKPAVTSL-KAISNVGE--ALF", 3, 34);
119 expectedHiddenSeqs[0] = hiddenSeq;
121 // create and add sequence features
122 SequenceFeature seqFeature2 = new SequenceFeature("feature_x",
123 "description", "status", 6, 15, "Jalview");
124 SequenceFeature seqFeature3 = new SequenceFeature("feature_x",
125 "description", "status", 9, 18, "Jalview");
126 SequenceFeature seqFeature4 = new SequenceFeature("feature_x",
127 "description", "status", 9, 18, "Jalview");
128 // non-positional feature:
129 SequenceFeature seqFeature5 = new SequenceFeature("Domain",
130 "My description", "status", 0, 0, "Pfam");
131 seqs[2].addSequenceFeature(seqFeature2);
132 seqs[3].addSequenceFeature(seqFeature3);
133 seqs[4].addSequenceFeature(seqFeature4);
134 seqs[2].addSequenceFeature(seqFeature5);
136 for (Sequence seq : seqs)
138 seq.createDatasetSequence();
139 expectedSeqs.put(seq.getName(), seq);
142 // create and add a sequence group
143 List<SequenceI> grpSeqs = new ArrayList<SequenceI>();
144 grpSeqs.add(seqs[1]);
145 grpSeqs.add(seqs[2]);
146 grpSeqs.add(seqs[3]);
147 grpSeqs.add(seqs[4]);
148 SequenceGroup seqGrp = new SequenceGroup(grpSeqs,
150 null, true, true, false, 21, 29);
151 ColourSchemeI scheme = ColourSchemeMapper.getJalviewColourScheme(
153 seqGrp.cs.setColourScheme(scheme);
154 seqGrp.setShowNonconserved(false);
155 seqGrp.setDescription(null);
157 expectedGrps.put(seqGrp.getName(), seqGrp);
159 // create and add annotation
160 Annotation[] annot = new Annotation[35];
161 annot[0] = new Annotation("", "", '\u0000', 0);
162 annot[1] = new Annotation("", "", '\u0000', 0);
163 annot[2] = new Annotation("α", "", 'H', 0);
164 annot[3] = new Annotation("α", "", 'H', 0);
165 annot[4] = new Annotation("α", "", 'H', 0);
166 annot[5] = new Annotation("", "", '\u0000', 0);
167 annot[6] = new Annotation("", "", '\u0000', 0);
168 annot[7] = new Annotation("", "", '\u0000', 0);
169 annot[8] = new Annotation("β", "", 'E', 0);
170 annot[9] = new Annotation("β", "", 'E', 0);
171 annot[10] = new Annotation("β", "", 'E', 0);
172 annot[11] = new Annotation("β", "", 'E', 0);
173 annot[12] = new Annotation("β", "", 'E', 0);
174 annot[13] = new Annotation("β", "", 'E', 0);
175 annot[14] = new Annotation("β", "", 'E', 0);
176 annot[15] = new Annotation("β", "", 'E', 0);
177 annot[16] = new Annotation("", "", '\u0000', 0);
178 annot[17] = new Annotation("", "", '\u0000', 0);
179 annot[18] = new Annotation("", "", '\u0000', 0);
180 annot[19] = new Annotation("", "", '\u0000', 0);
181 annot[20] = new Annotation("", "", '\u0000', 0);
182 annot[21] = new Annotation("", "", '\u0000', 0);
183 annot[22] = new Annotation("", "", '\u0000', 0);
184 annot[23] = new Annotation("", "", '\u0000', 0);
185 annot[24] = new Annotation("", "", '\u0000', 0);
186 annot[25] = new Annotation("", "", '\u0000', 0);
187 annot[26] = new Annotation("α", "", 'H', 0);
188 annot[27] = new Annotation("α", "", 'H', 0);
189 annot[28] = new Annotation("α", "", 'H', 0);
190 annot[29] = new Annotation("α", "", 'H', 0);
191 annot[30] = new Annotation("α", "", 'H', 0);
192 annot[31] = new Annotation("", "", '\u0000', 0);
193 annot[32] = new Annotation("", "", '\u0000', 0);
194 annot[33] = new Annotation("", "", '\u0000', 0);
195 annot[34] = new Annotation("", "", '\u0000', 0);
197 AlignmentAnnotation alignAnnot = new AlignmentAnnotation(
198 "Secondary Structure", "New description", annot);
199 expectedAnnots.put(alignAnnot.label, alignAnnot);
201 expectedColSel.hideColumns(32, 33);
202 expectedColSel.hideColumns(34, 34);
204 TEST_SEQ_HEIGHT = expectedSeqs.size();
205 TEST_GRP_HEIGHT = expectedGrps.size();
206 TEST_ANOT_HEIGHT = expectedAnnots.size();
207 TEST_CS_HEIGHT = expectedColSel.getHiddenRegions().size();
209 exportSettings = new AlignExportSettingI()
212 public boolean isExportHiddenSequences()
218 public boolean isExportHiddenColumns()
224 public boolean isExportGroups()
230 public boolean isExportFeatures()
236 public boolean isExportAnnotations()
242 public boolean isCancelled()
248 AppletFormatAdapter formatAdapter = new AppletFormatAdapter();
251 alignment = (Alignment) formatAdapter.readFile(TEST_JSON_FILE,
252 DataSourceType.FILE, FileFormat.Json);
253 jf = (JSONFile) formatAdapter.getAlignFile();
255 AlignFrame af = new AlignFrame(alignment, jf.getHiddenSequences(),
256 jf.getHiddenColumns(), AlignFrame.DEFAULT_WIDTH,
257 AlignFrame.DEFAULT_HEIGHT);
258 af.getViewport().setShowSequenceFeatures(jf.isShowSeqFeatures());
259 String colourSchemeName = jf.getGlobalColourScheme();
260 ColourSchemeI cs = ColourSchemeMapper.getJalviewColourScheme(
261 colourSchemeName, alignment);
263 af.getViewport().setFeaturesDisplayed(jf.getDisplayedFeatures());
265 formatAdapter = new AppletFormatAdapter(af.alignPanel, exportSettings);
266 String jsonOutput = formatAdapter.formatSequences(FileFormat.Json,
267 af.alignPanel.getAlignment(), false);
269 formatAdapter = new AppletFormatAdapter();
270 testAlignment = formatAdapter.readFile(jsonOutput,
271 DataSourceType.PASTE, FileFormat.Json);
272 testJsonFile = (JSONFile) formatAdapter.getAlignFile();
273 // System.out.println(jsonOutput);
274 } catch (IOException e)
281 @BeforeMethod(alwaysRun = true)
282 public void methodSetup()
287 @AfterTest(alwaysRun = true)
288 public void tearDown() throws Exception
293 expectedAnnots = null;
295 testAlignment = null;
299 @Test(groups = { "Functional" })
300 public void roundTripTest()
302 assertNotNull("JSON roundtrip test failed!", testJsonFile);
305 @Test(groups = { "Functional" })
306 public void testSeqParsed()
308 assertNotNull("Couldn't read supplied alignment data.", testAlignment);
309 Assert.assertNotNull(testAlignment.getSequences());
310 for (SequenceI seq : testAlignment.getSequences())
312 SequenceI expectedSeq = expectedSeqs.get(seq.getName());
313 AssertJUnit.assertTrue(
314 "Failed Sequence Test for >>> " + seq.getName(),
315 isSeqMatched(expectedSeq, seq));
318 AssertJUnit.assertEquals("Some Sequences did not pass the test",
319 TEST_SEQ_HEIGHT, passedCount);
322 @Test(groups = { "Functional" })
323 public void hiddenColsTest()
325 HiddenColumns cs = testJsonFile.getHiddenColumns();
326 Assert.assertNotNull(cs);
327 Assert.assertNotNull(cs.getHiddenRegions());
328 List<int[]> hiddenCols = cs.getHiddenRegions();
329 Assert.assertEquals(hiddenCols.size(), TEST_CS_HEIGHT);
330 Assert.assertEquals(hiddenCols.get(0), expectedColSel
331 .getHiddenRegions().get(0),
332 "Mismatched hidden columns!");
335 @Test(groups = { "Functional" })
336 public void hiddenSeqsTest()
338 Assert.assertNotNull(testJsonFile.getHiddenSequences(),
339 "Hidden sequence Expected but found Null");
340 Assert.assertEquals(jf.getHiddenSequences().length, 1,
344 @Test(groups = { "Functional" })
345 public void colorSchemeTest()
347 Assert.assertNotNull(testJsonFile.getGlobalColourScheme(),
348 "Colourscheme is null, parsing failed!");
349 Assert.assertEquals(testJsonFile.getGlobalColourScheme(), "Zappo",
350 "Zappo colour scheme expected!");
354 * Test for bug JAL-2489, NPE when exporting BioJSON with global colour
355 * scheme, and a group colour scheme, set as 'None'
357 @Test(groups = { "Functional" })
358 public void testBioJSONRoundTripWithColourSchemeNone()
360 AppletFormatAdapter formatAdapter = new AppletFormatAdapter();
362 Alignment _alignment;
365 // load example BioJSON file
366 _alignment = (Alignment) formatAdapter.readFile(TEST_JSON_FILE,
367 DataSourceType.FILE, FileFormat.Json);
368 JSONFile bioJsonFile = (JSONFile) formatAdapter.getAlignFile();
369 AlignFrame alignFrame = new AlignFrame(_alignment,
370 bioJsonFile.getHiddenSequences(),
371 bioJsonFile.getHiddenColumns(), AlignFrame.DEFAULT_WIDTH,
372 AlignFrame.DEFAULT_HEIGHT);
375 * Create a group on the alignment;
376 * Change global and group colour scheme to 'None' and perform round trip
378 SequenceGroup sg = new SequenceGroup();
379 sg.addSequence(_alignment.getSequenceAt(0), false);
380 sg.setColourScheme(null);
381 ColourSchemeI cs = ColourSchemeMapper.getJalviewColourScheme(
382 ResidueColourScheme.NONE, _alignment);
383 alignFrame.changeColour(cs);
384 alignFrame.getViewport().setFeaturesDisplayed(
385 bioJsonFile.getDisplayedFeatures());
386 formatAdapter = new AppletFormatAdapter(alignFrame.alignPanel,
388 // export BioJSON string
389 String jsonOutput = formatAdapter.formatSequences(FileFormat.Json,
390 alignFrame.alignPanel.getAlignment(), false);
391 // read back Alignment from BioJSON string
392 formatAdapter = new AppletFormatAdapter();
393 formatAdapter.readFile(jsonOutput, DataSourceType.PASTE,
395 // assert 'None' colour scheme is retained after round trip
396 JSONFile _bioJsonFile = (JSONFile) formatAdapter.getAlignFile();
397 Assert.assertEquals(_bioJsonFile.getGlobalColourScheme(),
398 ResidueColourScheme.NONE);
399 } catch (IOException e)
405 @Test(groups = { "Functional" })
406 public void isShowSeqFeaturesSet()
408 Assert.assertTrue(testJsonFile.isShowSeqFeatures(),
409 "Sequence feature isDisplayed setting expected to be true");
412 @Test(groups = { "Functional" })
413 public void testGrpParsed()
415 Assert.assertNotNull(testAlignment.getGroups());
416 for (SequenceGroup seqGrp : testAlignment.getGroups())
418 SequenceGroup expectedGrp = expectedGrps.get(seqGrp.getName());
419 AssertJUnit.assertTrue(
420 "Failed SequenceGroup Test for >>> " + seqGrp.getName(),
421 isGroupMatched(expectedGrp, seqGrp));
424 AssertJUnit.assertEquals("Some SequenceGroups did not pass the test",
425 TEST_GRP_HEIGHT, passedCount);
428 @Test(groups = { "Functional" })
429 public void testAnnotationParsed()
431 Assert.assertNotNull(testAlignment.getAlignmentAnnotation());
432 for (AlignmentAnnotation annot : testAlignment.getAlignmentAnnotation())
434 AlignmentAnnotation expectedAnnot = expectedAnnots.get(annot.label);
435 AssertJUnit.assertTrue("Failed AlignmentAnnotation Test for >>> "
436 + annot.label, isAnnotationMatched(expectedAnnot, annot));
439 AssertJUnit.assertEquals("Some Sequences did not pass the test",
440 TEST_ANOT_HEIGHT, passedCount);
443 public boolean isAnnotationMatched(AlignmentAnnotation eAnnot,
444 AlignmentAnnotation annot)
446 if (!eAnnot.label.equals(annot.label)
447 || !eAnnot.description.equals(annot.description)
448 || eAnnot.annotations.length != annot.annotations.length)
453 for (int x = 0; x < annot.annotations.length; x++)
455 Annotation y = annot.annotations[x];
456 Annotation z = annot.annotations[x];
458 if (!y.displayCharacter.equals(z.displayCharacter)
459 || y.value != z.value
460 || y.secondaryStructure != z.secondaryStructure)
468 boolean isSeqMatched(SequenceI expectedSeq, SequenceI actualSeq)
470 System.out.println("Testing >>> " + actualSeq.getName());
472 if (expectedSeq.getName().equals(actualSeq.getName())
473 && expectedSeq.getSequenceAsString().equals(
474 actualSeq.getSequenceAsString())
475 && expectedSeq.getStart() == actualSeq.getStart()
476 && expectedSeq.getEnd() == actualSeq.getEnd()
477 && featuresMatched(expectedSeq, actualSeq))
484 public boolean isGroupMatched(SequenceGroup expectedGrp,
485 SequenceGroup actualGrp)
488 System.out.println("Testing >>> " + actualGrp.getName());
489 System.out.println(expectedGrp.getName() + " | " + actualGrp.getName());
490 System.out.println(expectedGrp.getColourText() + " | "
491 + actualGrp.getColourText());
492 System.out.println(expectedGrp.getDisplayBoxes() + " | "
493 + actualGrp.getDisplayBoxes());
494 System.out.println(expectedGrp.getIgnoreGapsConsensus() + " | "
495 + actualGrp.getIgnoreGapsConsensus());
496 System.out.println(expectedGrp.getSequences().size() + " | "
497 + actualGrp.getSequences().size());
498 System.out.println(expectedGrp.getStartRes() + " | "
499 + actualGrp.getStartRes());
500 System.out.println(expectedGrp.getEndRes() + " | "
501 + actualGrp.getEndRes());
502 System.out.println(expectedGrp.cs.getColourScheme() + " | "
503 + actualGrp.cs.getColourScheme());
505 boolean colourSchemeMatches = (expectedGrp.cs.getColourScheme() == null && actualGrp.cs
506 .getColourScheme() == null)
507 || expectedGrp.cs.getColourScheme().getClass()
508 .equals(actualGrp.cs.getColourScheme().getClass());
509 if (expectedGrp.getName().equals(actualGrp.getName())
510 && expectedGrp.getColourText() == actualGrp.getColourText()
511 && expectedGrp.getDisplayBoxes() == actualGrp.getDisplayBoxes()
512 && expectedGrp.getIgnoreGapsConsensus() == actualGrp
513 .getIgnoreGapsConsensus()
514 && colourSchemeMatches
515 && expectedGrp.getSequences().size() == actualGrp
516 .getSequences().size()
517 && expectedGrp.getStartRes() == actualGrp.getStartRes()
518 && expectedGrp.getEndRes() == actualGrp.getEndRes())
525 private boolean featuresMatched(SequenceI seq1, SequenceI seq2)
529 if (seq1 == null && seq2 == null)
534 List<SequenceFeature> inFeature = seq1.getFeatures().getAllFeatures();
535 List<SequenceFeature> outFeature = seq2.getFeatures()
538 if (inFeature.size() != outFeature.size())
540 System.err.println("Feature count in: " + inFeature.size()
541 + ", out: " + outFeature.size());
545 SequenceFeatures.sortFeatures(inFeature, true);
546 SequenceFeatures.sortFeatures(outFeature, true);
548 for (SequenceFeature in : inFeature)
550 SequenceFeature out = outFeature.get(i);
551 System.out.println(out.getType() + " | " + in.getType());
552 System.out.println(out.getBegin() + " | " + in.getBegin());
553 System.out.println(out.getEnd() + " | " + in.getEnd());
555 if (in.getBegin() == out.getBegin() && in.getEnd() == out.getEnd()
556 && in.getScore() == out.getScore()
557 && in.getFeatureGroup().equals(out.getFeatureGroup())
558 && in.getType().equals(out.getType()))
563 System.err.println("Feature[" + i + "] mismatch, in: "
564 + in.toString() + ", out: "
565 + outFeature.get(i).toString());
570 } catch (Exception e)
574 // System.out.println(">>>>>>>>>>>>>> features matched : " + matched);
579 * Test group roundtrip with null (None) group colour scheme
581 * @throws IOException
583 @Test(groups = { "Functional" })
584 public void testGrpParsed_colourNone() throws IOException
586 AlignmentI copy = new Alignment(testAlignment);
587 SequenceGroup sg = testAlignment.getGroups().get(0);
588 SequenceGroup copySg = new SequenceGroup(new ArrayList<SequenceI>(),
590 null, sg.getDisplayBoxes(), sg.getDisplayText(),
591 sg.getColourText(), sg.getStartRes(), sg.getEndRes());
592 for (SequenceI seq : sg.getSequences())
594 int seqIndex = testAlignment.findIndex(seq);
595 copySg.addSequence(copy.getSequenceAt(seqIndex), false);
597 copy.addGroup(copySg);
599 AlignFrame af = new AlignFrame(copy, copy.getWidth(), copy.getHeight());
600 AppletFormatAdapter formatAdapter = new AppletFormatAdapter(
602 String jsonOutput = formatAdapter.formatSequences(FileFormat.Json,
604 formatAdapter = new AppletFormatAdapter();
605 AlignmentI newAlignment = formatAdapter.readFile(jsonOutput,
606 DataSourceType.PASTE, FileFormat.Json);
608 Assert.assertNotNull(newAlignment.getGroups());
609 for (SequenceGroup seqGrp : newAlignment.getGroups())
611 SequenceGroup expectedGrp = copySg;
612 AssertJUnit.assertTrue(
613 "Failed SequenceGroup Test for >>> " + seqGrp.getName(),
614 isGroupMatched(expectedGrp, seqGrp));
617 AssertJUnit.assertEquals("Some SequenceGroups did not pass the test",
618 TEST_GRP_HEIGHT, passedCount);