Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(88567)

Delta Between Two Patch Sets: Lib/test/test_bisect.py

Issue 16510: Using appropriate checks in tests
Left Patch Set: Created 6 years, 9 months ago
Right Patch Set: Created 5 years, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/test/test_binop.py ('k') | Lib/test/test_buffer.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 import sys 1 import sys
2 import unittest 2 import unittest
3 from test import support 3 from test import support
4 from collections import UserList 4 from collections import UserList
5 5
6 # We do a bit of trickery here to be able to test both the C implementation 6 py_bisect = support.import_fresh_module('bisect', blocked=['_bisect'])
7 # and the Python implementation of the module. 7 c_bisect = support.import_fresh_module('bisect', fresh=['_bisect'])
8
9 # Make it impossible to import the C implementation anymore.
10 sys.modules['_bisect'] = 0
11 # We must also handle the case that bisect was imported before.
12 if 'bisect' in sys.modules:
13 del sys.modules['bisect']
14
15 # Now we can import the module and get the pure Python implementation.
16 import bisect as py_bisect
17
18 # Restore everything to normal.
19 del sys.modules['_bisect']
20 del sys.modules['bisect']
21
22 # This is now the module with the C implementation.
23 import bisect as c_bisect
24
25 8
26 class Range(object): 9 class Range(object):
27 """A trivial range()-like object without any integer width limitations.""" 10 """A trivial range()-like object that has an insert() method."""
28 def __init__(self, start, stop): 11 def __init__(self, start, stop):
29 self.start = start 12 self.start = start
30 self.stop = stop 13 self.stop = stop
31 self.last_insert = None 14 self.last_insert = None
32 15
33 def __len__(self): 16 def __len__(self):
34 return self.stop - self.start 17 return self.stop - self.start
35 18
36 def __getitem__(self, idx): 19 def __getitem__(self, idx):
37 n = self.stop - self.start 20 n = self.stop - self.start
38 if idx < 0: 21 if idx < 0:
39 idx += n 22 idx += n
40 if idx >= n: 23 if idx >= n:
41 raise IndexError(idx) 24 raise IndexError(idx)
42 return self.start + idx 25 return self.start + idx
43 26
44 def insert(self, idx, item): 27 def insert(self, idx, item):
45 self.last_insert = idx, item 28 self.last_insert = idx, item
46 29
47 30
48 class TestBisect(unittest.TestCase): 31 class TestBisect:
49 module = None
50
51 def setUp(self): 32 def setUp(self):
52 self.precomputedCases = [ 33 self.precomputedCases = [
53 (self.module.bisect_right, [], 1, 0), 34 (self.module.bisect_right, [], 1, 0),
54 (self.module.bisect_right, [1], 0, 0), 35 (self.module.bisect_right, [1], 0, 0),
55 (self.module.bisect_right, [1], 1, 1), 36 (self.module.bisect_right, [1], 1, 1),
56 (self.module.bisect_right, [1], 2, 1), 37 (self.module.bisect_right, [1], 2, 1),
57 (self.module.bisect_right, [1, 1], 0, 0), 38 (self.module.bisect_right, [1, 1], 0, 0),
58 (self.module.bisect_right, [1, 1], 1, 2), 39 (self.module.bisect_right, [1, 1], 1, 2),
59 (self.module.bisect_right, [1, 1], 2, 2), 40 (self.module.bisect_right, [1, 1], 2, 2),
60 (self.module.bisect_right, [1, 1, 1], 0, 0), 41 (self.module.bisect_right, [1, 1, 1], 0, 0),
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 ] 113 ]
133 114
134 def test_precomputed(self): 115 def test_precomputed(self):
135 for func, data, elem, expected in self.precomputedCases: 116 for func, data, elem, expected in self.precomputedCases:
136 self.assertEqual(func(data, elem), expected) 117 self.assertEqual(func(data, elem), expected)
137 self.assertEqual(func(UserList(data), elem), expected) 118 self.assertEqual(func(UserList(data), elem), expected)
138 119
139 def test_negative_lo(self): 120 def test_negative_lo(self):
140 # Issue 3301 121 # Issue 3301
141 mod = self.module 122 mod = self.module
142 self.assertRaises(ValueError, mod.bisect_left, [1, 2, 3], 5, -1, 3), 123 self.assertRaises(ValueError, mod.bisect_left, [1, 2, 3], 5, -1, 3)
143 self.assertRaises(ValueError, mod.bisect_right, [1, 2, 3], 5, -1, 3), 124 self.assertRaises(ValueError, mod.bisect_right, [1, 2, 3], 5, -1, 3)
144 self.assertRaises(ValueError, mod.insort_left, [1, 2, 3], 5, -1, 3), 125 self.assertRaises(ValueError, mod.insort_left, [1, 2, 3], 5, -1, 3)
145 self.assertRaises(ValueError, mod.insort_right, [1, 2, 3], 5, -1, 3), 126 self.assertRaises(ValueError, mod.insort_right, [1, 2, 3], 5, -1, 3)
146 127
147 def test_large_range(self): 128 def test_large_range(self):
148 # Issue 13496 129 # Issue 13496
149 mod = self.module 130 mod = self.module
150 n = sys.maxsize 131 n = sys.maxsize
151 data = range(n-1) 132 data = range(n-1)
152 self.assertEqual(mod.bisect_left(data, n-3), n-3) 133 self.assertEqual(mod.bisect_left(data, n-3), n-3)
153 self.assertEqual(mod.bisect_right(data, n-3), n-2) 134 self.assertEqual(mod.bisect_right(data, n-3), n-2)
154 self.assertEqual(mod.bisect_left(data, n-3, n-10, n), n-3) 135 self.assertEqual(mod.bisect_left(data, n-3, n-10, n), n-3)
155 self.assertEqual(mod.bisect_right(data, n-3, n-10, n), n-2) 136 self.assertEqual(mod.bisect_right(data, n-3, n-10, n), n-2)
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 def test_keyword_args(self): 192 def test_keyword_args(self):
212 data = [10, 20, 30, 40, 50] 193 data = [10, 20, 30, 40, 50]
213 self.assertEqual(self.module.bisect_left(a=data, x=25, lo=1, hi=3), 2) 194 self.assertEqual(self.module.bisect_left(a=data, x=25, lo=1, hi=3), 2)
214 self.assertEqual(self.module.bisect_right(a=data, x=25, lo=1, hi=3), 2) 195 self.assertEqual(self.module.bisect_right(a=data, x=25, lo=1, hi=3), 2)
215 self.assertEqual(self.module.bisect(a=data, x=25, lo=1, hi=3), 2) 196 self.assertEqual(self.module.bisect(a=data, x=25, lo=1, hi=3), 2)
216 self.module.insort_left(a=data, x=25, lo=1, hi=3) 197 self.module.insort_left(a=data, x=25, lo=1, hi=3)
217 self.module.insort_right(a=data, x=25, lo=1, hi=3) 198 self.module.insort_right(a=data, x=25, lo=1, hi=3)
218 self.module.insort(a=data, x=25, lo=1, hi=3) 199 self.module.insort(a=data, x=25, lo=1, hi=3)
219 self.assertEqual(data, [10, 20, 25, 25, 25, 30, 40, 50]) 200 self.assertEqual(data, [10, 20, 25, 25, 25, 30, 40, 50])
220 201
221 class TestBisectPython(TestBisect): 202 class TestBisectPython(TestBisect, unittest.TestCase):
222 module = py_bisect 203 module = py_bisect
223 204
224 class TestBisectC(TestBisect): 205 class TestBisectC(TestBisect, unittest.TestCase):
225 module = c_bisect 206 module = c_bisect
226 207
227 #============================================================================== 208 #==============================================================================
228 209
229 class TestInsort(unittest.TestCase): 210 class TestInsort:
230 module = None
231
232 def test_vsBuiltinSort(self, n=500): 211 def test_vsBuiltinSort(self, n=500):
233 from random import choice 212 from random import choice
234 for insorted in (list(), UserList()): 213 for insorted in (list(), UserList()):
235 for i in range(n): 214 for i in range(n):
236 digit = choice("0123456789") 215 digit = choice("0123456789")
237 if digit in "02468": 216 if digit in "02468":
238 f = self.module.insort_left 217 f = self.module.insort_left
239 else: 218 else:
240 f = self.module.insort_right 219 f = self.module.insort_right
241 f(insorted, digit) 220 f(insorted, digit)
242 self.assertEqual(sorted(insorted), insorted) 221 self.assertEqual(sorted(insorted), insorted)
243 222
244 def test_backcompatibility(self): 223 def test_backcompatibility(self):
245 self.assertEqual(self.module.insort, self.module.insort_right) 224 self.assertEqual(self.module.insort, self.module.insort_right)
246 225
247 def test_listDerived(self): 226 def test_listDerived(self):
248 class List(list): 227 class List(list):
249 data = [] 228 data = []
250 def insert(self, index, item): 229 def insert(self, index, item):
251 self.data.insert(index, item) 230 self.data.insert(index, item)
252 231
253 lst = List() 232 lst = List()
254 self.module.insort_left(lst, 10) 233 self.module.insort_left(lst, 10)
255 self.module.insort_right(lst, 5) 234 self.module.insort_right(lst, 5)
256 self.assertEqual([5, 10], lst.data) 235 self.assertEqual([5, 10], lst.data)
257 236
258 class TestInsortPython(TestInsort): 237 class TestInsortPython(TestInsort, unittest.TestCase):
259 module = py_bisect 238 module = py_bisect
260 239
261 class TestInsortC(TestInsort): 240 class TestInsortC(TestInsort, unittest.TestCase):
262 module = c_bisect 241 module = c_bisect
263 242
264 #============================================================================== 243 #==============================================================================
265
266 244
267 class LenOnly: 245 class LenOnly:
268 "Dummy sequence class defining __len__ but not __getitem__." 246 "Dummy sequence class defining __len__ but not __getitem__."
269 def __len__(self): 247 def __len__(self):
270 return 10 248 return 10
271 249
272 class GetOnly: 250 class GetOnly:
273 "Dummy sequence class defining __getitem__ but not __len__." 251 "Dummy sequence class defining __getitem__ but not __len__."
274 def __getitem__(self, ndx): 252 def __getitem__(self, ndx):
275 return 10 253 return 10
276 254
277 class CmpErr: 255 class CmpErr:
278 "Dummy element that always raises an error during comparison" 256 "Dummy element that always raises an error during comparison"
279 def __lt__(self, other): 257 def __lt__(self, other):
280 raise ZeroDivisionError 258 raise ZeroDivisionError
281 __gt__ = __lt__ 259 __gt__ = __lt__
282 __le__ = __lt__ 260 __le__ = __lt__
283 __ge__ = __lt__ 261 __ge__ = __lt__
284 __eq__ = __lt__ 262 __eq__ = __lt__
285 __ne__ = __lt__ 263 __ne__ = __lt__
286 264
287 class TestErrorHandling(unittest.TestCase): 265 class TestErrorHandling:
288 module = None
289
290 def test_non_sequence(self): 266 def test_non_sequence(self):
291 for f in (self.module.bisect_left, self.module.bisect_right, 267 for f in (self.module.bisect_left, self.module.bisect_right,
292 self.module.insort_left, self.module.insort_right): 268 self.module.insort_left, self.module.insort_right):
293 self.assertRaises(TypeError, f, 10, 10) 269 self.assertRaises(TypeError, f, 10, 10)
294 270
295 def test_len_only(self): 271 def test_len_only(self):
296 for f in (self.module.bisect_left, self.module.bisect_right, 272 for f in (self.module.bisect_left, self.module.bisect_right,
297 self.module.insort_left, self.module.insort_right): 273 self.module.insort_left, self.module.insort_right):
298 self.assertRaises(TypeError, f, LenOnly(), 10) 274 self.assertRaises(TypeError, f, LenOnly(), 10)
299 275
300 def test_get_only(self): 276 def test_get_only(self):
301 for f in (self.module.bisect_left, self.module.bisect_right, 277 for f in (self.module.bisect_left, self.module.bisect_right,
302 self.module.insort_left, self.module.insort_right): 278 self.module.insort_left, self.module.insort_right):
303 self.assertRaises(TypeError, f, GetOnly(), 10) 279 self.assertRaises(TypeError, f, GetOnly(), 10)
304 280
305 def test_cmp_err(self): 281 def test_cmp_err(self):
306 seq = [CmpErr(), CmpErr(), CmpErr()] 282 seq = [CmpErr(), CmpErr(), CmpErr()]
307 for f in (self.module.bisect_left, self.module.bisect_right, 283 for f in (self.module.bisect_left, self.module.bisect_right,
308 self.module.insort_left, self.module.insort_right): 284 self.module.insort_left, self.module.insort_right):
309 self.assertRaises(ZeroDivisionError, f, seq, 10) 285 self.assertRaises(ZeroDivisionError, f, seq, 10)
310 286
311 def test_arg_parsing(self): 287 def test_arg_parsing(self):
312 for f in (self.module.bisect_left, self.module.bisect_right, 288 for f in (self.module.bisect_left, self.module.bisect_right,
313 self.module.insort_left, self.module.insort_right): 289 self.module.insort_left, self.module.insort_right):
314 self.assertRaises(TypeError, f, 10) 290 self.assertRaises(TypeError, f, 10)
315 291
316 class TestErrorHandlingPython(TestErrorHandling): 292 class TestErrorHandlingPython(TestErrorHandling, unittest.TestCase):
317 module = py_bisect 293 module = py_bisect
318 294
319 class TestErrorHandlingC(TestErrorHandling): 295 class TestErrorHandlingC(TestErrorHandling, unittest.TestCase):
320 module = c_bisect 296 module = c_bisect
321 297
322 #============================================================================== 298 #==============================================================================
323 299
324 libreftest = """ 300 class TestDocExample:
325 Example from the Library Reference: Doc/library/bisect.rst 301 def test_grades(self):
326 302 def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
327 The bisect() function is generally useful for categorizing numeric data. 303 i = self.module.bisect(breakpoints, score)
328 This example uses bisect() to look up a letter grade for an exam total 304 return grades[i]
329 (say) based on a set of ordered numeric breakpoints: 85 and up is an `A', 305
330 75..84 is a `B', etc. 306 result = [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
331 307 self.assertEqual(result, ['F', 'A', 'C', 'C', 'B', 'A', 'A'])
332 >>> grades = "FEDCBA" 308
333 >>> breakpoints = [30, 44, 66, 75, 85] 309 def test_colors(self):
334 >>> from bisect import bisect 310 data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)]
335 >>> def grade(total): 311 data.sort(key=lambda r: r[1])
336 ... return grades[bisect(breakpoints, total)] 312 keys = [r[1] for r in data]
337 ... 313 bisect_left = self.module.bisect_left
338 >>> grade(66) 314 self.assertEqual(data[bisect_left(keys, 0)], ('black', 0))
339 'C' 315 self.assertEqual(data[bisect_left(keys, 1)], ('blue', 1))
340 >>> list(map(grade, [33, 99, 77, 44, 12, 88])) 316 self.assertEqual(data[bisect_left(keys, 5)], ('red', 5))
341 ['E', 'A', 'B', 'D', 'F', 'A'] 317 self.assertEqual(data[bisect_left(keys, 8)], ('yellow', 8))
342 318
343 """ 319 class TestDocExamplePython(TestDocExample, unittest.TestCase):
320 module = py_bisect
321
322 class TestDocExampleC(TestDocExample, unittest.TestCase):
323 module = c_bisect
344 324
345 #------------------------------------------------------------------------------ 325 #------------------------------------------------------------------------------
346 326
347 __test__ = {'libreftest' : libreftest}
348
349 def test_main(verbose=None):
350 from test import test_bisect
351
352 test_classes = [TestBisectPython, TestBisectC,
353 TestInsortPython, TestInsortC,
354 TestErrorHandlingPython, TestErrorHandlingC]
355
356 support.run_unittest(*test_classes)
357 support.run_doctest(test_bisect, verbose)
358
359 # verify reference counting
360 if verbose and hasattr(sys, "gettotalrefcount"):
361 import gc
362 counts = [None] * 5
363 for i in range(len(counts)):
364 support.run_unittest(*test_classes)
365 gc.collect()
366 counts[i] = sys.gettotalrefcount()
367 print(counts)
368
369 if __name__ == "__main__": 327 if __name__ == "__main__":
370 test_main(verbose=True) 328 unittest.main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+