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