JAL-3383 code and unit test tweaks
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 3 Oct 2019 12:39:53 +0000 (13:39 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 3 Oct 2019 12:39:53 +0000 (13:39 +0100)
src/jalview/datamodel/features/FeatureStore.java
src/jalview/datamodel/features/SequenceFeatures.java
test/jalview/datamodel/features/FeatureStoreLinkedTest.java
test/jalview/datamodel/features/FeatureStoreNCListBufferTest.java
test/jalview/datamodel/features/FeatureStoreTest.java

index c582e56..6204f18 100644 (file)
@@ -355,6 +355,14 @@ public class FeatureStore
     return true;
   }
 
+  /**
+   * A helper method that adds to the result list any features from the
+   * collection provided whose feature group matches the specified group
+   * 
+   * @param group
+   * @param sfs
+   * @param result
+   */
   private void addFeaturesForGroup(String group,
           Collection<SequenceFeature> sfs, List<SequenceFeature> result)
   {
@@ -499,9 +507,37 @@ public class FeatureStore
     return removed;
   }
 
-  public List<SequenceFeature> findOverlappingFeatures(long start, long end)
+  public List<SequenceFeature> findFeatures(long start, long end)
   {
-    return findOverlappingFeatures(start, end, null);
+    return findFeatures(start, end, null);
+  }
+
+  /**
+   * Returns a (possibly empty) list of features whose extent overlaps the given
+   * range. The returned list is not ordered. Contact features are included if
+   * either of the contact points lies within the range. If the {@code result}
+   * parameter is not null, new entries are added to this list and the (possibly
+   * extended) list returned.
+   * 
+   * @param start
+   *          start position of overlap range (inclusive)
+   * @param end
+   *          end position of overlap range (inclusive)
+   * @param result
+   * @return
+   */
+  public List<SequenceFeature> findFeatures(long start, long end,
+          List<SequenceFeature> result)
+  {
+    if (result == null)
+    {
+      result = new ArrayList<>();
+    }
+
+    findContactFeatures(start, end, result);
+    features.findOverlaps(start, end, result);
+
+    return result;
   }
 
   public List<SequenceFeature> getContactFeatures()
@@ -540,8 +576,19 @@ public class FeatureStore
               : nonPositionalFeatures.size();
     }
 
-    return (contactFeatureStarts == null ? 0 : contactFeatureStarts.size())
-            + features.size();
+    int size = 0;
+
+    if (contactFeatureStarts != null)
+    {
+      // note a contact feature (start/end) counts as one
+      size += contactFeatureStarts.size();
+    }
+
+    if (features != null)
+    {
+      size += features.size();
+    }
+    return size;
   }
 
   /**
@@ -627,41 +674,50 @@ public class FeatureStore
     return positional ? positionalMinScore : nonPositionalMinScore;
   }
 
+  /**
+   * Answers a (possibly empty) list of all non-positional features
+   * 
+   * @return
+   */
   public List<SequenceFeature> getNonPositionalFeatures()
   {
-    return getNonPositionalFeatures(new ArrayList<>());
+    List<SequenceFeature> result = new ArrayList<>();
+    getNonPositionalFeatures(result);
+    return result;
   }
 
   /**
-   * Answers a list of all non-positional features. If there are none, returns
-   * an immutable empty list.
+   * Adds any stored non-positional features to the result list
    * 
    * @return
    */
-  public List<SequenceFeature> getNonPositionalFeatures(
-          List<SequenceFeature> result)
+  public void getNonPositionalFeatures(List<SequenceFeature> result)
   {
     if (nonPositionalFeatures != null)
     {
       result.addAll(nonPositionalFeatures);
     }
-    return result;
   }
 
+  /**
+   * Returns a (possibly empty) list of all positional features stored
+   * 
+   * @return
+   */
   public List<SequenceFeature> getPositionalFeatures()
   {
-    return getPositionalFeatures(new ArrayList<>());
+    List<SequenceFeature> result = new ArrayList<>();
+    getPositionalFeatures(result);
+
+    return result;
   }
 
   /**
-   * Answers a list of all positional features stored, in no guaranteed order
-   * 
-   * @return
+   * Adds all positional features stored to the result list, in no guaranteed
+   * order, and with no check for duplicates
    */
-  public List<SequenceFeature> getPositionalFeatures(
-          List<SequenceFeature> result)
+  public void getPositionalFeatures(List<SequenceFeature> result)
   {
-
     /*
      * add any contact features - from the list by start position
      */
@@ -677,8 +733,6 @@ public class FeatureStore
     {
       result.addAll(features);
     }
-
-    return result;
   }
 
   /**
@@ -703,7 +757,7 @@ public class FeatureStore
             && !contactFeatureStarts.isEmpty())
             || (nonPositionalFeatures != null
                     && !nonPositionalFeatures.isEmpty())
-            || features.size() > 0;
+            || (features != null && features.size() > 0);
 
     return !hasFeatures;
   }
@@ -938,32 +992,4 @@ public class FeatureStore
     }
   }
 
-  /**
-   * Returns a (possibly empty) list of features whose extent overlaps the given
-   * range. The returned list is not ordered. Contact features are included if
-   * either of the contact points lies within the range. If the {@code result}
-   * parameter is not null, new entries are added to this list and the (possibly
-   * extended) list returned.
-   * 
-   * @param start
-   *          start position of overlap range (inclusive)
-   * @param end
-   *          end position of overlap range (inclusive)
-   * @param result
-   * @return
-   */
-  public List<SequenceFeature> findOverlappingFeatures(long start, long end,
-          List<SequenceFeature> result)
-  {
-    if (result == null)
-    {
-      result = new ArrayList<>();
-    }
-
-    findContactFeatures(start, end, result);
-    features.findOverlaps(start, end, result);
-
-    return result;
-  }
-
 }
index 9a7ef1b..c75dbe0 100644 (file)
@@ -111,7 +111,7 @@ public class SequenceFeatures implements SequenceFeaturesI
     List<SequenceFeature> result = new ArrayList<>();
     for (FeatureStore featureSet : varargToTypes(type))
     {
-      featureSet.findOverlappingFeatures(from, to, result);
+      featureSet.findFeatures(from, to, result);
     }
     return result;
   }
@@ -477,7 +477,7 @@ public class SequenceFeatures implements SequenceFeaturesI
     {
       return list == null ? new ArrayList<>() : list;
     }
-    return fs.findOverlappingFeatures(pos, pos, list);
+    return fs.findFeatures(pos, pos, list);
   }
 
   @Override
index df4e983..23d0d8d 100644 (file)
@@ -42,21 +42,21 @@ public class FeatureStoreLinkedTest
     SequenceFeature sf3 = new SequenceFeature("", "", 20, 35, Float.NaN, null);
     fs.addFeature(sf3);
 
-    List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+    List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
     assertTrue(overlaps.isEmpty());
 
-    overlaps = fs.findOverlappingFeatures(8, 10);
+    overlaps = fs.findFeatures(8, 10);
     assertEquals(overlaps.size(), 2);
     assertTrue(overlaps.contains(sf0));
     assertTrue(overlaps.contains(sf1));
 
-    overlaps = fs.findOverlappingFeatures(12, 16);
+    overlaps = fs.findFeatures(12, 16);
     assertEquals(overlaps.size(), 3);
     assertTrue(overlaps.contains(sf0));
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
 
-    overlaps = fs.findOverlappingFeatures(33, 33);
+    overlaps = fs.findFeatures(33, 33);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf3));
   }
@@ -74,25 +74,25 @@ public class FeatureStoreLinkedTest
     fs.addFeature(sf4);
     SequenceFeature sf5 = addFeature(fs, 35, 36);
 
-    List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+    List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
     assertTrue(overlaps.isEmpty());
 
-    overlaps = fs.findOverlappingFeatures(10, 15);
+    overlaps = fs.findFeatures(10, 15);
     assertEquals(overlaps.size(), 2);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
 
-    overlaps = fs.findOverlappingFeatures(45, 60);
+    overlaps = fs.findFeatures(45, 60);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf1));
 
-    overlaps = fs.findOverlappingFeatures(32, 38);
+    overlaps = fs.findFeatures(32, 38);
     assertEquals(overlaps.size(), 3);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
     assertTrue(overlaps.contains(sf5));
 
-    overlaps = fs.findOverlappingFeatures(15, 25);
+    overlaps = fs.findFeatures(15, 25);
     assertEquals(overlaps.size(), 4);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
@@ -111,30 +111,30 @@ public class FeatureStoreLinkedTest
     SequenceFeature sf5 = addFeature(fs, 60, 100);
     SequenceFeature sf6 = addFeature(fs, 70, 70);
 
-    List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
+    List<SequenceFeature> overlaps = fs.findFeatures(200, 200);
     assertTrue(overlaps.isEmpty());
 
-    overlaps = fs.findOverlappingFeatures(1, 9);
+    overlaps = fs.findFeatures(1, 9);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf2));
 
-    overlaps = fs.findOverlappingFeatures(5, 18);
+    overlaps = fs.findFeatures(5, 18);
     assertEquals(overlaps.size(), 2);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
 
-    overlaps = fs.findOverlappingFeatures(30, 40);
+    overlaps = fs.findFeatures(30, 40);
     assertEquals(overlaps.size(), 3);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf3));
     assertTrue(overlaps.contains(sf4));
 
-    overlaps = fs.findOverlappingFeatures(80, 90);
+    overlaps = fs.findFeatures(80, 90);
     assertEquals(overlaps.size(), 2);
     assertTrue(overlaps.contains(sf4));
     assertTrue(overlaps.contains(sf5));
 
-    overlaps = fs.findOverlappingFeatures(68, 70);
+    overlaps = fs.findFeatures(68, 70);
     assertEquals(overlaps.size(), 3);
     assertTrue(overlaps.contains(sf4));
     assertTrue(overlaps.contains(sf5));
@@ -169,33 +169,33 @@ public class FeatureStoreLinkedTest
     /*
      * neither contact point in range
      */
-    List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+    List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
     assertTrue(overlaps.isEmpty());
 
     /*
      * neither contact point in range
      */
-    overlaps = fs.findOverlappingFeatures(11, 19);
+    overlaps = fs.findFeatures(11, 19);
     assertTrue(overlaps.isEmpty());
 
     /*
      * first contact point in range
      */
-    overlaps = fs.findOverlappingFeatures(5, 15);
+    overlaps = fs.findFeatures(5, 15);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf));
 
     /*
      * second contact point in range
      */
-    overlaps = fs.findOverlappingFeatures(15, 25);
+    overlaps = fs.findFeatures(15, 25);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf));
 
     /*
      * both contact points in range
      */
-    overlaps = fs.findOverlappingFeatures(5, 25);
+    overlaps = fs.findFeatures(5, 25);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf));
   }
index 5cf74bc..14f0f07 100644 (file)
@@ -38,21 +38,21 @@ public class FeatureStoreNCListBufferTest
     fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
     fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
 
-    List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+    List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
     assertTrue(overlaps.isEmpty());
 
-    overlaps = fs.findOverlappingFeatures(8, 10);
+    overlaps = fs.findFeatures(8, 10);
     assertEquals(overlaps.size(), 2);
     assertEquals(overlaps.get(0).getEnd(), 20);
     assertEquals(overlaps.get(1).getEnd(), 20);
 
-    overlaps = fs.findOverlappingFeatures(12, 16);
+    overlaps = fs.findFeatures(12, 16);
     assertEquals(overlaps.size(), 3);
     assertEquals(overlaps.get(0).getEnd(), 20);
     assertEquals(overlaps.get(1).getEnd(), 20);
     assertEquals(overlaps.get(2).getEnd(), 25);
 
-    overlaps = fs.findOverlappingFeatures(33, 33);
+    overlaps = fs.findFeatures(33, 33);
     assertEquals(overlaps.size(), 1);
     assertEquals(overlaps.get(0).getEnd(), 35);
   }
@@ -70,25 +70,25 @@ public class FeatureStoreNCListBufferTest
     fs.addFeature(sf4);
     SequenceFeature sf5 = addFeature(fs, 35, 36);
 
-    List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+    List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
     assertTrue(overlaps.isEmpty());
 
-    overlaps = fs.findOverlappingFeatures(10, 15);
+    overlaps = fs.findFeatures(10, 15);
     assertEquals(overlaps.size(), 2);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
 
-    overlaps = fs.findOverlappingFeatures(45, 60);
+    overlaps = fs.findFeatures(45, 60);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf1));
 
-    overlaps = fs.findOverlappingFeatures(32, 38);
+    overlaps = fs.findFeatures(32, 38);
     assertEquals(overlaps.size(), 3);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
     assertTrue(overlaps.contains(sf5));
 
-    overlaps = fs.findOverlappingFeatures(15, 25);
+    overlaps = fs.findFeatures(15, 25);
     assertEquals(overlaps.size(), 4);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
@@ -107,30 +107,30 @@ public class FeatureStoreNCListBufferTest
     SequenceFeature sf5 = addFeature(fs, 60, 100);
     SequenceFeature sf6 = addFeature(fs, 70, 70);
 
-    List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
+    List<SequenceFeature> overlaps = fs.findFeatures(200, 200);
     assertTrue(overlaps.isEmpty());
 
-    overlaps = fs.findOverlappingFeatures(1, 9);
+    overlaps = fs.findFeatures(1, 9);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf2));
 
-    overlaps = fs.findOverlappingFeatures(5, 18);
+    overlaps = fs.findFeatures(5, 18);
     assertEquals(overlaps.size(), 2);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
 
-    overlaps = fs.findOverlappingFeatures(30, 40);
+    overlaps = fs.findFeatures(30, 40);
     assertEquals(overlaps.size(), 3);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf3));
     assertTrue(overlaps.contains(sf4));
 
-    overlaps = fs.findOverlappingFeatures(80, 90);
+    overlaps = fs.findFeatures(80, 90);
     assertEquals(overlaps.size(), 2);
     assertTrue(overlaps.contains(sf4));
     assertTrue(overlaps.contains(sf5));
 
-    overlaps = fs.findOverlappingFeatures(68, 70);
+    overlaps = fs.findFeatures(68, 70);
     assertEquals(overlaps.size(), 3);
     assertTrue(overlaps.contains(sf4));
     assertTrue(overlaps.contains(sf5));
@@ -165,33 +165,33 @@ public class FeatureStoreNCListBufferTest
     /*
      * neither contact point in range
      */
-    List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+    List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
     assertTrue(overlaps.isEmpty());
 
     /*
      * neither contact point in range
      */
-    overlaps = fs.findOverlappingFeatures(11, 19);
+    overlaps = fs.findFeatures(11, 19);
     assertTrue(overlaps.isEmpty());
 
     /*
      * first contact point in range
      */
-    overlaps = fs.findOverlappingFeatures(5, 15);
+    overlaps = fs.findFeatures(5, 15);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf));
 
     /*
      * second contact point in range
      */
-    overlaps = fs.findOverlappingFeatures(15, 25);
+    overlaps = fs.findFeatures(15, 25);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf));
 
     /*
      * both contact points in range
      */
-    overlaps = fs.findOverlappingFeatures(5, 25);
+    overlaps = fs.findFeatures(5, 25);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf));
   }
index bc179f6..db0fabf 100644 (file)
@@ -4,6 +4,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
 import jalview.datamodel.SequenceFeature;
 
@@ -34,21 +35,21 @@ public class FeatureStoreTest
     fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
     fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
 
-    List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+    List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
     assertTrue(overlaps.isEmpty());
 
-    overlaps = fs.findOverlappingFeatures(8, 10);
+    overlaps = fs.findFeatures(8, 10);
     assertEquals(overlaps.size(), 2);
     assertEquals(overlaps.get(0).getEnd(), 20);
     assertEquals(overlaps.get(1).getEnd(), 20);
 
-    overlaps = fs.findOverlappingFeatures(12, 16);
+    overlaps = fs.findFeatures(12, 16);
     assertEquals(overlaps.size(), 3);
     assertEquals(overlaps.get(0).getEnd(), 20);
     assertEquals(overlaps.get(1).getEnd(), 20);
     assertEquals(overlaps.get(2).getEnd(), 25);
 
-    overlaps = fs.findOverlappingFeatures(33, 33);
+    overlaps = fs.findFeatures(33, 33);
     assertEquals(overlaps.size(), 1);
     assertEquals(overlaps.get(0).getEnd(), 35);
   }
@@ -66,25 +67,25 @@ public class FeatureStoreTest
     fs.addFeature(sf4);
     SequenceFeature sf5 = addFeature(fs, 35, 36);
 
-    List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+    List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
     assertTrue(overlaps.isEmpty());
 
-    overlaps = fs.findOverlappingFeatures(10, 15);
+    overlaps = fs.findFeatures(10, 15);
     assertEquals(overlaps.size(), 2);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
 
-    overlaps = fs.findOverlappingFeatures(45, 60);
+    overlaps = fs.findFeatures(45, 60);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf1));
 
-    overlaps = fs.findOverlappingFeatures(32, 38);
+    overlaps = fs.findFeatures(32, 38);
     assertEquals(overlaps.size(), 3);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
     assertTrue(overlaps.contains(sf5));
 
-    overlaps = fs.findOverlappingFeatures(15, 25);
+    overlaps = fs.findFeatures(15, 25);
     assertEquals(overlaps.size(), 4);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
@@ -103,30 +104,30 @@ public class FeatureStoreTest
     SequenceFeature sf5 = addFeature(fs, 60, 100);
     SequenceFeature sf6 = addFeature(fs, 70, 70);
 
-    List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
+    List<SequenceFeature> overlaps = fs.findFeatures(200, 200);
     assertTrue(overlaps.isEmpty());
 
-    overlaps = fs.findOverlappingFeatures(1, 9);
+    overlaps = fs.findFeatures(1, 9);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf2));
 
-    overlaps = fs.findOverlappingFeatures(5, 18);
+    overlaps = fs.findFeatures(5, 18);
     assertEquals(overlaps.size(), 2);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf2));
 
-    overlaps = fs.findOverlappingFeatures(30, 40);
+    overlaps = fs.findFeatures(30, 40);
     assertEquals(overlaps.size(), 3);
     assertTrue(overlaps.contains(sf1));
     assertTrue(overlaps.contains(sf3));
     assertTrue(overlaps.contains(sf4));
 
-    overlaps = fs.findOverlappingFeatures(80, 90);
+    overlaps = fs.findFeatures(80, 90);
     assertEquals(overlaps.size(), 2);
     assertTrue(overlaps.contains(sf4));
     assertTrue(overlaps.contains(sf5));
 
-    overlaps = fs.findOverlappingFeatures(68, 70);
+    overlaps = fs.findFeatures(68, 70);
     assertEquals(overlaps.size(), 3);
     assertTrue(overlaps.contains(sf4));
     assertTrue(overlaps.contains(sf5));
@@ -161,38 +162,132 @@ public class FeatureStoreTest
     /*
      * neither contact point in range
      */
-    List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+    List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
     assertTrue(overlaps.isEmpty());
 
     /*
      * neither contact point in range
      */
-    overlaps = fs.findOverlappingFeatures(11, 19);
+    overlaps = fs.findFeatures(11, 19);
     assertTrue(overlaps.isEmpty());
 
     /*
      * first contact point in range
      */
-    overlaps = fs.findOverlappingFeatures(5, 15);
+    overlaps = fs.findFeatures(5, 15);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf));
 
     /*
      * second contact point in range
      */
-    overlaps = fs.findOverlappingFeatures(15, 25);
+    overlaps = fs.findFeatures(15, 25);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf));
 
     /*
      * both contact points in range
      */
-    overlaps = fs.findOverlappingFeatures(5, 25);
+    overlaps = fs.findFeatures(5, 25);
     assertEquals(overlaps.size(), 1);
     assertTrue(overlaps.contains(sf));
   }
 
   @Test(groups = "Functional")
+  public void testGetPositionalFeatures_withResultList()
+  {
+    FeatureStore store = newFeatureStore();
+    SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
+            Float.NaN, null);
+    store.addFeature(sf1);
+    // contact feature
+    SequenceFeature sf2 = new SequenceFeature("Disulphide bond", "desc", 18,
+            45, Float.NaN, null);
+    store.addFeature(sf2);
+
+    List<SequenceFeature> features = new ArrayList<>();
+    store.getPositionalFeatures(features);
+    assertEquals(features.size(), 2);
+    assertTrue(features.contains(sf1));
+    assertTrue(features.contains(sf2));
+
+    /*
+     * no check for duplicates
+     */
+    features.remove(sf1);
+    assertEquals(features.size(), 1);
+    assertTrue(features.contains(sf2));
+    store.getPositionalFeatures(features);
+    assertEquals(features.size(), 3);
+    assertTrue(features.contains(sf1));
+    assertTrue(features.contains(sf2)); // two copies now
+    features.remove(sf2);
+    assertTrue(features.contains(sf2)); // one copy left
+    assertEquals(features.size(), 2);
+
+    /*
+     * null argument throws exception
+     */
+    try
+    {
+      store.getPositionalFeatures(null);
+      fail("expected exception");
+    } catch (NullPointerException e)
+    {
+      // expected
+    }
+  }
+
+  @Test(groups = "Functional")
+  public void testGetNonPositionalFeatures()
+  {
+    FeatureStore store = newFeatureStore();
+    List<SequenceFeature> features = store.getNonPositionalFeatures();
+    assertTrue(features.isEmpty());
+
+    SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
+            Float.NaN, null);
+    store.addFeature(sf1);
+    assertTrue(features.isEmpty());
+
+    SequenceFeature sf2 = new SequenceFeature("Metal", "desc", 0, 0,
+            Float.NaN, null);
+    store.addFeature(sf2);
+    features = store.getNonPositionalFeatures();
+    assertEquals(features.size(), 1);
+    assertTrue(features.contains(sf2));
+
+    /*
+     * with result list argument
+     */
+    features.clear();
+    store.getNonPositionalFeatures(features);
+    assertEquals(features.size(), 1);
+    assertTrue(features.contains(sf2));
+
+    /*
+     * no check for duplicates
+     */
+    store.getNonPositionalFeatures(features);
+    assertEquals(features.size(), 2);
+    assertTrue(features.contains(sf2)); // two copies
+    features.remove(sf2);
+    assertTrue(features.contains(sf2));
+
+    /*
+     * null argument throws exception
+     */
+    try
+    {
+      store.getNonPositionalFeatures(null);
+      fail("expected exception");
+    } catch (NullPointerException e)
+    {
+      // expected
+    }
+  }
+
+  @Test(groups = "Functional")
   public void testGetPositionalFeatures()
   {
     FeatureStore store = newFeatureStore();
@@ -902,7 +997,7 @@ public class FeatureStoreTest
     SequenceFeature sf2 = addFeature(fs, 150, 250);
   
     List<SequenceFeature> overlaps = new ArrayList<>();
-    List<SequenceFeature> result = fs.findOverlappingFeatures(200, 200,
+    List<SequenceFeature> result = fs.findFeatures(200, 200,
             overlaps);
     assertSame(result, overlaps);
     assertEquals(result.size(), 1);
@@ -912,7 +1007,7 @@ public class FeatureStoreTest
     /*
      * if no list supplied, method creates one
      */
-    result = fs.findOverlappingFeatures(200, 200, null);
+    result = fs.findFeatures(200, 200, null);
     assertEquals(result.size(), 1);
     assertTrue(result.contains(sf2));
     assertFalse(result.contains(sf1));