1from test.support import import_helper 2from test.support import os_helper 3import_helper.import_module("dbm.ndbm") #skip if not supported 4import os 5import unittest 6import dbm.ndbm 7from dbm.ndbm import error 8 9class DbmTestCase(unittest.TestCase): 10 11 def setUp(self): 12 self.filename = os_helper.TESTFN 13 self.d = dbm.ndbm.open(self.filename, 'c') 14 self.d.close() 15 16 def tearDown(self): 17 for suffix in ['', '.pag', '.dir', '.db']: 18 os_helper.unlink(self.filename + suffix) 19 20 def test_keys(self): 21 self.d = dbm.ndbm.open(self.filename, 'c') 22 self.assertEqual(self.d.keys(), []) 23 self.d['a'] = 'b' 24 self.d[b'bytes'] = b'data' 25 self.d['12345678910'] = '019237410982340912840198242' 26 self.d.keys() 27 self.assertIn('a', self.d) 28 self.assertIn(b'a', self.d) 29 self.assertEqual(self.d[b'bytes'], b'data') 30 # get() and setdefault() work as in the dict interface 31 self.assertEqual(self.d.get(b'a'), b'b') 32 self.assertIsNone(self.d.get(b'xxx')) 33 self.assertEqual(self.d.get(b'xxx', b'foo'), b'foo') 34 with self.assertRaises(KeyError): 35 self.d['xxx'] 36 self.assertEqual(self.d.setdefault(b'xxx', b'foo'), b'foo') 37 self.assertEqual(self.d[b'xxx'], b'foo') 38 self.d.close() 39 40 def test_empty_value(self): 41 if dbm.ndbm.library == 'Berkeley DB': 42 self.skipTest("Berkeley DB doesn't distinguish the empty value " 43 "from the absent one") 44 self.d = dbm.ndbm.open(self.filename, 'c') 45 self.assertEqual(self.d.keys(), []) 46 self.d['empty'] = '' 47 self.assertEqual(self.d.keys(), [b'empty']) 48 self.assertIn(b'empty', self.d) 49 self.assertEqual(self.d[b'empty'], b'') 50 self.assertEqual(self.d.get(b'empty'), b'') 51 self.assertEqual(self.d.setdefault(b'empty'), b'') 52 self.d.close() 53 54 def test_modes(self): 55 for mode in ['r', 'rw', 'w', 'n']: 56 try: 57 self.d = dbm.ndbm.open(self.filename, mode) 58 self.d.close() 59 except error: 60 self.fail() 61 62 def test_context_manager(self): 63 with dbm.ndbm.open(self.filename, 'c') as db: 64 db["ndbm context manager"] = "context manager" 65 66 with dbm.ndbm.open(self.filename, 'r') as db: 67 self.assertEqual(list(db.keys()), [b"ndbm context manager"]) 68 69 with self.assertRaises(dbm.ndbm.error) as cm: 70 db.keys() 71 self.assertEqual(str(cm.exception), 72 "DBM object has already been closed") 73 74 def test_bytes(self): 75 with dbm.ndbm.open(self.filename, 'c') as db: 76 db[b'bytes key \xbd'] = b'bytes value \xbd' 77 with dbm.ndbm.open(self.filename, 'r') as db: 78 self.assertEqual(list(db.keys()), [b'bytes key \xbd']) 79 self.assertTrue(b'bytes key \xbd' in db) 80 self.assertEqual(db[b'bytes key \xbd'], b'bytes value \xbd') 81 82 def test_unicode(self): 83 with dbm.ndbm.open(self.filename, 'c') as db: 84 db['Unicode key \U0001f40d'] = 'Unicode value \U0001f40d' 85 with dbm.ndbm.open(self.filename, 'r') as db: 86 self.assertEqual(list(db.keys()), ['Unicode key \U0001f40d'.encode()]) 87 self.assertTrue('Unicode key \U0001f40d'.encode() in db) 88 self.assertTrue('Unicode key \U0001f40d' in db) 89 self.assertEqual(db['Unicode key \U0001f40d'.encode()], 90 'Unicode value \U0001f40d'.encode()) 91 self.assertEqual(db['Unicode key \U0001f40d'], 92 'Unicode value \U0001f40d'.encode()) 93 94 def test_write_readonly_file(self): 95 with dbm.ndbm.open(self.filename, 'c') as db: 96 db[b'bytes key'] = b'bytes value' 97 with dbm.ndbm.open(self.filename, 'r') as db: 98 with self.assertRaises(error): 99 del db[b'not exist key'] 100 with self.assertRaises(error): 101 del db[b'bytes key'] 102 with self.assertRaises(error): 103 db[b'not exist key'] = b'not exist value' 104 105 @unittest.skipUnless(os_helper.TESTFN_NONASCII, 106 'requires OS support of non-ASCII encodings') 107 def test_nonascii_filename(self): 108 filename = os_helper.TESTFN_NONASCII 109 for suffix in ['', '.pag', '.dir', '.db']: 110 self.addCleanup(os_helper.unlink, filename + suffix) 111 with dbm.ndbm.open(filename, 'c') as db: 112 db[b'key'] = b'value' 113 self.assertTrue(any(os.path.exists(filename + suffix) 114 for suffix in ['', '.pag', '.dir', '.db'])) 115 with dbm.ndbm.open(filename, 'r') as db: 116 self.assertEqual(list(db.keys()), [b'key']) 117 self.assertTrue(b'key' in db) 118 self.assertEqual(db[b'key'], b'value') 119 120 def test_nonexisting_file(self): 121 nonexisting_file = 'nonexisting-file' 122 with self.assertRaises(dbm.ndbm.error) as cm: 123 dbm.ndbm.open(nonexisting_file) 124 self.assertIn(nonexisting_file, str(cm.exception)) 125 self.assertEqual(cm.exception.filename, nonexisting_file) 126 127 128if __name__ == '__main__': 129 unittest.main() 130