+
+ @Test(groups = "Functional")
+ public void testDelete()
+ {
+ List<Range> ranges = new ArrayList<Range>();
+ Range r1 = new Range(20, 30);
+ ranges.add(r1);
+ NCList<Range> ncl = new NCList<Range>(ranges);
+ assertTrue(ncl.getEntries().contains(r1));
+
+ Range r2 = new Range(20, 30);
+ assertFalse(ncl.delete(null)); // null argument
+ assertFalse(ncl.delete(r2)); // never added
+ assertTrue(ncl.delete(r1)); // success
+ assertTrue(ncl.getEntries().isEmpty());
+
+ /*
+ * tests where object.equals() == true
+ */
+ NCList<SequenceFeature> features = new NCList<SequenceFeature>();
+ SequenceFeature sf1 = new SequenceFeature("type", "desc", 1, 10, 2f,
+ "group");
+ SequenceFeature sf2 = new SequenceFeature("type", "desc", 1, 10, 2f,
+ "group");
+ features.add(sf1);
+ assertEquals(sf1, sf2); // sf1.equals(sf2)
+ assertFalse(features.delete(sf2)); // equality is not enough for deletion
+ assertTrue(features.getEntries().contains(sf1)); // still there!
+ assertTrue(features.delete(sf1));
+ assertTrue(features.getEntries().isEmpty()); // gone now
+
+ /*
+ * test with duplicate objects in NCList
+ */
+ features.add(sf1);
+ features.add(sf1);
+ assertEquals(features.getEntries().size(), 2);
+ assertSame(features.getEntries().get(0), sf1);
+ assertSame(features.getEntries().get(1), sf1);
+ assertTrue(features.delete(sf1)); // first match only is deleted
+ assertTrue(features.contains(sf1));
+ assertEquals(features.size(), 1);
+ assertTrue(features.delete(sf1));
+ assertTrue(features.getEntries().isEmpty());
+ }
+
+ @Test(groups = "Functional")
+ public void testAdd_overlapping()
+ {
+ List<Range> ranges = new ArrayList<Range>();
+ ranges.add(new Range(40, 50));
+ ranges.add(new Range(20, 30));
+ NCList<Range> ncl = new NCList<Range>(ranges);
+ assertEquals(ncl.toString(), "[20-30, 40-50]");
+ assertTrue(ncl.isValid());
+
+ /*
+ * add range overlapping internally
+ */
+ ncl.add(new Range(25, 35));
+ assertEquals(ncl.toString(), "[20-30, 25-35, 40-50]");
+ assertTrue(ncl.isValid());
+
+ /*
+ * add range overlapping last range
+ */
+ ncl.add(new Range(45, 55));
+ assertEquals(ncl.toString(), "[20-30, 25-35, 40-50, 45-55]");
+ assertTrue(ncl.isValid());
+
+ /*
+ * add range overlapping first range
+ */
+ ncl.add(new Range(15, 25));
+ assertEquals(ncl.toString(), "[15-25, 20-30, 25-35, 40-50, 45-55]");
+ assertTrue(ncl.isValid());
+ }
+
+ /**
+ * Test the contains method (which uses object equals test)
+ */
+ @Test(groups = "Functional")
+ public void testContains()
+ {
+ NCList<SequenceFeature> ncl = new NCList<SequenceFeature>();
+ SequenceFeature sf1 = new SequenceFeature("type", "desc", 1, 10, 2f,
+ "group");
+ SequenceFeature sf2 = new SequenceFeature("type", "desc", 1, 10, 2f,
+ "group");
+ SequenceFeature sf3 = new SequenceFeature("type", "desc", 1, 10, 2f,
+ "anothergroup");
+ ncl.add(sf1);
+
+ assertTrue(ncl.contains(sf1));
+ assertTrue(ncl.contains(sf2)); // sf1.equals(sf2)
+ assertFalse(ncl.contains(sf3)); // !sf1.equals(sf3)
+
+ /*
+ * make some deeper structure in the NCList
+ */
+ SequenceFeature sf4 = new SequenceFeature("type", "desc", 2, 9, 2f,
+ "group");
+ ncl.add(sf4);
+ assertTrue(ncl.contains(sf4));
+ SequenceFeature sf5 = new SequenceFeature("type", "desc", 4, 5, 2f,
+ "group");
+ SequenceFeature sf6 = new SequenceFeature("type", "desc", 6, 8, 2f,
+ "group");
+ ncl.add(sf5);
+ ncl.add(sf6);
+ assertTrue(ncl.contains(sf5));
+ assertTrue(ncl.contains(sf6));
+ }
+
+ @Test(groups = "Functional")
+ public void testIsValid()
+ {
+ List<Range> ranges = new ArrayList<Range>();
+ Range r1 = new Range(40, 50);
+ ranges.add(r1);
+ NCList<Range> ncl = new NCList<Range>(ranges);
+ assertTrue(ncl.isValid());
+
+ Range r2 = new Range(42, 44);
+ ncl.add(r2);
+ assertTrue(ncl.isValid());
+ Range r3 = new Range(46, 48);
+ ncl.add(r3);
+ assertTrue(ncl.isValid());
+ Range r4 = new Range(43, 43);
+ ncl.add(r4);
+ assertTrue(ncl.isValid());
+
+ assertEquals(ncl.toString(), "[40-50 [42-44 [43-43], 46-48]]");
+ assertTrue(ncl.isValid());
+
+ PA.setValue(r1, "start", 43);
+ assertFalse(ncl.isValid()); // r2 not inside r1
+ PA.setValue(r1, "start", 40);
+ assertTrue(ncl.isValid());
+
+ PA.setValue(r3, "start", 41);
+ assertFalse(ncl.isValid()); // r3 should precede r2
+ PA.setValue(r3, "start", 46);
+ assertTrue(ncl.isValid());
+
+ PA.setValue(r4, "start", 41);
+ assertFalse(ncl.isValid()); // r4 not inside r2
+ PA.setValue(r4, "start", 43);
+ assertTrue(ncl.isValid());
+
+ PA.setValue(r4, "start", 44);
+ assertFalse(ncl.isValid()); // r4 has reverse range
+ }
+
+ @Test(groups = "Functional")
+ public void testPrettyPrint()
+ {
+ /*
+ * construct NCList from a list of ranges
+ * they are sorted then assembled into NCList subregions
+ * notice that 42-42 end up inside 41-46
+ */
+ List<Range> ranges = new ArrayList<Range>();
+ ranges.add(new Range(40, 50));
+ ranges.add(new Range(45, 55));
+ ranges.add(new Range(40, 45));
+ ranges.add(new Range(41, 46));
+ ranges.add(new Range(42, 42));
+ ranges.add(new Range(42, 42));
+ NCList<Range> ncl = new NCList<Range>(ranges);
+ assertTrue(ncl.isValid());
+ assertEquals(ncl.toString(),
+ "[40-50 [40-45], 41-46 [42-42 [42-42]], 45-55]");
+ String expected = "40-50\n 40-45\n41-46\n 42-42\n 42-42\n45-55\n";
+ assertEquals(ncl.prettyPrint(), expected);
+
+ /*
+ * repeat but now add ranges one at a time
+ * notice that 42-42 end up inside 40-50 so we get
+ * a different but equal valid NCList structure
+ */
+ ranges.clear();
+ ncl = new NCList<Range>(ranges);
+ ncl.add(new Range(40, 50));
+ ncl.add(new Range(45, 55));
+ ncl.add(new Range(40, 45));
+ ncl.add(new Range(41, 46));
+ ncl.add(new Range(42, 42));
+ ncl.add(new Range(42, 42));
+ assertTrue(ncl.isValid());
+ assertEquals(ncl.toString(),
+ "[40-50 [40-45 [42-42 [42-42]], 41-46], 45-55]");
+ expected = "40-50\n 40-45\n 42-42\n 42-42\n 41-46\n45-55\n";
+ assertEquals(ncl.prettyPrint(), expected);
+ }
+
+ /**
+ * A test that shows different valid trees can be constructed from the same
+ * set of ranges, depending on the order of construction
+ */
+ @Test(groups = "Functional")
+ public void testConstructor_alternativeTrees()
+ {
+ List<Range> ranges = new ArrayList<Range>();
+ ranges.add(new Range(10, 60));
+ ranges.add(new Range(20, 30));
+ ranges.add(new Range(40, 50));
+
+ /*
+ * constructor with greedy traversal of sorted ranges to build nested
+ * containment lists results in 20-30 inside 10-60, 40-50 a sibling
+ */
+ NCList<Range> ncl = new NCList<Range>(ranges);
+ assertEquals(ncl.toString(), "[10-60 [20-30], 40-50]");
+ assertTrue(ncl.isValid());
+
+ /*
+ * adding ranges one at a time results in 40-50
+ * a sibling of 20-30 inside 10-60
+ */
+ ncl = new NCList<Range>(new Range(10, 60));
+ ncl.add(new Range(20, 30));
+ ncl.add(new Range(40, 50));
+ assertEquals(ncl.toString(), "[10-60 [20-30, 40-50]]");
+ assertTrue(ncl.isValid());
+ }