def test_union_overlap_compound(self): """Test some compound cases of union with overlap.""" a = Interval.fromAtoms([(5, 10), (20, 10), (50, 50)]) b = Interval.fromAtoms([(0, 8), (10, 15), (28, 82)]) self.assertEqual(a.union(b, True), b.union(a, True)) self.assertEqual(a.union(b, True), Interval.fromAtom(0, 110)) b = Interval.fromAtoms([(0, 8), (28, 82)]) self.assertEqual(a.union(b, True), Interval.fromAtoms([(0, 15), (20, 90)]))
def test_union_merge_start_nonzero(self): """Tests merges for several coumpound intervals, all starting after 0 (regression test against special-case bug)""" a = Interval.fromAtoms([(1, 2), (5, 2), (9, 2)]) b = Interval.fromAtoms([(3, 2), (7, 1)]) a_b = a.union(b) self.assertEqual(a_b, Interval.fromAtoms([(1, 7), (9, 2)])) a_b_c = Interval.fromAtom(8, 1).union(a_b) self.assertEqual(a_b_c, Interval.fromAtom(1, 10)) self.assertEqual(len(a_b_c), 10)
def test_union_overlap(self): """It is part of the design spec that intervals to union must be disjoint, since otherwise would likely indicate an error in the main program.""" # Off by one with self.assertRaises(AssertionError): Interval.fromAtom(0, 5).union(Interval.fromAtom(4, 5)) a = Interval.fromAtom(0, 5).union(Interval.fromAtom(5, 5)) self.assertEqual(a, Interval.fromAtom(0, 10)) # Containment with self.assertRaises(AssertionError): Interval.fromAtom(0, 5).union(Interval.fromAtom(2, 1)) with self.assertRaises(AssertionError): Interval.fromAtom(2, 1).union(Interval.fromAtom(0, 5)) # Overlap by 1 (regression test) with self.assertRaises(AssertionError): Interval.fromAtom(0, 5).union(Interval.fromAtom(4, 1)) # Multiple intervals b = Interval.fromAtoms([(2, 3), (10, 3), (20, 10000)]) with self.assertRaises(AssertionError): Interval.fromAtom(0, 5).union(b) with self.assertRaises(AssertionError): Interval.fromAtom(2, 19).union(b) with self.assertRaises(AssertionError): Interval.fromAtom(900, 2).union(b) # With self with self.assertRaises(AssertionError): a.union(a) with self.assertRaises(AssertionError): b.union(b)
def test_constructor(self): """Tests that fromAtom can create empty intervals.""" a = Interval.fromAtom(0, 0) b = Interval.fromAtom(10, 0) self.assertEqual(a, b) self.assertEqual(a, Interval()) self.assertEqual(a, Interval.fromAtoms([(0, 0), (5, 0)]))
def test_eq_neq(self): """Makes sure equality and inequality work, since all other tests depend on them. I test many values because Python's default eq/neq behavion can be weird and miss edge cases.""" # The other tests thoroughly test eq == true, so I focus on eq == false and # both values of ne. a = Interval.fromAtoms([(0, 2), (4, 2), (8, 2)]) empty = Interval() self.assertFalse(a == Interval.fromAtoms([(0, 2)])) self.assertTrue(a != Interval.fromAtoms([(0, 2)])) self.assertTrue(a == a) self.assertFalse(a != a) self.assertFalse(a == empty) self.assertTrue(a != empty) self.assertTrue(empty == Interval()) self.assertFalse(empty != Interval()) self.assertTrue(empty == empty) self.assertFalse(empty != empty) b = Interval.fromAtoms([(0, 2), (4, 2), (6, 2)]) c = Interval.fromAtoms([(0, 2), (4, 4)]) self.assertTrue(b == c) self.assertFalse(b != c) self.assertFalse(b != b) self.assertTrue(b == b) self.assertFalse(c != c) self.assertTrue(c == Interval.fromAtoms([(0, 2), (4, 4)]))
def test_iterExterior(self): """Tests the iterExterior method.""" atoms = [(0, 2), (4, 2), (8, 2)] ival = Interval.fromAtoms(atoms) self.assertEquals(list(ival.iterExterior()), [(2, 2), (6, 2)]) self.assertEquals(list(ival.iterExterior(10)), [(2, 2), (6, 2)]) self.assertRaises(AssertionError, lambda: list(ival.iterExterior(9))) self.assertEquals(list(ival.iterExterior(11)), [(2, 2), (6, 2), (10, 1)]) self.assertEquals(list(ival.iterExterior(3000)), [(2, 2), (6, 2), (10, 2990)]) # Length identities cmpl = Interval.fromAtoms(ival.iterExterior(50)) self.assertEquals(len(cmpl) + len(ival), 50) self.assertEquals(cmpl.union(ival), Interval.fromAtom(0, 50)) empty = Interval() for length in (0, 1, 2, 5): self.assertEquals(len(Interval.fromAtoms(empty.iterExterior(length))), \ length) ival = Interval.fromAtom(0, 1) for length in (1, 2, 5): self.assertEquals(len(Interval.fromAtoms(ival.iterExterior(length))), \ length - 1)
def test_min_max(self): """Test the min and max of the interval.""" atoms = [(0, 2), (8, 2), (4, 2)] ival = Interval.fromAtoms(atoms) self.assertEquals(ival.min(), 0) self.assertEquals(ival.max(), 9) ival = Interval.fromAtom(5, 1) self.assertEquals(ival.min(), 5) self.assertEquals(ival.max(), 5) ival = Interval() self.assertIsNone(ival.min()) self.assertIsNone(ival.max())
def test_union_merge_start_zero(self): """Tests merges for several coumpound intervals, all start at 0.""" # Simple case with an extra hole in the original spec. a = Interval.fromAtoms([(0, 2), (4, 2), (6, 2)]) b = Interval.fromAtoms([(2, 2)]) self.assertEqual(a.union(b), Interval.fromAtom(0, 8)) # Holes filled partially a = Interval.fromAtoms([(0, 2), (4, 2), (8, 2), (20, 3)]) b = Interval.fromAtoms([(2, 1), (6, 1), (10, 5), (16, 4)]) a_b = a.union(b) self.assertEqual(Interval.fromAtoms([(0, 3), (4, 3), (8, 7), (16, 7)]), a_b) a_b_c = a_b.union(Interval.fromAtoms([(3, 1), (7, 1)])) self.assertEqual(Interval.fromAtoms([(0, 15), (16, 7)]), a_b_c) a_b_c_d = a_b_c.union(Interval.fromAtom(15, 1)) self.assertEqual(Interval.fromAtom(0, 23), a_b_c_d) self.assertEqual(len(a_b_c_d), 23)
def test_constructor_equiv(self): """Make sure the from* constructors are equivalent. (Default is tested with union).""" a = Interval.fromAtom(3, 4).union(Interval.fromAtom(12, 10)) b = Interval.fromAtoms([(3, 4), (12, 10)]) self.assertEqual(a, b) c = Interval.fromAtom(3, 4).union(Interval.fromAtom(7, 10)) d = Interval.fromAtoms([(7, 10), (3, 4)]) e = Interval.fromAtom(3, 14) self.assertEqual(c, d) self.assertEqual(d, e) # fromAtoms must tolerate 0-length intervals. f = Interval.fromAtoms([(0, 2), (2, 0), (2, 2)]) self.assertEqual(f, Interval.fromAtom(0, 4)) # and must not tolerate overlap. with self.assertRaises(AssertionError): Interval.fromAtoms([(0, 5), (4, 5)]) # and should be able to create empty intervals (regression test) self.assertEqual(Interval.fromAtoms([]), Interval()) self.assertEqual(Interval.fromAtoms([(5, 0)]), Interval())
def fromSerializationState(klass, state): """See Allocation.toSerializationState""" self = klass() for (filename, atoms) in state: self.unionUpdate(Allocation(filename, Interval.fromAtoms(atoms))) return self
def test_iterInterior(self): """Tests the iterInterior method.""" atoms = [(0, 2), (4, 2), (8, 2)] self.assertEqual(atoms, list(Interval.fromAtoms(atoms).iterInterior())) self.assertEqual([], list(Interval().iterInterior()))