import jalview.datamodel.features.SequenceFeatures;
import jalview.gui.JvOptionPane;
++import java.util.Collections;
++import java.util.Comparator;
import java.util.List;
import java.util.Map;
sfs = seq0.getSequenceFeatures();
/*
++ * sort just for ease of inspection in the debugger
++ */
++ Collections.sort(sfs, new Comparator<SequenceFeature>()
++ {
++
++ @Override
++ public int compare(SequenceFeature o1, SequenceFeature o2)
++ {
++ return o1.getDescription().compareTo(o2.getDescription());
++ }
++ });
++
++ /*
* confirm the number of features has reduced by the
* number of features within the cut region i.e. by
* func(length of cut)
}
else
{
++ // failure in checkFeatureRelocation is more informative!
assertEquals(msg + "wrong number of features left", func(5)
- func(to - from + 1), sfs.size());
}
* undo ready for next cut
*/
testee.undoCommand(new AlignmentI[] { alignment });
- int size = seq0.getSequenceFeatures().size();
- assertEquals(func(5), size);
- assertEquals(func(5), seq0.getSequenceFeatures().size());
++ sfs = seq0.getSequenceFeatures();
++ assertEquals(func(5), sfs.size());
++ verifyUndo(from, to, sfs);
}
}
}
/**
++ * Check that after Undo, every feature has start/end that match its original
++ * "start" and "end" properties
++ *
++ * @param from
++ * @param to
++ * @param sfs
++ */
++ protected void verifyUndo(int from, int to, List<SequenceFeature> sfs)
++ {
++ for (SequenceFeature sf : sfs)
++ {
++ final int oldFrom = ((Integer) sf.getValue("from")).intValue();
++ final int oldTo = ((Integer) sf.getValue("to")).intValue();
++ String msg = String.format(
++ "Undo cut of [%d-%d], feature at [%d-%d] ", from, to,
++ oldFrom, oldTo);
++ assertEquals(msg + "start", oldFrom, sf.getBegin());
++ assertEquals(msg + "end", oldTo, sf.getEnd());
++ }
++ }
++
++ /**
* Helper method to check a feature has been correctly relocated after a cut
*
* @param sf
null);
sq.addSequenceFeature(sf0);
// add feature on BCD
- SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 9, 11, 2f,
+ SequenceFeature sfBCD = new SequenceFeature("Cath", "desc", 9, 11, 2f,
null);
- sq.addSequenceFeature(sf1);
+ sq.addSequenceFeature(sfBCD);
// add feature on DE
- SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 11, 12, 2f,
+ SequenceFeature sfDE = new SequenceFeature("Cath", "desc", 11, 12, 2f,
null);
- sq.addSequenceFeature(sf2);
+ sq.addSequenceFeature(sfDE);
// add contact feature at [B, H]
- SequenceFeature sf3 = new SequenceFeature("Disulphide bond", "desc", 9,
- SequenceFeature sfContactBH = new SequenceFeature("Disulphide bond",
- "desc", 9, 15, 2f, null);
++ SequenceFeature sfContactBH = new SequenceFeature("Disulphide bond", "desc", 9,
+ 15, 2f,
+ null);
- sq.addSequenceFeature(sf3);
+ sq.addSequenceFeature(sfContactBH);
// add contact feature at [F, G]
- SequenceFeature sf4 = new SequenceFeature("Disulfide Bond", "desc", 13,
- 14, 2f,
- null);
- sq.addSequenceFeature(sf4);
+ SequenceFeature sfContactFG = new SequenceFeature("Disulfide Bond",
+ "desc", 13, 14, 2f, null);
+ sq.addSequenceFeature(sfContactFG);
// no features in columns 1-2 (-A)
List<SequenceFeature> found = sq.findFeatures(1, 2);
assertEquals(pos.get(0).getEnd(), 4);
assertEquals(pos.get(1).getBegin(), 13);
assertEquals(pos.get(1).getEnd(), 22);
+
+ /*
+ * shift right by 4 from position 2 onwards
+ * feature at [1-4] unchanged, feature at [13-22] shifts
+ */
+ assertTrue(fs.shiftFeatures(2, 4));
+ pos = fs.getPositionalFeatures();
+ assertEquals(pos.size(), 2);
+ SequenceFeatures.sortFeatures(pos, true);
+ assertEquals(pos.get(0).getBegin(), 1);
+ assertEquals(pos.get(0).getEnd(), 4);
+ assertEquals(pos.get(1).getBegin(), 17);
+ assertEquals(pos.get(1).getEnd(), 26);
+
+ /*
+ * shift right by 4 from position 18 onwards
+ * should be no change
+ */
+ SequenceFeature f1 = pos.get(0);
+ SequenceFeature f2 = pos.get(1);
+ assertFalse(fs.shiftFeatures(18, 4)); // no update
+ pos = fs.getPositionalFeatures();
+ assertEquals(pos.size(), 2);
+ SequenceFeatures.sortFeatures(pos, true);
+ assertSame(pos.get(0), f1);
+ assertSame(pos.get(1), f2);
}
+
+ @Test(groups = "Functional")
+ public void testDelete_readd()
+ {
+ /*
+ * add a feature and a nested feature
+ */
+ FeatureStore store = new FeatureStore();
+ SequenceFeature sf1 = addFeature(store, 10, 20);
+ // sf2 is nested in sf1 so will be stored in nestedFeatures
+ SequenceFeature sf2 = addFeature(store, 12, 14);
+ List<SequenceFeature> features = store.getPositionalFeatures();
+ assertEquals(features.size(), 2);
+ assertTrue(features.contains(sf1));
+ assertTrue(features.contains(sf2));
+ assertTrue(store.nonNestedFeatures.contains(sf1));
+ assertTrue(store.nestedFeatures.contains(sf2));
+
+ /*
+ * delete the first feature
+ */
+ assertTrue(store.delete(sf1));
+ features = store.getPositionalFeatures();
+ assertFalse(features.contains(sf1));
+ assertTrue(features.contains(sf2));
+
+ /*
+ * re-add the 'nested' feature; is it now duplicated?
+ */
+ store.addFeature(sf2);
+ features = store.getPositionalFeatures();
+ assertEquals(features.size(), 1);
+ assertTrue(features.contains(sf2));
+ }
+
+ @Test(groups = "Functional")
+ public void testContains()
+ {
+ FeatureStore fs = new FeatureStore();
+ SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
+ Float.NaN, "group1");
+ SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
+ Float.NaN, "group2");
+ SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
+ "group1");
+ SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
+ "group1");
+ SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
+ Float.NaN, "group1");
+ SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
+ Float.NaN, "group2");
+
+ fs.addFeature(sf1);
+ fs.addFeature(sf3);
+ fs.addFeature(sf5);
+ assertTrue(fs.contains(sf1)); // positional feature
+ assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
+ assertFalse(fs.contains(sf2)); // different group
+ assertTrue(fs.contains(sf3)); // non-positional
+ assertTrue(fs.contains(new SequenceFeature(sf3)));
+ assertFalse(fs.contains(sf4)); // different score
+ assertTrue(fs.contains(sf5)); // contact feature
+ assertTrue(fs.contains(new SequenceFeature(sf5)));
+ assertFalse(fs.contains(sf6)); // different group
+
+ /*
+ * add a nested feature
+ */
+ SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
+ Float.NaN, "group1");
+ fs.addFeature(sf7);
+ assertTrue(fs.contains(sf7));
+ assertTrue(fs.contains(new SequenceFeature(sf7)));
+
+ /*
+ * delete the outer (enclosing, non-nested) feature
+ */
+ fs.delete(sf1);
+ assertFalse(fs.contains(sf1));
+ assertTrue(fs.contains(sf7));
+ }
}