diff -r ffa851df0825 -r 2fb8b9db1c86 symbian-qemu-0.9.1-12/python-2.6.1/Lib/bsddb/test/test_compare.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian-qemu-0.9.1-12/python-2.6.1/Lib/bsddb/test/test_compare.py Fri Jul 31 15:01:17 2009 +0100 @@ -0,0 +1,257 @@ +""" +TestCases for python DB Btree key comparison function. +""" + +import sys, os, re +import test_all +from cStringIO import StringIO + +import unittest + +from test_all import db, dbshelve, test_support, \ + get_new_environment_path, get_new_database_path + + +lexical_cmp = cmp + +def lowercase_cmp(left, right): + return cmp (left.lower(), right.lower()) + +def make_reverse_comparator (cmp): + def reverse (left, right, delegate=cmp): + return - delegate (left, right) + return reverse + +_expected_lexical_test_data = ['', 'CCCP', 'a', 'aaa', 'b', 'c', 'cccce', 'ccccf'] +_expected_lowercase_test_data = ['', 'a', 'aaa', 'b', 'c', 'CC', 'cccce', 'ccccf', 'CCCP'] + +class ComparatorTests (unittest.TestCase): + def comparator_test_helper (self, comparator, expected_data): + data = expected_data[:] + + import sys + if sys.version_info[0] < 3 : + if sys.version_info[:3] < (2, 4, 0): + data.sort(comparator) + else : + data.sort(cmp=comparator) + else : # Insertion Sort. Please, improve + data2 = [] + for i in data : + for j, k in enumerate(data2) : + r = comparator(k, i) + if r == 1 : + data2.insert(j, i) + break + else : + data2.append(i) + data = data2 + + self.failUnless (data == expected_data, + "comparator `%s' is not right: %s vs. %s" + % (comparator, expected_data, data)) + def test_lexical_comparator (self): + self.comparator_test_helper (lexical_cmp, _expected_lexical_test_data) + def test_reverse_lexical_comparator (self): + rev = _expected_lexical_test_data[:] + rev.reverse () + self.comparator_test_helper (make_reverse_comparator (lexical_cmp), + rev) + def test_lowercase_comparator (self): + self.comparator_test_helper (lowercase_cmp, + _expected_lowercase_test_data) + +class AbstractBtreeKeyCompareTestCase (unittest.TestCase): + env = None + db = None + + def setUp (self): + self.filename = self.__class__.__name__ + '.db' + self.homeDir = get_new_environment_path() + env = db.DBEnv() + env.open (self.homeDir, + db.DB_CREATE | db.DB_INIT_MPOOL + | db.DB_INIT_LOCK | db.DB_THREAD) + self.env = env + + def tearDown (self): + self.closeDB() + if self.env is not None: + self.env.close() + self.env = None + test_support.rmtree(self.homeDir) + + def addDataToDB (self, data): + i = 0 + for item in data: + self.db.put (item, str (i)) + i = i + 1 + + def createDB (self, key_comparator): + self.db = db.DB (self.env) + self.setupDB (key_comparator) + self.db.open (self.filename, "test", db.DB_BTREE, db.DB_CREATE) + + def setupDB (self, key_comparator): + self.db.set_bt_compare (key_comparator) + + def closeDB (self): + if self.db is not None: + self.db.close () + self.db = None + + def startTest (self): + pass + + def finishTest (self, expected = None): + if expected is not None: + self.check_results (expected) + self.closeDB () + + def check_results (self, expected): + curs = self.db.cursor () + try: + index = 0 + rec = curs.first () + while rec: + key, ignore = rec + self.failUnless (index < len (expected), + "to many values returned from cursor") + self.failUnless (expected[index] == key, + "expected value `%s' at %d but got `%s'" + % (expected[index], index, key)) + index = index + 1 + rec = curs.next () + self.failUnless (index == len (expected), + "not enough values returned from cursor") + finally: + curs.close () + +class BtreeKeyCompareTestCase (AbstractBtreeKeyCompareTestCase): + def runCompareTest (self, comparator, data): + self.startTest () + self.createDB (comparator) + self.addDataToDB (data) + self.finishTest (data) + + def test_lexical_ordering (self): + self.runCompareTest (lexical_cmp, _expected_lexical_test_data) + + def test_reverse_lexical_ordering (self): + expected_rev_data = _expected_lexical_test_data[:] + expected_rev_data.reverse () + self.runCompareTest (make_reverse_comparator (lexical_cmp), + expected_rev_data) + + def test_compare_function_useless (self): + self.startTest () + def socialist_comparator (l, r): + return 0 + self.createDB (socialist_comparator) + self.addDataToDB (['b', 'a', 'd']) + # all things being equal the first key will be the only key + # in the database... (with the last key's value fwiw) + self.finishTest (['b']) + + +class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase): + def test_raises_non_callable (self): + self.startTest () + self.assertRaises (TypeError, self.createDB, 'abc') + self.assertRaises (TypeError, self.createDB, None) + self.finishTest () + + def test_set_bt_compare_with_function (self): + self.startTest () + self.createDB (lexical_cmp) + self.finishTest () + + def check_results (self, results): + pass + + def test_compare_function_incorrect (self): + self.startTest () + def bad_comparator (l, r): + return 1 + # verify that set_bt_compare checks that comparator('', '') == 0 + self.assertRaises (TypeError, self.createDB, bad_comparator) + self.finishTest () + + def verifyStderr(self, method, successRe): + """ + Call method() while capturing sys.stderr output internally and + call self.fail() if successRe.search() does not match the stderr + output. This is used to test for uncatchable exceptions. + """ + stdErr = sys.stderr + sys.stderr = StringIO() + try: + method() + finally: + temp = sys.stderr + sys.stderr = stdErr + errorOut = temp.getvalue() + if not successRe.search(errorOut): + self.fail("unexpected stderr output:\n"+errorOut) + + def _test_compare_function_exception (self): + self.startTest () + def bad_comparator (l, r): + if l == r: + # pass the set_bt_compare test + return 0 + raise RuntimeError, "i'm a naughty comparison function" + self.createDB (bad_comparator) + #print "\n*** test should print 2 uncatchable tracebacks ***" + self.addDataToDB (['a', 'b', 'c']) # this should raise, but... + self.finishTest () + + def test_compare_function_exception(self): + self.verifyStderr( + self._test_compare_function_exception, + re.compile('(^RuntimeError:.* naughty.*){2}', re.M|re.S) + ) + + def _test_compare_function_bad_return (self): + self.startTest () + def bad_comparator (l, r): + if l == r: + # pass the set_bt_compare test + return 0 + return l + self.createDB (bad_comparator) + #print "\n*** test should print 2 errors about returning an int ***" + self.addDataToDB (['a', 'b', 'c']) # this should raise, but... + self.finishTest () + + def test_compare_function_bad_return(self): + self.verifyStderr( + self._test_compare_function_bad_return, + re.compile('(^TypeError:.* return an int.*){2}', re.M|re.S) + ) + + + def test_cannot_assign_twice (self): + + def my_compare (a, b): + return 0 + + self.startTest () + self.createDB (my_compare) + try: + self.db.set_bt_compare (my_compare) + self.assert_(0, "this set should fail") + + except RuntimeError, msg: + pass + +def test_suite (): + res = unittest.TestSuite () + + res.addTest (unittest.makeSuite (ComparatorTests)) + res.addTest (unittest.makeSuite (BtreeExceptionsTestCase)) + res.addTest (unittest.makeSuite (BtreeKeyCompareTestCase)) + return res + +if __name__ == '__main__': + unittest.main (defaultTest = 'suite')