def test_Reverse(self): """Range reverse property should return True if any span reversed""" self.assertFalse(self.one.reverse) self.one.reverses() self.assertTrue(self.one.reverse) self.assertFalse(self.two.reverse) self.two.spans.append(Span(0, 100, reverse=True)) self.assertTrue(self.two.reverse) self.two.reverses() self.assertTrue(self.two.reverse)
def test_reverse(self): """Range reverse method should reverse each span""" for s in self.overlapping.spans: self.assertFalse(s.reverse) self.overlapping.reverses() for s in self.overlapping.spans: self.assertTrue(s.reverse) self.overlapping.spans.append(Span(0, 100)) self.overlapping.reverses() for s in self.overlapping.spans[0:1]: self.assertFalse(s.reverse) self.assertTrue(self.overlapping.spans[-1].reverse)
def test_init(self): """Span object should init with start, end, and Length""" s = Span(0) self.assertEqual(s.start, 0) self.assertEqual(s.end, 1) self.assertEqual(s.reverse, False) # to get an empty interval, must specify start and end explicitly t = Span(0, 0) self.assertEqual(t.start, 0) self.assertEqual(t.end, 0) self.assertEqual(t.reverse, False) # should be able to specify direction also u = Span(5, 15, reverse=True) self.assertEqual(u.start, 5) self.assertEqual(u.end, 15) self.assertEqual(u.reverse, True) # should be able to init from another span v = Span(u) self.assertEqual(v.start, 5) self.assertEqual(v.end, 15) self.assertEqual(v.reverse, True)
def test_endsAt(self): """Span endsAt should return True if input matches""" e, f = self.empty, self.full s = Span(30, 1000) t = Span(-100, 35) self.assertTrue(e.ends_at(0)) self.assertTrue(f.ends_at(35)) self.assertTrue(s.ends_at(1000)) self.assertFalse(f.ends_at(s)) self.assertFalse(s.ends_at(f)) self.assertTrue(f.ends_at(t)) self.assertTrue(t.ends_at(f))
def cigar_to_map(cigar_text): """convert cigar string into Map""" assert "I" not in cigar_text spans, posn = [], 0 for n, c in pattern.findall(cigar_text): if n: n = int(n) else: n = 1 if c == "M": spans.append(Span(posn, posn + n)) posn += n else: spans.append(LostSpan(n)) map = Map(spans=spans, parent_length=posn) return map
def test_spans(self): # a simple two part map of length 10 map = Map([(0, 5), (5, 10)], parent_length=10) # try different spans on the above map for ((start, end), expected) in [ ((0, 4), "[0:4]"), ((0, 5), "[0:5]"), ((0, 6), "[0:5, 5:6]"), ((5, 10), "[5:10]"), ((-1, 10), "[-1-, 0:5, 5:10]"), ((5, 11), "[5:10, -1-]"), ((0, 10), "[0:5, 5:10]"), ((10, 0), "[10:5, 5:0]"), ]: r = repr(Span(start, end, reverse=start > end).remap_with(map)) # print (start, end), r, if r != expected: self.fail(repr((r, expected)))
def test_sort(self): """Span should support sort by 1st/2nd index and direction""" s, e, f, r, i, o = ( self.spans_zero, self.empty, self.full, self.reverse, self.inside, self.overlapping, ) n = Span(30, 36) expected_order = [s, e] first = expected_order[:] first.sort() for i, j in zip(first, expected_order): self.assertSameObj(i, j)
def test_cmp(self): """Span cmp should support sort by 1st/2nd index and direction""" s, e, f, r, i, o = ( self.spans_zero, self.empty, self.full, self.reverse, self.inside, self.overlapping, ) n = Span(30, 36) expected_order = [s, e, f, r, n, i, o] first = expected_order[:] first.sort() second = [r, o, f, s, e, i, n] second.sort() for i, j in zip(first, second): self.assertIs(i, j) for i, j in zip(first, expected_order): self.assertIs(i, j)
def test_simplify(self): """Range reduce should group overlapping ranges""" # consolidate should have no effect when no overlap r = self.two r.simplify() self.assertEqual(r.spans, [Span(3, 5), Span(8, 11)]) # should consolidate an overlap of the same direction r.spans.append(Span(-1, 4)) r.simplify() self.assertEqual(r.spans, [Span(-1, 5), Span(8, 11)]) # should also consolidate _adjacent_ spans of the same direction r.spans.append(Span(11, 14)) r.simplify() self.assertEqual(r.spans, [Span(-1, 5), Span(8, 14)]) # bridge should cause consolidations s = Range(r) s.spans.append(Span(5, 8)) s.simplify() self.assertEqual(s.spans, [Span(-1, 14)]) # ditto for bridge that overlaps everything s = Range(r) s.spans.append(Span(-100, 100)) s.simplify() self.assertEqual(s.spans, [Span(-100, 100)]) # however, can't consolidate span in other orientation s = Range(r) s.spans.append(Span(-100, 100, reverse=True)) self.assertEqual( s.spans, [Span(-1, 5), Span(8, 14), Span(-100, 100, reverse=True)])
def test_iter(self): """Range iter should iterate through each span in turn""" self.assertEqual(list(iter(self.two)), [3, 4, 8, 9, 10]) self.two.spans.insert(1, Span(103, 101, reverse=True)) self.assertEqual(list(iter(self.two)), [3, 4, 102, 101, 8, 9, 10])
def test_sort(self): """Range sort should sort component spans""" one = self.one one.sort() self.assertEqual(one.spans, [Span(100, 0)]) one.spans.append(Span(-20, -10)) self.assertEqual(one.spans, [Span(0, 100), Span(-20, -10)]) one.sort() self.assertEqual(one.spans, [Span(-20, -10), Span(0, 100)]) one.spans.append(Span(-20, -10, reverse=True)) self.assertEqual( one.spans, [Span(-20, -10), Span(0, 100), Span(-20, -10, reverse=True)]) one.sort() self.assertEqual( one.spans, [Span(-20, -10), Span(-20, -10, reverse=True), Span(0, 100)])
def test_init(self): """Range init from Spans, numbers, or Ranges should work OK.""" # single span self.assertEqual(self.one, Span(0, 100)) # list of spans self.assertEqual(self.two.spans, [Span(3, 5), Span(8, 11)]) # another range self.assertEqual(self.two, self.twocopy) # list of ranges self.assertEqual( self.twothree.spans, [Span(3, 5), Span(8, 11), Span(6, 7), Span(15, 17), Span(30, 35)], ) # list of numbers self.assertEqual(self.singles.spans, [Span(3, 4), Span(11, 12)]) # single number self.assertEqual(self.single.spans, [Span(0, 1)]) # nothing self.assertEqual(Range().spans, [])
def setUp(self): """Define some standard Spans""" self.empty = Span(0, 0) self.full = Span(35, 30) # will convert to (30, 35) internally self.overlapping = Span(32, 36) self.inside = Span(31, 32) self.before = Span(25, 30) self.after = Span(35, 40) self.reverse = Span(30, 35, reverse=True) self.spans_zero = Span(-5, 5)
class SpanTests(TestCase): """Tests of the Span object.""" def setUp(self): """Define some standard Spans""" self.empty = Span(0, 0) self.full = Span(35, 30) # will convert to (30, 35) internally self.overlapping = Span(32, 36) self.inside = Span(31, 32) self.before = Span(25, 30) self.after = Span(35, 40) self.reverse = Span(30, 35, reverse=True) self.spans_zero = Span(-5, 5) def test_init(self): """Span object should init with start, end, and Length""" s = Span(0) self.assertEqual(s.start, 0) self.assertEqual(s.end, 1) self.assertEqual(s.reverse, False) # to get an empty interval, must specify start and end explicitly t = Span(0, 0) self.assertEqual(t.start, 0) self.assertEqual(t.end, 0) self.assertEqual(t.reverse, False) # should be able to specify direction also u = Span(5, 15, reverse=True) self.assertEqual(u.start, 5) self.assertEqual(u.end, 15) self.assertEqual(u.reverse, True) # should be able to init from another span v = Span(u) self.assertEqual(v.start, 5) self.assertEqual(v.end, 15) self.assertEqual(v.reverse, True) def test_contains(self): """Span object contains its start but not its end""" self.assertNotContains(self.empty, 0) self.assertContains(self.full, 30) self.assertContains(self.full, 34) self.assertNotContains(self.full, 35) self.assertContains(self.full, self.inside) self.assertNotContains(self.full, self.overlapping) self.assertContains(self.spans_zero, 0) self.assertContains(self.spans_zero, -5) self.assertNotContains(self.spans_zero, 5) def test_overlaps(self): """Span objects should be able to overlap points or spans""" self.assertTrue(self.full.overlaps(self.overlapping)) self.assertFalse(self.full.overlaps(self.before)) self.assertFalse(self.before.overlaps(self.overlapping)) self.assertFalse(self.full.overlaps(self.after)) self.assertFalse(self.after.overlaps(self.before)) self.assertTrue(self.full.overlaps(self.inside)) self.assertTrue(self.spans_zero.overlaps(self.empty)) self.assertTrue(self.empty.overlaps(self.spans_zero)) def test_reverses(self): """Span.reverses should change direction""" self.assertFalse(self.empty.reverse) self.empty.reverses() self.assertTrue(self.empty.reverse) self.empty.reverses() self.assertFalse(self.empty.reverse) self.assertTrue(self.reverse.reverse) self.reverse.reverses() self.assertFalse(self.reverse.reverse) def test_iter(self): """Span iter should loop through (integer) contents""" self.assertEqual(list(iter(self.empty)), []) self.assertEqual(list(iter(self.full)), [30, 31, 32, 33, 34]) self.assertEqual(list(iter(self.spans_zero)), [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]) self.assertEqual(list(iter(self.inside)), [31]) self.assertEqual(list(self.reverse), [34, 33, 32, 31, 30]) def test_str(self): """Span str should print start, stop, reverse""" self.assertEqual(str(self.empty), "(0,0,False)") self.assertEqual(str(self.full), "(30,35,False)") self.assertEqual(str(self.reverse), "(30,35,True)") def test_len(self): """Span len should return difference between start and end""" self.assertEqual(len(self.empty), 0) self.assertEqual(len(self.full), 5) self.assertEqual(len(self.inside), 1) self.assertEqual(len(self.spans_zero), 10) def test_cmp(self): """Span cmp should support sort by 1st/2nd index and direction""" s, e, f, r, i, o = ( self.spans_zero, self.empty, self.full, self.reverse, self.inside, self.overlapping, ) n = Span(30, 36) expected_order = [s, e, f, r, n, i, o] first = expected_order[:] first.sort() second = [r, o, f, s, e, i, n] second.sort() for i, j in zip(first, second): self.assertSameObj(i, j) for i, j in zip(first, expected_order): self.assertSameObj(i, j) def test_sort(self): """Span should support sort by 1st/2nd index and direction""" s, e, f, r, i, o = ( self.spans_zero, self.empty, self.full, self.reverse, self.inside, self.overlapping, ) n = Span(30, 36) expected_order = [s, e] first = expected_order[:] first.sort() for i, j in zip(first, expected_order): self.assertSameObj(i, j) def test_starts_before(self): """Span starts_before should match hand-calculated results""" e, f = self.empty, self.full self.assertTrue(e.starts_before(f)) self.assertFalse(f.starts_before(e)) self.assertTrue(e.starts_before(1)) self.assertTrue(e.starts_before(1000)) self.assertFalse(e.starts_before(0)) self.assertFalse(e.starts_before(-1)) self.assertFalse(f.starts_before(30)) self.assertTrue(f.starts_before(31)) self.assertTrue(f.starts_before(1000)) def test_starts_after(self): """Span starts_after should match hand-calculated results""" e, f = self.empty, self.full self.assertFalse(e.starts_after(f)) self.assertTrue(f.starts_after(e)) self.assertFalse(e.starts_after(1)) self.assertFalse(e.starts_after(1000)) self.assertFalse(e.starts_after(0)) self.assertTrue(e.starts_after(-1)) self.assertTrue(f.starts_after(29)) self.assertFalse(f.starts_after(30)) self.assertFalse(f.starts_after(31)) self.assertFalse(f.starts_after(1000)) def test_startsAt(self): """Span startsAt should return True if input matches""" e, f = self.empty, self.full s = Span(30, 1000) self.assertTrue(e.starts_at(0)) self.assertTrue(f.starts_at(30)) self.assertTrue(s.starts_at(30)) self.assertTrue(f.starts_at(s)) self.assertTrue(s.starts_at(f)) self.assertFalse(e.starts_at(f)) self.assertFalse(e.starts_at(-1)) self.assertFalse(e.starts_at(1)) self.assertFalse(f.starts_at(29)) def test_startsInside(self): """Span startsInside should return True if input starts inside span""" e, f, i, o = self.empty, self.full, self.inside, self.overlapping self.assertFalse(e.starts_inside(0)) self.assertFalse(f.starts_inside(30)) self.assertFalse(e.starts_inside(f)) self.assertTrue(i.starts_inside(f)) self.assertFalse(f.starts_inside(i)) self.assertTrue(o.starts_inside(f)) self.assertFalse(o.ends_inside(i)) def test_endsBefore(self): """Span endsBefore should match hand-calculated results""" e, f = self.empty, self.full self.assertTrue(e.ends_before(f)) self.assertFalse(f.ends_before(e)) self.assertTrue(e.ends_before(1)) self.assertTrue(e.ends_before(1000)) self.assertFalse(e.ends_before(0)) self.assertFalse(e.ends_before(-1)) self.assertFalse(f.ends_before(30)) self.assertFalse(f.ends_before(31)) self.assertTrue(f.ends_before(1000)) def test_endsAfter(self): """Span endsAfter should match hand-calculated results""" e, f = self.empty, self.full self.assertFalse(e.ends_after(f)) self.assertTrue(f.ends_after(e)) self.assertFalse(e.ends_after(1)) self.assertFalse(e.ends_after(1000)) self.assertFalse(e.ends_after(0)) self.assertTrue(e.ends_after(-1)) self.assertTrue(f.ends_after(29)) self.assertTrue(f.ends_after(30)) self.assertTrue(f.ends_after(34)) self.assertFalse(f.ends_after(35)) self.assertFalse(f.ends_after(1000)) def test_endsAt(self): """Span endsAt should return True if input matches""" e, f = self.empty, self.full s = Span(30, 1000) t = Span(-100, 35) self.assertTrue(e.ends_at(0)) self.assertTrue(f.ends_at(35)) self.assertTrue(s.ends_at(1000)) self.assertFalse(f.ends_at(s)) self.assertFalse(s.ends_at(f)) self.assertTrue(f.ends_at(t)) self.assertTrue(t.ends_at(f)) def test_ends_inside(self): """Span ends_inside should return True if input ends inside span""" e, f, i, o = self.empty, self.full, self.inside, self.overlapping self.assertFalse(e.ends_inside(0)) self.assertFalse(f.ends_inside(30)) self.assertFalse(f.ends_inside(34)) self.assertFalse(f.ends_inside(35)) self.assertFalse(e.ends_inside(f)) self.assertTrue(i.ends_inside(f)) self.assertFalse(f.ends_inside(i)) self.assertFalse(o.ends_inside(f)) self.assertFalse(o.ends_inside(i)) self.assertTrue(e.ends_inside(Span(-1, 1))) self.assertTrue(e.ends_inside(Span(0, 1))) self.assertFalse(e.ends_inside(Span(-1, 0)))
def test_span(self): length = 100 forward = Span(20, 30) reverse = Span(70, 80, reverse=True) assert forward.reversed_relative_to(100) == reverse assert reverse.reversed_relative_to(100) == forward
def test_init(self): self.assertEqual(RangeFromString(""), Range()) self.assertEqual(RangeFromString(" 3 , 4\t, ,, 10 ,"), Range([3, 4, 10])) self.assertEqual( RangeFromString("3,4-10,1-5"), Range([Span(3), Span(4, 10), Span(1, 5)]) )