JAL-653 test updated for 'use ID for description'
[jalview.git] / test / jalview / io / FeaturesFileTest.java
index 1592392..385e049 100644 (file)
@@ -23,10 +23,14 @@ package jalview.io;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceDummy;
 import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
 import jalview.schemes.AnnotationColourGradient;
 import jalview.schemes.GraduatedColor;
@@ -41,6 +45,8 @@ import org.testng.annotations.Test;
 public class FeaturesFileTest
 {
 
+  private static String simpleGffFile = "examples/testdata/simpleGff3.gff";
+
   @Test(groups = { "Functional" })
   public void testParse() throws Exception
   {
@@ -136,8 +142,9 @@ public class FeaturesFileTest
     AlignFrame af = new AlignFrame(al, 500, 500);
     Map<String, Object> colours = af.getFeatureRenderer()
             .getFeatureColours();
+    // GFF2 uses space as name/value separator in column 9
     String gffData = "METAL\tcc9900\n" + "GFF\n"
-            + "FER_CAPAA\tuniprot\tMETAL\t44\t45\t4.0\t.\t.\n"
+            + "FER_CAPAA\tuniprot\tMETAL\t44\t45\t4.0\t.\t.\tNote Iron-sulfur; Note 2Fe-2S\n"
             + "FER1_SOLLC\tuniprot\tPfam\t55\t130\t2.0\t.\t.";
     FeaturesFile featuresFile = new FeaturesFile(gffData,
             FormatAdapter.PASTE);
@@ -154,7 +161,7 @@ public class FeaturesFileTest
             .getSequenceFeatures();
     assertEquals(1, sfs.length);
     SequenceFeature sf = sfs[0];
-    assertEquals("uniprot", sf.description);
+    assertEquals("Iron-sulfur,2Fe-2S", sf.description);
     assertEquals(44, sf.begin);
     assertEquals(45, sf.end);
     assertEquals("uniprot", sf.featureGroup);
@@ -232,17 +239,18 @@ public class FeaturesFileTest
    * @throws Exception
    */
   @Test(groups = { "Functional" })
-  public void testParse_pureGff() throws Exception
+  public void testParse_pureGff3() throws Exception
   {
     File f = new File("examples/uniref50.fa");
     AlignmentI al = readAlignmentFile(f);
     AlignFrame af = new AlignFrame(al, 500, 500);
     Map<String, Object> colours = af.getFeatureRenderer()
             .getFeatureColours();
-    String gffData = "##gff-version 2\n"
+    // GFF3 uses '=' separator for name/value pairs in colum 9
+    String gffData = "##gff-version 3\n"
             + "FER_CAPAA\tuniprot\tMETAL\t39\t39\t0.0\t.\t.\t"
             + "Note=Iron-sulfur (2Fe-2S);Note=another note;evidence=ECO:0000255|PROSITE-ProRule:PRU00465\n"
-            + "FER1_SOLLC\tuniprot\tPfam\t55\t130\t3.0\t.\t.";
+            + "FER1_SOLLC\tuniprot\tPfam\t55\t130\t3.0\t.\t.\tID=$23";
     FeaturesFile featuresFile = new FeaturesFile(gffData,
             FormatAdapter.PASTE);
     assertTrue("Failed to parse features file",
@@ -254,7 +262,7 @@ public class FeaturesFileTest
     assertEquals(1, sfs.length);
     SequenceFeature sf = sfs[0];
     // description parsed from Note attribute
-    assertEquals("Iron-sulfur (2Fe-2S); another note", sf.description);
+    assertEquals("Iron-sulfur (2Fe-2S),another note", sf.description);
     assertEquals(39, sf.begin);
     assertEquals(39, sf.end);
     assertEquals("uniprot", sf.featureGroup);
@@ -267,7 +275,8 @@ public class FeaturesFileTest
     sfs = al.getSequenceAt(2).getDatasetSequence().getSequenceFeatures();
     assertEquals(1, sfs.length);
     sf = sfs[0];
-    assertEquals("uniprot", sf.description);
+    // ID used for description if available
+    assertEquals("$23", sf.description);
     assertEquals(55, sf.begin);
     assertEquals(130, sf.end);
     assertEquals("uniprot", sf.featureGroup);
@@ -319,4 +328,88 @@ public class FeaturesFileTest
     assertEquals(87, sf.end);
     assertEquals("METALLIC", sf.type);
   }
+
+  private void checkDatasetfromSimpleGff3(AlignmentI dataset)
+  {
+    assertEquals("no sequences extracted from GFF3 file", 2,
+            dataset.getHeight());
+  
+    SequenceI seq1 = dataset.findName("seq1");
+    SequenceI seq2 = dataset.findName("seq2");
+    assertNotNull(seq1);
+    assertNotNull(seq2);
+    assertFalse(
+            "Failed to replace dummy seq1 with real sequence",
+            seq1 instanceof SequenceDummy
+                    && ((SequenceDummy) seq1).isDummy());
+    assertFalse(
+            "Failed to replace dummy seq2 with real sequence",
+            seq2 instanceof SequenceDummy
+                    && ((SequenceDummy) seq2).isDummy());
+    String placeholderseq = new SequenceDummy("foo").getSequenceAsString();
+    assertFalse("dummy replacement buggy for seq1",
+            placeholderseq.equals(seq1.getSequenceAsString()));
+    assertFalse("dummy replacement buggy for seq2",
+            placeholderseq.equals(seq2.getSequenceAsString()));
+    assertNotNull("No features added to seq1", seq1.getSequenceFeatures());
+    assertEquals("Wrong number of features", 3,
+            seq1.getSequenceFeatures().length);
+    assertNull(seq2.getSequenceFeatures());
+    assertEquals(
+            "Wrong number of features",
+            0,
+            seq2.getSequenceFeatures() == null ? 0 : seq2
+                    .getSequenceFeatures().length);
+    assertTrue(
+            "Expected at least one CDNA/Protein mapping for seq1",
+            dataset.getCodonFrame(seq1) != null
+                    && dataset.getCodonFrame(seq1).size() > 0);
+  
+  }
+
+  @Test(groups = { "Functional" })
+  public void readGff3File() throws IOException
+  {
+    FeaturesFile gffreader = new FeaturesFile(true, simpleGffFile,
+            FormatAdapter.FILE);
+    Alignment dataset = new Alignment(gffreader.getSeqsAsArray());
+    gffreader.addProperties(dataset);
+    checkDatasetfromSimpleGff3(dataset);
+  }
+
+  @Test(groups = { "Functional" })
+  public void simpleGff3FileClass() throws IOException
+  {
+    AlignmentI dataset = new Alignment(new SequenceI[] {});
+    FeaturesFile ffile = new FeaturesFile(simpleGffFile,
+            FormatAdapter.FILE);
+  
+    boolean parseResult = ffile.parse(dataset, null, false, false);
+    assertTrue("return result should be true", parseResult);
+    checkDatasetfromSimpleGff3(dataset);
+  }
+
+  @Test(groups = { "Functional" })
+  public void simpleGff3FileLoader() throws IOException
+  {
+    AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
+            simpleGffFile, FormatAdapter.FILE);
+    assertTrue(
+            "Didn't read the alignment into an alignframe from Gff3 File",
+            af != null);
+    checkDatasetfromSimpleGff3(af.getViewport().getAlignment());
+  }
+
+  @Test(groups = { "Functional" })
+  public void simpleGff3RelaxedIdMatching() throws IOException
+  {
+    AlignmentI dataset = new Alignment(new SequenceI[] {});
+    FeaturesFile ffile = new FeaturesFile(simpleGffFile,
+            FormatAdapter.FILE);
+  
+    boolean parseResult = ffile.parse(dataset, null, false, true);
+    assertTrue("return result (relaxedID matching) should be true",
+            parseResult);
+    checkDatasetfromSimpleGff3(dataset);
+  }
 }