1############################################################################## 2# 3# Copyright (c) 2001, 2002 Zope Foundation and Contributors. 4# All Rights Reserved. 5# 6# This software is subject to the provisions of the Zope Public License, 7# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. 8# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED 9# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 10# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS 11# FOR A PARTICULAR PURPOSE. 12# 13############################################################################## 14"""Tests for PersistentList 15""" 16 17import unittest 18 19 20from persistent.tests.utils import TrivialJar 21from persistent.tests.utils import copy_test 22 23 24l0 = [] 25l1 = [0] 26l2 = [0, 1] 27 28# pylint:disable=protected-access 29 30class OtherList: 31 def __init__(self, initlist): 32 self.__data = initlist 33 def __len__(self): 34 return len(self.__data) 35 def __getitem__(self, i): 36 return self.__data[i] 37 38 39class TestPList(unittest.TestCase): 40 41 def _getTargetClass(self): 42 from persistent.list import PersistentList 43 return PersistentList 44 45 def _makeJar(self): 46 return TrivialJar() 47 48 def _makeOne(self, *args): 49 inst = self._getTargetClass()(*args) 50 inst._p_jar = self._makeJar() 51 return inst 52 53 def test_volatile_attributes_not_persisted(self): 54 # http://www.zope.org/Collectors/Zope/2052 55 m = self._getTargetClass()() 56 m.foo = 'bar' 57 m._v_baz = 'qux' 58 state = m.__getstate__() 59 self.assertTrue('foo' in state) 60 self.assertFalse('_v_baz' in state) 61 62 def testTheWorld(self): 63 from persistent._compat import PYTHON2 64 # Test constructors 65 pl = self._getTargetClass() 66 u = pl() 67 u0 = pl(l0) 68 u1 = pl(l1) 69 u2 = pl(l2) 70 71 uu = pl(u) 72 uu0 = pl(u0) 73 uu1 = pl(u1) 74 uu2 = pl(u2) 75 76 pl(tuple(u)) 77 pl(OtherList(u0)) 78 pl("this is also a sequence") 79 80 # Test __repr__ 81 eq = self.assertEqual 82 83 eq(str(u0), str(l0), "str(u0) == str(l0)") 84 eq(repr(u1), repr(l1), "repr(u1) == repr(l1)") 85 86 # Test __cmp__ and __len__ 87 try: 88 cmp 89 except NameError: 90 def cmp(a, b): 91 if a == b: 92 return 0 93 if a < b: 94 return -1 95 return 1 96 97 def mycmp(a, b): 98 r = cmp(a, b) 99 if r < 0: 100 return -1 101 if r > 0: 102 return 1 103 return r 104 105 to_test = [l0, l1, l2, u, u0, u1, u2, uu, uu0, uu1, uu2] 106 for a in to_test: 107 for b in to_test: 108 eq(mycmp(a, b), mycmp(len(a), len(b)), 109 "mycmp(a, b) == mycmp(len(a), len(b))") 110 111 # Test __getitem__ 112 113 for i, val in enumerate(u2): 114 eq(val, i, "u2[i] == i") 115 116 # Test __setitem__ 117 118 uu2[0] = 0 119 uu2[1] = 100 120 with self.assertRaises(IndexError): 121 uu2[2] = 200 122 123 # Test __delitem__ 124 125 del uu2[1] 126 del uu2[0] 127 with self.assertRaises(IndexError): 128 del uu2[0] 129 130 # Test __getslice__ 131 132 for i in range(-3, 4): 133 eq(u2[:i], l2[:i], "u2[:i] == l2[:i]") 134 eq(u2[i:], l2[i:], "u2[i:] == l2[i:]") 135 for j in range(-3, 4): 136 eq(u2[i:j], l2[i:j], "u2[i:j] == l2[i:j]") 137 138 # Test __setslice__ 139 140 for i in range(-3, 4): 141 u2[:i] = l2[:i] 142 eq(u2, l2, "u2 == l2") 143 u2[i:] = l2[i:] 144 eq(u2, l2, "u2 == l2") 145 for j in range(-3, 4): 146 u2[i:j] = l2[i:j] 147 eq(u2, l2, "u2 == l2") 148 149 uu2 = u2[:] 150 uu2[:0] = [-2, -1] 151 eq(uu2, [-2, -1, 0, 1], "uu2 == [-2, -1, 0, 1]") 152 uu2[0:] = [] 153 eq(uu2, [], "uu2 == []") 154 155 # Test __contains__ 156 for i in u2: 157 self.assertTrue(i in u2, "i in u2") 158 for i in min(u2)-1, max(u2)+1: 159 self.assertTrue(i not in u2, "i not in u2") 160 161 # Test __delslice__ 162 163 uu2 = u2[:] 164 del uu2[1:2] 165 del uu2[0:1] 166 eq(uu2, [], "uu2 == []") 167 168 uu2 = u2[:] 169 del uu2[1:] 170 del uu2[:1] 171 eq(uu2, [], "uu2 == []") 172 173 # Test __add__, __radd__, __mul__ and __rmul__ 174 175 #self.assertTrue(u1 + [] == [] + u1 == u1, "u1 + [] == [] + u1 == u1") 176 self.assertTrue(u1 + [1] == u2, "u1 + [1] == u2") 177 #self.assertTrue([-1] + u1 == [-1, 0], "[-1] + u1 == [-1, 0]") 178 self.assertTrue(u2 == u2*1 == 1*u2, "u2 == u2*1 == 1*u2") 179 self.assertTrue(u2+u2 == u2*2 == 2*u2, "u2+u2 == u2*2 == 2*u2") 180 self.assertTrue(u2+u2+u2 == u2*3 == 3*u2, "u2+u2+u2 == u2*3 == 3*u2") 181 182 # Test append 183 184 u = u1[:] 185 u.append(1) 186 eq(u, u2, "u == u2") 187 188 # Test insert 189 190 u = u2[:] 191 u.insert(0, -1) 192 eq(u, [-1, 0, 1], "u == [-1, 0, 1]") 193 194 # Test pop 195 196 u = pl([0, -1, 1]) 197 u.pop() 198 eq(u, [0, -1], "u == [0, -1]") 199 u.pop(0) 200 eq(u, [-1], "u == [-1]") 201 202 # Test remove 203 204 u = u2[:] 205 u.remove(1) 206 eq(u, u1, "u == u1") 207 208 # Test count 209 u = u2*3 210 eq(u.count(0), 3, "u.count(0) == 3") 211 eq(u.count(1), 3, "u.count(1) == 3") 212 eq(u.count(2), 0, "u.count(2) == 0") 213 214 215 # Test index 216 217 eq(u2.index(0), 0, "u2.index(0) == 0") 218 eq(u2.index(1), 1, "u2.index(1) == 1") 219 with self.assertRaises(ValueError): 220 u2.index(2) 221 222 # Test reverse 223 224 u = u2[:] 225 u.reverse() 226 eq(u, [1, 0], "u == [1, 0]") 227 u.reverse() 228 eq(u, u2, "u == u2") 229 230 # Test sort 231 232 u = pl([1, 0]) 233 u.sort() 234 eq(u, u2, "u == u2") 235 236 # Test keyword arguments to sort 237 if PYTHON2: # pragma: no cover 238 u.sort(cmp=lambda x, y: cmp(y, x)) 239 eq(u, [1, 0], "u == [1, 0]") 240 241 u.sort(key=lambda x: -x) 242 eq(u, [1, 0], "u == [1, 0]") 243 244 u.sort(reverse=True) 245 eq(u, [1, 0], "u == [1, 0]") 246 247 # Passing any other keyword arguments results in a TypeError 248 with self.assertRaises(TypeError): 249 u.sort(blah=True) 250 251 # Test extend 252 253 u = u1[:] 254 u.extend(u2) 255 eq(u, u1 + u2, "u == u1 + u2") 256 257 # Test iadd 258 u = u1[:] 259 u += u2 260 eq(u, u1 + u2, "u == u1 + u2") 261 262 # Test imul 263 u = u1[:] 264 u *= 3 265 eq(u, u1 + u1 + u1, "u == u1 + u1 + u1") 266 267 def test_setslice(self): 268 inst = self._makeOne() 269 self.assertFalse(inst._p_changed) 270 inst[:] = [1, 2, 3] 271 self.assertEqual(inst, [1, 2, 3]) 272 self.assertTrue(inst._p_changed) 273 274 def test_delslice_all_nonempty_list(self): 275 # Delete everything from a non-empty list 276 inst = self._makeOne([1, 2, 3]) 277 self.assertFalse(inst._p_changed) 278 self.assertEqual(inst, [1, 2, 3]) 279 del inst[:] 280 self.assertEqual(inst, []) 281 self.assertTrue(inst._p_changed) 282 283 def test_delslice_sub_nonempty_list(self): 284 # delete a sub-list from a non-empty list 285 inst = self._makeOne([0, 1, 2, 3]) 286 self.assertFalse(inst._p_changed) 287 del inst[1:2] 288 self.assertEqual(inst, [0, 2, 3]) 289 self.assertTrue(inst._p_changed) 290 291 def test_delslice_empty_nonempty_list(self): 292 # delete an empty sub-list from a non-empty list 293 inst = self._makeOne([0, 1, 2, 3]) 294 self.assertFalse(inst._p_changed) 295 del inst[1:1] 296 self.assertEqual(inst, [0, 1, 2, 3]) 297 self.assertFalse(inst._p_changed) 298 299 def test_delslice_all_empty_list(self): 300 inst = self._makeOne([]) 301 self.assertFalse(inst._p_changed) 302 self.assertEqual(inst, []) 303 del inst[:] 304 self.assertEqual(inst, []) 305 self.assertFalse(inst._p_changed) 306 307 def test_iadd(self): 308 inst = self._makeOne() 309 self.assertFalse(inst._p_changed) 310 inst += [1, 2, 3] 311 self.assertEqual(inst, [1, 2, 3]) 312 self.assertTrue(inst._p_changed) 313 314 def test_extend(self): 315 inst = self._makeOne() 316 self.assertFalse(inst._p_changed) 317 inst.extend([1, 2, 3]) 318 self.assertEqual(inst, [1, 2, 3]) 319 self.assertTrue(inst._p_changed) 320 321 def test_imul(self): 322 inst = self._makeOne([1]) 323 self.assertFalse(inst._p_changed) 324 inst *= 2 325 self.assertEqual(inst, [1, 1]) 326 self.assertTrue(inst._p_changed) 327 328 def test_append(self): 329 inst = self._makeOne() 330 self.assertFalse(inst._p_changed) 331 inst.append(1) 332 self.assertEqual(inst, [1]) 333 self.assertTrue(inst._p_changed) 334 335 def test_clear_nonempty(self): 336 inst = self._makeOne([1, 2, 3, 4]) 337 self.assertFalse(inst._p_changed) 338 inst.clear() 339 self.assertEqual(inst, []) 340 self.assertTrue(inst._p_changed) 341 342 def test_clear_empty(self): 343 inst = self._makeOne([]) 344 self.assertFalse(inst._p_changed) 345 inst.clear() 346 self.assertEqual(inst, []) 347 self.assertFalse(inst._p_changed) 348 349 def test_insert(self): 350 inst = self._makeOne() 351 self.assertFalse(inst._p_changed) 352 inst.insert(0, 1) 353 self.assertEqual(inst, [1]) 354 self.assertTrue(inst._p_changed) 355 356 def test_remove(self): 357 inst = self._makeOne([1]) 358 self.assertFalse(inst._p_changed) 359 inst.remove(1) 360 self.assertEqual(inst, []) 361 self.assertTrue(inst._p_changed) 362 363 def test_reverse(self): 364 inst = self._makeOne([2, 1]) 365 self.assertFalse(inst._p_changed) 366 inst.reverse() 367 self.assertEqual(inst, [1, 2]) 368 self.assertTrue(inst._p_changed) 369 370 def test_getslice_same_class(self): 371 class MyList(self._getTargetClass()): 372 pass 373 374 inst = MyList() 375 inst._p_jar = self._makeJar() 376 # Entire thing, empty. 377 inst2 = inst[:] 378 self.assertIsNot(inst, inst2) 379 self.assertEqual(inst, inst2) 380 self.assertIsInstance(inst2, MyList) 381 # The _p_jar is *not* propagated. 382 self.assertIsNotNone(inst._p_jar) 383 self.assertIsNone(inst2._p_jar) 384 385 # Partial 386 inst.extend((1, 2, 3)) 387 inst2 = inst[1:2] 388 self.assertEqual(inst2, [2]) 389 self.assertIsInstance(inst2, MyList) 390 self.assertIsNone(inst2._p_jar) 391 392 def test_copy(self): 393 inst = self._makeOne() 394 inst.append(42) 395 copy_test(self, inst) 396 397 398def test_suite(): 399 return unittest.defaultTestLoader.loadTestsFromName(__name__) 400 401if __name__ == '__main__': 402 unittest.main() 403