JAL-2446 add call to SequenceFeatures.delete(); use varargs for type
[jalview.git] / test / jalview / datamodel / features / SequenceFeaturesTest.java
index 7edd67d..84a07b4 100644 (file)
@@ -7,20 +7,21 @@ import static org.testng.Assert.assertTrue;
 import jalview.datamodel.SequenceFeature;
 
 import java.util.List;
+import java.util.Set;
 
 import org.testng.annotations.Test;
 
 public class SequenceFeaturesTest
 {
   @Test(groups = "Functional")
-  public void testGetFeatures()
+  public void testGetPositionalFeatures()
   {
     SequenceFeatures store = new SequenceFeatures();
     SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
             Float.NaN, null);
     store.add(sf1);
-    // same range
-    SequenceFeature sf2 = new SequenceFeature("Metal", "desc", 10, 20,
+    // same range, different description
+    SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
             Float.NaN, null);
     store.add(sf2);
     // discontiguous range
@@ -52,16 +53,16 @@ public class SequenceFeaturesTest
     store.add(sf9);
 
     /*
-     * get all features
+     * get all positional features
      */
-    List<SequenceFeature> features = store.getFeatures();
-    assertEquals(features.size(), 9);
+    List<SequenceFeature> features = store.getPositionalFeatures();
+    assertEquals(features.size(), 8);
     assertTrue(features.contains(sf1));
     assertTrue(features.contains(sf2));
     assertTrue(features.contains(sf3));
     assertTrue(features.contains(sf4));
     assertTrue(features.contains(sf5));
-    assertTrue(features.contains(sf6));
+    assertFalse(features.contains(sf6)); // non-positional
     assertTrue(features.contains(sf7));
     assertTrue(features.contains(sf8));
     assertTrue(features.contains(sf9));
@@ -69,24 +70,24 @@ public class SequenceFeaturesTest
     /*
      * get features by type
      */
-    assertTrue(store.getFeatures(null).isEmpty());
-    assertTrue(store.getFeatures("Cath").isEmpty());
-    assertTrue(store.getFeatures("METAL").isEmpty());
+    assertTrue(store.getPositionalFeatures((String) null).isEmpty());
+    assertTrue(store.getPositionalFeatures("Cath").isEmpty());
+    assertTrue(store.getPositionalFeatures("METAL").isEmpty());
 
-    features = store.getFeatures("Metal");
-    assertEquals(features.size(), 6);
+    features = store.getPositionalFeatures("Metal");
+    assertEquals(features.size(), 5);
     assertTrue(features.contains(sf1));
     assertTrue(features.contains(sf2));
     assertTrue(features.contains(sf3));
     assertTrue(features.contains(sf4));
     assertTrue(features.contains(sf5));
-    assertTrue(features.contains(sf6));
+    assertFalse(features.contains(sf6));
 
-    features = store.getFeatures("Disulphide bond");
+    features = store.getPositionalFeatures("Disulphide bond");
     assertEquals(features.size(), 1);
     assertTrue(features.contains(sf7));
 
-    features = store.getFeatures("Pfam");
+    features = store.getPositionalFeatures("Pfam");
     assertEquals(features.size(), 2);
     assertTrue(features.contains(sf8));
     assertTrue(features.contains(sf9));
@@ -130,7 +131,7 @@ public class SequenceFeaturesTest
     /*
      * get contact features by type
      */
-    assertTrue(store.getContactFeatures(null).isEmpty());
+    assertTrue(store.getContactFeatures((String) null).isEmpty());
     assertTrue(store.getContactFeatures("Cath").isEmpty());
     assertTrue(store.getContactFeatures("Pfam").isEmpty());
     assertTrue(store.getContactFeatures("DISULPHIDE BOND").isEmpty());
@@ -170,8 +171,8 @@ public class SequenceFeaturesTest
     SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "desc", 18,
             45, Float.NaN, null);
     store.add(sf6);
-    // on more non-positional
-    SequenceFeature sf7 = new SequenceFeature("Pfam", "desc", 0, 0,
+    // one more non-positional, different description
+    SequenceFeature sf7 = new SequenceFeature("Pfam", "desc2", 0, 0,
             Float.NaN, null);
     store.add(sf7);
   
@@ -187,7 +188,7 @@ public class SequenceFeaturesTest
     /*
      * get non-positional features by type
      */
-    assertTrue(store.getNonPositionalFeatures(null).isEmpty());
+    assertTrue(store.getNonPositionalFeatures((String) null).isEmpty());
     assertTrue(store.getNonPositionalFeatures("Cath").isEmpty());
     assertTrue(store.getNonPositionalFeatures("PFAM").isEmpty());
   
@@ -239,36 +240,36 @@ public class SequenceFeaturesTest
     // null type is weird but possible:
     SequenceFeature sf13 = addFeature(sf, null, 5, 12);
   
-    List<SequenceFeature> overlaps = sf.findFeatures("Pfam", 200, 200);
+    List<SequenceFeature> overlaps = sf.findFeatures(200, 200, "Pfam");
     assertTrue(overlaps.isEmpty());
   
-    overlaps = sf.findFeatures("Pfam", 1, 9);
+    overlaps = sf.findFeatures( 1, 9, "Pfam");
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf2));
   
-    overlaps = sf.findFeatures("Pfam", 5, 18);
+    overlaps = sf.findFeatures( 5, 18, "Pfam");
     assertEquals(overlaps.size(), 2);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
   
-    overlaps = sf.findFeatures("Pfam", 30, 40);
+    overlaps = sf.findFeatures(30, 40, "Pfam");
     assertEquals(overlaps.size(), 3);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf3));
     assertTrue(overlaps.contains(sf4));
   
-    overlaps = sf.findFeatures("Pfam", 80, 90);
+    overlaps = sf.findFeatures( 80, 90, "Pfam");
     assertEquals(overlaps.size(), 2);
     assertTrue(overlaps.contains(sf4));
     assertTrue(overlaps.contains(sf5));
   
-    overlaps = sf.findFeatures("Pfam", 68, 70);
+    overlaps = sf.findFeatures( 68, 70, "Pfam");
     assertEquals(overlaps.size(), 3);
     assertTrue(overlaps.contains(sf4));
     assertTrue(overlaps.contains(sf5));
     assertTrue(overlaps.contains(sf6));
 
-    overlaps = sf.findFeatures("Cath", 16, 69);
+    overlaps = sf.findFeatures(16, 69, "Cath");
     assertEquals(overlaps.size(), 4);
     assertTrue(overlaps.contains(sf7));
     assertFalse(overlaps.contains(sf8));
@@ -277,10 +278,219 @@ public class SequenceFeaturesTest
     assertTrue(overlaps.contains(sf11));
     assertFalse(overlaps.contains(sf12));
 
-    assertTrue(sf.findFeatures("Metal", 0, 1000).isEmpty());
+    assertTrue(sf.findFeatures(0, 1000, "Metal").isEmpty());
 
-    overlaps = sf.findFeatures(null, 7, 7);
+    overlaps = sf.findFeatures(7, 7, (String) null);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf13));
   }
+
+  @Test(groups = "Functional")
+  public void testDelete()
+  {
+    SequenceFeatures sf = new SequenceFeatures();
+    SequenceFeature sf1 = addFeature(sf, "Pfam", 10, 50);
+    assertTrue(sf.getPositionalFeatures().contains(sf1));
+
+    assertFalse(sf.delete(null));
+    SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 15, 0f, null);
+    assertFalse(sf.delete(sf2)); // not added, can't delete it
+    assertTrue(sf.delete(sf1));
+    assertTrue(sf.getPositionalFeatures().isEmpty());
+  }
+
+  @Test(groups = "Functional")
+  public void testHasFeatures()
+  {
+    SequenceFeatures sf = new SequenceFeatures();
+    assertFalse(sf.hasFeatures());
+
+    SequenceFeature sf1 = addFeature(sf, "Pfam", 10, 50);
+    assertTrue(sf.hasFeatures());
+
+    sf.delete(sf1);
+    assertFalse(sf.hasFeatures());
+  }
+
+  /**
+   * Tests for the method that gets feature groups for positional or
+   * non-positional features
+   */
+  @Test(groups = "Functional")
+  public void testGetFeatureGroups()
+  {
+    SequenceFeatures sf = new SequenceFeatures();
+    assertTrue(sf.getFeatureGroups(true).isEmpty());
+    assertTrue(sf.getFeatureGroups(false).isEmpty());
+
+    /*
+     * add a non-positional feature (begin/end = 0/0)
+     */
+    SequenceFeature sfx = new SequenceFeature("AType", "Desc", 0, 0, 0f,
+            "AGroup");
+    sf.add(sfx);
+    Set<String> groups = sf.getFeatureGroups(true); // for positional
+    assertTrue(groups.isEmpty());
+    groups = sf.getFeatureGroups(false); // for non-positional
+    assertEquals(groups.size(), 1);
+    assertTrue(groups.contains("AGroup"));
+
+    /*
+     * add, then delete, more non-positional features of different types
+     */
+    SequenceFeature sfy = new SequenceFeature("AnotherType", "Desc", 0, 0,
+            0f,
+            "AnotherGroup");
+    sf.add(sfy);
+    SequenceFeature sfz = new SequenceFeature("AThirdType", "Desc", 0, 0,
+            0f,
+            null);
+    sf.add(sfz);
+    groups = sf.getFeatureGroups(false);
+    assertEquals(groups.size(), 3);
+    assertTrue(groups.contains("AGroup"));
+    assertTrue(groups.contains("AnotherGroup"));
+    assertTrue(groups.contains(null)); // null is a possible group
+    sf.delete(sfz);
+    sf.delete(sfy);
+    groups = sf.getFeatureGroups(false);
+    assertEquals(groups.size(), 1);
+    assertTrue(groups.contains("AGroup"));
+
+    /*
+     * add positional features
+     */
+    SequenceFeature sf1 = new SequenceFeature("Pfam", "Desc", 10, 50, 0f,
+            "PfamGroup");
+    sf.add(sf1);
+    groups = sf.getFeatureGroups(true);
+    assertEquals(groups.size(), 1);
+    assertTrue(groups.contains("PfamGroup"));
+    groups = sf.getFeatureGroups(false); // non-positional unchanged
+    assertEquals(groups.size(), 1);
+    assertTrue(groups.contains("AGroup"));
+
+    SequenceFeature sf2 = new SequenceFeature("Cath", "Desc", 10, 50, 0f,
+            null);
+    sf.add(sf2);
+    groups = sf.getFeatureGroups(true);
+    assertEquals(groups.size(), 2);
+    assertTrue(groups.contains("PfamGroup"));
+    assertTrue(groups.contains(null));
+
+    sf.delete(sf1);
+    sf.delete(sf2);
+    assertTrue(sf.getFeatureGroups(true).isEmpty());
+
+    SequenceFeature sf3 = new SequenceFeature("CDS", "", 10, 50, 0f,
+            "Ensembl");
+    sf.add(sf3);
+    SequenceFeature sf4 = new SequenceFeature("exon", "", 10, 50, 0f,
+            "Ensembl");
+    sf.add(sf4);
+    groups = sf.getFeatureGroups(true);
+    assertEquals(groups.size(), 1);
+    assertTrue(groups.contains("Ensembl"));
+
+    /*
+     * delete last Ensembl group feature from CDS features
+     * but still have one in exon features
+     */
+    sf.delete(sf3);
+    groups = sf.getFeatureGroups(true);
+    assertEquals(groups.size(), 1);
+    assertTrue(groups.contains("Ensembl"));
+
+    /*
+     * delete the last non-positional feature
+     */
+    sf.delete(sfx);
+    groups = sf.getFeatureGroups(false);
+    assertTrue(groups.isEmpty());
+  }
+
+  @Test(groups = "Functional")
+  public void testGetFeatureTypesForGroups()
+  {
+    SequenceFeatures sf = new SequenceFeatures();
+    assertTrue(sf.getFeatureTypesForGroups(true, (String) null).isEmpty());
+  
+    /*
+     * add feature with group = "Uniprot", type = "helix"
+     */
+    String groupUniprot = "Uniprot";
+    SequenceFeature sf1 = new SequenceFeature("helix", "Desc", 10, 50, 0f,
+            groupUniprot);
+    sf.add(sf1);
+    Set<String> groups = sf.getFeatureTypesForGroups(true, groupUniprot);
+    assertEquals(groups.size(), 1);
+    assertTrue(groups.contains("helix"));
+    assertTrue(sf.getFeatureTypesForGroups(true, (String) null).isEmpty());
+  
+    /*
+     * add feature with group = "Uniprot", type = "strand"
+     */
+    SequenceFeature sf2 = new SequenceFeature("strand", "Desc", 10, 50, 0f,
+            groupUniprot);
+    sf.add(sf2);
+    groups = sf.getFeatureTypesForGroups(true, groupUniprot);
+    assertEquals(groups.size(), 2);
+    assertTrue(groups.contains("helix"));
+    assertTrue(groups.contains("strand"));
+
+    /*
+     * delete the "strand" Uniprot feature - still have "helix"
+     */
+    sf.delete(sf2);
+    groups = sf.getFeatureTypesForGroups(true, groupUniprot);
+    assertEquals(groups.size(), 1);
+    assertTrue(groups.contains("helix"));
+
+    /*
+     * delete the "helix" Uniprot feature - none left
+     */
+    sf.delete(sf1);
+    assertTrue(sf.getFeatureTypesForGroups(true, groupUniprot).isEmpty());
+
+    /*
+     * add some null group features
+     */
+    SequenceFeature sf3 = new SequenceFeature("strand", "Desc", 10, 50, 0f,
+            null);
+    sf.add(sf3);
+    SequenceFeature sf4 = new SequenceFeature("turn", "Desc", 10, 50, 0f,
+            null);
+    sf.add(sf4);
+    groups = sf.getFeatureTypesForGroups(true, (String) null);
+    assertEquals(groups.size(), 2);
+    assertTrue(groups.contains("strand"));
+    assertTrue(groups.contains("turn"));
+
+    /*
+     * add strand/Cath  and turn/Scop and query for one or both groups
+     * (find feature types for groups selected in Feature Settings)
+     */
+    SequenceFeature sf5 = new SequenceFeature("strand", "Desc", 10, 50, 0f,
+            "Cath");
+    sf.add(sf5);
+    SequenceFeature sf6 = new SequenceFeature("turn", "Desc", 10, 50, 0f,
+            "Scop");
+    sf.add(sf6);
+    groups = sf.getFeatureTypesForGroups(true, "Cath");
+    assertEquals(groups.size(), 1);
+    assertTrue(groups.contains("strand"));
+    groups = sf.getFeatureTypesForGroups(true, "Scop");
+    assertEquals(groups.size(), 1);
+    assertTrue(groups.contains("turn"));
+    groups = sf.getFeatureTypesForGroups(true, "Cath", "Scop");
+    assertEquals(groups.size(), 2);
+    assertTrue(groups.contains("turn"));
+    assertTrue(groups.contains("strand"));
+    // alternative vararg syntax
+    groups = sf.getFeatureTypesForGroups(true, new String[] { "Cath",
+        "Scop" });
+    assertEquals(groups.size(), 2);
+    assertTrue(groups.contains("turn"));
+    assertTrue(groups.contains("strand"));
+  }
 }