def test_no_overlap_diff(self): s1 = Span(20, 80, 100, True) s2 = Span(90, 95, 100, True) diff = s1.differences(s2) assert len(diff) == 1 assert s1.a == 20 assert s1.b == 80
def test_connecting_span_consecutive_is_empty(self): """The connecting span between two consecutive spans is empty.""" s1 = Span(10, 30, 100, True) s2 = Span(30, 50, 100, True) assert not s1.overlaps_with(s2) s3 = s1.connecting_span(s2) assert len(s3) == 0
def test_abs_wrap_doctest(): # all of the following initializations result in equivalent spans # starts at 1, wraps around one full time, ends at 5. # Length is 15 - 1 s1 = Span(1, 15, 10, cyclic=True, abs_wrap=True) assert len(s1) == 14 # starts at 11, wraps around one full time, ends at 15. # Then positions are mapped back to context at 1 and 5. # Length is still 25 - 11 == 14 s2 = Span(11, 25, 10, cyclic=True, abs_wrap=True) assert len(s2) == 14 # starts at 11, wraps around one full time, ends at 15. # Then positions are mapped back to context at 1 and 5. # Length is now 11 + 5 = 14 s3 = Span(11, 5, 10, cyclic=True, abs_wrap=True) assert len(s3) == 14 # the lengths change with the abs diff in number of times wrapped _s = Span(21, 5, 10, cyclic=True, abs_wrap=True) assert len(_s) == 24 _s = Span(21, 15, 10, cyclic=True, abs_wrap=True) assert len(_s) == 14 # all assert s1 == s2 assert s2 == s3
def test_connecting_span_over_origin(self): """The connecting span should span the origin.""" s1 = Span(50, 60, 100, True) s2 = Span(5, 30, 100, True) s3 = s1.connecting_span(s2) assert s3.a == 60 assert s3.b == 5
def test_cyclic_edge_case(self): s = Span(5, 10, 10, cyclic=True) s.a == 5 s.b == 10 s = Span(5, 0, 10, cyclic=True) assert s.a == 5 assert s.b == 0
def test_span_over_region_twice(self): s1 = Span(2000, 3000, 3000, cyclic=True, ignore_wrap=False) s2 = Span(5000, 6000, 3000, cyclic=True, ignore_wrap=False) assert s1.a == 2000 assert s1.b == 3000 assert s2.a == 2000 assert s2.b == 3000
def test_cyclic_invalid_when_strict(self, abi): a, b, index, does_raise = abi if does_raise: with pytest.raises(IndexError): Span(a, b, 20, cyclic=True, index=index, strict=True) else: Span(a, b, 20, cyclic=True, index=index, strict=True) assert Span(a, b, 20, cyclic=True, index=index, strict=False)
def test_cyclic_wrapped_beyond_rbound(self): s = Span(9, 15, 10, cyclic=True) assert list(s) == [9, 0, 1, 2, 3, 4] s = Span(5, 16, 10, cyclic=True) assert list(s) == [5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5] s = Span(5, 15, 10, cyclic=True) assert list(s) == [5, 6, 7, 8, 9, 0, 1, 2, 3, 4]
def test_cyclic_range(self): s = Span(8, 10, 10, cyclic=True) assert list(s) == [8, 9] s = Span(8, 0, 10, cyclic=True) assert list(s) == [8, 9] s = Span(8, 2, 10, cyclic=True) assert list(s) == [8, 9, 0, 1]
def test_abs_wrap(): s = Span(6010, 1, 3000, cyclic=True, abs_wrap=True) assert s.a == 10 assert s.b == 1 assert s.c == 6001 with pytest.raises(IndexError): Span(6010, 1, 3000, cyclic=True, abs_wrap=False)
def test_does_not_contain(self): s1 = Span(10, 50, 100, True) s2 = Span(11, 50, 100, True) assert s1 not in s2 assert s2 in s1 s1 = Span(10, 50, 100, True) s2 = Span(10, 49, 100, True) assert s1 not in s2 assert s2 in s1
def test_invalid_slice(self): s = Span(90, 10, 100, True) sliced = s[:15] assert sliced.a == 90 assert sliced.b == 5 s = Span(90, 10, 100, True) sliced = s[-15:] assert sliced.a == 95 assert sliced.b == 10
def test_connecting_span_cyclic(self): s1 = Span(10, 20, 100, True) s2 = Span(80, 90, 100, True) s3 = s1.connecting_span(s2) assert s3.a == 20 assert s3.b == 80 s4 = s2.connecting_span(s1) assert s4.a == 90 assert s4.b == 10
def test_cyclic_beyond_right_bound(self): """Endpoints outside of right bound should be translated.""" # index 0 s = Span(5, 10, 10, cyclic=True, index=0) assert s.b == 10 s = Span(5, 11, 10, cyclic=True, index=0) assert s.b == 1 s = Span(5, 12, 10, cyclic=True, index=0) assert s.b == 2 # index 1 s = Span(5, 10, 10, cyclic=True, index=1) assert s.b == 10 s = Span(5, 11, 10, cyclic=True, index=1) assert s.b == 11 s = Span(5, 12, 10, cyclic=True, index=1) assert s.b == 2 s = Span(5, 13, 10, cyclic=True, index=1) assert s.b == 3 # index 2 s = Span(5, 12, 10, cyclic=True, index=2) assert s.b == 12 s = Span(5, 13, 10, cyclic=True, index=2) assert s.b == 3
def test_linear(self, a, b, index): """Any linear span outside of bounds or with a > b is invalid.""" length = 20 bounds = [index, length + index] if a < bounds[0] or a >= bounds[1] or b > bounds[1] or a > b: with pytest.raises(IndexError): Span(a, b, length, cyclic=False, index=index) else: s = Span(a, b, length, cyclic=False, index=index) assert s.a == a assert s.b == b
def test_slice_indexing_basic(self): s = Span(5, 9, 10, index=1) assert s[0] == 5 assert s[-1] == 8 s = Span(5, 12, 10, cyclic=True, index=0) print(list(s)) assert s[0] == 5 assert s[6] == 1 assert s[-1] == 1 assert s[len(s) - 1] == 1
def test_linear_diff(self): s1 = Span(20, 80, 100, True) s2 = Span(30, 50, 100, True) diff = s1.differences(s2) assert len(diff) == 2 assert diff[0].a == 20 assert diff[0].b == 30 assert diff[1].a == 50 assert diff[1].b == 80
def test_intersection(self): s1 = Span(10, 50, 100, True) s2 = Span(40, 60, 100, True) sliced = s1.intersection(s2) assert sliced.a == 40 assert sliced.b == 50 sliced = s2.intersection(s1) assert sliced.a == 40 assert sliced.b == 50
def test_wrapped_twice(self): s = Span(5, 15, 10, cyclic=True) assert len(s) == 10 assert list(s) == list(range(5, 10)) + list(range(5)) s = Span(5, 25, 10, cyclic=True) assert list(s) == list(range(5, 10)) + list(range(10)) + list(range(5)) assert len(s) == 20 assert s.a == 5 assert s.b == 5 assert s.c == 25
def test_special_case_empty_linear(self, x): """Special case of empty span should be valid for any endpoints that are the same.""" if x < 0 or x >= 10: with pytest.raises(IndexError): Span(x, x, 10, cyclic=False) else: s = Span(x, x, 10, cyclic=False) assert s.a == x assert s.b == x assert s.c == x assert len(s) == 0
def test_cyclic_basic(self): s = Span(5, 10, 20, cyclic=True) assert s.a == 5 assert s.b == 10 s = Span(15, 5, 20, cyclic=True) assert s.a == 15 assert s.b == 5 s = Span(-1, 5, 20, cyclic=True) assert s.a == 19 assert s.b == 5
def test_wrapped_twice_at_index(self): s = Span(0, 10, 10, cyclic=True) assert list(s) == list(range(0, 10)) s = Span(0, 11, 10, cyclic=True) assert list(s) == list(range(0, 10)) + [0] s = Span(0, 20, 10, cyclic=True) assert list(s) == list(range(0, 10)) + list(range(0, 10)) s = Span(0, 21, 10, cyclic=True) assert list(s) == list(range(0, 10)) + list(range(0, 10)) + [0]
def test_overhang_right_diff(self): s1 = Span(20, 80, 100, True) s2 = Span(70, 90, 100, True) diff = s1.differences(s2) assert len(diff) == 1 assert diff[0].a == 20 assert diff[0].b == 70 diff = s2.differences(s1) print(diff) assert len(diff) == 1 assert diff[0].a == 80 assert diff[0].b == 90
def test_cyclic_range_beyond_rbound(self): s = Span(8, 11, 10, cyclic=True) assert list(s) == [8, 9, 0] s = Span(8, 12, 10, cyclic=True) assert list(s) == [8, 9, 0, 1] s = Span(8, 12, 10, cyclic=True, index=1) assert list(s) == [8, 9, 10, 1] s = Span(8, 13, 10, cyclic=True, index=2) assert list(s) == [8, 9, 10, 11, 2]
def test_cyclic_range_beyond_lbound(self): s = Span(0, 4, 10, cyclic=True) assert list(s) == [0, 1, 2, 3] s = Span(-1, 4, 10, cyclic=True) assert list(s) == [9, 0, 1, 2, 3] s = Span(0, 4, 10, cyclic=True, index=1) assert list(s) == [10, 1, 2, 3] s = Span(0, 4, 10, cyclic=True, index=2) assert list(s) == [10, 11, 2, 3]
def test_ignore_wrap(): with pytest.raises(IndexError): Span(3000, 1, 3000, cyclic=True, ignore_wrap=False) s = Span(3000, 1, 3000, cyclic=True, ignore_wrap=True) assert s.a == 0 assert s.b == 1 assert s.c == 1 s = Span(3000, 3000 * 10 + 1, 3000, cyclic=True, ignore_wrap=True) assert s.a == 0 assert s.b == 1 assert s.c == 1
def test_overhang_left_diff(self): s1 = Span(20, 80, 100, True) s2 = Span(10, 30, 100, True) diff = s1.differences(s2) assert len(diff) == 1 assert diff[0].a == 30 assert diff[0].b == 80 diff = s2.differences(s1) print(diff) assert len(diff) == 1 assert diff[0].a == 10 assert diff[0].b == 20
def test_wrapped_when_allow_wrapping_is_false(self): # 5, 6, 7, 8, 9, 0 s = Span(5, 11, 10, cyclic=True, ignore_wrap=True) assert s.a == 5 assert s.b == 1 assert s.c == 1 assert len(s) == 6 # 5, 6, 7, 8, 9, 0, 1 s = Span(5, 12, 10, cyclic=True, ignore_wrap=True) assert s.a == 5 assert s.b == 2 assert s.c == 2 assert len(s) == 7
def test_slice_wrapped_adv1(self): s = Span(5, 36, 10, True) assert s.a == 5 assert s.b == 6 assert s.c == 36 assert len(s) == 31 s1 = s[:-10] assert s1.a == 5 assert s1.b == 6 assert s1.c == 26 assert len(s1) == 21 s1 = s[:-20] assert s1.a == 5 assert s1.b == 6 assert s1.c == 16 assert len(s1) == 11 s1 = s[:-30] assert s1.a == 5 assert s1.b == 6 assert s1.c == 6 assert len(s1) == 1 with pytest.raises(IndexError): s1 = s[:-40]