blob: 580a963f627a34dd2cadd078f02e9fe1949f61af [file] [log] [blame]
Christian Heimesd3eb5a152008-02-24 00:38:49 +00001import sys
Raymond Hettingerd2305502003-01-16 12:02:35 +00002import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003from test import support
Raymond Hettinger53dbe392008-02-12 20:03:09 +00004from collections import UserList
Tim Peters36cdad12000-12-29 02:06:45 +00005
Ezio Melottif472a902013-01-10 04:32:01 +02006py_bisect = support.import_fresh_module('bisect', blocked=['_bisect'])
7c_bisect = support.import_fresh_module('bisect', fresh=['_bisect'])
Christian Heimesd3eb5a152008-02-24 00:38:49 +00008
Antoine Pitroufb5b9542012-05-16 15:01:40 +02009class Range(object):
Brett Cannona66c2ee2013-01-27 18:58:20 -050010 """A trivial range()-like object that has an insert() method."""
Antoine Pitroufb5b9542012-05-16 15:01:40 +020011 def __init__(self, start, stop):
12 self.start = start
13 self.stop = stop
14 self.last_insert = None
15
16 def __len__(self):
17 return self.stop - self.start
18
19 def __getitem__(self, idx):
20 n = self.stop - self.start
21 if idx < 0:
22 idx += n
23 if idx >= n:
24 raise IndexError(idx)
25 return self.start + idx
26
27 def insert(self, idx, item):
28 self.last_insert = idx, item
29
30
Ezio Melottif472a902013-01-10 04:32:01 +020031class TestBisect:
Christian Heimesd3eb5a152008-02-24 00:38:49 +000032 def setUp(self):
33 self.precomputedCases = [
34 (self.module.bisect_right, [], 1, 0),
35 (self.module.bisect_right, [1], 0, 0),
36 (self.module.bisect_right, [1], 1, 1),
37 (self.module.bisect_right, [1], 2, 1),
38 (self.module.bisect_right, [1, 1], 0, 0),
39 (self.module.bisect_right, [1, 1], 1, 2),
40 (self.module.bisect_right, [1, 1], 2, 2),
41 (self.module.bisect_right, [1, 1, 1], 0, 0),
42 (self.module.bisect_right, [1, 1, 1], 1, 3),
43 (self.module.bisect_right, [1, 1, 1], 2, 3),
44 (self.module.bisect_right, [1, 1, 1, 1], 0, 0),
45 (self.module.bisect_right, [1, 1, 1, 1], 1, 4),
46 (self.module.bisect_right, [1, 1, 1, 1], 2, 4),
47 (self.module.bisect_right, [1, 2], 0, 0),
48 (self.module.bisect_right, [1, 2], 1, 1),
49 (self.module.bisect_right, [1, 2], 1.5, 1),
50 (self.module.bisect_right, [1, 2], 2, 2),
51 (self.module.bisect_right, [1, 2], 3, 2),
52 (self.module.bisect_right, [1, 1, 2, 2], 0, 0),
53 (self.module.bisect_right, [1, 1, 2, 2], 1, 2),
54 (self.module.bisect_right, [1, 1, 2, 2], 1.5, 2),
55 (self.module.bisect_right, [1, 1, 2, 2], 2, 4),
56 (self.module.bisect_right, [1, 1, 2, 2], 3, 4),
57 (self.module.bisect_right, [1, 2, 3], 0, 0),
58 (self.module.bisect_right, [1, 2, 3], 1, 1),
59 (self.module.bisect_right, [1, 2, 3], 1.5, 1),
60 (self.module.bisect_right, [1, 2, 3], 2, 2),
61 (self.module.bisect_right, [1, 2, 3], 2.5, 2),
62 (self.module.bisect_right, [1, 2, 3], 3, 3),
63 (self.module.bisect_right, [1, 2, 3], 4, 3),
64 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
65 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 1),
66 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
67 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 3),
68 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
69 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 6),
70 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
71 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 10),
72 (self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10),
Tim Peters36cdad12000-12-29 02:06:45 +000073
Christian Heimesd3eb5a152008-02-24 00:38:49 +000074 (self.module.bisect_left, [], 1, 0),
75 (self.module.bisect_left, [1], 0, 0),
76 (self.module.bisect_left, [1], 1, 0),
77 (self.module.bisect_left, [1], 2, 1),
78 (self.module.bisect_left, [1, 1], 0, 0),
79 (self.module.bisect_left, [1, 1], 1, 0),
80 (self.module.bisect_left, [1, 1], 2, 2),
81 (self.module.bisect_left, [1, 1, 1], 0, 0),
82 (self.module.bisect_left, [1, 1, 1], 1, 0),
83 (self.module.bisect_left, [1, 1, 1], 2, 3),
84 (self.module.bisect_left, [1, 1, 1, 1], 0, 0),
85 (self.module.bisect_left, [1, 1, 1, 1], 1, 0),
86 (self.module.bisect_left, [1, 1, 1, 1], 2, 4),
87 (self.module.bisect_left, [1, 2], 0, 0),
88 (self.module.bisect_left, [1, 2], 1, 0),
89 (self.module.bisect_left, [1, 2], 1.5, 1),
90 (self.module.bisect_left, [1, 2], 2, 1),
91 (self.module.bisect_left, [1, 2], 3, 2),
92 (self.module.bisect_left, [1, 1, 2, 2], 0, 0),
93 (self.module.bisect_left, [1, 1, 2, 2], 1, 0),
94 (self.module.bisect_left, [1, 1, 2, 2], 1.5, 2),
95 (self.module.bisect_left, [1, 1, 2, 2], 2, 2),
96 (self.module.bisect_left, [1, 1, 2, 2], 3, 4),
97 (self.module.bisect_left, [1, 2, 3], 0, 0),
98 (self.module.bisect_left, [1, 2, 3], 1, 0),
99 (self.module.bisect_left, [1, 2, 3], 1.5, 1),
100 (self.module.bisect_left, [1, 2, 3], 2, 1),
101 (self.module.bisect_left, [1, 2, 3], 2.5, 2),
102 (self.module.bisect_left, [1, 2, 3], 3, 2),
103 (self.module.bisect_left, [1, 2, 3], 4, 3),
104 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
105 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 0),
106 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
107 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 1),
108 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
109 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 3),
110 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
111 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 6),
112 (self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10)
113 ]
Tim Peters36cdad12000-12-29 02:06:45 +0000114
Raymond Hettingerd2305502003-01-16 12:02:35 +0000115 def test_precomputed(self):
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000116 for func, data, elem, expected in self.precomputedCases:
117 self.assertEqual(func(data, elem), expected)
Raymond Hettinger0c410272004-01-05 10:13:35 +0000118 self.assertEqual(func(UserList(data), elem), expected)
Raymond Hettingerd2305502003-01-16 12:02:35 +0000119
Georg Brandl2ee470f2008-07-16 12:55:28 +0000120 def test_negative_lo(self):
121 # Issue 3301
122 mod = self.module
Victor Stinner3fa1aae2013-03-26 01:14:08 +0100123 self.assertRaises(ValueError, mod.bisect_left, [1, 2, 3], 5, -1, 3)
124 self.assertRaises(ValueError, mod.bisect_right, [1, 2, 3], 5, -1, 3)
125 self.assertRaises(ValueError, mod.insort_left, [1, 2, 3], 5, -1, 3)
126 self.assertRaises(ValueError, mod.insort_right, [1, 2, 3], 5, -1, 3)
Georg Brandl2ee470f2008-07-16 12:55:28 +0000127
Mark Dickinsona13b1092012-04-15 16:30:35 +0100128 def test_large_range(self):
129 # Issue 13496
130 mod = self.module
Antoine Pitroufb5b9542012-05-16 15:01:40 +0200131 n = sys.maxsize
132 data = range(n-1)
133 self.assertEqual(mod.bisect_left(data, n-3), n-3)
134 self.assertEqual(mod.bisect_right(data, n-3), n-2)
135 self.assertEqual(mod.bisect_left(data, n-3, n-10, n), n-3)
136 self.assertEqual(mod.bisect_right(data, n-3, n-10, n), n-2)
137
138 def test_large_pyrange(self):
139 # Same as above, but without C-imposed limits on range() parameters
140 mod = self.module
141 n = sys.maxsize
142 data = Range(0, n-1)
143 self.assertEqual(mod.bisect_left(data, n-3), n-3)
144 self.assertEqual(mod.bisect_right(data, n-3), n-2)
145 self.assertEqual(mod.bisect_left(data, n-3, n-10, n), n-3)
146 self.assertEqual(mod.bisect_right(data, n-3, n-10, n), n-2)
147 x = n - 100
148 mod.insort_left(data, x, x - 50, x + 50)
149 self.assertEqual(data.last_insert, (x, x))
150 x = n - 200
151 mod.insort_right(data, x, x - 50, x + 50)
152 self.assertEqual(data.last_insert, (x + 1, x))
Mark Dickinsona13b1092012-04-15 16:30:35 +0100153
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000154 def test_random(self, n=25):
Raymond Hettinger44223752003-01-16 12:31:36 +0000155 from random import randrange
Guido van Rossum805365e2007-05-07 22:24:25 +0000156 for i in range(n):
157 data = [randrange(0, n, 2) for j in range(i)]
Raymond Hettinger44223752003-01-16 12:31:36 +0000158 data.sort()
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000159 elem = randrange(-1, n+1)
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000160 ip = self.module.bisect_left(data, elem)
Raymond Hettinger44223752003-01-16 12:31:36 +0000161 if ip < len(data):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000162 self.assertTrue(elem <= data[ip])
Raymond Hettinger44223752003-01-16 12:31:36 +0000163 if ip > 0:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000164 self.assertTrue(data[ip-1] < elem)
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000165 ip = self.module.bisect_right(data, elem)
Raymond Hettinger44223752003-01-16 12:31:36 +0000166 if ip < len(data):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000167 self.assertTrue(elem < data[ip])
Raymond Hettinger44223752003-01-16 12:31:36 +0000168 if ip > 0:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000169 self.assertTrue(data[ip-1] <= elem)
Raymond Hettinger44223752003-01-16 12:31:36 +0000170
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000171 def test_optionalSlicing(self):
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000172 for func, data, elem, expected in self.precomputedCases:
Guido van Rossum805365e2007-05-07 22:24:25 +0000173 for lo in range(4):
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000174 lo = min(len(data), lo)
Guido van Rossum805365e2007-05-07 22:24:25 +0000175 for hi in range(3,8):
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000176 hi = min(len(data), hi)
177 ip = func(data, elem, lo, hi)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000178 self.assertTrue(lo <= ip <= hi)
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000179 if func is self.module.bisect_left and ip < hi:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000180 self.assertTrue(elem <= data[ip])
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000181 if func is self.module.bisect_left and ip > lo:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000182 self.assertTrue(data[ip-1] < elem)
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000183 if func is self.module.bisect_right and ip < hi:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000184 self.assertTrue(elem < data[ip])
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000185 if func is self.module.bisect_right and ip > lo:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000186 self.assertTrue(data[ip-1] <= elem)
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000187 self.assertEqual(ip, max(lo, min(hi, expected)))
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000188
189 def test_backcompatibility(self):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000190 self.assertEqual(self.module.bisect, self.module.bisect_right)
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000191
Raymond Hettingercc9a9512005-10-05 11:39:12 +0000192 def test_keyword_args(self):
193 data = [10, 20, 30, 40, 50]
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000194 self.assertEqual(self.module.bisect_left(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)
196 self.assertEqual(self.module.bisect(a=data, x=25, lo=1, hi=3), 2)
197 self.module.insort_left(a=data, x=25, lo=1, hi=3)
198 self.module.insort_right(a=data, x=25, lo=1, hi=3)
199 self.module.insort(a=data, x=25, lo=1, hi=3)
Raymond Hettingercc9a9512005-10-05 11:39:12 +0000200 self.assertEqual(data, [10, 20, 25, 25, 25, 30, 40, 50])
201
Ezio Melottif472a902013-01-10 04:32:01 +0200202class TestBisectPython(TestBisect, unittest.TestCase):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000203 module = py_bisect
204
Ezio Melottif472a902013-01-10 04:32:01 +0200205class TestBisectC(TestBisect, unittest.TestCase):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000206 module = c_bisect
207
Raymond Hettingerd2305502003-01-16 12:02:35 +0000208#==============================================================================
209
Ezio Melottif472a902013-01-10 04:32:01 +0200210class TestInsort:
Raymond Hettinger0c410272004-01-05 10:13:35 +0000211 def test_vsBuiltinSort(self, n=500):
Raymond Hettingerd2305502003-01-16 12:02:35 +0000212 from random import choice
Raymond Hettinger0c410272004-01-05 10:13:35 +0000213 for insorted in (list(), UserList()):
Guido van Rossum805365e2007-05-07 22:24:25 +0000214 for i in range(n):
Raymond Hettinger0c410272004-01-05 10:13:35 +0000215 digit = choice("0123456789")
216 if digit in "02468":
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000217 f = self.module.insort_left
Raymond Hettinger0c410272004-01-05 10:13:35 +0000218 else:
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000219 f = self.module.insort_right
Raymond Hettinger0c410272004-01-05 10:13:35 +0000220 f(insorted, digit)
Andrew Svetloveda1f4c2012-10-31 22:37:50 +0200221 self.assertEqual(sorted(insorted), insorted)
Raymond Hettingerd2305502003-01-16 12:02:35 +0000222
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000223 def test_backcompatibility(self):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000224 self.assertEqual(self.module.insort, self.module.insort_right)
225
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000226 def test_listDerived(self):
227 class List(list):
228 data = []
229 def insert(self, index, item):
230 self.data.insert(index, item)
231
232 lst = List()
233 self.module.insort_left(lst, 10)
234 self.module.insort_right(lst, 5)
235 self.assertEqual([5, 10], lst.data)
236
Ezio Melottif472a902013-01-10 04:32:01 +0200237class TestInsortPython(TestInsort, unittest.TestCase):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000238 module = py_bisect
239
Ezio Melottif472a902013-01-10 04:32:01 +0200240class TestInsortC(TestInsort, unittest.TestCase):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000241 module = c_bisect
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000242
Raymond Hettingerd2305502003-01-16 12:02:35 +0000243#==============================================================================
244
Raymond Hettinger63251782004-09-27 22:48:40 +0000245class LenOnly:
246 "Dummy sequence class defining __len__ but not __getitem__."
247 def __len__(self):
248 return 10
249
250class GetOnly:
251 "Dummy sequence class defining __getitem__ but not __len__."
252 def __getitem__(self, ndx):
253 return 10
254
255class CmpErr:
256 "Dummy element that always raises an error during comparison"
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000257 def __lt__(self, other):
Raymond Hettinger63251782004-09-27 22:48:40 +0000258 raise ZeroDivisionError
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000259 __gt__ = __lt__
260 __le__ = __lt__
261 __ge__ = __lt__
262 __eq__ = __lt__
263 __ne__ = __lt__
Raymond Hettinger63251782004-09-27 22:48:40 +0000264
Ezio Melottif472a902013-01-10 04:32:01 +0200265class TestErrorHandling:
Raymond Hettinger63251782004-09-27 22:48:40 +0000266 def test_non_sequence(self):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000267 for f in (self.module.bisect_left, self.module.bisect_right,
268 self.module.insort_left, self.module.insort_right):
Raymond Hettinger63251782004-09-27 22:48:40 +0000269 self.assertRaises(TypeError, f, 10, 10)
270
271 def test_len_only(self):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000272 for f in (self.module.bisect_left, self.module.bisect_right,
273 self.module.insort_left, self.module.insort_right):
Thomas Wouters1ae9afa2006-04-15 09:12:14 +0000274 self.assertRaises(TypeError, f, LenOnly(), 10)
Raymond Hettinger63251782004-09-27 22:48:40 +0000275
276 def test_get_only(self):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000277 for f in (self.module.bisect_left, self.module.bisect_right,
278 self.module.insort_left, self.module.insort_right):
Thomas Wouters1ae9afa2006-04-15 09:12:14 +0000279 self.assertRaises(TypeError, f, GetOnly(), 10)
Raymond Hettinger63251782004-09-27 22:48:40 +0000280
Raymond Hettinger630e5352004-09-27 23:11:35 +0000281 def test_cmp_err(self):
Raymond Hettinger63251782004-09-27 22:48:40 +0000282 seq = [CmpErr(), CmpErr(), CmpErr()]
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000283 for f in (self.module.bisect_left, self.module.bisect_right,
284 self.module.insort_left, self.module.insort_right):
Raymond Hettinger63251782004-09-27 22:48:40 +0000285 self.assertRaises(ZeroDivisionError, f, seq, 10)
286
287 def test_arg_parsing(self):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000288 for f in (self.module.bisect_left, self.module.bisect_right,
289 self.module.insort_left, self.module.insort_right):
Raymond Hettinger63251782004-09-27 22:48:40 +0000290 self.assertRaises(TypeError, f, 10)
291
Ezio Melottif472a902013-01-10 04:32:01 +0200292class TestErrorHandlingPython(TestErrorHandling, unittest.TestCase):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000293 module = py_bisect
294
Ezio Melottif472a902013-01-10 04:32:01 +0200295class TestErrorHandlingC(TestErrorHandling, unittest.TestCase):
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000296 module = c_bisect
297
Raymond Hettinger63251782004-09-27 22:48:40 +0000298#==============================================================================
299
Ezio Melottif472a902013-01-10 04:32:01 +0200300class TestDocExample:
301 def test_grades(self):
302 def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
303 i = self.module.bisect(breakpoints, score)
304 return grades[i]
Raymond Hettinger44223752003-01-16 12:31:36 +0000305
Ezio Melottif472a902013-01-10 04:32:01 +0200306 result = [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
307 self.assertEqual(result, ['F', 'A', 'C', 'C', 'B', 'A', 'A'])
Raymond Hettinger44223752003-01-16 12:31:36 +0000308
Ezio Melottif472a902013-01-10 04:32:01 +0200309 def test_colors(self):
310 data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)]
311 data.sort(key=lambda r: r[1])
312 keys = [r[1] for r in data]
313 bisect_left = self.module.bisect_left
314 self.assertEqual(data[bisect_left(keys, 0)], ('black', 0))
315 self.assertEqual(data[bisect_left(keys, 1)], ('blue', 1))
316 self.assertEqual(data[bisect_left(keys, 5)], ('red', 5))
317 self.assertEqual(data[bisect_left(keys, 8)], ('yellow', 8))
Raymond Hettinger44223752003-01-16 12:31:36 +0000318
Ezio Melottif472a902013-01-10 04:32:01 +0200319class TestDocExamplePython(TestDocExample, unittest.TestCase):
320 module = py_bisect
321
322class TestDocExampleC(TestDocExample, unittest.TestCase):
323 module = c_bisect
Raymond Hettinger44223752003-01-16 12:31:36 +0000324
Raymond Hettingerd2305502003-01-16 12:02:35 +0000325#------------------------------------------------------------------------------
326
Raymond Hettingerd2305502003-01-16 12:02:35 +0000327if __name__ == "__main__":
Ezio Melottif472a902013-01-10 04:32:01 +0200328 unittest.main()