blob: fc7990d765e53b08c959c1ee94271a0500ba1ed1 [file] [log] [blame]
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001import sys
Raymond Hettingerd2305502003-01-16 12:02:35 +00002import unittest
Hai Shia7f5d932020-08-04 00:41:24 +08003from test.support import import_helper
Raymond Hettinger53dbe392008-02-12 20:03:09 +00004from collections import UserList
Tim Peters36cdad12000-12-29 02:06:45 +00005
Hai Shia7f5d932020-08-04 00:41:24 +08006
7py_bisect = import_helper.import_fresh_module('bisect', blocked=['_bisect'])
8c_bisect = import_helper.import_fresh_module('bisect', fresh=['_bisect'])
Christian Heimesd3eb5a152008-02-24 00:38:49 +00009
Antoine Pitroufb5b9542012-05-16 15:01:40 +020010class Range(object):
Brett Cannona66c2ee2013-01-27 18:58:20 -050011 """A trivial range()-like object that has an insert() method."""
Antoine Pitroufb5b9542012-05-16 15:01:40 +020012 def __init__(self, start, stop):
13 self.start = start
14 self.stop = stop
15 self.last_insert = None
16
17 def __len__(self):
18 return self.stop - self.start
19
20 def __getitem__(self, idx):
21 n = self.stop - self.start
22 if idx < 0:
23 idx += n
24 if idx >= n:
25 raise IndexError(idx)
26 return self.start + idx
27
28 def insert(self, idx, item):
29 self.last_insert = idx, item
30
31
Ezio Melottif472a902013-01-10 04:32:01 +020032class TestBisect:
Christian Heimesd3eb5a152008-02-24 00:38:49 +000033 def setUp(self):
34 self.precomputedCases = [
35 (self.module.bisect_right, [], 1, 0),
36 (self.module.bisect_right, [1], 0, 0),
37 (self.module.bisect_right, [1], 1, 1),
38 (self.module.bisect_right, [1], 2, 1),
39 (self.module.bisect_right, [1, 1], 0, 0),
40 (self.module.bisect_right, [1, 1], 1, 2),
41 (self.module.bisect_right, [1, 1], 2, 2),
42 (self.module.bisect_right, [1, 1, 1], 0, 0),
43 (self.module.bisect_right, [1, 1, 1], 1, 3),
44 (self.module.bisect_right, [1, 1, 1], 2, 3),
45 (self.module.bisect_right, [1, 1, 1, 1], 0, 0),
46 (self.module.bisect_right, [1, 1, 1, 1], 1, 4),
47 (self.module.bisect_right, [1, 1, 1, 1], 2, 4),
48 (self.module.bisect_right, [1, 2], 0, 0),
49 (self.module.bisect_right, [1, 2], 1, 1),
50 (self.module.bisect_right, [1, 2], 1.5, 1),
51 (self.module.bisect_right, [1, 2], 2, 2),
52 (self.module.bisect_right, [1, 2], 3, 2),
53 (self.module.bisect_right, [1, 1, 2, 2], 0, 0),
54 (self.module.bisect_right, [1, 1, 2, 2], 1, 2),
55 (self.module.bisect_right, [1, 1, 2, 2], 1.5, 2),
56 (self.module.bisect_right, [1, 1, 2, 2], 2, 4),
57 (self.module.bisect_right, [1, 1, 2, 2], 3, 4),
58 (self.module.bisect_right, [1, 2, 3], 0, 0),
59 (self.module.bisect_right, [1, 2, 3], 1, 1),
60 (self.module.bisect_right, [1, 2, 3], 1.5, 1),
61 (self.module.bisect_right, [1, 2, 3], 2, 2),
62 (self.module.bisect_right, [1, 2, 3], 2.5, 2),
63 (self.module.bisect_right, [1, 2, 3], 3, 3),
64 (self.module.bisect_right, [1, 2, 3], 4, 3),
65 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
66 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 1),
67 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
68 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 3),
69 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
70 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 6),
71 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
72 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 10),
73 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10),
Tim Peters36cdad12000-12-29 02:06:45 +000074
Christian Heimesd3eb5a152008-02-24 00:38:49 +000075 (self.module.bisect_left, [], 1, 0),
76 (self.module.bisect_left, [1], 0, 0),
77 (self.module.bisect_left, [1], 1, 0),
78 (self.module.bisect_left, [1], 2, 1),
79 (self.module.bisect_left, [1, 1], 0, 0),
80 (self.module.bisect_left, [1, 1], 1, 0),
81 (self.module.bisect_left, [1, 1], 2, 2),
82 (self.module.bisect_left, [1, 1, 1], 0, 0),
83 (self.module.bisect_left, [1, 1, 1], 1, 0),
84 (self.module.bisect_left, [1, 1, 1], 2, 3),
85 (self.module.bisect_left, [1, 1, 1, 1], 0, 0),
86 (self.module.bisect_left, [1, 1, 1, 1], 1, 0),
87 (self.module.bisect_left, [1, 1, 1, 1], 2, 4),
88 (self.module.bisect_left, [1, 2], 0, 0),
89 (self.module.bisect_left, [1, 2], 1, 0),
90 (self.module.bisect_left, [1, 2], 1.5, 1),
91 (self.module.bisect_left, [1, 2], 2, 1),
92 (self.module.bisect_left, [1, 2], 3, 2),
93 (self.module.bisect_left, [1, 1, 2, 2], 0, 0),
94 (self.module.bisect_left, [1, 1, 2, 2], 1, 0),
95 (self.module.bisect_left, [1, 1, 2, 2], 1.5, 2),
96 (self.module.bisect_left, [1, 1, 2, 2], 2, 2),
97 (self.module.bisect_left, [1, 1, 2, 2], 3, 4),
98 (self.module.bisect_left, [1, 2, 3], 0, 0),
99 (self.module.bisect_left, [1, 2, 3], 1, 0),
100 (self.module.bisect_left, [1, 2, 3], 1.5, 1),
101 (self.module.bisect_left, [1, 2, 3], 2, 1),
102 (self.module.bisect_left, [1, 2, 3], 2.5, 2),
103 (self.module.bisect_left, [1, 2, 3], 3, 2),
104 (self.module.bisect_left, [1, 2, 3], 4, 3),
105 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
106 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 0),
107 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
108 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 1),
109 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
110 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 3),
111 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
112 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 6),
113 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10)
114 ]
Tim Peters36cdad12000-12-29 02:06:45 +0000115
Raymond Hettingerd2305502003-01-16 12:02:35 +0000116 def test_precomputed(self):
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000117 for func, data, elem, expected in self.precomputedCases:
118 self.assertEqual(func(data, elem), expected)
Raymond Hettinger0c410272004-01-05 10:13:35 +0000119 self.assertEqual(func(UserList(data), elem), expected)
Raymond Hettingerd2305502003-01-16 12:02:35 +0000120
Georg Brandl2ee470f2008-07-16 12:55:28 +0000121 def test_negative_lo(self):
122 # Issue 3301
123 mod = self.module
Victor Stinner3fa1aae2013-03-26 01:14:08 +0100124 self.assertRaises(ValueError, mod.bisect_left, [1, 2, 3], 5, -1, 3)
125 self.assertRaises(ValueError, mod.bisect_right, [1, 2, 3], 5, -1, 3)
126 self.assertRaises(ValueError, mod.insort_left, [1, 2, 3], 5, -1, 3)
127 self.assertRaises(ValueError, mod.insort_right, [1, 2, 3], 5, -1, 3)
Georg Brandl2ee470f2008-07-16 12:55:28 +0000128
Mark Dickinsona13b1092012-04-15 16:30:35 +0100129 def test_large_range(self):
130 # Issue 13496
131 mod = self.module
Antoine Pitroufb5b9542012-05-16 15:01:40 +0200132 n = sys.maxsize
133 data = range(n-1)
134 self.assertEqual(mod.bisect_left(data, n-3), n-3)
135 self.assertEqual(mod.bisect_right(data, n-3), n-2)
136 self.assertEqual(mod.bisect_left(data, n-3, n-10, n), n-3)
137 self.assertEqual(mod.bisect_right(data, n-3, n-10, n), n-2)
138
139 def test_large_pyrange(self):
140 # Same as above, but without C-imposed limits on range() parameters
141 mod = self.module
142 n = sys.maxsize
143 data = Range(0, n-1)
144 self.assertEqual(mod.bisect_left(data, n-3), n-3)
145 self.assertEqual(mod.bisect_right(data, n-3), n-2)
146 self.assertEqual(mod.bisect_left(data, n-3, n-10, n), n-3)
147 self.assertEqual(mod.bisect_right(data, n-3, n-10, n), n-2)
148 x = n - 100
149 mod.insort_left(data, x, x - 50, x + 50)
150 self.assertEqual(data.last_insert, (x, x))
151 x = n - 200
152 mod.insort_right(data, x, x - 50, x + 50)
153 self.assertEqual(data.last_insert, (x + 1, x))
Mark Dickinsona13b1092012-04-15 16:30:35 +0100154
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000155 def test_random(self, n=25):
Raymond Hettinger44223752003-01-16 12:31:36 +0000156 from random import randrange
Guido van Rossum805365e2007-05-07 22:24:25 +0000157 for i in range(n):
158 data = [randrange(0, n, 2) for j in range(i)]
Raymond Hettinger44223752003-01-16 12:31:36 +0000159 data.sort()
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000160 elem = randrange(-1, n+1)
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000161 ip = self.module.bisect_left(data, elem)
Raymond Hettinger44223752003-01-16 12:31:36 +0000162 if ip < len(data):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000163 self.assertTrue(elem <= data[ip])
Raymond Hettinger44223752003-01-16 12:31:36 +0000164 if ip > 0:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000165 self.assertTrue(data[ip-1] < elem)
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000166 ip = self.module.bisect_right(data, elem)
Raymond Hettinger44223752003-01-16 12:31:36 +0000167 if ip < len(data):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000168 self.assertTrue(elem < data[ip])
Raymond Hettinger44223752003-01-16 12:31:36 +0000169 if ip > 0:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000170 self.assertTrue(data[ip-1] <= elem)
Raymond Hettinger44223752003-01-16 12:31:36 +0000171
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000172 def test_optionalSlicing(self):
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000173 for func, data, elem, expected in self.precomputedCases:
Guido van Rossum805365e2007-05-07 22:24:25 +0000174 for lo in range(4):
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000175 lo = min(len(data), lo)
Guido van Rossum805365e2007-05-07 22:24:25 +0000176 for hi in range(3,8):
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000177 hi = min(len(data), hi)
178 ip = func(data, elem, lo, hi)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000179 self.assertTrue(lo <= ip <= hi)
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000180 if func is self.module.bisect_left and ip < hi:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000181 self.assertTrue(elem <= data[ip])
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000182 if func is self.module.bisect_left and ip > lo:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000183 self.assertTrue(data[ip-1] < elem)
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000184 if func is self.module.bisect_right and ip < hi:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000185 self.assertTrue(elem < data[ip])
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000186 if func is self.module.bisect_right and ip > lo:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000187 self.assertTrue(data[ip-1] <= elem)
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000188 self.assertEqual(ip, max(lo, min(hi, expected)))
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000189
190 def test_backcompatibility(self):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000191 self.assertEqual(self.module.bisect, self.module.bisect_right)
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000192
Raymond Hettingercc9a9512005-10-05 11:39:12 +0000193 def test_keyword_args(self):
194 data = [10, 20, 30, 40, 50]
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000195 self.assertEqual(self.module.bisect_left(a=data, x=25, lo=1, hi=3), 2)
196 self.assertEqual(self.module.bisect_right(a=data, x=25, lo=1, hi=3), 2)
197 self.assertEqual(self.module.bisect(a=data, x=25, lo=1, hi=3), 2)
198 self.module.insort_left(a=data, x=25, lo=1, hi=3)
199 self.module.insort_right(a=data, x=25, lo=1, hi=3)
200 self.module.insort(a=data, x=25, lo=1, hi=3)
Raymond Hettingercc9a9512005-10-05 11:39:12 +0000201 self.assertEqual(data, [10, 20, 25, 25, 25, 30, 40, 50])
202
Ezio Melottif472a902013-01-10 04:32:01 +0200203class TestBisectPython(TestBisect, unittest.TestCase):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000204 module = py_bisect
205
Ezio Melottif472a902013-01-10 04:32:01 +0200206class TestBisectC(TestBisect, unittest.TestCase):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000207 module = c_bisect
208
Raymond Hettingerd2305502003-01-16 12:02:35 +0000209#==============================================================================
210
Ezio Melottif472a902013-01-10 04:32:01 +0200211class TestInsort:
Raymond Hettinger0c410272004-01-05 10:13:35 +0000212 def test_vsBuiltinSort(self, n=500):
Raymond Hettingerd2305502003-01-16 12:02:35 +0000213 from random import choice
Raymond Hettinger0c410272004-01-05 10:13:35 +0000214 for insorted in (list(), UserList()):
Guido van Rossum805365e2007-05-07 22:24:25 +0000215 for i in range(n):
Raymond Hettinger0c410272004-01-05 10:13:35 +0000216 digit = choice("0123456789")
217 if digit in "02468":
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000218 f = self.module.insort_left
Raymond Hettinger0c410272004-01-05 10:13:35 +0000219 else:
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000220 f = self.module.insort_right
Raymond Hettinger0c410272004-01-05 10:13:35 +0000221 f(insorted, digit)
Andrew Svetloveda1f4c2012-10-31 22:37:50 +0200222 self.assertEqual(sorted(insorted), insorted)
Raymond Hettingerd2305502003-01-16 12:02:35 +0000223
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000224 def test_backcompatibility(self):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000225 self.assertEqual(self.module.insort, self.module.insort_right)
226
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000227 def test_listDerived(self):
228 class List(list):
229 data = []
230 def insert(self, index, item):
231 self.data.insert(index, item)
232
233 lst = List()
234 self.module.insort_left(lst, 10)
235 self.module.insort_right(lst, 5)
236 self.assertEqual([5, 10], lst.data)
237
Ezio Melottif472a902013-01-10 04:32:01 +0200238class TestInsortPython(TestInsort, unittest.TestCase):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000239 module = py_bisect
240
Ezio Melottif472a902013-01-10 04:32:01 +0200241class TestInsortC(TestInsort, unittest.TestCase):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000242 module = c_bisect
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000243
Raymond Hettingerd2305502003-01-16 12:02:35 +0000244#==============================================================================
245
Raymond Hettinger63251782004-09-27 22:48:40 +0000246class LenOnly:
247 "Dummy sequence class defining __len__ but not __getitem__."
248 def __len__(self):
249 return 10
250
251class GetOnly:
252 "Dummy sequence class defining __getitem__ but not __len__."
253 def __getitem__(self, ndx):
254 return 10
255
256class CmpErr:
257 "Dummy element that always raises an error during comparison"
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000258 def __lt__(self, other):
Raymond Hettinger63251782004-09-27 22:48:40 +0000259 raise ZeroDivisionError
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000260 __gt__ = __lt__
261 __le__ = __lt__
262 __ge__ = __lt__
263 __eq__ = __lt__
264 __ne__ = __lt__
Raymond Hettinger63251782004-09-27 22:48:40 +0000265
Ezio Melottif472a902013-01-10 04:32:01 +0200266class TestErrorHandling:
Raymond Hettinger63251782004-09-27 22:48:40 +0000267 def test_non_sequence(self):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000268 for f in (self.module.bisect_left, self.module.bisect_right,
269 self.module.insort_left, self.module.insort_right):
Raymond Hettinger63251782004-09-27 22:48:40 +0000270 self.assertRaises(TypeError, f, 10, 10)
271
272 def test_len_only(self):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000273 for f in (self.module.bisect_left, self.module.bisect_right,
274 self.module.insort_left, self.module.insort_right):
Thomas Wouters1ae9afa2006-04-15 09:12:14 +0000275 self.assertRaises(TypeError, f, LenOnly(), 10)
Raymond Hettinger63251782004-09-27 22:48:40 +0000276
277 def test_get_only(self):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000278 for f in (self.module.bisect_left, self.module.bisect_right,
279 self.module.insort_left, self.module.insort_right):
Thomas Wouters1ae9afa2006-04-15 09:12:14 +0000280 self.assertRaises(TypeError, f, GetOnly(), 10)
Raymond Hettinger63251782004-09-27 22:48:40 +0000281
Raymond Hettinger630e5352004-09-27 23:11:35 +0000282 def test_cmp_err(self):
Raymond Hettinger63251782004-09-27 22:48:40 +0000283 seq = [CmpErr(), CmpErr(), CmpErr()]
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000284 for f in (self.module.bisect_left, self.module.bisect_right,
285 self.module.insort_left, self.module.insort_right):
Raymond Hettinger63251782004-09-27 22:48:40 +0000286 self.assertRaises(ZeroDivisionError, f, seq, 10)
287
288 def test_arg_parsing(self):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000289 for f in (self.module.bisect_left, self.module.bisect_right,
290 self.module.insort_left, self.module.insort_right):
Raymond Hettinger63251782004-09-27 22:48:40 +0000291 self.assertRaises(TypeError, f, 10)
292
Ezio Melottif472a902013-01-10 04:32:01 +0200293class TestErrorHandlingPython(TestErrorHandling, unittest.TestCase):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000294 module = py_bisect
295
Ezio Melottif472a902013-01-10 04:32:01 +0200296class TestErrorHandlingC(TestErrorHandling, unittest.TestCase):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000297 module = c_bisect
298
Raymond Hettinger63251782004-09-27 22:48:40 +0000299#==============================================================================
300
Ezio Melottif472a902013-01-10 04:32:01 +0200301class TestDocExample:
302 def test_grades(self):
303 def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
304 i = self.module.bisect(breakpoints, score)
305 return grades[i]
Raymond Hettinger44223752003-01-16 12:31:36 +0000306
Ezio Melottif472a902013-01-10 04:32:01 +0200307 result = [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
308 self.assertEqual(result, ['F', 'A', 'C', 'C', 'B', 'A', 'A'])
Raymond Hettinger44223752003-01-16 12:31:36 +0000309
Ezio Melottif472a902013-01-10 04:32:01 +0200310 def test_colors(self):
311 data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)]
312 data.sort(key=lambda r: r[1])
313 keys = [r[1] for r in data]
314 bisect_left = self.module.bisect_left
315 self.assertEqual(data[bisect_left(keys, 0)], ('black', 0))
316 self.assertEqual(data[bisect_left(keys, 1)], ('blue', 1))
317 self.assertEqual(data[bisect_left(keys, 5)], ('red', 5))
318 self.assertEqual(data[bisect_left(keys, 8)], ('yellow', 8))
Raymond Hettinger44223752003-01-16 12:31:36 +0000319
Ezio Melottif472a902013-01-10 04:32:01 +0200320class TestDocExamplePython(TestDocExample, unittest.TestCase):
321 module = py_bisect
322
323class TestDocExampleC(TestDocExample, unittest.TestCase):
324 module = c_bisect
Raymond Hettinger44223752003-01-16 12:31:36 +0000325
Raymond Hettingerd2305502003-01-16 12:02:35 +0000326#------------------------------------------------------------------------------
327
Raymond Hettingerd2305502003-01-16 12:02:35 +0000328if __name__ == "__main__":
Ezio Melottif472a902013-01-10 04:32:01 +0200329 unittest.main()