Commit 406dc9d2 authored by Tres Seaver's avatar Tres Seaver

Test cleanups.

parent cae9f1dd
...@@ -42,7 +42,8 @@ from BTrees.LOBTree import LOBTree, LOBucket, LOSet, LOTreeSet ...@@ -42,7 +42,8 @@ from BTrees.LOBTree import LOBTree, LOBucket, LOSet, LOTreeSet
from BTrees.LLBTree import LLBTree, LLBucket, LLSet, LLTreeSet from BTrees.LLBTree import LLBTree, LLBucket, LLSet, LLTreeSet
from BTrees.LFBTree import LFBTree, LFBucket, LFSet, LFTreeSet from BTrees.LFBTree import LFBTree, LFBucket, LFSet, LFTreeSet
from ZODB.utils import positive_id, oid_repr from BTrees.utils import positive_id
from BTrees.utils import oid_repr
TYPE_UNKNOWN, TYPE_BTREE, TYPE_BUCKET = range(3) TYPE_UNKNOWN, TYPE_BTREE, TYPE_BUCKET = range(3)
......
...@@ -34,25 +34,23 @@ import BTrees ...@@ -34,25 +34,23 @@ import BTrees
from BTrees.IIBTree import using64bits from BTrees.IIBTree import using64bits
from BTrees.check import check from BTrees.check import check
import transaction
from ZODB import DB
from ZODB.MappingStorage import MappingStorage
class Base(TestCase): class Base(object):
""" Tests common to all types: sets, buckets, and BTrees """ # Tests common to all types: sets, buckets, and BTrees
db = None db = None
def setUp(self): def _makeOne(self):
self.t = self.t_class() return self.klass()
def tearDown(self): def tearDown(self):
if self.db is not None: if self.db is not None:
self.db.close() self.db.close()
self.t = None
del self.t
def _getRoot(self): def _getRoot(self):
from ZODB import DB
from ZODB.MappingStorage import MappingStorage
if self.db is None: if self.db is None:
# Unclear: On the next line, the ZODB4 flavor of this routine # Unclear: On the next line, the ZODB4 flavor of this routine
# [asses a cache_size argument: # [asses a cache_size argument:
...@@ -67,8 +65,9 @@ class Base(TestCase): ...@@ -67,8 +65,9 @@ class Base(TestCase):
root._p_jar.close() root._p_jar.close()
def testLoadAndStore(self): def testLoadAndStore(self):
import transaction
for i in 0, 10, 1000: for i in 0, 10, 1000:
t = self.t.__class__() t = self._makeOne()
self._populate(t, i) self._populate(t, i)
root = None root = None
root = self._getRoot() root = self._getRoot()
...@@ -85,15 +84,17 @@ class Base(TestCase): ...@@ -85,15 +84,17 @@ class Base(TestCase):
self._closeRoot(root2) self._closeRoot(root2)
def testSetstateArgumentChecking(self): def testSetstateArgumentChecking(self):
try: self.t.__class__().__setstate__(('',)) try:
self._makeOne().__setstate__(('',))
except TypeError, v: except TypeError, v:
self.assertEqual(str(v), 'tuple required for first state element') self.assertEqual(str(v), 'tuple required for first state element')
else: else:
raise AssertionError("Expected exception") raise AssertionError("Expected exception")
def testGhostUnghost(self): def testGhostUnghost(self):
import transaction
for i in 0, 10, 1000: for i in 0, 10, 1000:
t = self.t.__class__() t = self._makeOne()
self._populate(t, i) self._populate(t, i)
root = self._getRoot() root = self._getRoot()
root[i] = t root[i] = t
...@@ -111,7 +112,7 @@ class Base(TestCase): ...@@ -111,7 +112,7 @@ class Base(TestCase):
self._closeRoot(root2) self._closeRoot(root2)
def testSimpleExclusiveKeyRange(self): def testSimpleExclusiveKeyRange(self):
t = self.t.__class__() t = self._makeOne()
self.assertEqual(list(t.keys()), []) self.assertEqual(list(t.keys()), [])
self.assertEqual(list(t.keys(excludemin=True)), []) self.assertEqual(list(t.keys(excludemin=True)), [])
self.assertEqual(list(t.keys(excludemax=True)), []) self.assertEqual(list(t.keys(excludemax=True)), [])
...@@ -147,7 +148,10 @@ class Base(TestCase): ...@@ -147,7 +148,10 @@ class Base(TestCase):
[1]) [1])
def testUpdatesDoReadChecksOnInternalNodes(self): def testUpdatesDoReadChecksOnInternalNodes(self):
t = self.t import transaction
from ZODB import DB
from ZODB.MappingStorage import MappingStorage
t = self._makeOne()
if not hasattr(t, '_firstbucket'): if not hasattr(t, '_firstbucket'):
return return
self._populate(t, 1000) self._populate(t, 1000)
...@@ -190,7 +194,7 @@ class Base(TestCase): ...@@ -190,7 +194,7 @@ class Base(TestCase):
class MappingBase(Base): class MappingBase(Base):
""" Tests common to mappings (buckets, btrees) """ # Tests common to mappings (buckets, btrees)
def _populate(self, t, l): def _populate(self, t, l):
# Make some data # Make some data
...@@ -200,9 +204,10 @@ class MappingBase(Base): ...@@ -200,9 +204,10 @@ class MappingBase(Base):
# test the repr because buckets have a complex repr implementation # test the repr because buckets have a complex repr implementation
# internally the cutoff from a stack allocated buffer to a heap # internally the cutoff from a stack allocated buffer to a heap
# allocated buffer is 10000. # allocated buffer is 10000.
t = self._makeOne()
for i in range(1000): for i in range(1000):
self.t[i] = i t[i] = i
r = repr(self.t) r = repr(t)
# Make sure the repr is 10000 bytes long for a bucket. # Make sure the repr is 10000 bytes long for a bucket.
# But since the test is also run for btrees, skip the length # But since the test is also run for btrees, skip the length
# check if the repr starts with '<' # check if the repr starts with '<'
...@@ -213,79 +218,87 @@ class MappingBase(Base): ...@@ -213,79 +218,87 @@ class MappingBase(Base):
self.assertRaises(KeyError, self._getitemfail) self.assertRaises(KeyError, self._getitemfail)
def _getitemfail(self): def _getitemfail(self):
return self.t[1] return self._makeOne()[1]
def testGetReturnsDefault(self): def testGetReturnsDefault(self):
self.assertEqual(self.t.get(1) , None) self.assertEqual(self._makeOne().get(1) , None)
self.assertEqual(self.t.get(1, 'foo') , 'foo') self.assertEqual(self._makeOne().get(1, 'foo') , 'foo')
def testSetItemGetItemWorks(self): def testSetItemGetItemWorks(self):
self.t[1] = 1 t = self._makeOne()
a = self.t[1] t[1] = 1
a = t[1]
self.assertEqual(a , 1, `a`) self.assertEqual(a , 1, `a`)
def testReplaceWorks(self): def testReplaceWorks(self):
self.t[1] = 1 t = self._makeOne()
self.assertEqual(self.t[1] , 1, self.t[1]) t[1] = 1
self.t[1] = 2 self.assertEqual(t[1] , 1, t[1])
self.assertEqual(self.t[1] , 2, self.t[1]) t[1] = 2
self.assertEqual(t[1] , 2, t[1])
def testLen(self): def testLen(self):
t = self._makeOne()
added = {} added = {}
r = range(1000) r = range(1000)
for x in r: for x in r:
k = random.choice(r) k = random.choice(r)
self.t[k] = x t[k] = x
added[k] = x added[k] = x
addl = added.keys() addl = added.keys()
self.assertEqual(len(self.t) , len(addl), len(self.t)) self.assertEqual(len(t) , len(addl), len(t))
def testHasKeyWorks(self): def testHasKeyWorks(self):
self.t[1] = 1 t = self._makeOne()
self.assert_(self.t.has_key(1)) t[1] = 1
self.assert_(1 in self.t) self.assert_(t.has_key(1))
self.assert_(0 not in self.t) self.assert_(1 in t)
self.assert_(2 not in self.t) self.assert_(0 not in t)
self.assert_(2 not in t)
def testValuesWorks(self): def testValuesWorks(self):
t = self._makeOne()
for x in range(100): for x in range(100):
self.t[x] = x*x t[x] = x*x
v = self.t.values() v = t.values()
for i in range(100): for i in range(100):
self.assertEqual(v[i], i*i) self.assertEqual(v[i], i*i)
self.assertRaises(IndexError, lambda: v[i+1]) self.assertRaises(IndexError, lambda: v[i+1])
i = 0 i = 0
for value in self.t.itervalues(): for value in t.itervalues():
self.assertEqual(value, i*i) self.assertEqual(value, i*i)
i += 1 i += 1
def testValuesWorks1(self): def testValuesWorks1(self):
t = self._makeOne()
for x in range(100): for x in range(100):
self.t[99-x] = x t[99-x] = x
for x in range(40): for x in range(40):
lst = list(self.t.values(0+x,99-x)) lst = list(t.values(0+x,99-x))
lst.sort() lst.sort()
self.assertEqual(lst,range(0+x,99-x+1)) self.assertEqual(lst,range(0+x,99-x+1))
lst = list(self.t.values(max=99-x, min=0+x)) lst = list(t.values(max=99-x, min=0+x))
lst.sort() lst.sort()
self.assertEqual(lst,range(0+x,99-x+1)) self.assertEqual(lst,range(0+x,99-x+1))
def testValuesNegativeIndex(self): def testValuesNegativeIndex(self):
t = self._makeOne()
L = [-3, 6, -11, 4] L = [-3, 6, -11, 4]
for i in L: for i in L:
self.t[i] = i t[i] = i
L.sort() L.sort()
vals = self.t.values() vals = t.values()
for i in range(-1, -5, -1): for i in range(-1, -5, -1):
self.assertEqual(vals[i], L[i]) self.assertEqual(vals[i], L[i])
self.assertRaises(IndexError, lambda: vals[-5]) self.assertRaises(IndexError, lambda: vals[-5])
def testKeysWorks(self): def testKeysWorks(self):
t = self._makeOne()
for x in range(100): for x in range(100):
self.t[x] = x t[x] = x
v = self.t.keys() v = t.keys()
i = 0 i = 0
for x in v: for x in v:
self.assertEqual(x,i) self.assertEqual(x,i)
...@@ -293,28 +306,30 @@ class MappingBase(Base): ...@@ -293,28 +306,30 @@ class MappingBase(Base):
self.assertRaises(IndexError, lambda: v[i]) self.assertRaises(IndexError, lambda: v[i])
for x in range(40): for x in range(40):
lst = self.t.keys(0+x,99-x) lst = t.keys(0+x,99-x)
self.assertEqual(list(lst), range(0+x, 99-x+1)) self.assertEqual(list(lst), range(0+x, 99-x+1))
lst = self.t.keys(max=99-x, min=0+x) lst = t.keys(max=99-x, min=0+x)
self.assertEqual(list(lst), range(0+x, 99-x+1)) self.assertEqual(list(lst), range(0+x, 99-x+1))
self.assertEqual(len(v), 100) self.assertEqual(len(v), 100)
def testKeysNegativeIndex(self): def testKeysNegativeIndex(self):
t = self._makeOne()
L = [-3, 6, -11, 4] L = [-3, 6, -11, 4]
for i in L: for i in L:
self.t[i] = i t[i] = i
L.sort() L.sort()
keys = self.t.keys() keys = t.keys()
for i in range(-1, -5, -1): for i in range(-1, -5, -1):
self.assertEqual(keys[i], L[i]) self.assertEqual(keys[i], L[i])
self.assertRaises(IndexError, lambda: keys[-5]) self.assertRaises(IndexError, lambda: keys[-5])
def testItemsWorks(self): def testItemsWorks(self):
t = self._makeOne()
for x in range(100): for x in range(100):
self.t[x] = 2*x t[x] = 2*x
v = self.t.items() v = t.items()
i = 0 i = 0
for x in v: for x in v:
self.assertEqual(x[0], i) self.assertEqual(x[0], i)
...@@ -323,22 +338,23 @@ class MappingBase(Base): ...@@ -323,22 +338,23 @@ class MappingBase(Base):
self.assertRaises(IndexError, lambda: v[i+1]) self.assertRaises(IndexError, lambda: v[i+1])
i = 0 i = 0
for x in self.t.iteritems(): for x in t.iteritems():
self.assertEqual(x, (i, 2*i)) self.assertEqual(x, (i, 2*i))
i += 1 i += 1
items = list(self.t.items(min=12, max=20)) items = list(t.items(min=12, max=20))
self.assertEqual(items, zip(range(12, 21), range(24, 43, 2))) self.assertEqual(items, zip(range(12, 21), range(24, 43, 2)))
items = list(self.t.iteritems(min=12, max=20)) items = list(t.iteritems(min=12, max=20))
self.assertEqual(items, zip(range(12, 21), range(24, 43, 2))) self.assertEqual(items, zip(range(12, 21), range(24, 43, 2)))
def testItemsNegativeIndex(self): def testItemsNegativeIndex(self):
t = self._makeOne()
L = [-3, 6, -11, 4] L = [-3, 6, -11, 4]
for i in L: for i in L:
self.t[i] = i t[i] = i
L.sort() L.sort()
items = self.t.items() items = t.items()
for i in range(-1, -5, -1): for i in range(-1, -5, -1):
self.assertEqual(items[i], (L[i], L[i])) self.assertEqual(items[i], (L[i], L[i]))
self.assertRaises(IndexError, lambda: items[-5]) self.assertRaises(IndexError, lambda: items[-5])
...@@ -347,19 +363,20 @@ class MappingBase(Base): ...@@ -347,19 +363,20 @@ class MappingBase(Base):
self.assertRaises(KeyError, self._deletefail) self.assertRaises(KeyError, self._deletefail)
def _deletefail(self): def _deletefail(self):
del self.t[1] t = self._makeOne()
del t[1]
def testMaxKeyMinKey(self): def testMaxKeyMinKey(self):
self.t[7] = 6 t = self._makeOne()
self.t[3] = 10 t[7] = 6
self.t[8] = 12 t[3] = 10
self.t[1] = 100 t[8] = 12
self.t[5] = 200 t[1] = 100
self.t[10] = 500 t[5] = 200
self.t[6] = 99 t[10] = 500
self.t[4] = 150 t[6] = 99
del self.t[7] t[4] = 150
t = self.t del t[7]
self.assertEqual(t.maxKey(), 10) self.assertEqual(t.maxKey(), 10)
self.assertEqual(t.maxKey(6), 6) self.assertEqual(t.maxKey(6), 6)
self.assertEqual(t.maxKey(9), 8) self.assertEqual(t.maxKey(9), 8)
...@@ -382,15 +399,17 @@ class MappingBase(Base): ...@@ -382,15 +399,17 @@ class MappingBase(Base):
self.fail("expected ValueError") self.fail("expected ValueError")
def testClear(self): def testClear(self):
t = self._makeOne()
r = range(100) r = range(100)
for x in r: for x in r:
rnd = random.choice(r) rnd = random.choice(r)
self.t[rnd] = 0 t[rnd] = 0
self.t.clear() t.clear()
diff = lsubtract(list(self.t.keys()), []) diff = lsubtract(list(t.keys()), [])
self.assertEqual(diff, []) self.assertEqual(diff, [])
def testUpdate(self): def testUpdate(self):
t = self._makeOne()
d={} d={}
l=[] l=[]
for i in range(10000): for i in range(10000):
...@@ -401,29 +420,29 @@ class MappingBase(Base): ...@@ -401,29 +420,29 @@ class MappingBase(Base):
items=d.items() items=d.items()
items.sort() items.sort()
self.t.update(d) t.update(d)
self.assertEqual(list(self.t.items()), items) self.assertEqual(list(t.items()), items)
self.t.clear() t.clear()
self.assertEqual(list(self.t.items()), []) self.assertEqual(list(t.items()), [])
self.t.update(l) t.update(l)
self.assertEqual(list(self.t.items()), items) self.assertEqual(list(t.items()), items)
# Before ZODB 3.4.2, update/construction from PersistentMapping failed. # Before ZODB 3.4.2, update/construction from PersistentMapping failed.
def testUpdateFromPersistentMapping(self): def testUpdateFromPersistentMapping(self):
from persistent.mapping import PersistentMapping from persistent.mapping import PersistentMapping
t = self._makeOne()
pm = PersistentMapping({1: 2}) pm = PersistentMapping({1: 2})
self.t.update(pm) t.update(pm)
self.assertEqual(list(self.t.items()), [(1, 2)]) self.assertEqual(list(t.items()), [(1, 2)])
# Construction goes thru the same internals as .update(). # Construction goes thru the same internals as .update().
t = self.t.__class__(pm) t = t.__class__(pm)
self.assertEqual(list(t.items()), [(1, 2)]) self.assertEqual(list(t.items()), [(1, 2)])
def testEmptyRangeSearches(self): def testEmptyRangeSearches(self):
t = self.t t = self._makeOne()
t.update([(1,1), (5,5), (9,9)]) t.update([(1,1), (5,5), (9,9)])
self.assertEqual(list(t.keys(-6,-4)), [], list(t.keys(-6,-4))) self.assertEqual(list(t.keys(-6,-4)), [], list(t.keys(-6,-4)))
self.assertEqual(list(t.keys(2,4)), [], list(t.keys(2,4))) self.assertEqual(list(t.keys(2,4)), [], list(t.keys(2,4)))
...@@ -451,8 +470,7 @@ class MappingBase(Base): ...@@ -451,8 +470,7 @@ class MappingBase(Base):
# This tests fixes to several bugs in this area, starting with # This tests fixes to several bugs in this area, starting with
# http://collector.zope.org/Zope/419, # http://collector.zope.org/Zope/419,
# "BTreeItems slice contains 1 too many elements". # "BTreeItems slice contains 1 too many elements".
t = self._makeOne()
t = self.t
for n in range(10): for n in range(10):
t.clear() t.clear()
self.assertEqual(len(t), 0) self.assertEqual(len(t), 0)
...@@ -522,7 +540,7 @@ class MappingBase(Base): ...@@ -522,7 +540,7 @@ class MappingBase(Base):
self.assertEqual(list(tslice), zip(range(20, 80), [1]*60)) self.assertEqual(list(tslice), zip(range(20, 80), [1]*60))
def testIterators(self): def testIterators(self):
t = self.t t = self._makeOne()
for keys in [], [-2], [1, 4], range(-170, 2000, 6): for keys in [], [-2], [1, 4], range(-170, 2000, 6):
t.clear() t.clear()
...@@ -551,7 +569,7 @@ class MappingBase(Base): ...@@ -551,7 +569,7 @@ class MappingBase(Base):
self.assertEqual(list(t.iteritems()), list(t.items())) self.assertEqual(list(t.iteritems()), list(t.items()))
def testRangedIterators(self): def testRangedIterators(self):
t = self.t t = self._makeOne()
for keys in [], [-2], [1, 4], range(-170, 2000, 13): for keys in [], [-2], [1, 4], range(-170, 2000, 13):
t.clear() t.clear()
...@@ -601,24 +619,15 @@ class MappingBase(Base): ...@@ -601,24 +619,15 @@ class MappingBase(Base):
def testBadUpdateTupleSize(self): def testBadUpdateTupleSize(self):
# This one silently ignored the excess in Zope3. # This one silently ignored the excess in Zope3.
try: t = self._makeOne()
self.t.update([(1, 2, 3)]) self.assertRaises(TypeError, t.update, [(1, 2, 3)])
except TypeError:
pass
else:
self.fail("update() with 3-tuple didn't complain")
# This one dumped core in Zope3. # This one dumped core in Zope3.
try: self.assertRaises(TypeError, t.update, [(1,)])
self.t.update([(1,)])
except TypeError:
pass
else:
self.fail("update() with 1-tuple didn't complain")
# This one should simply succeed. # This one should simply succeed.
self.t.update([(1, 2)]) t.update([(1, 2)])
self.assertEqual(list(self.t.items()), [(1, 2)]) self.assertEqual(list(t.items()), [(1, 2)])
def testSimpleExclusivRanges(self): def testSimpleExclusivRanges(self):
def identity(x): def identity(x):
...@@ -633,7 +642,7 @@ class MappingBase(Base): ...@@ -633,7 +642,7 @@ class MappingBase(Base):
("itervalues", identity), ("itervalues", identity),
("iteritems", dup)): ("iteritems", dup)):
t = self.t.__class__() t = self._makeOne()
meth = getattr(t, methodname, None) meth = getattr(t, methodname, None)
if meth is None: if meth is None:
continue continue
...@@ -677,7 +686,7 @@ class MappingBase(Base): ...@@ -677,7 +686,7 @@ class MappingBase(Base):
f([1])) f([1]))
def testSetdefault(self): def testSetdefault(self):
t = self.t t = self._makeOne()
self.assertEqual(t.setdefault(1, 2), 2) self.assertEqual(t.setdefault(1, 2), 2)
# That should also have associated 1 with 2 in the tree. # That should also have associated 1 with 2 in the tree.
...@@ -695,7 +704,7 @@ class MappingBase(Base): ...@@ -695,7 +704,7 @@ class MappingBase(Base):
def testPop(self): def testPop(self):
t = self.t t = self._makeOne()
# Empty container. # Empty container.
# If no default given, raises KeyError. # If no default given, raises KeyError.
...@@ -732,32 +741,32 @@ class MappingBase(Base): ...@@ -732,32 +741,32 @@ class MappingBase(Base):
class NormalSetTests(Base): class NormalSetTests(Base):
""" Test common to all set types """ # Test common to all set types
def _populate(self, t, l): def _populate(self, t, l):
# Make some data # Make some data
t.update(range(l)) t.update(range(l))
def testInsertReturnsValue(self): def testInsertReturnsValue(self):
t = self.t t = self._makeOne()
self.assertEqual(t.insert(5) , 1) self.assertEqual(t.insert(5) , 1)
self.assertEqual(t.add(4) , 1) self.assertEqual(t.add(4) , 1)
def testDuplicateInsert(self): def testDuplicateInsert(self):
t = self.t t = self._makeOne()
t.insert(5) t.insert(5)
self.assertEqual(t.insert(5) , 0) self.assertEqual(t.insert(5) , 0)
self.assertEqual(t.add(5) , 0) self.assertEqual(t.add(5) , 0)
def testInsert(self): def testInsert(self):
t = self.t t = self._makeOne()
t.insert(1) t.insert(1)
self.assert_(t.has_key(1)) self.assert_(t.has_key(1))
self.assert_(1 in t) self.assert_(1 in t)
self.assert_(2 not in t) self.assert_(2 not in t)
def testBigInsert(self): def testBigInsert(self):
t = self.t t = self._makeOne()
r = xrange(10000) r = xrange(10000)
for x in r: for x in r:
t.insert(x) t.insert(x)
...@@ -766,7 +775,7 @@ class NormalSetTests(Base): ...@@ -766,7 +775,7 @@ class NormalSetTests(Base):
self.assert_(x in t) self.assert_(x in t)
def testRemoveSucceeds(self): def testRemoveSucceeds(self):
t = self.t t = self._makeOne()
r = xrange(10000) r = xrange(10000)
for x in r: t.insert(x) for x in r: t.insert(x)
for x in r: t.remove(x) for x in r: t.remove(x)
...@@ -775,15 +784,15 @@ class NormalSetTests(Base): ...@@ -775,15 +784,15 @@ class NormalSetTests(Base):
self.assertRaises(KeyError, self._removenonexistent) self.assertRaises(KeyError, self._removenonexistent)
def _removenonexistent(self): def _removenonexistent(self):
self.t.remove(1) self._makeOne().remove(1)
def testHasKeyFails(self): def testHasKeyFails(self):
t = self.t t = self._makeOne()
self.assert_(not t.has_key(1)) self.assert_(not t.has_key(1))
self.assert_(1 not in t) self.assert_(1 not in t)
def testKeys(self): def testKeys(self):
t = self.t t = self._makeOne()
r = xrange(1000) r = xrange(1000)
for x in r: for x in r:
t.insert(x) t.insert(x)
...@@ -792,7 +801,7 @@ class NormalSetTests(Base): ...@@ -792,7 +801,7 @@ class NormalSetTests(Base):
def testClear(self): def testClear(self):
t = self.t t = self._makeOne()
r = xrange(1000) r = xrange(1000)
for x in r: t.insert(x) for x in r: t.insert(x)
t.clear() t.clear()
...@@ -800,7 +809,7 @@ class NormalSetTests(Base): ...@@ -800,7 +809,7 @@ class NormalSetTests(Base):
self.assertEqual(diff , [], diff) self.assertEqual(diff , [], diff)
def testMaxKeyMinKey(self): def testMaxKeyMinKey(self):
t = self.t t = self._makeOne()
t.insert(1) t.insert(1)
t.insert(2) t.insert(2)
t.insert(3) t.insert(3)
...@@ -835,6 +844,7 @@ class NormalSetTests(Base): ...@@ -835,6 +844,7 @@ class NormalSetTests(Base):
self.fail("expected ValueError") self.fail("expected ValueError")
def testUpdate(self): def testUpdate(self):
t = self._makeOne()
d={} d={}
l=[] l=[]
for i in range(10000): for i in range(10000):
...@@ -845,11 +855,11 @@ class NormalSetTests(Base): ...@@ -845,11 +855,11 @@ class NormalSetTests(Base):
items = d.keys() items = d.keys()
items.sort() items.sort()
self.t.update(l) t.update(l)
self.assertEqual(list(self.t.keys()), items) self.assertEqual(list(t.keys()), items)
def testEmptyRangeSearches(self): def testEmptyRangeSearches(self):
t = self.t t = self._makeOne()
t.update([1, 5, 9]) t.update([1, 5, 9])
self.assertEqual(list(t.keys(-6,-4)), [], list(t.keys(-6,-4))) self.assertEqual(list(t.keys(-6,-4)), [], list(t.keys(-6,-4)))
self.assertEqual(list(t.keys(2,4)), [], list(t.keys(2,4))) self.assertEqual(list(t.keys(2,4)), [], list(t.keys(2,4)))
...@@ -872,8 +882,7 @@ class NormalSetTests(Base): ...@@ -872,8 +882,7 @@ class NormalSetTests(Base):
def testSlicing(self): def testSlicing(self):
# Test that slicing of .keys() works exactly the same way as slicing # Test that slicing of .keys() works exactly the same way as slicing
# a Python list with the same contents. # a Python list with the same contents.
t = self._makeOne()
t = self.t
for n in range(10): for n in range(10):
t.clear() t.clear()
self.assertEqual(len(t), 0) self.assertEqual(len(t), 0)
...@@ -902,7 +911,7 @@ class NormalSetTests(Base): ...@@ -902,7 +911,7 @@ class NormalSetTests(Base):
self.assertEqual(list(x), keys[lo:hi]) self.assertEqual(list(x), keys[lo:hi])
def testIterator(self): def testIterator(self):
t = self.t t = self._makeOne()
for keys in [], [-2], [1, 4], range(-170, 2000, 6): for keys in [], [-2], [1, 4], range(-170, 2000, 6):
t.clear() t.clear()
...@@ -926,293 +935,20 @@ class NormalSetTests(Base): ...@@ -926,293 +935,20 @@ class NormalSetTests(Base):
self.assertEqual(x, keys) self.assertEqual(x, keys)
class ExtendedSetTests(NormalSetTests): class ExtendedSetTests(NormalSetTests):
def testLen(self): def testLen(self):
t = self.t t = self._makeOne()
r = xrange(10000) r = xrange(10000)
for x in r: t.insert(x) for x in r: t.insert(x)
self.assertEqual(len(t) , 10000, len(t)) self.assertEqual(len(t) , 10000, len(t))
def testGetItem(self): def testGetItem(self):
t = self.t t = self._makeOne()
r = xrange(10000) r = xrange(10000)
for x in r: t.insert(x) for x in r: t.insert(x)
for x in r: for x in r:
self.assertEqual(t[x] , x) self.assertEqual(t[x] , x)
class BTreeTests(MappingBase):
""" Tests common to all BTrees """
def tearDown(self):
self.t._check()
check(self.t)
MappingBase.tearDown(self)
def testDeleteNoChildrenWorks(self):
self.t[5] = 6
self.t[2] = 10
self.t[6] = 12
self.t[1] = 100
self.t[3] = 200
self.t[10] = 500
self.t[4] = 99
del self.t[4]
diff = lsubtract(self.t.keys(), [1,2,3,5,6,10])
self.assertEqual(diff , [], diff)
def testDeleteOneChildWorks(self):
self.t[5] = 6
self.t[2] = 10
self.t[6] = 12
self.t[1] = 100
self.t[3] = 200
self.t[10] = 500
self.t[4] = 99
del self.t[3]
diff = lsubtract(self.t.keys(), [1,2,4,5,6,10])
self.assertEqual(diff , [], diff)
def testDeleteTwoChildrenNoInorderSuccessorWorks(self):
self.t[5] = 6
self.t[2] = 10
self.t[6] = 12
self.t[1] = 100
self.t[3] = 200
self.t[10] = 500
self.t[4] = 99
del self.t[2]
diff = lsubtract(self.t.keys(), [1,3,4,5,6,10])
self.assertEqual(diff , [], diff)
def testDeleteTwoChildrenInorderSuccessorWorks(self):
# 7, 3, 8, 1, 5, 10, 6, 4 -- del 3
self.t[7] = 6
self.t[3] = 10
self.t[8] = 12
self.t[1] = 100
self.t[5] = 200
self.t[10] = 500
self.t[6] = 99
self.t[4] = 150
del self.t[3]
diff = lsubtract(self.t.keys(), [1,4,5,6,7,8,10])
self.assertEqual(diff , [], diff)
def testDeleteRootWorks(self):
# 7, 3, 8, 1, 5, 10, 6, 4 -- del 7
self.t[7] = 6
self.t[3] = 10
self.t[8] = 12
self.t[1] = 100
self.t[5] = 200
self.t[10] = 500
self.t[6] = 99
self.t[4] = 150
del self.t[7]
diff = lsubtract(self.t.keys(), [1,3,4,5,6,8,10])
self.assertEqual(diff , [], diff)
def testRandomNonOverlappingInserts(self):
added = {}
r = range(100)
for x in r:
k = random.choice(r)
if not added.has_key(k):
self.t[k] = x
added[k] = 1
addl = added.keys()
addl.sort()
diff = lsubtract(list(self.t.keys()), addl)
self.assertEqual(diff , [], (diff, addl, list(self.t.keys())))
def testRandomOverlappingInserts(self):
added = {}
r = range(100)
for x in r:
k = random.choice(r)
self.t[k] = x
added[k] = 1
addl = added.keys()
addl.sort()
diff = lsubtract(self.t.keys(), addl)
self.assertEqual(diff , [], diff)
def testRandomDeletes(self):
r = range(1000)
added = []
for x in r:
k = random.choice(r)
self.t[k] = x
added.append(k)
deleted = []
for x in r:
k = random.choice(r)
if self.t.has_key(k):
self.assert_(k in self.t)
del self.t[k]
deleted.append(k)
if self.t.has_key(k):
self.fail( "had problems deleting %s" % k )
badones = []
for x in deleted:
if self.t.has_key(x):
badones.append(x)
self.assertEqual(badones , [], (badones, added, deleted))
def testTargetedDeletes(self):
r = range(1000)
for x in r:
k = random.choice(r)
self.t[k] = x
for x in r:
try:
del self.t[x]
except KeyError:
pass
self.assertEqual(realseq(self.t.keys()) , [], realseq(self.t.keys()))
def testPathologicalRightBranching(self):
r = range(1000)
for x in r:
self.t[x] = 1
self.assertEqual(realseq(self.t.keys()) , r, realseq(self.t.keys()))
for x in r:
del self.t[x]
self.assertEqual(realseq(self.t.keys()) , [], realseq(self.t.keys()))
def testPathologicalLeftBranching(self):
r = range(1000)
revr = r[:]
revr.reverse()
for x in revr:
self.t[x] = 1
self.assertEqual(realseq(self.t.keys()) , r, realseq(self.t.keys()))
for x in revr:
del self.t[x]
self.assertEqual(realseq(self.t.keys()) , [], realseq(self.t.keys()))
def testSuccessorChildParentRewriteExerciseCase(self):
add_order = [
85, 73, 165, 273, 215, 142, 233, 67, 86, 166, 235, 225, 255,
73, 175, 171, 285, 162, 108, 28, 283, 258, 232, 199, 260,
298, 275, 44, 261, 291, 4, 181, 285, 289, 216, 212, 129,
243, 97, 48, 48, 159, 22, 285, 92, 110, 27, 55, 202, 294,
113, 251, 193, 290, 55, 58, 239, 71, 4, 75, 129, 91, 111,
271, 101, 289, 194, 218, 77, 142, 94, 100, 115, 101, 226,
17, 94, 56, 18, 163, 93, 199, 286, 213, 126, 240, 245, 190,
195, 204, 100, 199, 161, 292, 202, 48, 165, 6, 173, 40, 218,
271, 228, 7, 166, 173, 138, 93, 22, 140, 41, 234, 17, 249,
215, 12, 292, 246, 272, 260, 140, 58, 2, 91, 246, 189, 116,
72, 259, 34, 120, 263, 168, 298, 118, 18, 28, 299, 192, 252,
112, 60, 277, 273, 286, 15, 263, 141, 241, 172, 255, 52, 89,
127, 119, 255, 184, 213, 44, 116, 231, 173, 298, 178, 196,
89, 184, 289, 98, 216, 115, 35, 132, 278, 238, 20, 241, 128,
179, 159, 107, 206, 194, 31, 260, 122, 56, 144, 118, 283,
183, 215, 214, 87, 33, 205, 183, 212, 221, 216, 296, 40,
108, 45, 188, 139, 38, 256, 276, 114, 270, 112, 214, 191,
147, 111, 299, 107, 101, 43, 84, 127, 67, 205, 251, 38, 91,
297, 26, 165, 187, 19, 6, 73, 4, 176, 195, 90, 71, 30, 82,
139, 210, 8, 41, 253, 127, 190, 102, 280, 26, 233, 32, 257,
194, 263, 203, 190, 111, 218, 199, 29, 81, 207, 18, 180,
157, 172, 192, 135, 163, 275, 74, 296, 298, 265, 105, 191,
282, 277, 83, 188, 144, 259, 6, 173, 81, 107, 292, 231,
129, 65, 161, 113, 103, 136, 255, 285, 289, 1
]
delete_order = [
276, 273, 12, 275, 2, 286, 127, 83, 92, 33, 101, 195,
299, 191, 22, 232, 291, 226, 110, 94, 257, 233, 215, 184,
35, 178, 18, 74, 296, 210, 298, 81, 265, 175, 116, 261,
212, 277, 260, 234, 6, 129, 31, 4, 235, 249, 34, 289, 105,
259, 91, 93, 119, 7, 183, 240, 41, 253, 290, 136, 75, 292,
67, 112, 111, 256, 163, 38, 126, 139, 98, 56, 282, 60, 26,
55, 245, 225, 32, 52, 40, 271, 29, 252, 239, 89, 87, 205,
213, 180, 97, 108, 120, 218, 44, 187, 196, 251, 202, 203,
172, 28, 188, 77, 90, 199, 297, 282, 141, 100, 161, 216,
73, 19, 17, 189, 30, 258
]
for x in add_order:
self.t[x] = 1
for x in delete_order:
try: del self.t[x]
except KeyError:
if self.t.has_key(x):
self.assertEqual(1,2,"failed to delete %s" % x)
def testRangeSearchAfterSequentialInsert(self):
r = range(100)
for x in r:
self.t[x] = 0
diff = lsubtract(list(self.t.keys(0, 100)), r)
self.assertEqual(diff , [], diff)
def testRangeSearchAfterRandomInsert(self):
r = range(100)
a = {}
for x in r:
rnd = random.choice(r)
self.t[rnd] = 0
a[rnd] = 0
diff = lsubtract(list(self.t.keys(0, 100)), a.keys())
self.assertEqual(diff , [], diff)
def testPathologicalRangeSearch(self):
t = self.t
# Build a 2-level tree with at least two buckets.
for i in range(200):
t[i] = i
items, dummy = t.__getstate__()
self.assert_(len(items) > 2) # at least two buckets and a key
# All values in the first bucket are < firstkey. All in the
# second bucket are >= firstkey, and firstkey is the first key in
# the second bucket.
firstkey = items[1]
therange = t.keys(-1, firstkey)
self.assertEqual(len(therange), firstkey + 1)
self.assertEqual(list(therange), range(firstkey + 1))
# Now for the tricky part. If we delete firstkey, the second bucket
# loses its smallest key, but firstkey remains in the BTree node.
# If we then do a high-end range search on firstkey, the BTree node
# directs us to look in the second bucket, but there's no longer any
# key <= firstkey in that bucket. The correct answer points to the
# end of the *first* bucket. The algorithm has to be smart enough
# to "go backwards" in the BTree then; if it doesn't, it will
# erroneously claim that the range is empty.
del t[firstkey]
therange = t.keys(min=-1, max=firstkey)
self.assertEqual(len(therange), firstkey)
self.assertEqual(list(therange), range(firstkey))
def testInsertMethod(self):
t = self.t
t[0] = 1
self.assertEqual(t.insert(0, 1) , 0)
self.assertEqual(t.insert(1, 1) , 1)
self.assertEqual(lsubtract(list(t.keys()), [0,1]) , [])
def testDamagedIterator(self):
# A cute one from Steve Alexander. This caused the BTreeItems
# object to go insane, accessing memory beyond the allocated part
# of the bucket. If it fails, the symptom is either a C-level
# assertion error (if the BTree code was compiled without NDEBUG),
# or most likely a segfault (if the BTree code was compiled with
# NDEBUG).
t = self.t.__class__()
self._populate(t, 10)
# In order for this to fail, it's important that k be a "lazy"
# iterator, referring to the BTree by indirect position (index)
# instead of a fully materialized list. Then the position can
# end up pointing into trash memory, if the bucket pointed to
# shrinks.
k = t.keys()
for dummy in range(20):
try:
del t[k[0]]
except RuntimeError, detail:
self.assertEqual(str(detail), "the bucket being iterated "
"changed size")
break
LARGEST_32_BITS = 2147483647 LARGEST_32_BITS = 2147483647
SMALLEST_32_BITS = -LARGEST_32_BITS - 1 SMALLEST_32_BITS = -LARGEST_32_BITS - 1
...@@ -1229,48 +965,46 @@ LARGEST_NEGATIVE_65_BITS = SMALLEST_64_BITS - 1 ...@@ -1229,48 +965,46 @@ LARGEST_NEGATIVE_65_BITS = SMALLEST_64_BITS - 1
class TestLongIntSupport: class TestLongIntSupport:
def getTwoValues(self): def getTwoValues(self):
"""Return two distinct values; these must compare as un-equal. # Return two distinct values; these must compare as un-equal.
#
These values must be usable as values. # These values must be usable as values.
"""
return object(), object() return object(), object()
def getTwoKeys(self): def getTwoKeys(self):
"""Return two distinct values, these must compare as un-equal. # Return two distinct values, these must compare as un-equal.
#
These values must be usable as keys. #These values must be usable as keys.
"""
return 0, 1 return 0, 1
def _set_value(self, key, value): def _set_value(self, key, value):
self.t[key] = value t = self._makeOne()
t[key] = value
class TestLongIntKeys(TestLongIntSupport): class TestLongIntKeys(TestLongIntSupport):
def testLongIntKeysWork(self): def testLongIntKeysWork(self):
t = self._makeOne()
o1, o2 = self.getTwoValues() o1, o2 = self.getTwoValues()
assert o1 != o2 assert o1 != o2
# Test some small key values first: # Test some small key values first:
self.t[0L] = o1 t[0L] = o1
self.assertEqual(self.t[0], o1) self.assertEqual(t[0], o1)
self.t[0] = o2 t[0] = o2
self.assertEqual(self.t[0L], o2) self.assertEqual(t[0L], o2)
self.assertEqual(list(self.t.keys()), [0]) self.assertEqual(list(t.keys()), [0])
# Test some large key values too: # Test some large key values too:
k1 = SMALLEST_POSITIVE_33_BITS k1 = SMALLEST_POSITIVE_33_BITS
k2 = LARGEST_64_BITS k2 = LARGEST_64_BITS
k3 = SMALLEST_64_BITS k3 = SMALLEST_64_BITS
self.t[k1] = o1 t[k1] = o1
self.t[k2] = o2 t[k2] = o2
self.t[k3] = o1 t[k3] = o1
self.assertEqual(self.t[k1], o1) self.assertEqual(t[k1], o1)
self.assertEqual(self.t[k2], o2) self.assertEqual(t[k2], o2)
self.assertEqual(self.t[k3], o1) self.assertEqual(t[k3], o1)
self.assertEqual(list(self.t.keys()), [k3, 0, k1, k2]) self.assertEqual(list(t.keys()), [k3, 0, k1, k2])
def testLongIntKeysOutOfRange(self): def testLongIntKeysOutOfRange(self):
o1, o2 = self.getTwoValues() o1, o2 = self.getTwoValues()
...@@ -1284,6 +1018,7 @@ class TestLongIntKeys(TestLongIntSupport): ...@@ -1284,6 +1018,7 @@ class TestLongIntKeys(TestLongIntSupport):
class TestLongIntValues(TestLongIntSupport): class TestLongIntValues(TestLongIntSupport):
def testLongIntValuesWork(self): def testLongIntValuesWork(self):
t = self._makeOne()
keys = list(self.getTwoKeys()) keys = list(self.getTwoKeys())
keys.sort() keys.sort()
k1, k2 = keys k1, k2 = keys
...@@ -1293,11 +1028,11 @@ class TestLongIntValues(TestLongIntSupport): ...@@ -1293,11 +1028,11 @@ class TestLongIntValues(TestLongIntSupport):
v1 = SMALLEST_POSITIVE_33_BITS v1 = SMALLEST_POSITIVE_33_BITS
v2 = v1 + 1 v2 = v1 + 1
self.t[k1] = v1 t[k1] = v1
self.t[k2] = v2 t[k2] = v2
self.assertEqual(self.t[k1], v1) self.assertEqual(t[k1], v1)
self.assertEqual(self.t[k2], v2) self.assertEqual(t[k2], v2)
self.assertEqual(list(self.t.values()), [v1, v2]) self.assertEqual(list(t.values()), [v1, v2])
def testLongIntValuesOutOfRange(self): def testLongIntValuesOutOfRange(self):
k1, k2 = self.getTwoKeys() k1, k2 = self.getTwoKeys()
...@@ -1322,41 +1057,41 @@ if not using64bits: ...@@ -1322,41 +1057,41 @@ if not using64bits:
# tests of various type errors # tests of various type errors
class TypeTest(TestCase): class TypeTest(object):
def testBadTypeRaises(self): def testBadTypeRaises(self):
self.assertRaises(TypeError, self._stringraises) self.assertRaises(TypeError, self._stringraises)
self.assertRaises(TypeError, self._floatraises) self.assertRaises(TypeError, self._floatraises)
self.assertRaises(TypeError, self._noneraises) self.assertRaises(TypeError, self._noneraises)
class TestIOBTrees(TypeTest): class TestIOBTrees(TypeTest, TestCase):
def setUp(self): def _makeOne(self):
self.t = IOBTree() return IOBTree()
def _stringraises(self): def _stringraises(self):
self.t['c'] = 1 self._makeOne()['c'] = 1
def _floatraises(self): def _floatraises(self):
self.t[2.5] = 1 self._makeOne()[2.5] = 1
def _noneraises(self): def _noneraises(self):
self.t[None] = 1 self._makeOne()[None] = 1
class TestOIBTrees(TypeTest): class TestOIBTrees(TypeTest, TestCase):
def setUp(self): def _makeOne(self):
self.t = OIBTree() return OIBTree()
def _stringraises(self): def _stringraises(self):
self.t[1] = 'c' self._makeOne()[1] = 'c'
def _floatraises(self): def _floatraises(self):
self.t[1] = 1.4 self._makeOne()[1] = 1.4
def _noneraises(self): def _noneraises(self):
self.t[1] = None self._makeOne()[1] = None
def testEmptyFirstBucketReportedByGuido(self): def testEmptyFirstBucketReportedByGuido(self):
b = self.t b = self._makeOne()
for i in xrange(29972): # reduce to 29971 and it works for i in xrange(29972): # reduce to 29971 and it works
b[i] = i b[i] = i
for i in xrange(30): # reduce to 29 and it works for i in xrange(30): # reduce to 29 and it works
...@@ -1366,8 +1101,8 @@ class TestOIBTrees(TypeTest): ...@@ -1366,8 +1101,8 @@ class TestOIBTrees(TypeTest):
self.assertEqual(b.keys()[0], 30) self.assertEqual(b.keys()[0], 30)
class TestIIBTrees(TestCase): class TestIIBTrees(TestCase):
def setUp(self): def _makeOne(self):
self.t = IIBTree() return IIBTree()
def testNonIntegerKeyRaises(self): def testNonIntegerKeyRaises(self):
self.assertRaises(TypeError, self._stringraiseskey) self.assertRaises(TypeError, self._stringraiseskey)
...@@ -1380,26 +1115,26 @@ class TestIIBTrees(TestCase): ...@@ -1380,26 +1115,26 @@ class TestIIBTrees(TestCase):
self.assertRaises(TypeError, self._noneraisesvalue) self.assertRaises(TypeError, self._noneraisesvalue)
def _stringraiseskey(self): def _stringraiseskey(self):
self.t['c'] = 1 self._makeOne()['c'] = 1
def _floatraiseskey(self): def _floatraiseskey(self):
self.t[2.5] = 1 self._makeOne()[2.5] = 1
def _noneraiseskey(self): def _noneraiseskey(self):
self.t[None] = 1 self._makeOne()[None] = 1
def _stringraisesvalue(self): def _stringraisesvalue(self):
self.t[1] = 'c' self._makeOne()[1] = 'c'
def _floatraisesvalue(self): def _floatraisesvalue(self):
self.t[1] = 1.4 self._makeOne()[1] = 1.4
def _noneraisesvalue(self): def _noneraisesvalue(self):
self.t[1] = None self._makeOne()[1] = None
class TestIFBTrees(TestCase): class TestIFBTrees(TestCase):
def setUp(self): def _makeOne(self):
self.t = IFBTree() return IFBTree()
def testNonIntegerKeyRaises(self): def testNonIntegerKeyRaises(self):
self.assertRaises(TypeError, self._stringraiseskey) self.assertRaises(TypeError, self._stringraiseskey)
...@@ -1409,33 +1144,33 @@ class TestIFBTrees(TestCase): ...@@ -1409,33 +1144,33 @@ class TestIFBTrees(TestCase):
def testNonNumericValueRaises(self): def testNonNumericValueRaises(self):
self.assertRaises(TypeError, self._stringraisesvalue) self.assertRaises(TypeError, self._stringraisesvalue)
self.assertRaises(TypeError, self._noneraisesvalue) self.assertRaises(TypeError, self._noneraisesvalue)
self.t[1] = 1 self._makeOne()[1] = 1
self.t[1] = 1.0 self._makeOne()[1] = 1.0
def _stringraiseskey(self): def _stringraiseskey(self):
self.t['c'] = 1 self._makeOne()['c'] = 1
def _floatraiseskey(self): def _floatraiseskey(self):
self.t[2.5] = 1 self._makeOne()[2.5] = 1
def _noneraiseskey(self): def _noneraiseskey(self):
self.t[None] = 1 self._makeOne()[None] = 1
def _stringraisesvalue(self): def _stringraisesvalue(self):
self.t[1] = 'c' self._makeOne()[1] = 'c'
def _floatraisesvalue(self): def _floatraisesvalue(self):
self.t[1] = 1.4 self._makeOne()[1] = 1.4
def _noneraisesvalue(self): def _noneraisesvalue(self):
self.t[1] = None self._makeOne()[1] = None
class TestI_Sets(TestCase): class I_SetsBase(object):
def testBadBadKeyAfterFirst(self): def testBadBadKeyAfterFirst(self):
self.assertRaises(TypeError, self.t.__class__, [1, '']) t = self._makeOne()
self.assertRaises(TypeError, self.t.update, [1, '']) self.assertRaises(TypeError, t.__class__, [1, ''])
del self.t self.assertRaises(TypeError, t.update, [1, ''])
def testNonIntegerInsertRaises(self): def testNonIntegerInsertRaises(self):
self.assertRaises(TypeError,self._insertstringraises) self.assertRaises(TypeError,self._insertstringraises)
...@@ -1443,53 +1178,53 @@ class TestI_Sets(TestCase): ...@@ -1443,53 +1178,53 @@ class TestI_Sets(TestCase):
self.assertRaises(TypeError,self._insertnoneraises) self.assertRaises(TypeError,self._insertnoneraises)
def _insertstringraises(self): def _insertstringraises(self):
self.t.insert('a') self._makeOne().insert('a')
def _insertfloatraises(self): def _insertfloatraises(self):
self.t.insert(1.4) self._makeOne().insert(1.4)
def _insertnoneraises(self): def _insertnoneraises(self):
self.t.insert(None) self._makeOne().insert(None)
class TestIOSets(TestI_Sets): class TestIOSets(I_SetsBase, TestCase):
def setUp(self): def _makeOne(self):
self.t = IOSet() return IOSet()
class TestIOTreeSets(TestI_Sets): class TestIOTreeSets(I_SetsBase, TestCase):
def setUp(self): def _makeOne(self):
self.t = IOTreeSet() return IOTreeSet()
class TestIISets(TestI_Sets): class TestIISets(I_SetsBase, TestCase):
def setUp(self): def _makeOne(self):
self.t = IISet() return IISet()
class TestIITreeSets(TestI_Sets): class TestIITreeSets(I_SetsBase, TestCase):
def setUp(self): def _makeOne(self):
self.t = IITreeSet() return IITreeSet()
class TestLOSets(TestI_Sets): class TestLOSets(I_SetsBase, TestCase):
def setUp(self): def _makeOne(self):
self.t = LOSet() return LOSet()
class TestLOTreeSets(TestI_Sets): class TestLOTreeSets(I_SetsBase, TestCase):
def setUp(self): def _makeOne(self):
self.t = LOTreeSet() return LOTreeSet()
class TestLLSets(TestI_Sets): class TestLLSets(I_SetsBase, TestCase):
def setUp(self): def _makeOne(self):
self.t = LLSet() return LLSet()
class TestLLTreeSets(TestI_Sets): class TestLLTreeSets(I_SetsBase, TestCase):
def setUp(self): def _makeOne(self):
self.t = LLTreeSet() return LLTreeSet()
class DegenerateBTree(TestCase): class DegenerateBTree(TestCase):
...@@ -1845,13 +1580,316 @@ class BugFixes(TestCase): ...@@ -1845,13 +1580,316 @@ class BugFixes(TestCase):
self.assertEqual(len(t), 0) self.assertEqual(len(t), 0)
self.assertEqual(len(LP294788_ids), 0) self.assertEqual(len(LP294788_ids), 0)
class IIBTreeTest(BTreeTests): class BTreeTests(MappingBase):
def setUp(self): # Tests common to all BTrees
self.t = IIBTree()
def _checkIt(self, t):
t._check()
check(t)
def testDeleteNoChildrenWorks(self):
t = self._makeOne()
t[5] = 6
t[2] = 10
t[6] = 12
t[1] = 100
t[3] = 200
t[10] = 500
t[4] = 99
del t[4]
diff = lsubtract(t.keys(), [1,2,3,5,6,10])
self.assertEqual(diff , [], diff)
self._checkIt(t)
def testDeleteOneChildWorks(self):
t = self._makeOne()
t[5] = 6
t[2] = 10
t[6] = 12
t[1] = 100
t[3] = 200
t[10] = 500
t[4] = 99
del t[3]
diff = lsubtract(t.keys(), [1,2,4,5,6,10])
self.assertEqual(diff , [], diff)
self._checkIt(t)
def testDeleteTwoChildrenNoInorderSuccessorWorks(self):
t = self._makeOne()
t[5] = 6
t[2] = 10
t[6] = 12
t[1] = 100
t[3] = 200
t[10] = 500
t[4] = 99
del t[2]
diff = lsubtract(t.keys(), [1,3,4,5,6,10])
self.assertEqual(diff , [], diff)
self._checkIt(t)
def testDeleteTwoChildrenInorderSuccessorWorks(self):
# 7, 3, 8, 1, 5, 10, 6, 4 -- del 3
t = self._makeOne()
t[7] = 6
t[3] = 10
t[8] = 12
t[1] = 100
t[5] = 200
t[10] = 500
t[6] = 99
t[4] = 150
del t[3]
diff = lsubtract(t.keys(), [1,4,5,6,7,8,10])
self.assertEqual(diff , [], diff)
self._checkIt(t)
def testDeleteRootWorks(self):
# 7, 3, 8, 1, 5, 10, 6, 4 -- del 7
t = self._makeOne()
t[7] = 6
t[3] = 10
t[8] = 12
t[1] = 100
t[5] = 200
t[10] = 500
t[6] = 99
t[4] = 150
del t[7]
diff = lsubtract(t.keys(), [1,3,4,5,6,8,10])
self.assertEqual(diff , [], diff)
self._checkIt(t)
def testRandomNonOverlappingInserts(self):
t = self._makeOne()
added = {}
r = range(100)
for x in r:
k = random.choice(r)
if not added.has_key(k):
t[k] = x
added[k] = 1
addl = added.keys()
addl.sort()
diff = lsubtract(list(t.keys()), addl)
self.assertEqual(diff , [], (diff, addl, list(t.keys())))
self._checkIt(t)
def testRandomOverlappingInserts(self):
t = self._makeOne()
added = {}
r = range(100)
for x in r:
k = random.choice(r)
t[k] = x
added[k] = 1
addl = added.keys()
addl.sort()
diff = lsubtract(t.keys(), addl)
self.assertEqual(diff , [], diff)
self._checkIt(t)
def testRandomDeletes(self):
t = self._makeOne()
r = range(1000)
added = []
for x in r:
k = random.choice(r)
t[k] = x
added.append(k)
deleted = []
for x in r:
k = random.choice(r)
if t.has_key(k):
self.assert_(k in t)
del t[k]
deleted.append(k)
if t.has_key(k):
self.fail( "had problems deleting %s" % k )
badones = []
for x in deleted:
if t.has_key(x):
badones.append(x)
self.assertEqual(badones , [], (badones, added, deleted))
self._checkIt(t)
def testTargetedDeletes(self):
t = self._makeOne()
r = range(1000)
for x in r:
k = random.choice(r)
t[k] = x
for x in r:
try:
del t[x]
except KeyError:
pass
self.assertEqual(realseq(t.keys()) , [], realseq(t.keys()))
self._checkIt(t)
def testPathologicalRightBranching(self):
t = self._makeOne()
r = range(1000)
for x in r:
t[x] = 1
self.assertEqual(realseq(t.keys()) , r, realseq(t.keys()))
for x in r:
del t[x]
self.assertEqual(realseq(t.keys()) , [], realseq(t.keys()))
self._checkIt(t)
def testPathologicalLeftBranching(self):
t = self._makeOne()
r = range(1000)
revr = r[:]
revr.reverse()
for x in revr:
t[x] = 1
self.assertEqual(realseq(t.keys()) , r, realseq(t.keys()))
for x in revr:
del t[x]
self.assertEqual(realseq(t.keys()) , [], realseq(t.keys()))
self._checkIt(t)
def testSuccessorChildParentRewriteExerciseCase(self):
t = self._makeOne()
add_order = [
85, 73, 165, 273, 215, 142, 233, 67, 86, 166, 235, 225, 255,
73, 175, 171, 285, 162, 108, 28, 283, 258, 232, 199, 260,
298, 275, 44, 261, 291, 4, 181, 285, 289, 216, 212, 129,
243, 97, 48, 48, 159, 22, 285, 92, 110, 27, 55, 202, 294,
113, 251, 193, 290, 55, 58, 239, 71, 4, 75, 129, 91, 111,
271, 101, 289, 194, 218, 77, 142, 94, 100, 115, 101, 226,
17, 94, 56, 18, 163, 93, 199, 286, 213, 126, 240, 245, 190,
195, 204, 100, 199, 161, 292, 202, 48, 165, 6, 173, 40, 218,
271, 228, 7, 166, 173, 138, 93, 22, 140, 41, 234, 17, 249,
215, 12, 292, 246, 272, 260, 140, 58, 2, 91, 246, 189, 116,
72, 259, 34, 120, 263, 168, 298, 118, 18, 28, 299, 192, 252,
112, 60, 277, 273, 286, 15, 263, 141, 241, 172, 255, 52, 89,
127, 119, 255, 184, 213, 44, 116, 231, 173, 298, 178, 196,
89, 184, 289, 98, 216, 115, 35, 132, 278, 238, 20, 241, 128,
179, 159, 107, 206, 194, 31, 260, 122, 56, 144, 118, 283,
183, 215, 214, 87, 33, 205, 183, 212, 221, 216, 296, 40,
108, 45, 188, 139, 38, 256, 276, 114, 270, 112, 214, 191,
147, 111, 299, 107, 101, 43, 84, 127, 67, 205, 251, 38, 91,
297, 26, 165, 187, 19, 6, 73, 4, 176, 195, 90, 71, 30, 82,
139, 210, 8, 41, 253, 127, 190, 102, 280, 26, 233, 32, 257,
194, 263, 203, 190, 111, 218, 199, 29, 81, 207, 18, 180,
157, 172, 192, 135, 163, 275, 74, 296, 298, 265, 105, 191,
282, 277, 83, 188, 144, 259, 6, 173, 81, 107, 292, 231,
129, 65, 161, 113, 103, 136, 255, 285, 289, 1
]
delete_order = [
276, 273, 12, 275, 2, 286, 127, 83, 92, 33, 101, 195,
299, 191, 22, 232, 291, 226, 110, 94, 257, 233, 215, 184,
35, 178, 18, 74, 296, 210, 298, 81, 265, 175, 116, 261,
212, 277, 260, 234, 6, 129, 31, 4, 235, 249, 34, 289, 105,
259, 91, 93, 119, 7, 183, 240, 41, 253, 290, 136, 75, 292,
67, 112, 111, 256, 163, 38, 126, 139, 98, 56, 282, 60, 26,
55, 245, 225, 32, 52, 40, 271, 29, 252, 239, 89, 87, 205,
213, 180, 97, 108, 120, 218, 44, 187, 196, 251, 202, 203,
172, 28, 188, 77, 90, 199, 297, 282, 141, 100, 161, 216,
73, 19, 17, 189, 30, 258
]
for x in add_order:
t[x] = 1
for x in delete_order:
try: del t[x]
except KeyError:
if t.has_key(x):
self.assertEqual(1,2,"failed to delete %s" % x)
self._checkIt(t)
def testRangeSearchAfterSequentialInsert(self):
t = self._makeOne()
r = range(100)
for x in r:
t[x] = 0
diff = lsubtract(list(t.keys(0, 100)), r)
self.assertEqual(diff , [], diff)
self._checkIt(t)
def testRangeSearchAfterRandomInsert(self):
t = self._makeOne()
r = range(100)
a = {}
for x in r:
rnd = random.choice(r)
t[rnd] = 0
a[rnd] = 0
diff = lsubtract(list(t.keys(0, 100)), a.keys())
self.assertEqual(diff, [], diff)
self._checkIt(t)
def testPathologicalRangeSearch(self):
t = self._makeOne()
# Build a 2-level tree with at least two buckets.
for i in range(200):
t[i] = i
items, dummy = t.__getstate__()
self.assert_(len(items) > 2) # at least two buckets and a key
# All values in the first bucket are < firstkey. All in the
# second bucket are >= firstkey, and firstkey is the first key in
# the second bucket.
firstkey = items[1]
therange = t.keys(-1, firstkey)
self.assertEqual(len(therange), firstkey + 1)
self.assertEqual(list(therange), range(firstkey + 1))
# Now for the tricky part. If we delete firstkey, the second bucket
# loses its smallest key, but firstkey remains in the BTree node.
# If we then do a high-end range search on firstkey, the BTree node
# directs us to look in the second bucket, but there's no longer any
# key <= firstkey in that bucket. The correct answer points to the
# end of the *first* bucket. The algorithm has to be smart enough
# to "go backwards" in the BTree then; if it doesn't, it will
# erroneously claim that the range is empty.
del t[firstkey]
therange = t.keys(min=-1, max=firstkey)
self.assertEqual(len(therange), firstkey)
self.assertEqual(list(therange), range(firstkey))
self._checkIt(t)
def testInsertMethod(self):
t = self._makeOne()
t[0] = 1
self.assertEqual(t.insert(0, 1) , 0)
self.assertEqual(t.insert(1, 1) , 1)
self.assertEqual(lsubtract(list(t.keys()), [0,1]) , [])
self._checkIt(t)
def testDamagedIterator(self):
# A cute one from Steve Alexander. This caused the BTreeItems
# object to go insane, accessing memory beyond the allocated part
# of the bucket. If it fails, the symptom is either a C-level
# assertion error (if the BTree code was compiled without NDEBUG),
# or most likely a segfault (if the BTree code was compiled with
# NDEBUG).
t = self._makeOne()
self._populate(t, 10)
# In order for this to fail, it's important that k be a "lazy"
# iterator, referring to the BTree by indirect position (index)
# instead of a fully materialized list. Then the position can
# end up pointing into trash memory, if the bucket pointed to
# shrinks.
k = t.keys()
for dummy in range(20):
try:
del t[k[0]]
except RuntimeError, detail:
self.assertEqual(str(detail), "the bucket being iterated "
"changed size")
break
self._checkIt(t)
class IIBTreeTest(BTreeTests, TestCase):
def _makeOne(self):
return IIBTree()
def testIIBTreeOverflow(self): def testIIBTreeOverflow(self):
good = set() good = set()
b = self.t b = self._makeOne()
def trial(i): def trial(i):
i = int(i) i = int(i)
...@@ -1871,18 +1909,21 @@ class IIBTreeTest(BTreeTests): ...@@ -1871,18 +1909,21 @@ class IIBTreeTest(BTreeTests):
del b[0] del b[0]
self.assertEqual(sorted(good), sorted(b)) self.assertEqual(sorted(good), sorted(b))
class IFBTreeTest(BTreeTests): class IFBTreeTest(BTreeTests, TestCase):
def setUp(self): def _makeOne(self):
self.t = IFBTree() return IFBTree()
class IOBTreeTest(BTreeTests):
def setUp(self): class IOBTreeTest(BTreeTests, TestCase):
self.t = IOBTree() def _makeOne(self):
class OIBTreeTest(BTreeTests): return IOBTree()
def setUp(self):
self.t = OIBTree() class OIBTreeTest(BTreeTests, TestCase):
class OOBTreeTest(BTreeTests): def _makeOne(self):
def setUp(self): return OIBTree()
self.t = OOBTree()
class OOBTreeTest(BTreeTests, TestCase):
def _makeOne(self):
return OOBTree()
def testRejectDefaultComparison(self): def testRejectDefaultComparison(self):
# Check that passing int keys w default comparison fails. # Check that passing int keys w default comparison fails.
...@@ -1893,66 +1934,74 @@ class OOBTreeTest(BTreeTests): ...@@ -1893,66 +1934,74 @@ class OOBTreeTest(BTreeTests):
# used in a function that's used in lots of places. # used in a function that's used in lots of places.
# Otherwise, there are many permutations that would have to be # Otherwise, there are many permutations that would have to be
# checked. # checked.
t = self._makeOne()
class C(object): class C(object):
pass pass
self.assertRaises(TypeError, lambda : self.t.__setitem__(C(), 1)) self.assertRaises(TypeError, lambda : t.__setitem__(C(), 1))
class C(object): class C(object):
def __cmp__(*args): def __cmp__(*args):
return 1 return 1
c = C() c = C()
self.t[c] = 1 t[c] = 1
self.t.clear() t.clear()
class C(object): class C(object):
def __lt__(*args): def __lt__(*args):
return 1 return 1
c = C() c = C()
self.t[c] = 1 t[c] = 1
self.t.clear() t.clear()
if using64bits: if using64bits:
class IIBTreeTest(BTreeTests, TestLongIntKeys, TestLongIntValues):
def setUp(self): class IIBTreeTest(BTreeTests, TestLongIntKeys, TestLongIntValues, TestCase):
self.t = IIBTree() def _makeOne(self):
return IIBTree()
def getTwoValues(self): def getTwoValues(self):
return 1, 2 return 1, 2
class IFBTreeTest(BTreeTests, TestLongIntKeys):
def setUp(self): class IFBTreeTest(BTreeTests, TestLongIntKeys, TestCase):
self.t = IFBTree() def _makeOne(self):
return IFBTree()
def getTwoValues(self): def getTwoValues(self):
return 0.5, 1.5 return 0.5, 1.5
class IOBTreeTest(BTreeTests, TestLongIntKeys):
def setUp(self): class IOBTreeTest(BTreeTests, TestLongIntKeys, TestCase):
self.t = IOBTree() def _makeOne(self):
class OIBTreeTest(BTreeTests, TestLongIntValues): return IOBTree()
def setUp(self):
self.t = OIBTree() class OIBTreeTest(BTreeTests, TestLongIntValues, TestCase):
def _makeOne(self):
return OIBTree()
def getTwoKeys(self): def getTwoKeys(self):
return object(), object() return object(), object()
class LLBTreeTest(BTreeTests, TestLongIntKeys, TestLongIntValues): class LLBTreeTest(BTreeTests, TestLongIntKeys, TestLongIntValues, TestCase):
def setUp(self): def _makeOne(self):
self.t = LLBTree() return LLBTree()
def getTwoValues(self): def getTwoValues(self):
return 1, 2 return 1, 2
class LFBTreeTest(BTreeTests, TestLongIntKeys):
def setUp(self): class LFBTreeTest(BTreeTests, TestLongIntKeys, TestCase):
self.t = LFBTree() def _makeOne(self):
return LFBTree()
def getTwoValues(self): def getTwoValues(self):
return 0.5, 1.5 return 0.5, 1.5
class LOBTreeTest(BTreeTests, TestLongIntKeys):
def setUp(self): class LOBTreeTest(BTreeTests, TestLongIntKeys, TestCase):
self.t = LOBTree() def _makeOne(self):
class OLBTreeTest(BTreeTests, TestLongIntValues): return LOBTree()
def setUp(self):
self.t = OLBTree() class OLBTreeTest(BTreeTests, TestLongIntValues, TestCase):
def _makeOne(self):
return OLBTree()
def getTwoKeys(self): def getTwoKeys(self):
return object(), object() return object(), object()
...@@ -1977,7 +2026,7 @@ class TestCmpError(TestCase): ...@@ -1977,7 +2026,7 @@ class TestCmpError(TestCase):
# test for presence of generic names in module # test for presence of generic names in module
class ModuleTest(TestCase): class ModuleTest(object):
module = None module = None
prefix = None prefix = None
iface = None iface = None
...@@ -2089,26 +2138,24 @@ class FamilyTest(TestCase): ...@@ -2089,26 +2138,24 @@ class FamilyTest(TestCase):
self.failUnless(f2 is family) self.failUnless(f2 is family)
class InternalKeysMappingTest(TestCase): class InternalKeysMappingTest(TestCase):
"""There must not be any internal keys not in the BTree # There must not be any internal keys not in the BTree
"""
def add_key(self, tree, key): def add_key(self, tree, key):
tree[key] = key tree[key] = key
def test_internal_keys_after_deletion(self): def test_internal_keys_after_deletion(self):
"""Make sure when a key's deleted, it's not an internal key # Make sure when a key's deleted, it's not an internal key
#
We'll leverage __getstate__ to introspect the internal structures. # We'll leverage __getstate__ to introspect the internal structures.
#
We need to check BTrees with BTree children as well as BTrees # We need to check BTrees with BTree children as well as BTrees
with bucket children. # with bucket children.
""" import transaction
from ZODB.MappingStorage import DB from ZODB.MappingStorage import DB
db = DB() db = DB()
conn = db.open() conn = db.open()
tree = conn.root.tree = self.t_class() tree = conn.root.tree = self._makeOne()
i = 0 i = 0
# Grow the btree until we have multiple buckets # Grow the btree until we have multiple buckets
...@@ -2149,80 +2196,11 @@ class InternalKeysMappingTest(TestCase): ...@@ -2149,80 +2196,11 @@ class InternalKeysMappingTest(TestCase):
db.close() db.close()
class InternalKeysSetTest: class InternalKeysSetTest:
"""There must not be any internal keys not in the TreeSet # There must not be any internal keys not in the TreeSet
"""
def add_key(self, tree, key): def add_key(self, tree, key):
tree.add(key) tree.add(key)
def test_suite():
s = TestSuite()
for kv in ('OO',
'II', 'IO', 'OI', 'IF',
'LL', 'LO', 'OL', 'LF',
):
for name, bases in (
('BTree', (InternalKeysMappingTest,)),
('TreeSet', (InternalKeysSetTest,)),
):
klass = ClassType(kv + name + 'InternalKeyTest', bases,
dict(t_class=globals()[kv+name]))
s.addTest(makeSuite(klass))
for kv in ('OO',
'II', 'IO', 'OI', 'IF',
'LL', 'LO', 'OL', 'LF',
):
for name, bases in (
('Bucket', (MappingBase,)),
('TreeSet', (NormalSetTests,)),
('Set', (ExtendedSetTests,)),
):
klass = ClassType(kv + name + 'Test', bases,
dict(t_class=globals()[kv+name]))
s.addTest(makeSuite(klass))
for kv, iface in (
('OO', BTrees.Interfaces.IObjectObjectBTreeModule),
('IO', BTrees.Interfaces.IIntegerObjectBTreeModule),
('LO', BTrees.Interfaces.IIntegerObjectBTreeModule),
('OI', BTrees.Interfaces.IObjectIntegerBTreeModule),
('OL', BTrees.Interfaces.IObjectIntegerBTreeModule),
('II', BTrees.Interfaces.IIntegerIntegerBTreeModule),
('LL', BTrees.Interfaces.IIntegerIntegerBTreeModule),
('IF', BTrees.Interfaces.IIntegerFloatBTreeModule),
('LF', BTrees.Interfaces.IIntegerFloatBTreeModule)):
s.addTest(
makeSuite(
ClassType(
kv + 'ModuleTest',
(ModuleTest,),
dict(
prefix=kv,
module=getattr(BTrees, kv + 'BTree'),
iface=iface))))
for klass in (
IIBTreeTest, IFBTreeTest, IOBTreeTest, OIBTreeTest,
LLBTreeTest, LFBTreeTest, LOBTreeTest, OLBTreeTest,
OOBTreeTest,
# Note: there is no TestOOBTrees. The next three are
# checking for assorted TypeErrors, and when both keys
# and values are objects (OO), there's nothing to test.
TestIIBTrees, TestIFBTrees, TestIOBTrees, TestOIBTrees,
TestIOSets, TestIOTreeSets, TestIISets, TestIITreeSets,
TestLOSets, TestLOTreeSets, TestLLSets, TestLLTreeSets,
DegenerateBTree,
TestCmpError,
BugFixes,
FamilyTest,
):
s.addTest(makeSuite(klass))
return s
## utility functions ## utility functions
def lsubtract(l1, l2): def lsubtract(l1, l2):
...@@ -2249,9 +2227,226 @@ def permutations(x): ...@@ -2249,9 +2227,226 @@ def permutations(x):
result.extend([[first] + p for p in permutations(xcopy[1:])]) result.extend([[first] + p for p in permutations(xcopy[1:])])
return result return result
# Unroll stuff in 'test_suite'
class OOBTreeInternalKeyTest(InternalKeysMappingTest, TestCase):
klass = OOBTree
class OOTreeSetInternalKeyTest(InternalKeysSetTest, TestCase):
klass = OOTreeSet
class OOBucketTest(MappingBase, TestCase):
klass = OOBucket
class OOTreeSetTest(NormalSetTests, TestCase):
klass = OOTreeSet
class OOSetTest(ExtendedSetTests, TestCase):
klass = OOSet
class OOModuleTest(ModuleTest, TestCase):
prefix = 'OO'
module = BTrees.OOBTree
iface = BTrees.Interfaces.IObjectObjectBTreeModule
class IIBTreeInternalKeyTest(InternalKeysMappingTest, TestCase):
klass = IIBTree
class IITreeSetInternalKeyTest(InternalKeysSetTest, TestCase):
klass = IITreeSet
class IIBucketTest(MappingBase, TestCase):
klass = IIBucket
class IITreeSetTest(NormalSetTests, TestCase):
klass = IITreeSet
class IISetTest(ExtendedSetTests, TestCase):
klass = IISet
class IIModuleTest(ModuleTest, TestCase):
prefix = 'II'
module = BTrees.IIBTree
iface = BTrees.Interfaces.IIntegerIntegerBTreeModule
class IOBTreeInternalKeyTest(InternalKeysMappingTest, TestCase):
klass = IOBTree
class IOTreeSetInternalKeyTest(InternalKeysSetTest, TestCase):
klass = IOTreeSet
class IOBucketTest(MappingBase, TestCase):
klass = IOBucket
class IOTreeSetTest(NormalSetTests, TestCase):
klass = IOTreeSet
class IOSetTest(ExtendedSetTests, TestCase):
klass = IOSet
class IOModuleTest(ModuleTest, TestCase):
prefix = 'IO'
module = BTrees.IOBTree
iface = BTrees.Interfaces.IIntegerObjectBTreeModule
class OIBTreeInternalKeyTest(InternalKeysMappingTest, TestCase):
klass = OIBTree
class OITreeSetInternalKeyTest(InternalKeysSetTest, TestCase):
klass = OITreeSet
class OIBucketTest(MappingBase, TestCase):
klass = OIBucket
class OITreeSetTest(NormalSetTests, TestCase):
klass = OITreeSet
class OISetTest(ExtendedSetTests, TestCase):
klass = OISet
class OIModuleTest(ModuleTest, TestCase):
prefix = 'OI'
module = BTrees.OIBTree
iface = BTrees.Interfaces.IObjectIntegerBTreeModule
class IFBTreeInternalKeyTest(InternalKeysMappingTest, TestCase):
klass = IFBTree
class IFTreeSetInternalKeyTest(InternalKeysSetTest, TestCase):
klass = IFTreeSet
class IFBucketTest(MappingBase, TestCase):
klass = IFBucket
class IFTreeSetTest(NormalSetTests, TestCase):
klass = IFTreeSet
class IFSetTest(ExtendedSetTests, TestCase):
klass = IFSet
class IFModuleTest(ModuleTest, TestCase):
prefix = 'IF'
module = BTrees.IFBTree
iface = BTrees.Interfaces.IIntegerFloatBTreeModule
class LLBTreeInternalKeyTest(InternalKeysMappingTest, TestCase):
klass = LLBTree
class LLTreeSetInternalKeyTest(InternalKeysSetTest, TestCase):
klass = LLTreeSet
class LLBucketTest(MappingBase, TestCase):
klass = LLBucket
class LLTreeSetTest(NormalSetTests, TestCase):
klass = LLTreeSet
class LLSetTest(ExtendedSetTests, TestCase):
klass = LLSet
class LLSetTest(ExtendedSetTests, TestCase):
klass = LLSet
class LLModuleTest(ModuleTest, TestCase):
prefix = 'LL'
module = BTrees.LLBTree
iface = BTrees.Interfaces.IIntegerIntegerBTreeModule
class LOBTreeInternalKeyTest(InternalKeysMappingTest, TestCase):
klass = LOBTree
class LOTreeSetInternalKeyTest(InternalKeysSetTest, TestCase):
klass = LOTreeSet
class LOBucketTest(MappingBase, TestCase):
klass = LOBucket
class LOTreeSetTest(NormalSetTests, TestCase):
klass = LOTreeSet
class LOSetTest(ExtendedSetTests, TestCase):
klass = LOSet
class LOModuleTest(ModuleTest, TestCase):
prefix = 'LO'
module = BTrees.LOBTree
iface =BTrees.Interfaces.IIntegerObjectBTreeModule
class OLBTreeInternalKeyTest(InternalKeysMappingTest, TestCase):
klass = OLBTree
class OLTreeSetInternalKeyTest(InternalKeysSetTest, TestCase):
klass = OLTreeSet
class OLBucketTest(MappingBase, TestCase):
klass = OLBucket
class OLTreeSetTest(NormalSetTests, TestCase):
klass = OLTreeSet
class OLSetTest(ExtendedSetTests, TestCase):
klass = OLSet
class OLModuleTest(ModuleTest, TestCase):
prefix = 'OL'
module = BTrees.OLBTree
iface = BTrees.Interfaces.IObjectIntegerBTreeModule
class LFBTreeInternalKeyTest(InternalKeysMappingTest, TestCase):
klass = LFBTree
class LFTreeSetInternalKeyTest(InternalKeysSetTest, TestCase):
klass = LFTreeSet
class LFBucketTest(MappingBase, TestCase):
klass = LFBucket
class LFTreeSetTest(NormalSetTests, TestCase):
klass = LFTreeSet
class LFSetTest(ExtendedSetTests, TestCase):
klass = LFSet
class LFModuleTest(ModuleTest, TestCase):
prefix = 'LF'
module = BTrees.LFBTree
iface = BTrees.Interfaces.IIntegerFloatBTreeModule
def main():
TextTestRunner().run(test_suite())
if __name__ == '__main__': def test_suite():
main() return TestSuite((
makeSuite(OOBTreeInternalKeyTest),
makeSuite(OOTreeSetInternalKeyTest),
makeSuite(OOBucketTest),
makeSuite(OOTreeSetTest),
makeSuite(OOSetTest),
makeSuite(OOModuleTest),
makeSuite(IIBTreeInternalKeyTest),
makeSuite(IITreeSetInternalKeyTest),
makeSuite(IIBucketTest),
makeSuite(IITreeSetTest),
makeSuite(IISetTest),
makeSuite(IIModuleTest),
makeSuite(IOBTreeInternalKeyTest),
makeSuite(IOTreeSetInternalKeyTest),
makeSuite(IOBucketTest),
makeSuite(IOTreeSetTest),
makeSuite(IOSetTest),
makeSuite(IOModuleTest),
makeSuite(OIBTreeInternalKeyTest),
makeSuite(OITreeSetInternalKeyTest),
makeSuite(OIBucketTest),
makeSuite(OITreeSetTest),
makeSuite(OISetTest),
makeSuite(OIModuleTest),
makeSuite(IFBTreeInternalKeyTest),
makeSuite(IFTreeSetInternalKeyTest),
makeSuite(IFBucketTest),
makeSuite(IFTreeSetTest),
makeSuite(IFSetTest),
makeSuite(IFModuleTest),
makeSuite(LLBTreeInternalKeyTest),
makeSuite(LLTreeSetInternalKeyTest),
makeSuite(LLBucketTest),
makeSuite(LLTreeSetTest),
makeSuite(LLSetTest),
makeSuite(LLModuleTest),
makeSuite(LOBTreeInternalKeyTest),
makeSuite(LOTreeSetInternalKeyTest),
makeSuite(LOBucketTest),
makeSuite(LOTreeSetTest),
makeSuite(LOSetTest),
makeSuite(LOModuleTest),
makeSuite(OLBTreeInternalKeyTest),
makeSuite(OLTreeSetInternalKeyTest),
makeSuite(OLBucketTest),
makeSuite(OLTreeSetTest),
makeSuite(OLSetTest),
makeSuite(OLModuleTest),
makeSuite(LFBTreeInternalKeyTest),
makeSuite(LFTreeSetInternalKeyTest),
makeSuite(LFBucketTest),
makeSuite(LFTreeSetTest),
makeSuite(LFSetTest),
makeSuite(LFModuleTest),
makeSuite(IIBTreeTest),
makeSuite(IFBTreeTest),
makeSuite(IOBTreeTest),
makeSuite(OIBTreeTest),
makeSuite(LLBTreeTest),
makeSuite(LFBTreeTest),
makeSuite(LOBTreeTest),
makeSuite(OLBTreeTest),
makeSuite(OOBTreeTest),
makeSuite(TestIIBTrees),
makeSuite(TestIFBTrees),
makeSuite(TestIOBTrees),
makeSuite(TestOIBTrees),
makeSuite(TestIOSets),
makeSuite(TestIOTreeSets),
makeSuite(TestIISets),
makeSuite(TestIITreeSets),
makeSuite(TestLOSets),
makeSuite(TestLOTreeSets),
makeSuite(TestLLSets),
makeSuite(TestLLTreeSets),
makeSuite(DegenerateBTree),
makeSuite(TestCmpError),
makeSuite(BugFixes),
makeSuite(FamilyTest),
))
...@@ -68,9 +68,3 @@ class TestBTreesUnicode(unittest.TestCase): ...@@ -68,9 +68,3 @@ class TestBTreesUnicode(unittest.TestCase):
def test_suite(): def test_suite():
return unittest.makeSuite(TestBTreesUnicode) return unittest.makeSuite(TestBTreesUnicode)
def main():
unittest.TextTestRunner().run(test_suite())
if __name__ == '__main__':
main()
...@@ -570,9 +570,3 @@ def test_suite(): ...@@ -570,9 +570,3 @@ def test_suite():
): ):
s.addTest(makeSuite(klass)) s.addTest(makeSuite(klass))
return s return s
def main():
TextTestRunner().run(test_suite())
if __name__ == '__main__':
main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment