X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fdatamodel%2Ffeatures%2FSequenceFeaturesTest.java;h=56512cdc4ea65efab57839dfbe337fde15e3a996;hb=7dc7404ce7a339c600130e9828e3efc05b1e3270;hp=5ff2d7bac1b3c5fd2ac475fbc16d744b0751689c;hpb=87a85be7fc7678455c298287349b03fdd12fd3ad;p=jalview.git diff --git a/test/jalview/datamodel/features/SequenceFeaturesTest.java b/test/jalview/datamodel/features/SequenceFeaturesTest.java index 5ff2d7b..56512cd 100644 --- a/test/jalview/datamodel/features/SequenceFeaturesTest.java +++ b/test/jalview/datamodel/features/SequenceFeaturesTest.java @@ -5,18 +5,51 @@ import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; -import jalview.datamodel.SequenceFeature; - import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.testng.annotations.Test; +import jalview.datamodel.SequenceFeature; +import junit.extensions.PA; + public class SequenceFeaturesTest { @Test(groups = "Functional") + public void testConstructor() + { + SequenceFeaturesI store = new SequenceFeatures(); + assertFalse(store.hasFeatures()); + + store = new SequenceFeatures((List) null); + assertFalse(store.hasFeatures()); + + List features = new ArrayList<>(); + store = new SequenceFeatures(features); + assertFalse(store.hasFeatures()); + + SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20, + Float.NaN, null); + features.add(sf1); + SequenceFeature sf2 = new SequenceFeature("Metal", "desc", 15, 18, + Float.NaN, null); + features.add(sf2); // nested + SequenceFeature sf3 = new SequenceFeature("Pfam", "desc2", 0, 0, + Float.NaN, null); // non-positional + features.add(sf3); + store = new SequenceFeatures(features); + assertTrue(store.hasFeatures()); + assertEquals(2, store.getFeatureCount(true)); // positional + assertEquals(1, store.getFeatureCount(false)); // non-positional + assertFalse(store.add(sf1)); // already contained + assertFalse(store.add(sf2)); // already contained + assertFalse(store.add(sf3)); // already contained + } + + @Test(groups = "Functional") public void testGetPositionalFeatures() { SequenceFeaturesI store = new SequenceFeatures(); @@ -334,6 +367,11 @@ public class SequenceFeaturesTest groups = sf.getFeatureGroups(false); // for non-positional assertEquals(groups.size(), 1); assertTrue(groups.contains("AGroup")); + groups = sf.getFeatureGroups(false, "AType"); + assertEquals(groups.size(), 1); + assertTrue(groups.contains("AGroup")); + groups = sf.getFeatureGroups(true, "AnotherType"); + assertTrue(groups.isEmpty()); /* * add, then delete, more non-positional features of different types @@ -689,8 +727,14 @@ public class SequenceFeaturesTest features = store.getAllFeatures(); assertEquals(features.size(), 5); assertTrue(features.contains(sf5)); + + /* + * select by type does not apply to non-positional features + */ features = store.getAllFeatures("Cath"); - assertTrue(features.isEmpty()); + assertEquals(features.size(), 1); + assertTrue(features.contains(sf3)); + features = store.getAllFeatures("Pfam", "Cath", "Metal"); assertEquals(features.size(), 3); assertTrue(features.contains(sf1)); @@ -724,6 +768,8 @@ public class SequenceFeaturesTest Float.NaN, null); assertTrue(store.add(sf1)); assertEquals(store.getTotalFeatureLength(), 11); + assertEquals(store.getTotalFeatureLength("Metal"), 11); + assertEquals(store.getTotalFeatureLength("Plastic"), 0); // re-add does nothing! assertFalse(store.add(sf1)); @@ -842,12 +888,15 @@ public class SequenceFeaturesTest * no type specified - get all types stored * they are returned in keyset (alphabetical) order */ - Iterable types = sf.varargToTypes(); - Iterator iterator = types.iterator(); + Map featureStores = (Map) PA + .getValue(sf, "featureStore"); + + Iterable types = sf.varargToTypes(); + Iterator iterator = types.iterator(); assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "Cath"); + assertSame(iterator.next(), featureStores.get("Cath")); assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "Metal"); + assertSame(iterator.next(), featureStores.get("Metal")); assertFalse(iterator.hasNext()); /* @@ -857,9 +906,9 @@ public class SequenceFeaturesTest types = sf.varargToTypes(new String[] {}); iterator = types.iterator(); assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "Cath"); + assertSame(iterator.next(), featureStores.get("Cath")); assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "Metal"); + assertSame(iterator.next(), featureStores.get("Metal")); assertFalse(iterator.hasNext()); /* @@ -875,9 +924,9 @@ public class SequenceFeaturesTest types = sf.varargToTypes((String[]) null); iterator = types.iterator(); assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "Cath"); + assertSame(iterator.next(), featureStores.get("Cath")); assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "Metal"); + assertSame(iterator.next(), featureStores.get("Metal")); assertFalse(iterator.hasNext()); /* @@ -886,29 +935,27 @@ public class SequenceFeaturesTest types = sf.varargToTypes("Metal"); iterator = types.iterator(); assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "Metal"); + assertSame(iterator.next(), featureStores.get("Metal")); assertFalse(iterator.hasNext()); /* - * two types specified + * two types specified - order is preserved */ - types = sf.varargToTypes("Metal", "Helix"); + types = sf.varargToTypes("Metal", "Cath"); iterator = types.iterator(); assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "Metal"); + assertSame(iterator.next(), featureStores.get("Metal")); assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "Helix"); + assertSame(iterator.next(), featureStores.get("Cath")); assertFalse(iterator.hasNext()); /* - * null type included - should get removed + * null type included - should be ignored */ types = sf.varargToTypes("Metal", null, "Helix"); iterator = types.iterator(); assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "Metal"); - assertTrue(iterator.hasNext()); - assertEquals(iterator.next(), "Helix"); + assertSame(iterator.next(), featureStores.get("Metal")); assertFalse(iterator.hasNext()); } @@ -957,40 +1004,55 @@ public class SequenceFeaturesTest assertTrue(store.getFeaturesByOntology(new String[] {}).isEmpty()); assertTrue(store.getFeaturesByOntology((String[]) null).isEmpty()); - SequenceFeature sf1 = new SequenceFeature("transcript", "desc", 10, 20, + SequenceFeature transcriptFeature = new SequenceFeature("transcript", "desc", 10, 20, Float.NaN, null); - store.add(sf1); + store.add(transcriptFeature); - // mRNA isA transcript; added here 'as if' non-positional - // just to show that non-positional features are included in results - SequenceFeature sf2 = new SequenceFeature("mRNA", "desc", 0, 0, + /* + * mRNA is a sub-type of transcript; added here 'as if' non-positional + * just to show that non-positional features are included in results + */ + SequenceFeature mrnaFeature = new SequenceFeature("mRNA", "desc", 0, 0, Float.NaN, null); - store.add(sf2); + store.add(mrnaFeature); - SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 30, 40, + SequenceFeature pfamFeature = new SequenceFeature("Pfam", "desc", 30, 40, Float.NaN, null); - store.add(sf3); + store.add(pfamFeature); + /* + * "transcript" matches both itself and the sub-term "mRNA" + */ features = store.getFeaturesByOntology("transcript"); assertEquals(features.size(), 2); - assertTrue(features.contains(sf1)); - assertTrue(features.contains(sf2)); + assertTrue(features.contains(transcriptFeature)); + assertTrue(features.contains(mrnaFeature)); + /* + * "mRNA" matches itself but not parent term "transcript" + */ features = store.getFeaturesByOntology("mRNA"); assertEquals(features.size(), 1); - assertTrue(features.contains(sf2)); + assertTrue(features.contains(mrnaFeature)); + /* + * "pfam" is not an SO term but is included as an exact match + */ features = store.getFeaturesByOntology("mRNA", "Pfam"); assertEquals(features.size(), 2); - assertTrue(features.contains(sf2)); - assertTrue(features.contains(sf3)); + assertTrue(features.contains(mrnaFeature)); + assertTrue(features.contains(pfamFeature)); + + features = store.getFeaturesByOntology("sequence_variant"); + assertTrue(features.isEmpty()); } @Test(groups = "Functional") public void testSortFeatures() { - List sfs = new ArrayList(); - SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 30, 80, + List sfs = new ArrayList<>(); + SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 30, + 60, Float.NaN, null); sfs.add(sf1); SequenceFeature sf2 = new SequenceFeature("Rfam", "desc", 40, 50, @@ -999,17 +1061,234 @@ public class SequenceFeaturesTest SequenceFeature sf3 = new SequenceFeature("Rfam", "desc", 50, 60, Float.NaN, null); sfs.add(sf3); + SequenceFeature sf4 = new SequenceFeature("Xfam", "desc", 30, + 80, + Float.NaN, null); + sfs.add(sf4); + SequenceFeature sf5 = new SequenceFeature("Xfam", "desc", 30, + 90, + Float.NaN, null); + sfs.add(sf5); - // sort by end position descending + /* + * sort by end position descending, order unchanged if matched + */ SequenceFeatures.sortFeatures(sfs, false); - assertSame(sfs.get(0), sf1); - assertSame(sfs.get(1), sf3); - assertSame(sfs.get(2), sf2); + assertSame(sfs.get(0), sf5); // end 90 + assertSame(sfs.get(1), sf4); // end 80 + assertSame(sfs.get(2), sf1); // end 60, start 50 + assertSame(sfs.get(3), sf3); // end 60, start 30 + assertSame(sfs.get(4), sf2); // end 50 - // sort by start position ascending + /* + * resort {5, 4, 1, 3, 2} by start position ascending, end descending + */ SequenceFeatures.sortFeatures(sfs, true); - assertSame(sfs.get(0), sf1); - assertSame(sfs.get(1), sf2); - assertSame(sfs.get(2), sf3); + assertSame(sfs.get(0), sf5); // start 30, end 90 + assertSame(sfs.get(1), sf4); // start 30, end 80 + assertSame(sfs.get(2), sf1); // start 30, end 60 + assertSame(sfs.get(3), sf2); // start 40 + assertSame(sfs.get(4), sf3); // start 50 + } + + @Test(groups = "Functional") + public void testGetFeaturesForGroup() + { + SequenceFeaturesI store = new SequenceFeatures(); + + List features = store.getFeaturesForGroup(true, null); + assertTrue(features.isEmpty()); + assertTrue(store.getFeaturesForGroup(false, null).isEmpty()); + assertTrue(store.getFeaturesForGroup(true, "Uniprot").isEmpty()); + assertTrue(store.getFeaturesForGroup(false, "Uniprot").isEmpty()); + + SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f, + null); + SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f, + null); + SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f, + "Uniprot"); + SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 0, 0, 0f, + "Rfam"); + SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 5, 15, 0f, + null); + store.add(sf1); + store.add(sf2); + store.add(sf3); + store.add(sf4); + store.add(sf5); + + // positional features for null group, any type + features = store.getFeaturesForGroup(true, null); + assertEquals(features.size(), 2); + assertTrue(features.contains(sf1)); + assertTrue(features.contains(sf5)); + + // positional features for null group, specified type + features = store.getFeaturesForGroup(true, null, new String[] { "Pfam", + "Xfam" }); + assertEquals(features.size(), 1); + assertTrue(features.contains(sf1)); + features = store.getFeaturesForGroup(true, null, new String[] { "Pfam", + "Xfam", "Cath" }); + assertEquals(features.size(), 2); + assertTrue(features.contains(sf1)); + assertTrue(features.contains(sf5)); + + // positional features for non-null group, any type + features = store.getFeaturesForGroup(true, "Uniprot"); + assertEquals(features.size(), 1); + assertTrue(features.contains(sf3)); + assertTrue(store.getFeaturesForGroup(true, "Rfam").isEmpty()); + + // positional features for non-null group, specified type + features = store.getFeaturesForGroup(true, "Uniprot", "Pfam", "Xfam", + "Rfam"); + assertEquals(features.size(), 1); + assertTrue(features.contains(sf3)); + assertTrue(store.getFeaturesForGroup(true, "Uniprot", "Cath").isEmpty()); + + // non-positional features for null group, any type + features = store.getFeaturesForGroup(false, null); + assertEquals(features.size(), 1); + assertTrue(features.contains(sf2)); + + // non-positional features for null group, specified type + features = store.getFeaturesForGroup(false, null, "Pfam", "Xfam"); + assertEquals(features.size(), 1); + assertTrue(features.contains(sf2)); + assertTrue(store.getFeaturesForGroup(false, null, "Cath").isEmpty()); + + // non-positional features for non-null group, any type + features = store.getFeaturesForGroup(false, "Rfam"); + assertEquals(features.size(), 1); + assertTrue(features.contains(sf4)); + assertTrue(store.getFeaturesForGroup(false, "Uniprot").isEmpty()); + + // non-positional features for non-null group, specified type + features = store.getFeaturesForGroup(false, "Rfam", "Pfam", "Metal"); + assertEquals(features.size(), 1); + assertTrue(features.contains(sf4)); + assertTrue(store.getFeaturesForGroup(false, "Rfam", "Cath", "Pfam") + .isEmpty()); + } + + @Test(groups = "Functional") + public void testShiftFeatures() + { + SequenceFeatures store = new SequenceFeatures(); + assertFalse(store.shiftFeatures(0, 1)); + + SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null); + store.add(sf1); + // nested feature: + SequenceFeature sf2 = new SequenceFeature("Metal", "", 8, 14, 0f, null); + store.add(sf2); + // contact feature: + SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32, + 0f, null); + store.add(sf3); + // non-positional feature: + SequenceFeature sf4 = new SequenceFeature("Pfam", "", 0, 0, 0f, null); + store.add(sf4); + + /* + * shift features right by 5 + */ + assertTrue(store.shiftFeatures(0, 5)); + + // non-positional features untouched: + List nonPos = store.getNonPositionalFeatures(); + assertEquals(nonPos.size(), 1); + assertTrue(nonPos.contains(sf4)); + + // positional features are replaced + List pos = store.getPositionalFeatures(); + assertEquals(pos.size(), 3); + assertFalse(pos.contains(sf1)); + assertFalse(pos.contains(sf2)); + assertFalse(pos.contains(sf3)); + SequenceFeatures.sortFeatures(pos, true); // ascending start pos + assertEquals(pos.get(0).getBegin(), 7); + assertEquals(pos.get(0).getEnd(), 10); + assertEquals(pos.get(0).getType(), "Cath"); + assertEquals(pos.get(1).getBegin(), 13); + assertEquals(pos.get(1).getEnd(), 19); + assertEquals(pos.get(1).getType(), "Metal"); + assertEquals(pos.get(2).getBegin(), 28); + assertEquals(pos.get(2).getEnd(), 37); + assertEquals(pos.get(2).getType(), "Disulfide bond"); + + /* + * now shift left by 15 + * feature at [7-10] should be removed + * feature at [13-19] should become [1-4] + */ + assertTrue(store.shiftFeatures(0, -15)); + pos = store.getPositionalFeatures(); + assertEquals(pos.size(), 2); + SequenceFeatures.sortFeatures(pos, true); + assertEquals(pos.get(0).getBegin(), 1); + assertEquals(pos.get(0).getEnd(), 4); + assertEquals(pos.get(0).getType(), "Metal"); + assertEquals(pos.get(1).getBegin(), 13); + assertEquals(pos.get(1).getEnd(), 22); + assertEquals(pos.get(1).getType(), "Disulfide bond"); + + /* + * shift right by 4 from column 2 + * feature at [1-4] should be unchanged + * feature at [13-22] should become [17-26] + */ + assertTrue(store.shiftFeatures(2, 4)); + pos = store.getPositionalFeatures(); + assertEquals(pos.size(), 2); + SequenceFeatures.sortFeatures(pos, true); + assertEquals(pos.get(0).getBegin(), 1); + assertEquals(pos.get(0).getEnd(), 4); + assertEquals(pos.get(0).getType(), "Metal"); + assertEquals(pos.get(1).getBegin(), 17); + assertEquals(pos.get(1).getEnd(), 26); + assertEquals(pos.get(1).getType(), "Disulfide bond"); + + /* + * shift right from column 18 + * should be no updates + */ + SequenceFeature f1 = pos.get(0); + SequenceFeature f2 = pos.get(1); + assertFalse(store.shiftFeatures(18, 6)); + pos = store.getPositionalFeatures(); + assertEquals(pos.size(), 2); + SequenceFeatures.sortFeatures(pos, true); + assertSame(pos.get(0), f1); + assertSame(pos.get(1), f2); + } + + @Test(groups = "Functional") + public void testIsOntologyTerm() + { + SequenceFeatures store = new SequenceFeatures(); + assertTrue(store.isOntologyTerm("gobbledygook")); + assertTrue(store.isOntologyTerm("transcript", "transcript")); + assertTrue(store.isOntologyTerm("mRNA", "transcript")); + assertFalse(store.isOntologyTerm("transcript", "mRNA")); + assertTrue(store.isOntologyTerm("junk", "transcript", "junk")); + assertTrue(store.isOntologyTerm("junk", new String[] {})); + assertTrue(store.isOntologyTerm("junk", (String[]) null)); + } + + @Test(groups = "Functional") + public void testDeleteAll() + { + SequenceFeaturesI store = new SequenceFeatures(); + assertFalse(store.hasFeatures()); + store.deleteAll(); + assertFalse(store.hasFeatures()); + store.add(new SequenceFeature("Cath", "Desc", 12, 20, 0f, "Group")); + store.add(new SequenceFeature("Pfam", "Desc", 6, 12, 2f, "Group2")); + assertTrue(store.hasFeatures()); + store.deleteAll(); + assertFalse(store.hasFeatures()); } }