1#!/usr/bin/python
2from __future__ import print_function
3
4"""
5Copyright 2007-2010 Stutzbach Enterprises, LLC (daniel@stutzbachenterprises.com)
6
7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions are
9met:
10
11   1. Redistributions of source code must retain the above copyright
12      notice, this list of conditions and the following disclaimer.
13   2. Redistributions in binary form must reproduce the above
14      copyright notice, this list of conditions and the following
15      disclaimer in the documentation and/or other materials provided
16      with the distribution.
17   3. The name of the author may not be used to endorse or promote
18      products derived from this software without specific prior written
19      permission.
20
21THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31POSSIBILITY OF SUCH DAMAGE.
32
33"""
34
35
36import sys
37import os
38
39import unittest, operator
40import blist, pickle
41from blist import _blist
42#BList = list
43from blist.test import test_support, list_tests, sortedlist_tests, btuple_tests
44from blist.test import sorteddict_tests, test_set
45
46limit = _blist._limit
47n = 512//8 * limit
48
49class BListTest(list_tests.CommonTest):
50    type2test = blist.blist
51
52    def test_delmul(self):
53        x = self.type2test(list(range(10000)))
54        for i in range(100):
55            del x[len(x)//4:3*len(x)//4]
56            x *= 2
57
58    def test_truth(self):
59        super(BListTest, self).test_truth()
60        self.assert_(not self.type2test())
61        self.assert_(self.type2test([42]))
62
63    def test_identity(self):
64        self.assert_(self.type2test([]) is not self.type2test([]))
65
66    def test_len(self):
67        super(BListTest, self).test_len()
68        self.assertEqual(len(self.type2test()), 0)
69        self.assertEqual(len(self.type2test([0])), 1)
70        self.assertEqual(len(self.type2test([0, 1, 2])), 3)
71
72    def test_append2(self):
73        lst = self.type2test()
74        t = tuple(range(n))
75        for i in range(n):
76            lst.append(i)
77            self.assertEqual(tuple(lst), t[:i+1])
78
79    def test_delstuff(self):
80        lst = self.type2test(list(range(n)))
81        t = tuple(range(n))
82        x = lst[4:258]
83        self.assertEqual(tuple(x), tuple(t[4:258]))
84        x.append(-1)
85        self.assertEqual(tuple(x), tuple(t[4:258] + (-1,)))
86        self.assertEqual(tuple(lst), t)
87        lst[200] = 6
88        self.assertEqual(tuple(x), tuple(t[4:258] + (-1,)))
89        self.assertEqual(tuple(lst), tuple(t[0:200] + (6,) + t[201:]))
90        del lst[200]
91        self.assertEqual(tuple(lst), tuple(t[0:200] + t[201:]))
92
93    def test_del1(self):
94        lst2 = self.type2test(list(range(limit+1)))
95        self.assertEqual(tuple(lst2), tuple(range(limit+1)))
96        del lst2[1]
97        del lst2[-1]
98        self.assertEqual(tuple(lst2), (0,) + tuple(range(2,limit)))
99
100    def test_insert_and_del(self):
101        lst = self.type2test(list(range(n)))
102        t = tuple(range(n))
103        lst.insert(200, 0)
104        self.assertEqual(tuple(lst), (t[0:200] + (0,) + t[200:]))
105        del lst[200:]
106        self.assertEqual(tuple(lst), tuple(range(200)))
107
108    def test_mul3(self):
109        lst = self.type2test(list(range(3)))
110        self.assertEqual(tuple(lst*3), tuple(list(range(3))*3))
111
112    def test_mul(self):
113        x = self.type2test(list(range(limit**2)))
114        for i in range(10):
115            self.assertEqual(len(x*i), i*limit**2)
116
117    def test_extendspam(self):
118        a = self.type2test('spam')
119        a.extend('eggs')
120        self.assertEqual(list(a), list('spameggs'))
121
122    def test_bigmul1(self):
123        x = self.type2test([0])
124        for i in list(range(290)) + [1000, 10000, 100000, 1000000, 10000000, 2**29]:
125            self.assertEqual(len(x*i), i)
126
127    def test_badinit(self):
128        self.assertRaises(TypeError, self.type2test, 0, 0, 0)
129
130    def test_copyself(self):
131        x = self.type2test(list(range(n)))
132        x[:] = x
133
134    def test_nohash(self):
135        x = self.type2test()
136        d = {}
137        self.assertRaises(TypeError, d.__setitem__, x, 5)
138
139    def test_collapseboth(self):
140        x = self.type2test(list(range(512)))
141        del x[193:318]
142
143    def test_collapseright(self):
144        x = self.type2test(list(range(512)))
145        del x[248:318]
146
147    def test_badrepr(self):
148        class BadExc(Exception):
149            pass
150
151        class BadRepr:
152            def __repr__(self):
153                raise BadExc
154
155        x = self.type2test([BadRepr()])
156        self.assertRaises(BadExc, repr, x)
157        x = self.type2test(list(range(n)))
158        x.append(BadRepr())
159        self.assertRaises(BadExc, repr, x)
160
161    def test_slice0(self):
162        x = self.type2test(list(range(n)))
163        x[slice(5,3,1)] = []
164        self.assertEqual(x, list(range(n)))
165        x = self.type2test(list(range(n)))
166        self.assertRaises(ValueError, x.__setitem__, slice(5,3,1), [5,3,2])
167        del x[slice(5,3,1)]
168        self.assertEqual(x, list(range(n)))
169
170    def test_badindex(self):
171        x = self.type2test()
172        self.assertRaises(TypeError, x.__setitem__, 's', 5)
173
174    def test_comparelist(self):
175        x = self.type2test(list(range(n)))
176        y = list(range(n-1))
177        self.assert_(not (x == y))
178        self.assert_(x != y)
179        self.assert_(not (x < y))
180        self.assert_(not (x <= y))
181        self.assert_(x > y)
182        self.assert_(x >= y)
183
184        y = list(range(n))
185        self.assert_(x == y)
186        self.assert_(y == x)
187
188        y[100] = 6
189        self.assert_(not (x == y))
190        self.assert_(x != y)
191
192    def test_compareblist(self):
193        x = self.type2test(list(range(n)))
194        y = self.type2test(list(range(n-1)))
195        self.assert_(not (x == y))
196        self.assert_(x != y)
197        self.assert_(not (x < y))
198        self.assert_(not (x <= y))
199        self.assert_(x > y)
200        self.assert_(x >= y)
201
202        y[100] = 6
203        self.assert_(not (x == y))
204        self.assert_(x != y)
205
206    def test_comparetuple(self):
207        x = self.type2test(list(range(n)))
208        y = tuple(range(n))
209        self.assert_(x != y)
210
211    def test_indexempty(self):
212        x = self.type2test(list(range(10)))
213        self.assertRaises(ValueError, x.index, 'spam')
214
215    def test_indexargs(self):
216        x = self.type2test(list(range(10)))
217        self.assertEqual(x.index(5,1,-1), 5)
218        self.assertRaises(ValueError, x.index, 5, -1, -9)
219        self.assertRaises(ValueError, x.index, 8, 1, 4)
220        self.assertRaises(ValueError, x.index, 0, 1, 4)
221
222    def test_reversebig(self):
223        x = self.type2test(list(range(n)))
224        x.reverse()
225        self.assertEqual(x, list(range(n-1,-1,-1)))
226
227    def test_badconcat(self):
228        x = self.type2test()
229        y = 'foo'
230        self.assertRaises(TypeError, operator.add, x, y)
231
232    def test_bad_assign(self):
233        x = self.type2test(list(range(n)))
234        self.assertRaises(TypeError, x.__setitem__, slice(1,10,2), 5)
235
236    def sort_evil(self, after):
237        class EvilCompare:
238            count = 0
239            num_raises = 0
240            def __init__(self, x):
241                self.x = x
242            def __lt__(self, other):
243                EvilCompare.count += 1
244                if EvilCompare.count > after:
245                    EvilCompare.num_raises += 1
246                    raise ValueError
247                return self.x < other.x
248
249        x = self.type2test(EvilCompare(x) for x in range(n))
250        from random import shuffle
251        shuffle(x)
252        self.assertRaises(ValueError, x.sort)
253        self.assertEqual(EvilCompare.num_raises, 1)
254        x = [a.x for a in x]
255        x.sort()
256        self.assertEquals(x, list(range(n)))
257
258    def test_sort_evil_small(self):
259        self.sort_evil(limit * 5)
260
261    def test_sort_evil_big(self):
262        self.sort_evil(n + limit)
263
264    def test_big_extend(self):
265        x = self.type2test([1])
266        x.extend(range(n))
267        self.assertEqual(tuple(x), (1,) + tuple(range(n)))
268
269    def test_big_getslice(self):
270        x = self.type2test([0]) * 65536
271        self.assertEqual(len(x[256:512]), 256)
272
273    def test_modify_original(self):
274        x = self.type2test(list(range(1024)))
275        y = x[:]
276        x[5] = 'z'
277        self.assertEqual(tuple(y), tuple(range(1024)))
278        self.assertEqual(x[5], 'z')
279        self.assertEqual(tuple(x[:5]), tuple(range(5)))
280        self.assertEqual(tuple(x[6:]), tuple(range(6, 1024)))
281
282    def test_modify_copy(self):
283        x = self.type2test(list(range(1024)))
284        y = x[:]
285        y[5] = 'z'
286        self.assertEqual(tuple(x), tuple(range(1024)))
287        self.assertEqual(y[5], 'z')
288        self.assertEqual(tuple(y[:5]), tuple(range(5)))
289        self.assertEqual(tuple(y[6:]), tuple(range(6, 1024)))
290
291    def test_bigsort(self):
292        x = self.type2test(list(range(100000)))
293        x.sort()
294
295    def test_sort_twice(self):
296        y = blist.blist(list(range(limit+1)))
297        for i in range(2):
298            x = blist.blist(y)
299            x.sort()
300            self.assertEqual(tuple(x), tuple(range(limit+1)))
301
302    def test_LIFO(self):
303        x = blist.blist()
304        for i in range(1000):
305            x.append(i)
306        for j in range(1000-1,-1,-1):
307            self.assertEqual(x.pop(), j)
308
309    def pickle_test(self, pickler, x):
310        y = pickler.dumps(x)
311        z = pickler.loads(y)
312        self.assertEqual(x, z)
313        self.assertEqual(repr(x), repr(z))
314
315    def pickle_tests(self, pickler):
316        self.pickle_test(pickler, blist.blist())
317        self.pickle_test(pickler, blist.blist(list(range(limit))))
318        self.pickle_test(pickler, blist.blist(list(range(limit+1))))
319        self.pickle_test(pickler, blist.blist(list(range(n))))
320
321        x = blist.blist([0])
322        x *= n
323        self.pickle_test(pickler, x)
324        y = blist.blist(x)
325        y[5] = 'x'
326        self.pickle_test(pickler, x)
327        self.pickle_test(pickler, y)
328
329    def test_pickle(self):
330        self.pickle_tests(pickle)
331
332    def test_types(self):
333        type(blist.blist())
334        type(iter(blist.blist()))
335        type(iter(reversed(blist.blist())))
336
337    def test_iterlen_empty(self):
338        it = iter(blist.blist())
339        if hasattr(it, '__next__'): # pragma: no cover
340            self.assertRaises(StopIteration, it.__next__)
341        else: # pragma: no cover
342            self.assertRaises(StopIteration, it.next)
343        self.assertEqual(it.__length_hint__(), 0)
344
345    def test_sort_floats(self):
346        x = blist.blist([0.1, 0.2, 0.3])
347        x.sort()
348
349tests = [BListTest,
350         sortedlist_tests.SortedListTest,
351         sortedlist_tests.WeakSortedListTest,
352         sortedlist_tests.SortedSetTest,
353         sortedlist_tests.WeakSortedSetTest,
354         btuple_tests.bTupleTest,
355         sorteddict_tests.sorteddict_test
356         ]
357tests += test_set.test_classes
358
359def test_suite():
360    suite = unittest.TestSuite()
361    for test in tests:
362        suite.addTest(unittest.TestLoader().loadTestsFromTestCase(test))
363    return suite
364
365def test_main(verbose=None):
366    test_support.run_unittest(*tests)
367
368if __name__ == "__main__":
369    test_main(verbose=True)
370