JAL-1894 update year/version in copyright
[jalview.git] / test / jalview / io / JSONFileTest.java
index 0f957ea..6e4458e 100644 (file)
@@ -1,34 +1,89 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b1)
+ * Copyright (C) 2015 The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.io;
 
+import static org.testng.AssertJUnit.assertNotNull;
+
+import jalview.api.AlignExportSettingI;
+import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.json.binding.biojson.v1.ColourSchemeMapper;
 import jalview.schemes.ColourSchemeI;
-import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
 
+import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
 
 public class JSONFileTest
 {
-  private JSONFile jsonFile;
 
   private int TEST_SEQ_HEIGHT = 0;
 
   private int TEST_GRP_HEIGHT = 0;
 
-  @Before
-  public void setUp() throws Exception
-  {
-    jsonFile = new JSONFile();
+  private int TEST_ANOT_HEIGHT = 0;
+
+  private int TEST_CS_HEIGHT = 0;
+
+  private String TEST_JSON_FILE = "examples/example.json";
+
+  private Alignment alignment;
+
+  private HashMap<String, SequenceI> expectedSeqs = new HashMap<String, SequenceI>();
+
+  private HashMap<String, AlignmentAnnotation> expectedAnnots = new HashMap<String, AlignmentAnnotation>();
+
+  private HashMap<String, SequenceGroup> expectedGrps = new HashMap<String, SequenceGroup>();
+
+  private ColumnSelection expectedColSel = new ColumnSelection();
+
+  private SequenceI[] expectedHiddenSeqs = new SequenceI[1];
+
+  private AlignmentI testAlignment;
+
+  private int passedCount;
+
+  private JSONFile testJsonFile;
+
+  private JSONFile jf;
 
+  @BeforeTest(alwaysRun = true)
+  public void setup() throws Exception
+  {
     // create and add sequences
     Sequence[] seqs = new Sequence[5];
     seqs[0] = new Sequence("FER_CAPAN",
@@ -42,40 +97,42 @@ public class JSONFileTest
     seqs[4] = new Sequence("Q7XA98_TRIPR",
             "ALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGF", 6, 39);
 
+    SequenceI hiddenSeq = new Sequence("FER_TOCH",
+            "FILGTMISKSFLFRKPAVTSL-KAISNVGE--ALF", 3, 34);
+    expectedHiddenSeqs[0] = hiddenSeq;
+
     // create and add sequence features
     SequenceFeature seqFeature2 = new SequenceFeature("feature_x",
-            "desciption", "status", 22, 29, "jalview");
+            "desciption", "status", 6, 15, "Jalview");
     SequenceFeature seqFeature3 = new SequenceFeature("feature_x",
-            "desciption", "status", 25, 32, "jalview");
+            "desciption", "status", 9, 18, "Jalview");
     SequenceFeature seqFeature4 = new SequenceFeature("feature_x",
-            "desciption", "status", 25, 32, "jalview");
+            "desciption", "status", 9, 18, "Jalview");
     seqs[2].addSequenceFeature(seqFeature2);
     seqs[3].addSequenceFeature(seqFeature3);
     seqs[4].addSequenceFeature(seqFeature4);
 
-    // add created features to features displayed
-    FeaturesDisplayed fDis = new FeaturesDisplayed();
-    fDis.setVisible("feature_x");
-    jsonFile.setDisplayedFeatures(fDis);
-    JSONFile.setSeqFeaturesEnabled(true);
-
     for (Sequence seq : seqs)
     {
       seq.setDatasetSequence(seq);
-      jsonFile.seqs.add(seq);
+      expectedSeqs.put(seq.getName(), seq);
     }
 
     // create and add sequence groups
     ArrayList<SequenceI> grpSeqs = new ArrayList<SequenceI>();
-    grpSeqs.add(seqs[0]);
     grpSeqs.add(seqs[1]);
     grpSeqs.add(seqs[2]);
-    ColourSchemeI scheme = jsonFile.getJalviewColorScheme("zappo");
-    SequenceGroup seqGrp = new SequenceGroup(grpSeqs, "JGroup:1114606272",
-            scheme, true, true, false, 2, 9);
+    grpSeqs.add(seqs[3]);
+    grpSeqs.add(seqs[4]);
+    SequenceGroup seqGrp = new SequenceGroup(grpSeqs, "JGroup:1883305585",
+            null, true, true, false, 21, 29);
+    ColourSchemeI scheme = ColourSchemeMapper.getJalviewColourScheme(
+            "zappo", seqGrp);
+    seqGrp.cs = scheme;
     seqGrp.setShowNonconserved(false);
     seqGrp.setDescription(null);
-    jsonFile.seqGroups.add(seqGrp);
+
+    expectedGrps.put(seqGrp.getName(), seqGrp);
 
     // create and add annotation
     Annotation[] annot = new Annotation[35];
@@ -84,96 +141,304 @@ public class JSONFileTest
     annot[2] = new Annotation("α", "", 'H', 0);
     annot[3] = new Annotation("α", "", 'H', 0);
     annot[4] = new Annotation("α", "", 'H', 0);
-    annot[5] = new Annotation("α", "", 'H', 0);
+    annot[5] = new Annotation("", "", '\u0000', 0);
     annot[6] = new Annotation("", "", '\u0000', 0);
     annot[7] = new Annotation("", "", '\u0000', 0);
-    annot[8] = new Annotation("", "", '\u0000', 0);
-    annot[9] = new Annotation("", "", '\u0000', 0);
+    annot[8] = new Annotation("β", "", 'E', 0);
+    annot[9] = new Annotation("β", "", 'E', 0);
     annot[10] = new Annotation("β", "", 'E', 0);
     annot[11] = new Annotation("β", "", 'E', 0);
-    annot[12] = new Annotation("", "", '\u0000', 0);
-    annot[13] = new Annotation("", "", '\u0000', 0);
-    annot[14] = new Annotation("", "", '\u0000', 0);
-    annot[15] = new Annotation("", "", '\u0000', 0);
-    annot[16] = new Annotation("α", "", 'H', 0);
-    annot[17] = new Annotation("α", "", 'H', 0);
-    annot[18] = new Annotation("α", "", 'H', 0);
-    annot[19] = new Annotation("α", "", 'H', 0);
-    annot[20] = new Annotation("α", "", 'H', 0);
-
+    annot[12] = new Annotation("β", "", 'E', 0);
+    annot[13] = new Annotation("β", "", 'E', 0);
+    annot[14] = new Annotation("β", "", 'E', 0);
+    annot[15] = new Annotation("β", "", 'E', 0);
+    annot[16] = new Annotation("", "", '\u0000', 0);
+    annot[17] = new Annotation("", "", '\u0000', 0);
+    annot[18] = new Annotation("", "", '\u0000', 0);
+    annot[19] = new Annotation("", "", '\u0000', 0);
+    annot[20] = new Annotation("", "", '\u0000', 0);
     annot[21] = new Annotation("", "", '\u0000', 0);
     annot[22] = new Annotation("", "", '\u0000', 0);
     annot[23] = new Annotation("", "", '\u0000', 0);
     annot[24] = new Annotation("", "", '\u0000', 0);
     annot[25] = new Annotation("", "", '\u0000', 0);
-    annot[26] = new Annotation("", "", '\u0000', 0);
-    annot[27] = new Annotation("", "", '\u0000', 0);
-    annot[28] = new Annotation("", "", '\u0000', 0);
-    annot[29] = new Annotation("", "", '\u0000', 0);
-    annot[30] = new Annotation("", "", '\u0000', 0);
+    annot[26] = new Annotation("α", "", 'H', 0);
+    annot[27] = new Annotation("α", "", 'H', 0);
+    annot[28] = new Annotation("α", "", 'H', 0);
+    annot[29] = new Annotation("α", "", 'H', 0);
+    annot[30] = new Annotation("α", "", 'H', 0);
     annot[31] = new Annotation("", "", '\u0000', 0);
-    annot[32] = new Annotation("β", "", 'E', 0);
-    annot[33] = new Annotation("β", "", 'E', 0);
-    annot[34] = new Annotation("β", "", 'E', 0);
+    annot[32] = new Annotation("", "", '\u0000', 0);
+    annot[33] = new Annotation("", "", '\u0000', 0);
+    annot[34] = new Annotation("", "", '\u0000', 0);
 
     AlignmentAnnotation alignAnnot = new AlignmentAnnotation(
             "Secondary Structure", "New description", annot);
-    jsonFile.annotations.add(alignAnnot);
+    expectedAnnots.put(alignAnnot.label, alignAnnot);
+
+    expectedColSel.hideColumns(32, 33);
+    expectedColSel.hideColumns(34, 34);
+
+    TEST_SEQ_HEIGHT = expectedSeqs.size();
+    TEST_GRP_HEIGHT = expectedGrps.size();
+    TEST_ANOT_HEIGHT = expectedAnnots.size();
+    TEST_CS_HEIGHT = expectedColSel.getHiddenColumns().size();
+
+    AlignExportSettingI exportSettings = new AlignExportSettingI()
+    {
+      @Override
+      public boolean isExportHiddenSequences()
+      {
+        return true;
+      }
+
+      @Override
+      public boolean isExportHiddenColumns()
+      {
+        return true;
+      }
+
+      @Override
+      public boolean isExportGroups()
+      {
+        return true;
+      }
+
+      @Override
+      public boolean isExportFeatures()
+      {
+        return true;
+      }
+
+      @Override
+      public boolean isExportAnnotations()
+      {
+        return true;
+      }
+
+      @Override
+      public boolean isCancelled()
+      {
+        return false;
+      }
+    };
+
+    AppletFormatAdapter formatAdapter = new AppletFormatAdapter();
+    try
+    {
+      alignment = (Alignment) formatAdapter.readFile(TEST_JSON_FILE,
+              AppletFormatAdapter.FILE, JSONFile.FILE_DESC);
+      jf = (JSONFile) formatAdapter.getAlignFile();
+
+      AlignFrame af = new AlignFrame(alignment, jf.getHiddenSequences(),
+              jf.getColumnSelection(), AlignFrame.DEFAULT_WIDTH,
+              AlignFrame.DEFAULT_HEIGHT);
+      af.getViewport().setShowSequenceFeatures(jf.isShowSeqFeatures());
+      String colourSchemeName = jf.getGlobalColourScheme();
+      ColourSchemeI cs = ColourSchemeMapper.getJalviewColourScheme(
+              colourSchemeName, alignment);
+      af.changeColour(cs);
+      af.getViewport().setFeaturesDisplayed(jf.getDisplayedFeatures());
+
+      formatAdapter = new AppletFormatAdapter(af.alignPanel, exportSettings);
+      String jsonOutput = formatAdapter.formatSequences(JSONFile.FILE_DESC,
+              af.alignPanel.getAlignment(), false);
+
+      formatAdapter = new AppletFormatAdapter();
+      testAlignment = formatAdapter.readFile(jsonOutput,
+              AppletFormatAdapter.PASTE, JSONFile.FILE_DESC);
+      testJsonFile = (JSONFile) formatAdapter.getAlignFile();
+      // System.out.println(jsonOutput);
+    } catch (IOException e)
+    {
+      e.printStackTrace();
+    }
+
+  }
 
-    // Alignment al = new Alignment(seqs);
-    TEST_SEQ_HEIGHT = jsonFile.seqs.size();
-    TEST_GRP_HEIGHT = jsonFile.seqGroups.size();
+  @BeforeMethod(alwaysRun = true)
+  public void methodSetup()
+  {
+    passedCount = 0;
   }
 
-  @After
+  @AfterTest
   public void tearDown() throws Exception
   {
+    testJsonFile = null;
+    alignment = null;
+    expectedSeqs = null;
+    expectedAnnots = null;
+    expectedGrps = null;
+    testAlignment = null;
+    jf = null;
   }
 
-  @Test
-  public void test()
+  @Test(groups = { "Functional" })
+  public void roundTripTest()
   {
-    String jsonOuput = jsonFile.print();
-    // System.out.println(">>>>>>>>>>>>>> " + jsonOuput);
-    JSONFile output = new JSONFile().parse(jsonOuput);
+    assertNotNull("JSON roundtrip test failed!", testJsonFile);
+  }
 
-    int matchedCounter = 0;
-    for (SequenceI in : jsonFile.getSeqs())
+  @Test(groups = { "Functional" })
+  public void testSeqParsed()
+  {
+    assertNotNull("Couldn't read supplied alignment data.", testAlignment);
+    Assert.assertNotNull(testAlignment.getSequences());
+    for (SequenceI seq : testAlignment.getSequences())
     {
-      for (SequenceI out : output.getSeqs())
-      {
-        if (in.getName().equals(out.getName())
-                && in.getSequenceAsString().equals(
-                        out.getSequenceAsString())
-                && in.getStart() == out.getStart()
-                && in.getEnd() == out.getEnd() && featuresMatched(in, out))
-        {
-          // System.out.println(">>>> Seq Match Detected");
-          ++matchedCounter;
-        }
-      }
+      SequenceI expectedSeq = expectedSeqs.get(seq.getName());
+      AssertJUnit.assertTrue(
+              "Failed Sequence Test  for >>> " + seq.getName(),
+              isSeqMatched(expectedSeq, seq));
+      passedCount++;
+    }
+    AssertJUnit.assertEquals("Some Sequences did not pass the test",
+            TEST_SEQ_HEIGHT, passedCount);
+  }
+
+  @Test(groups = { "Functional" })
+  public void hiddenColsTest()
+  {
+    ColumnSelection cs = testJsonFile.getColumnSelection();
+    Assert.assertNotNull(cs);
+    Assert.assertNotNull(cs.getHiddenColumns());
+    List<int[]> hiddenCols = cs.getHiddenColumns();
+    Assert.assertEquals(hiddenCols.size(), TEST_CS_HEIGHT);
+    Assert.assertEquals(hiddenCols, expectedColSel.getHiddenColumns(),
+            "Mismatched hidden columns!");
+  }
+
+  @Test(groups = { "Functional" })
+  public void hiddenSeqsTest()
+  {
+    Assert.assertNotNull(testJsonFile.getHiddenSequences(),
+            "Hidden sequence Expected but found Null");
+    Assert.assertEquals(jf.getHiddenSequences().length, 1, "Hidden sequece");
+  }
+
+  @Test(groups = { "Functional" })
+  public void colorSchemeTest()
+  {
+    Assert.assertNotNull(testJsonFile.getGlobalColourScheme(),
+            "Colourscheme is null, parsing failed!");
+    Assert.assertEquals(testJsonFile.getGlobalColourScheme(), "Zappo",
+            "Zappo colour scheme expected!");
+  }
+
+  @Test(groups = { "Functional" })
+  public void isShowSeqFeaturesSet()
+  {
+    Assert.assertTrue(testJsonFile.isShowSeqFeatures(),
+            "Sequence feature isDisplayed setting expected to be true");
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGrpParsed()
+  {
+    Assert.assertNotNull(testAlignment.getGroups());
+    for (SequenceGroup seqGrp : testAlignment.getGroups())
+    {
+      SequenceGroup expectedGrp = expectedGrps.get(seqGrp.getName());
+      AssertJUnit.assertTrue(
+              "Failed SequenceGroup Test for >>> " + seqGrp.getName(),
+              isGroupMatched(expectedGrp, seqGrp));
+      passedCount++;
+    }
+    AssertJUnit.assertEquals("Some SequenceGroups did not pass the test",
+            TEST_GRP_HEIGHT, passedCount);
+  }
+
+  @Test(groups = { "Functional" })
+  public void testAnnotationParsed()
+  {
+    Assert.assertNotNull(testAlignment.getAlignmentAnnotation());
+    for (AlignmentAnnotation annot : testAlignment.getAlignmentAnnotation())
+    {
+      AlignmentAnnotation expectedAnnot = expectedAnnots.get(annot.label);
+      AssertJUnit.assertTrue("Failed AlignmentAnnotation Test for >>> "
+              + annot.label, isAnnotationMatched(expectedAnnot, annot));
+      passedCount++;
+    }
+    AssertJUnit.assertEquals("Some Sequences did not pass the test",
+            TEST_ANOT_HEIGHT, passedCount);
+  }
+
+  public boolean isAnnotationMatched(AlignmentAnnotation eAnnot,
+          AlignmentAnnotation annot)
+  {
+    if (!eAnnot.label.equals(annot.label)
+            || !eAnnot.description.equals(annot.description)
+            || eAnnot.annotations.length != annot.annotations.length)
+    {
+      return false;
     }
-    Assert.assertTrue(matchedCounter == TEST_SEQ_HEIGHT);
 
-    matchedCounter = 0;
-    for (SequenceGroup in : jsonFile.getSeqGroups())
+    for (int x = 0; x < annot.annotations.length; x++)
     {
-      for (SequenceGroup out : output.getSeqGroups())
+      Annotation y = annot.annotations[x];
+      Annotation z = annot.annotations[x];
+
+      if (!y.displayCharacter.equals(z.displayCharacter)
+              || y.value != z.value
+              || y.secondaryStructure != z.secondaryStructure)
       {
-        if (in.getName().equals(out.getName())
-                && in.getColourText() == out.getColourText()
-                && in.getDisplayBoxes() == out.getDisplayBoxes()
-                && in.getIgnoreGapsConsensus() == out
-                        .getIgnoreGapsConsensus() && in.cs.equals(out.cs)
-                && in.getSequences().size() == out.getSequences().size())
-        {
-          // System.out.println(">>>> Grp Match Detected");
-          ++matchedCounter;
-        }
+        return false;
       }
-      Assert.assertTrue(matchedCounter == TEST_GRP_HEIGHT);
     }
+    return true;
+  }
+
+  public boolean isSeqMatched(SequenceI expectedSeq, SequenceI actualSeq)
+  {
+    System.out.println("Testing >>> " + actualSeq.getName());
 
+    if (expectedSeq.getName().equals(actualSeq.getName())
+            && expectedSeq.getSequenceAsString().equals(
+                    actualSeq.getSequenceAsString())
+            && expectedSeq.getStart() == actualSeq.getStart()
+            && expectedSeq.getEnd() == actualSeq.getEnd()
+            && featuresMatched(expectedSeq, actualSeq))
+    {
+      return true;
+    }
+    return false;
+  }
+
+  public boolean isGroupMatched(SequenceGroup expectedGrp,
+          SequenceGroup actualGrp)
+  {
+
+    System.out.println("Testing >>> " + actualGrp.getName());
+    System.out.println(expectedGrp.getName() + " | " + actualGrp.getName());
+    System.out.println(expectedGrp.getColourText() + " | "
+            + actualGrp.getColourText());
+    System.out.println(expectedGrp.getDisplayBoxes() + " | "
+            + actualGrp.getDisplayBoxes());
+    System.out.println(expectedGrp.getIgnoreGapsConsensus() + " | "
+            + actualGrp.getIgnoreGapsConsensus());
+    System.out.println(expectedGrp.getSequences().size() + " | "
+            + actualGrp.getSequences().size());
+    System.out.println(expectedGrp.getStartRes() + " | "
+            + actualGrp.getStartRes());
+    System.out.println(expectedGrp.getEndRes() + " | "
+            + actualGrp.getEndRes());
+    System.out.println(expectedGrp.cs + " | " + actualGrp.cs);
+
+    if (expectedGrp.getName().equals(actualGrp.getName())
+            && expectedGrp.getColourText() == actualGrp.getColourText()
+            && expectedGrp.getDisplayBoxes() == actualGrp.getDisplayBoxes()
+            && expectedGrp.getIgnoreGapsConsensus() == actualGrp
+                    .getIgnoreGapsConsensus()
+            && (expectedGrp.cs.getClass().equals(actualGrp.cs.getClass()))
+            && expectedGrp.getSequences().size() == actualGrp
+                    .getSequences().size()
+            && expectedGrp.getStartRes() == actualGrp.getStartRes()
+            && expectedGrp.getEndRes() == actualGrp.getEndRes())
+    {
+      return true;
+    }
+    return false;
   }
 
   private boolean featuresMatched(SequenceI seq1, SequenceI seq2)
@@ -201,22 +466,27 @@ public class JSONFileTest
 
       int testSize = inFeature.length;
       int matchedCount = 0;
-      // System.out.println(">>>>>>>>>>>>> 1");
       for (SequenceFeature in : inFeature)
       {
-        for (SequenceFeature out : inFeature)
+        for (SequenceFeature out : outFeature)
         {
+          System.out.println(out.getType() + " | " + in.getType());
+          System.out.println(out.getBegin() + " | " + in.getBegin());
+          System.out.println(out.getEnd() + " | " + in.getEnd());
+
           if (inFeature.length == outFeature.length
                   && in.getBegin() == out.getBegin()
                   && in.getEnd() == out.getEnd()
                   && in.getScore() == out.getScore()
-                  && in.getFeatureGroup().equals(out.getFeatureGroup()))
+                  && in.getFeatureGroup().equals(out.getFeatureGroup())
+                  && in.getType().equals(out.getType()))
           {
 
             ++matchedCount;
           }
         }
       }
+      System.out.println("matched count >>>>>> " + matchedCount);
       if (testSize == matchedCount)
       {
         matched = true;