[Zope-Checkins] CVS: Zope3/lib/python/Persistence/BTrees/tests - __init__.py:1.2 testBTrees.py:1.2 testBTreesUnicode.py:1.2 testCompare.py:1.2 testConflict.py:1.2 testSetOps.py:1.2
Jim Fulton
jim@zope.com
Mon, 10 Jun 2002 19:28:44 -0400
Update of /cvs-repository/Zope3/lib/python/Persistence/BTrees/tests
In directory cvs.zope.org:/tmp/cvs-serv17445/lib/python/Persistence/BTrees/tests
Added Files:
__init__.py testBTrees.py testBTreesUnicode.py testCompare.py
testConflict.py testSetOps.py
Log Message:
Merged Zope-3x-branch into newly forked Zope3 CVS Tree.
=== Zope3/lib/python/Persistence/BTrees/tests/__init__.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+# If tests is a package, debugging is a bit easier.
+
=== Zope3/lib/python/Persistence/BTrees/tests/testBTrees.py 1.1 => 1.2 === (721/821 lines abridged)
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import os
+import random
+
+from Persistence.BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet
+from Persistence.BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
+from Persistence.BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
+from Persistence.BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet
+
+from unittest import TestCase, TestSuite, TextTestRunner, makeSuite
+
+from glob import glob
+
+class Base(TestCase):
+ """ Tests common to all types: sets, buckets, and BTrees """
+ def tearDown(self):
+ self.t = None
+ del self.t
+
+ def _getRoot(self):
+ from ZODB.FileStorage import FileStorage
+ from ZODB.DB import DB
+ n = 'fs_tmp__%s' % os.getpid()
+ s = FileStorage(n)
+ db = DB(s, cache_size=1)
+ root = db.open().root()
+ return root
+
+ def _closeDB(self, root):
+ if root is not None:
+ root._p_jar._db.close()
+
+ def _delDB(self):
+ for file in glob('fs_tmp__*'):
+ os.remove(file)
+
+ def testLoadAndStore(self):
+ for i in 0, 10, 1000:
+ t = self.t.__class__()
[-=- -=- -=- 721 lines omitted -=- -=- -=-]
+
+def make_test(klass, base):
+ class Test(base):
+ def setUp(self):
+ self.t = klass()
+ # Give the test an artificial name so that unittest output
+ # includes the name of the BTree object being tested. Include a
+ # '!' in the name so that it is obvious that it doesn't occur in
+ # the source code anywhere.
+ Test.__name__ = "!%sTest" % klass.__name__
+ return makeSuite(Test)
+
+def test_suite():
+ # Handle the basic test cases for each type of object via make_test().
+ template = [(MappingBase, (IIBucket, IOBucket, OIBucket, OOBucket)),
+ (NormalSetTests, (IITreeSet, IOTreeSet, OITreeSet, OOTreeSet)),
+ (ExtendedSetTests, (IISet, IOSet, OISet, OOSet)),
+ (BTreeTests, (IIBTree, IOBTree, OIBTree, OOBTree)),
+ ]
+
+ s = TestSuite()
+ for base, classes in template:
+ for klass in classes:
+ s.addTest(make_test(klass, base))
+
+ # Handle the odd assortment of other tests, which appear to be
+ # specific to whether keys and values are Is or Os.
+ for klass in TestIOBTrees, TestOIBTrees, TestIIBTrees, TestIOSets:
+ s.addTest(makeSuite(klass))
+
+ return s
+
+## utility functions
+
+def lsubtract(l1, l2):
+ l1 = list(l1)
+ l2 = list(l2)
+ l = filter(lambda x, l1=l1: x not in l1, l2)
+ l = l + filter(lambda x, l2=l2: x not in l2, l1)
+ return l
+
+def realseq(itemsob):
+ return [x for x in itemsob]
+
+def main():
+ TextTestRunner().run(test_suite())
+
+if __name__ == '__main__':
+ main()
+
=== Zope3/lib/python/Persistence/BTrees/tests/testBTreesUnicode.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+__version__ = '$Id$'
+
+import types
+import unittest
+from Persistence.BTrees.OOBTree import OOBTree
+
+# When an OOBtree contains unicode strings as keys,
+# it is neccessary accessing non-unicode strings are
+# either ascii strings or encoded as unicoded using the
+# corresponding encoding
+
+encoding = 'ISO-8859-1'
+
+class TestBTreesUnicode(unittest.TestCase):
+ """ test unicode"""
+
+ def setUp(self):
+ """setup an OOBTree with some unicode strings"""
+
+ self.s = unicode('dreit\xe4gigen', 'latin1')
+
+ self.data = [('alien', 1),
+ ('k\xf6nnten', 2),
+ ('fox', 3),
+ ('future', 4),
+ ('quick', 5),
+ ('zerst\xf6rt', 6),
+ (unicode('dreit\xe4gigen','latin1'), 7),
+ ]
+
+ self.tree = OOBTree()
+ for k, v in self.data:
+ if isinstance(k, types.StringType):
+ k = unicode(k, 'latin1')
+ self.tree[k] = v
+
+ def testAllKeys(self):
+ # check every item of the tree
+ for k, v in self.data:
+ if isinstance(k, types.StringType):
+ k = unicode(k, encoding)
+ self.assert_(self.tree.has_key(k))
+ self.assertEqual(self.tree[k], v)
+
+ def testUnicodeKeys(self):
+ # try to access unicode keys in tree
+ k, v = self.data[-1]
+ self.assertEqual(k, self.s)
+ self.assertEqual(self.tree[k], v)
+ self.assertEqual(self.tree[self.s], v)
+
+ def testAsciiKeys(self):
+ # try to access some "plain ASCII" keys in the tree
+ for k, v in self.data[0], self.data[2]:
+ self.assert_(isinstance(k, types.StringType))
+ self.assertEqual(self.tree[k], v)
+
+def test_suite():
+ return unittest.makeSuite(TestBTreesUnicode)
+
+def main():
+ unittest.TextTestRunner().run(test_suite())
+
+if __name__ == '__main__':
+ main()
=== Zope3/lib/python/Persistence/BTrees/tests/testCompare.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Test errors during comparison of BTree keys."""
+
+import unittest
+
+import ZODB
+from Persistence.BTrees.OOBTree import OOBucket as Bucket, OOSet as Set
+from ZODB.MappingStorage import MappingStorage
+
+class CompareTest(unittest.TestCase):
+
+ s = "A string with hi-bit-set characters: \700\701"
+ u = u"A unicode string"
+
+ def setUp(self):
+ # These defaults only make sense if the default encoding
+ # prevents s from being promoted to Unicode.
+ self.assertRaises(UnicodeError, unicode, self.s)
+
+ # An object needs to be added to the database to
+ self.db = ZODB.DB(MappingStorage())
+ root = self.db.open().root()
+ self.bucket = root["bucket"] = Bucket()
+ self.set = root["set"] = Set()
+ get_transaction().commit()
+
+ def tearDown(self):
+ self.assert_(self.bucket._p_changed != 2)
+ self.assert_(self.set._p_changed != 2)
+
+ def assertUE(self, callable, *args):
+ self.assertRaises(UnicodeError, callable, *args)
+
+ def testBucketGet(self):
+ self.bucket[self.s] = 1
+ self.assertUE(self.bucket.get, self.u)
+
+ def testSetGet(self):
+ self.set.insert(self.s)
+ self.assertUE(self.set.remove, self.u)
+
+ def testBucketSet(self):
+ self.bucket[self.s] = 1
+ self.assertUE(self.bucket.__setitem__, self.u, 1)
+
+ def testSetSet(self):
+ self.set.insert(self.s)
+ self.assertUE(self.set.insert, self.u)
+
+ def testBucketMinKey(self):
+ self.bucket[self.s] = 1
+ self.assertUE(self.bucket.minKey, self.u)
+
+ def testSetMinKey(self):
+ self.set.insert(self.s)
+ self.assertUE(self.set.minKey, self.u)
+
+def test_suite():
+ return unittest.makeSuite(CompareTest)
=== Zope3/lib/python/Persistence/BTrees/tests/testConflict.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import os
+
+from Persistence.BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet
+from Persistence.BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
+from Persistence.BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
+from Persistence.BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet
+from unittest import TestCase, TestSuite, TextTestRunner, makeSuite
+
+from Transaction.Exceptions import ConflictError
+
+class Base:
+ """ Tests common to all types: sets, buckets, and BTrees """
+ def tearDown(self):
+ self.t = None
+ del self.t
+
+ def _getRoot(self):
+ from ZODB.FileStorage import FileStorage
+ from ZODB.DB import DB
+ n = 'fs_tmp__%s' % os.getpid()
+ s = FileStorage(n)
+ db = DB(s)
+ root = db.open().root()
+ return root
+
+ def _closeDB(self, root):
+ root._p_jar._db.close()
+ root = None
+
+ def _delDB(self):
+ os.system('rm fs_tmp__*')
+
+class MappingBase(Base):
+ """ Tests common to mappings (buckets, btrees) """
+
+ def _deletefail(self):
+ del self.t[1]
+
+ def _setupConflict(self):
+
+ l=[ -5124, -7377, 2274, 8801, -9901, 7327, 1565, 17, -679,
+ 3686, -3607, 14, 6419, -5637, 6040, -4556, -8622, 3847, 7191,
+ -4067]
+
+
+ e1=[(-1704, 0), (5420, 1), (-239, 2), (4024, 3), (-6984, 4)]
+ e2=[(7745, 0), (4868, 1), (-2548, 2), (-2711, 3), (-3154, 4)]
+
+
+ base=self.t
+ base.update([(i, i*i) for i in l[:20]])
+ b1=base.__class__(base)
+ b2=base.__class__(base)
+ bm=base.__class__(base)
+
+ items=base.items()
+
+ return base, b1, b2, bm, e1, e2, items
+
+ def testMergeDelete(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ del b1[items[0][0]]
+ del b2[items[5][0]]
+ del b1[items[-1][0]]
+ del b2[items[-2][0]]
+ del bm[items[0][0]]
+ del bm[items[5][0]]
+ del bm[items[-1][0]]
+ del bm[items[-2][0]]
+ test_merge(base, b1, b2, bm, 'merge delete')
+
+ def testMergeDeleteAndUpdate(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ del b1[items[0][0]]
+ b2[items[5][0]]=1
+ del b1[items[-1][0]]
+ b2[items[-2][0]]=2
+ del bm[items[0][0]]
+ bm[items[5][0]]=1
+ del bm[items[-1][0]]
+ bm[items[-2][0]]=2
+ test_merge(base, b1, b2, bm, 'merge update and delete')
+
+ def testMergeUpdate(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ b1[items[0][0]]=1
+ b2[items[5][0]]=2
+ b1[items[-1][0]]=3
+ b2[items[-2][0]]=4
+ bm[items[0][0]]=1
+ bm[items[5][0]]=2
+ bm[items[-1][0]]=3
+ bm[items[-2][0]]=4
+ test_merge(base, b1, b2, bm, 'merge update')
+
+ def testFailMergeDelete(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ del b1[items[0][0]]
+ del b2[items[0][0]]
+ test_merge(base, b1, b2, bm, 'merge conflicting delete',
+ should_fail=1)
+
+ def testFailMergeUpdate(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ b1[items[0][0]]=1
+ b2[items[0][0]]=2
+ test_merge(base, b1, b2, bm, 'merge conflicting update',
+ should_fail=1)
+
+ def testFailMergeDeleteAndUpdate(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ del b1[items[0][0]]
+ b2[items[0][0]]=-9
+ test_merge(base, b1, b2, bm, 'merge conflicting update and delete',
+ should_fail=1)
+
+ def testMergeInserts(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ b1[-99999]=-99999
+ b1[e1[0][0]]=e1[0][1]
+ b2[99999]=99999
+ b2[e1[2][0]]=e1[2][1]
+
+ bm[-99999]=-99999
+ bm[e1[0][0]]=e1[0][1]
+ bm[99999]=99999
+ bm[e1[2][0]]=e1[2][1]
+ test_merge(base, b1, b2, bm, 'merge insert')
+
+ def testMergeInsertsFromEmpty(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ base.clear()
+ b1.clear()
+ b2.clear()
+ bm.clear()
+
+ b1.update(e1)
+ bm.update(e1)
+ b2.update(e2)
+ bm.update(e2)
+
+ test_merge(base, b1, b2, bm, 'merge insert from empty')
+
+ def testMergeEmptyAndFill(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ b1.clear()
+ bm.clear()
+ b2.update(e2)
+ bm.update(e2)
+
+ test_merge(base, b1, b2, bm, 'merge insert from empty')
+
+ def testMergeEmpty(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ b1.clear()
+ bm.clear()
+
+ test_merge(base, b1, b2, bm, 'empty one and not other')
+
+ def testFailMergeInsert(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ b1[-99999]=-99999
+ b1[e1[0][0]]=e1[0][1]
+ b2[99999]=99999
+ b2[e1[0][0]]=e1[0][1]
+ test_merge(base, b1, b2, bm, 'merge conflicting inserts',
+ should_fail=1)
+
+
+class NormalSetTests(Base):
+ """ Test common to all set types """
+
+
+
+class ExtendedSetTests(NormalSetTests):
+ "Set (as opposed to TreeSet) specific tests."
+
+ def _setupConflict(self):
+ l=[ -5124, -7377, 2274, 8801, -9901, 7327, 1565, 17, -679,
+ 3686, -3607, 14, 6419, -5637, 6040, -4556, -8622, 3847, 7191,
+ -4067]
+
+ e1=[-1704, 5420, -239, 4024, -6984]
+ e2=[7745, 4868, -2548, -2711, -3154]
+
+
+ base=self.t
+ base.update(l)
+ b1=base.__class__(base)
+ b2=base.__class__(base)
+ bm=base.__class__(base)
+
+ items=base.keys()
+
+ return base, b1, b2, bm, e1, e2, items
+
+ def testMergeDelete(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ b1.remove(items[0])
+ b2.remove(items[5])
+ b1.remove(items[-1])
+ b2.remove(items[-2])
+ bm.remove(items[0])
+ bm.remove(items[5])
+ bm.remove(items[-1])
+ bm.remove(items[-2])
+ test_merge(base, b1, b2, bm, 'merge delete')
+
+ def testFailMergeDelete(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ b1.remove(items[0])
+ b2.remove(items[0])
+ test_merge(base, b1, b2, bm, 'merge conflicting delete',
+ should_fail=1)
+
+ def testMergeInserts(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ b1.insert(-99999)
+ b1.insert(e1[0])
+ b2.insert(99999)
+ b2.insert(e1[2])
+
+ bm.insert(-99999)
+ bm.insert(e1[0])
+ bm.insert(99999)
+ bm.insert(e1[2])
+ test_merge(base, b1, b2, bm, 'merge insert')
+
+ def testMergeInsertsFromEmpty(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ base.clear()
+ b1.clear()
+ b2.clear()
+ bm.clear()
+
+ b1.update(e1)
+ bm.update(e1)
+ b2.update(e2)
+ bm.update(e2)
+
+ test_merge(base, b1, b2, bm, 'merge insert from empty')
+
+ def testMergeEmptyAndFill(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ b1.clear()
+ bm.clear()
+ b2.update(e2)
+ bm.update(e2)
+
+ test_merge(base, b1, b2, bm, 'merge insert from empty')
+
+ def testMergeEmpty(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ b1.clear()
+ bm.clear()
+
+ test_merge(base, b1, b2, bm, 'empty one and not other')
+
+ def testFailMergeInsert(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ b1.insert(-99999)
+ b1.insert(e1[0])
+ b2.insert(99999)
+ b2.insert(e1[0])
+ test_merge(base, b1, b2, bm, 'merge conflicting inserts',
+ should_fail=1)
+
+
+def test_merge(o1, o2, o3, expect, message='failed to merge', should_fail=0):
+ s1=o1.__getstate__()
+ s2=o2.__getstate__()
+ s3=o3.__getstate__()
+ expected=expect.__getstate__()
+ if expected is None: expected=((((),),),)
+
+ if should_fail:
+ try:
+ merged=o1._p_resolveConflict(s1, s2, s3)
+ except (ConflictError, ValueError), err:
+ pass # ConflictError is the only exception that should occur
+ else:
+ assert 0, message
+ else:
+ merged=o1._p_resolveConflict(s1, s2, s3)
+ assert merged==expected, message
+
+class BucketTests(MappingBase):
+ """ Tests common to all buckets """
+
+
+class BTreeTests(MappingBase):
+ """ Tests common to all BTrees """
+
+## BTree tests
+
+class TestIOBTrees(BTreeTests, TestCase):
+ def setUp(self):
+ self.t = IOBTree()
+
+class TestOOBTrees(BTreeTests, TestCase):
+ def setUp(self):
+ self.t = OOBTree()
+
+class TestOIBTrees(BTreeTests, TestCase):
+ def setUp(self):
+ self.t = OIBTree()
+
+class TestIIBTrees(BTreeTests, TestCase):
+ def setUp(self):
+ self.t = IIBTree()
+
+## Set tests
+
+class TestIOSets(ExtendedSetTests, TestCase):
+ def setUp(self):
+ self.t = IOSet()
+
+class TestOOSets(ExtendedSetTests, TestCase):
+ def setUp(self):
+ self.t = OOSet()
+
+class TestIISets(ExtendedSetTests, TestCase):
+ def setUp(self):
+ self.t = IISet()
+
+class TestOISets(ExtendedSetTests, TestCase):
+ def setUp(self):
+ self.t = OISet()
+
+class TestIOTreeSets(NormalSetTests, TestCase):
+ def setUp(self):
+ self.t = IOTreeSet()
+
+class TestOOTreeSets(NormalSetTests, TestCase):
+ def setUp(self):
+ self.t = OOTreeSet()
+
+class TestIITreeSets(NormalSetTests, TestCase):
+ def setUp(self):
+ self.t = IITreeSet()
+
+class TestOITreeSets(NormalSetTests, TestCase):
+ def setUp(self):
+ self.t = OITreeSet()
+
+## Bucket tests
+
+class TestIOBuckets(BucketTests, TestCase):
+ def setUp(self):
+ self.t = IOBucket()
+
+class TestOOBuckets(BucketTests, TestCase):
+ def setUp(self):
+ self.t = OOBucket()
+
+class TestIIBuckets(BucketTests, TestCase):
+ def setUp(self):
+ self.t = IIBucket()
+
+class TestOIBuckets(BucketTests, TestCase):
+ def setUp(self):
+ self.t = OIBucket()
+
+# XXX disable tests for now
+def test_suite():
+ TIOBTree = makeSuite(TestIOBTrees, 'test')
+ TOOBTree = makeSuite(TestOOBTrees, 'test')
+ TOIBTree = makeSuite(TestOIBTrees, 'test')
+ TIIBTree = makeSuite(TestIIBTrees, 'test')
+
+ TIOSet = makeSuite(TestIOSets, 'test')
+ TOOSet = makeSuite(TestOOSets, 'test')
+ TOISet = makeSuite(TestIOSets, 'test')
+ TIISet = makeSuite(TestOOSets, 'test')
+
+ TIOTreeSet = makeSuite(TestIOTreeSets, 'test')
+ TOOTreeSet = makeSuite(TestOOTreeSets, 'test')
+ TOITreeSet = makeSuite(TestIOTreeSets, 'test')
+ TIITreeSet = makeSuite(TestOOTreeSets, 'test')
+
+ TIOBucket = makeSuite(TestIOBuckets, 'test')
+ TOOBucket = makeSuite(TestOOBuckets, 'test')
+ TOIBucket = makeSuite(TestOIBuckets, 'test')
+ TIIBucket = makeSuite(TestIIBuckets, 'test')
+
+ alltests = TestSuite((TIOSet, TOOSet, TOISet, TIISet,
+ TIOTreeSet, TOOTreeSet, TOITreeSet, TIITreeSet,
+ TIOBucket, TOOBucket, TOIBucket, TIIBucket,
+ TOOBTree, TIOBTree, TOIBTree, TIIBTree))
+
+ return alltests
+
+## utility functions
+
+def lsubtract(l1, l2):
+ l1=list(l1)
+ l2=list(l2)
+ l = filter(lambda x, l1=l1: x not in l1, l2)
+ l = l + filter(lambda x, l2=l2: x not in l2, l1)
+ return l
+
+def realseq(itemsob):
+ return map(lambda x: x, itemsob)
+
+def main():
+ TextTestRunner().run(test_suite())
+
+if __name__ == '__main__':
+ main()
+
=== Zope3/lib/python/Persistence/BTrees/tests/testSetOps.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+import sys, os, time, random
+from unittest import TestCase, TestSuite, TextTestRunner, makeSuite
+
+from Persistence.BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet, \
+ union, intersection, difference, weightedUnion, weightedIntersection, \
+ multiunion
+
+# XXX TODO Needs more tests.
+# This file was created when multiunion was added. The other set operations
+# don't appear to be tested anywhere yet.
+
+class TestMultiUnion(TestCase):
+
+ def testEmpty(self):
+ self.assertEqual(len(multiunion([])), 0)
+
+ def testOne(self):
+ for sequence in [3], range(20), range(-10, 0, 2) + range(1, 10, 2):
+ seq1 = sequence[:]
+ seq2 = sequence[:]
+ seq2.reverse()
+ seqsorted = sequence[:]
+ seqsorted.sort()
+ for seq in seq1, seq2, seqsorted:
+ for builder in IISet, IITreeSet:
+ input = builder(seq)
+ output = multiunion([input])
+ self.assertEqual(len(seq), len(output))
+ self.assertEqual(seqsorted, list(output))
+
+ def testValuesIgnored(self):
+ for builder in IIBucket, IIBTree:
+ input = builder([(1, 2), (3, 4), (5, 6)])
+ output = multiunion([input])
+ self.assertEqual([1, 3, 5], list(output))
+
+ def testBigInput(self):
+ N = 100000
+ input = IISet(range(N))
+ output = multiunion([input] * 10)
+ self.assertEqual(len(output), N)
+ self.assertEqual(output.minKey(), 0)
+ self.assertEqual(output.maxKey(), N-1)
+ self.assertEqual(list(output), range(N))
+
+ def testLotsOfLittleOnes(self):
+ from random import shuffle
+ N = 5000
+ inputs = []
+ for i in range(N):
+ base = i * 4 - N
+ inputs.append(IISet([base, base+1]))
+ inputs.append(IITreeSet([base+2, base+3]))
+ shuffle(inputs)
+ output = multiunion(inputs)
+ self.assertEqual(len(output), N*4)
+ self.assertEqual(list(output), range(-N, 3*N))
+
+ def testFunkyKeyIteration(self):
+ # The internal set iteration protocol allows "iterating over" a
+ # a single key as if it were a set.
+ N = 100
+ slow = IISet()
+ for i in range(N):
+ slow = union(slow, IISet([i]))
+ fast = multiunion(range(N)) # acts like N distinct singleton sets
+ self.assertEqual(len(slow), N)
+ self.assertEqual(len(fast), N)
+ self.assertEqual(list(slow.keys()), list(fast.keys()))
+ self.assertEqual(list(fast.keys()), range(N))
+
+def test_suite():
+ return makeSuite(TestMultiUnion, 'test')
+
+def main():
+ TextTestRunner().run(test_suite())
+
+if __name__ == '__main__':
+ main()