JAL-1499 slight refactoring of handling interleaved data blocks
[jalview.git] / test / jalview / io / MegaFileTest.java
index bdae11a..860a898 100644 (file)
@@ -8,6 +8,7 @@ import static org.testng.AssertJUnit.fail;
 
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
@@ -73,7 +74,8 @@ public class MegaFileTest
           + "!TITLE Interleaved sequence data\n\n"
           + "#U455   ABCDEF\n" 
           + "#CPZANT  MNOPQR\n\n"
-          + "#U456   KLMNOP\n";
+          + "#U455   GHIJKL\n" 
+          + "#U456   KLMNOP\n"; // wossis?
 
   // interleaved with description, bases/gaps in triplet groups
   private static final String INTERLEAVED_WITH_DESCRIPTION = 
@@ -234,10 +236,14 @@ public class MegaFileTest
     // normally output should match input
     // we cheated here with a number of short input lines
     // nb don't get Title in output if not calling print(AlignmentI)
-    String expected = "#MEGA\n\n" + "#U455   ABCDEF [6]\n"
-            + "#CPZANT MNOPQR [6]\n\n" + "#U455   KLMNOP [12]\n"
-            + "#CPZANT WXYZGC [12]"
-            + "\n";
+    //@formatter:off
+    String expected = 
+        "#MEGA\n\n" + 
+        "#U455   ABCDEF [6]\n" +
+        "#CPZANT MNOPQR [6]\n\n" + 
+        "#U455   KLMNOP [12]\n" + 
+        "#CPZANT WXYZGC [12]\n";
+    //@formatter:on
     assertEquals("Print format wrong", expected, printed);
   }
 
@@ -685,27 +691,79 @@ public class MegaFileTest
       verifySequenceFeature(sfs[7], "MEF2A", "Gene", 31, 36);
       verifySequenceFeature(sfs[8], "BindingSite", "Domain", 37, 42);
     }
+
+    /*
+     * verify gene and domain alignment annotations
+     */
+    assertEquals(2, testee.annotations.size());
+    AlignmentAnnotation ann = testee.annotations.get(0);
+    assertEquals("MEGA Gene", ann.label);
+    assertEquals(42, ann.annotations.length);
+    verifyAnnotation(ann, 0, 6, null);
+    verifyAnnotation(ann, 6, 24, "Adh");
+    verifyAnnotation(ann, 24, 30, "Opsin");
+    verifyAnnotation(ann, 30, 36, "MEF2A");
+    verifyAnnotation(ann, 37, 42, null);
+
+    ann = testee.annotations.get(1);
+    assertEquals("MEGA Domain", ann.label);
+    assertEquals(42, ann.annotations.length);
+    verifyAnnotation(ann, 0, 6, null);
+    verifyAnnotation(ann, 6, 12, "Exon1 (Adh Coding)");
+    verifyAnnotation(ann, 12, 18, "Intron1 (Adh Noncoding)");
+    verifyAnnotation(ann, 19, 24, "Exon2 (Adh Coding)");
+    verifyAnnotation(ann, 25, 30, "Intron1 (Opsin Noncoding)");
+    verifyAnnotation(ann, 31, 36, "Exon1 (MEF2A Coding)");
+    verifyAnnotation(ann, 37, 42, "BindingSite");
+
+  }
+
+  /**
+   * Helper method to verify a range of annotation positions all have the given
+   * description
+   * 
+   * @param ann
+   *          array of annotations to check
+   * @param from
+   *          start index to check
+   * @param to
+   *          end index to check (exclusive)
+   * @param description
+   *          value to assert
+   */
+  protected void verifyAnnotation(AlignmentAnnotation ann, int from,
+          int to, String description)
+  {
+    for (int pos = from; pos < to; pos++)
+    {
+      if (description == null)
+      {
+        assertNull(ann.annotations[pos]);
+      }
+      else
+      {
+        assertEquals(description, ann.annotations[pos].description);
+      }
+    }
   }
 
   /**
    * Helper method to assert properties of a SequenceFeature
    * 
    * @param sf
-   * @param description
    * @param type
+   * @param description
    * @param begin
    * @param end
    */
-  protected void verifySequenceFeature(SequenceFeature sf,
-          String description, String type, int begin, int end)
+  protected void verifySequenceFeature(SequenceFeature sf, String type,
+          String description, int begin, int end)
   {
     assertEquals(description, sf.type);
     assertEquals(type, sf.description);
     assertEquals(begin, sf.begin);
     assertEquals(end, sf.end);
   }
-
-  //@formatter:on
   
   /**
    * Test parse of data including !Label statements. An underscore means no
@@ -865,4 +923,132 @@ public class MegaFileTest
     assertEquals("Roundtrip didn't match", expected,
             formatted);
   }
+
+  /**
+   * Test (parse and) print of MEGA data with !Gene statements.
+   * 
+   * @throws IOException
+   */
+  @Test(groups = { "Functional" })
+  public void testPrint_genes() throws IOException
+  {
+    /*
+     * to keep the test concise, input data is in the exact format that Jalview
+     * would output it; the important thing is functional equivalence of input
+     * and output
+     */
+    //@formatter:off
+    String data = "#MEGA\n\n"+ 
+      "#Seq1 ABCD [4]\n" + 
+      "#Seq2 MNOP [4]\n\n" + 
+      "!Domain=Exon1 Gene=Adh Property=Coding;\n" +
+      "#Seq1 EFGHI [9]\n" + 
+      "#Seq2 QRSTU [9]\n\n" +
+      "!Domain=Intron1 Gene=Adh Property=Noncoding;\n" +
+      "#Seq1 JK [11]\n" + 
+      "#Seq2 VW [11]\n\n" +
+      "!Domain=Intron1 Property=domainend;\n" +
+      "#Seq1 LMN [14]\n" + 
+      "#Seq2 XYZ [14]\n";
+    //@formatter:on
+    MegaFile testee = new MegaFile(data, AppletFormatAdapter.PASTE);
+    String printed = testee.print();
+    assertEquals("Print format wrong", data, printed);
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetDomainFromAnnotation()
+  {
+    Annotation[] anns = new Annotation[5];
+    anns[1] = new Annotation("", "Intron1", '0', 0f);
+    anns[2] = new Annotation("", "Intron2 (Aspx)", '0', 0f);
+    anns[3] = new Annotation("", "Intron3 (Aspy Coding)", '0', 0f);
+    anns[4] = new Annotation("", "Intron4 (Coding)", '0', 0f);
+    AlignmentAnnotation aa = new AlignmentAnnotation("", "", anns);
+    // no annotations:
+    assertNull(MegaFile.getDomainFromAnnotation(0, null));
+    // null annotation:
+    assertNull(MegaFile.getDomainFromAnnotation(0, aa));
+    // column out of range:
+    assertNull(MegaFile.getDomainFromAnnotation(5, aa));
+    // domain with no Gene or Property:
+    assertEquals("Intron1", MegaFile.getDomainFromAnnotation(1, aa));
+    // domain with Gene but no Property:
+    assertEquals("Intron2", MegaFile.getDomainFromAnnotation(2, aa));
+    // domain with Gene and Property:
+    assertEquals("Intron3", MegaFile.getDomainFromAnnotation(3, aa));
+    // domain with Property and no Gene:
+    assertEquals("Intron4", MegaFile.getDomainFromAnnotation(4, aa));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetGeneFromAnnotation()
+  {
+    Annotation[] anns = new Annotation[3];
+    anns[1] = new Annotation("", "Aspx", '0', 0f);
+    AlignmentAnnotation aa = new AlignmentAnnotation("", "", anns);
+    // no annotations:
+    assertNull(MegaFile.getGeneFromAnnotation(0, null));
+    // null annotation:
+    assertNull(MegaFile.getGeneFromAnnotation(0, aa));
+    // column out of range:
+    assertNull(MegaFile.getGeneFromAnnotation(3, aa));
+    // gene annotation:
+    assertEquals("Aspx", MegaFile.getGeneFromAnnotation(1, aa));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetPropertyFromAnnotation()
+  {
+    Annotation[] anns = new Annotation[5];
+    anns[1] = new Annotation("", "Intron1", '0', 0f);
+    anns[2] = new Annotation("", "Intron2 (Aspx)", '0', 0f);
+    anns[3] = new Annotation("", "Intron3 (Aspy Noncoding)", '0', 0f);
+    anns[4] = new Annotation("", "Exon1 (Aspx Coding)", '0', 0f);
+    AlignmentAnnotation aa = new AlignmentAnnotation("", "", anns);
+    // no annotations:
+    assertNull(MegaFile.getPropertyFromAnnotation(0, null));
+    // null annotation:
+    assertNull(MegaFile.getPropertyFromAnnotation(0, aa));
+    // column out of range:
+    assertNull(MegaFile.getPropertyFromAnnotation(5, aa));
+    // domain with no Gene or Property:
+    assertNull(MegaFile.getPropertyFromAnnotation(1, aa));
+    // domain with Gene but no Property:
+    assertNull(MegaFile.getPropertyFromAnnotation(2, aa));
+    // domain with Gene and Property:
+    assertEquals("Noncoding", MegaFile.getPropertyFromAnnotation(3, aa));
+    assertEquals("Coding", MegaFile.getPropertyFromAnnotation(4, aa));
+  }
+
+  //@formatter:on
+  
+  /**
+   * Test parse of interleaved data with no blank lines to separate blocks of
+   * sequence data; to confirm we can handle this correctly
+   * 
+   * @throws IOException
+   */
+  @Test(groups = { "Functional" })
+  public void testParse_interleaved_noBlankLines() throws IOException
+  {
+    String data = INTERLEAVED.replace("\n\n", "\n");
+    MegaFile testee = new MegaFile(data, AppletFormatAdapter.PASTE);
+    assertEquals("Title not as expected", "Interleaved sequence data",
+            testee.getAlignmentProperty(MegaFile.PROP_TITLE));
+    Vector<SequenceI> seqs = testee.getSeqs();
+    // should be 2 sequences
+    assertEquals("Expected two sequences", 2, seqs.size());
+    // check sequence names correct and order preserved
+    assertEquals("First sequence id wrong", "U455", seqs.get(0).getName());
+    assertEquals("Second sequence id wrong", "CPZANT", seqs.get(1)
+            .getName());
+    // check sequence data
+    assertEquals("First sequence data wrong", "ABCDEFKLMNOP", seqs.get(0)
+            .getSequenceAsString());
+    assertEquals("Second sequence data wrong", "MNOPQRWXYZGC", seqs.get(1)
+            .getSequenceAsString());
+    assertTrue("File format is not flagged as interleaved",
+            testee.isInterleaved());
+  }
 }