1# This file taken from Python, licensed under the Python License Agreement
2
3from __future__ import print_function
4"""
5Tests common to tuple, list and UserList.UserList
6"""
7
8from blist.test import test_support
9from blist.test import unittest
10import sys
11
12# Various iterables
13# This is used for checking the constructor (here and in test_deque.py)
14def iterfunc(seqn):
15    'Regular generator'
16    for i in seqn:
17        yield i
18
19class Sequence:
20    'Sequence using __getitem__'
21    def __init__(self, seqn):
22        self.seqn = seqn
23    def __getitem__(self, i):
24        return self.seqn[i]
25
26class IterFunc:
27    'Sequence using iterator protocol'
28    def __init__(self, seqn):
29        self.seqn = seqn
30        self.i = 0
31    def __iter__(self):
32        return self
33    def __next__(self):
34        if self.i >= len(self.seqn): raise StopIteration
35        v = self.seqn[self.i]
36        self.i += 1
37        return v
38    next = __next__
39
40class IterGen:
41    'Sequence using iterator protocol defined with a generator'
42    def __init__(self, seqn):
43        self.seqn = seqn
44        self.i = 0
45    def __iter__(self):
46        for val in self.seqn:
47            yield val
48
49class IterNextOnly:
50    'Missing __getitem__ and __iter__'
51    def __init__(self, seqn):
52        self.seqn = seqn
53        self.i = 0
54    def __next__(self): # pragma: no cover
55        if self.i >= len(self.seqn): raise StopIteration
56        v = self.seqn[self.i]
57        self.i += 1
58        return v
59    next = __next__
60
61class IterNoNext:
62    'Iterator missing next()'
63    def __init__(self, seqn):
64        self.seqn = seqn
65        self.i = 0
66    def __iter__(self):
67        return self
68
69class IterGenExc:
70    'Test propagation of exceptions'
71    def __init__(self, seqn):
72        self.seqn = seqn
73        self.i = 0
74    def __iter__(self):
75        return self
76    def __next__(self):
77        3 // 0
78    next = __next__
79
80class IterFuncStop:
81    'Test immediate stop'
82    def __init__(self, seqn):
83        pass
84    def __iter__(self):
85        return self
86    def __next__(self):
87        raise StopIteration
88    next = __next__
89
90from itertools import chain
91def itermulti(seqn):
92    'Test multiple tiers of iterators'
93    return chain(map(lambda x:x, iterfunc(IterGen(Sequence(seqn)))))
94
95class CommonTest(unittest.TestCase):
96    # The type to be tested
97    type2test = None
98
99    def test_constructors(self):
100        l0 = []
101        l1 = [0]
102        l2 = [0, 1]
103
104        u = self.type2test()
105        u0 = self.type2test(l0)
106        u1 = self.type2test(l1)
107        u2 = self.type2test(l2)
108
109        uu = self.type2test(u)
110        uu0 = self.type2test(u0)
111        uu1 = self.type2test(u1)
112        uu2 = self.type2test(u2)
113
114        v = self.type2test(tuple(u))
115        class OtherSeq:
116            def __init__(self, initseq):
117                self.__data = initseq
118            def __len__(self):
119                return len(self.__data)
120            def __getitem__(self, i):
121                return self.__data[i]
122        s = OtherSeq(u0)
123        v0 = self.type2test(s)
124        self.assertEqual(len(v0), len(s))
125
126        s = "this is also a sequence"
127        vv = self.type2test(s)
128        self.assertEqual(len(vv), len(s))
129
130        # Create from various iteratables
131        for s in ("123", "", list(range(1000)), ('do', 1.2), range(2000,2200,5)):
132            for g in (Sequence, IterFunc, IterGen,
133                      itermulti, iterfunc):
134                self.assertEqual(self.type2test(g(s)), self.type2test(s))
135            self.assertEqual(self.type2test(IterFuncStop(s)), self.type2test())
136            self.assertEqual(self.type2test(c for c in "123"), self.type2test("123"))
137            self.assertRaises(TypeError, self.type2test, IterNextOnly(s))
138            self.assertRaises(TypeError, self.type2test, IterNoNext(s))
139            self.assertRaises(ZeroDivisionError, self.type2test, IterGenExc(s))
140
141    def test_truth(self):
142        self.assert_(not self.type2test())
143        self.assert_(self.type2test([42]))
144
145    def test_getitem(self):
146        u = self.type2test([0, 1, 2, 3, 4])
147        for i in range(len(u)):
148            self.assertEqual(u[i], i)
149            self.assertEqual(u[int(i)], i)
150        for i in range(-len(u), -1):
151            self.assertEqual(u[i], len(u)+i)
152            self.assertEqual(u[int(i)], len(u)+i)
153        self.assertRaises(IndexError, u.__getitem__, -len(u)-1)
154        self.assertRaises(IndexError, u.__getitem__, len(u))
155        self.assertRaises(ValueError, u.__getitem__, slice(0,10,0))
156
157        u = self.type2test()
158        self.assertRaises(IndexError, u.__getitem__, 0)
159        self.assertRaises(IndexError, u.__getitem__, -1)
160
161        self.assertRaises(TypeError, u.__getitem__)
162
163        a = self.type2test([10, 11])
164        self.assertEqual(a[0], 10)
165        self.assertEqual(a[1], 11)
166        self.assertEqual(a[-2], 10)
167        self.assertEqual(a[-1], 11)
168        self.assertRaises(IndexError, a.__getitem__, -3)
169        self.assertRaises(IndexError, a.__getitem__, 3)
170
171    def test_getslice(self):
172        l = [0, 1, 2, 3, 4]
173        u = self.type2test(l)
174
175        self.assertEqual(u[0:0], self.type2test())
176        self.assertEqual(u[1:2], self.type2test([1]))
177        self.assertEqual(u[-2:-1], self.type2test([3]))
178        self.assertEqual(u[-1000:1000], u)
179        self.assertEqual(u[1000:-1000], self.type2test([]))
180        self.assertEqual(u[:], u)
181        self.assertEqual(u[1:None], self.type2test([1, 2, 3, 4]))
182        self.assertEqual(u[None:3], self.type2test([0, 1, 2]))
183
184        # Extended slices
185        self.assertEqual(u[::], u)
186        self.assertEqual(u[::2], self.type2test([0, 2, 4]))
187        self.assertEqual(u[1::2], self.type2test([1, 3]))
188        self.assertEqual(u[::-1], self.type2test([4, 3, 2, 1, 0]))
189        self.assertEqual(u[::-2], self.type2test([4, 2, 0]))
190        self.assertEqual(u[3::-2], self.type2test([3, 1]))
191        self.assertEqual(u[3:3:-2], self.type2test([]))
192        self.assertEqual(u[3:2:-2], self.type2test([3]))
193        self.assertEqual(u[3:1:-2], self.type2test([3]))
194        self.assertEqual(u[3:0:-2], self.type2test([3, 1]))
195        self.assertEqual(u[::-100], self.type2test([4]))
196        self.assertEqual(u[100:-100:], self.type2test([]))
197        self.assertEqual(u[-100:100:], u)
198        self.assertEqual(u[100:-100:-1], u[::-1])
199        self.assertEqual(u[-100:100:-1], self.type2test([]))
200        self.assertEqual(u[-100:100:2], self.type2test([0, 2, 4]))
201
202        # Test extreme cases with long ints
203        a = self.type2test([0,1,2,3,4])
204        self.assertEqual(a[ -pow(2,128): 3 ], self.type2test([0,1,2]))
205        self.assertEqual(a[ 3: pow(2,145) ], self.type2test([3,4]))
206
207        if sys.version_info[0] < 3:
208            self.assertRaises(TypeError, u.__getslice__)
209
210    def test_contains(self):
211        u = self.type2test([0, 1, 2])
212        for i in u:
213            self.assert_(i in u)
214        for i in min(u)-1, max(u)+1:
215            self.assert_(i not in u)
216
217        self.assertRaises(TypeError, u.__contains__)
218
219    def test_contains_fake(self):
220        class AllEq:
221            # Sequences must use rich comparison against each item
222            # (unless "is" is true, or an earlier item answered)
223            # So instances of AllEq must be found in all non-empty sequences.
224            def __eq__(self, other):
225                return True
226            def __hash__(self): # pragma: no cover
227                raise NotImplemented
228        self.assert_(AllEq() not in self.type2test([]))
229        self.assert_(AllEq() in self.type2test([1]))
230
231    def test_contains_order(self):
232        # Sequences must test in-order.  If a rich comparison has side
233        # effects, these will be visible to tests against later members.
234        # In this test, the "side effect" is a short-circuiting raise.
235        class DoNotTestEq(Exception):
236            pass
237        class StopCompares:
238            def __eq__(self, other):
239                raise DoNotTestEq
240
241        checkfirst = self.type2test([1, StopCompares()])
242        self.assert_(1 in checkfirst)
243        checklast = self.type2test([StopCompares(), 1])
244        self.assertRaises(DoNotTestEq, checklast.__contains__, 1)
245
246    def test_len(self):
247        self.assertEqual(len(self.type2test()), 0)
248        self.assertEqual(len(self.type2test([])), 0)
249        self.assertEqual(len(self.type2test([0])), 1)
250        self.assertEqual(len(self.type2test([0, 1, 2])), 3)
251
252    def test_minmax(self):
253        u = self.type2test([0, 1, 2])
254        self.assertEqual(min(u), 0)
255        self.assertEqual(max(u), 2)
256
257    def test_addmul(self):
258        u1 = self.type2test([0])
259        u2 = self.type2test([0, 1])
260        self.assertEqual(u1, u1 + self.type2test())
261        self.assertEqual(u1, self.type2test() + u1)
262        self.assertEqual(u1 + self.type2test([1]), u2)
263        self.assertEqual(self.type2test([-1]) + u1, self.type2test([-1, 0]))
264        self.assertEqual(self.type2test(), u2*0)
265        self.assertEqual(self.type2test(), 0*u2)
266        self.assertEqual(self.type2test(), u2*0)
267        self.assertEqual(self.type2test(), 0*u2)
268        self.assertEqual(u2, u2*1)
269        self.assertEqual(u2, 1*u2)
270        self.assertEqual(u2, u2*1)
271        self.assertEqual(u2, 1*u2)
272        self.assertEqual(u2+u2, u2*2)
273        self.assertEqual(u2+u2, 2*u2)
274        self.assertEqual(u2+u2, u2*2)
275        self.assertEqual(u2+u2, 2*u2)
276        self.assertEqual(u2+u2+u2, u2*3)
277        self.assertEqual(u2+u2+u2, 3*u2)
278
279        class subclass(self.type2test):
280            pass
281        u3 = subclass([0, 1])
282        self.assertEqual(u3, u3*1)
283        self.assert_(u3 is not u3*1)
284
285    def test_iadd(self):
286        u = self.type2test([0, 1])
287        u += self.type2test()
288        self.assertEqual(u, self.type2test([0, 1]))
289        u += self.type2test([2, 3])
290        self.assertEqual(u, self.type2test([0, 1, 2, 3]))
291        u += self.type2test([4, 5])
292        self.assertEqual(u, self.type2test([0, 1, 2, 3, 4, 5]))
293
294        u = self.type2test("spam")
295        u += self.type2test("eggs")
296        self.assertEqual(u, self.type2test("spameggs"))
297
298    def test_imul(self):
299        u = self.type2test([0, 1])
300        u *= 3
301        self.assertEqual(u, self.type2test([0, 1, 0, 1, 0, 1]))
302
303    def test_getitemoverwriteiter(self):
304        # Verify that __getitem__ overrides are not recognized by __iter__
305        class T(self.type2test):
306            def __getitem__(self, key): # pragma: no cover
307                return str(key) + '!!!'
308        self.assertEqual(next(iter(T((1,2)))), 1)
309
310    def test_repeat(self):
311        for m in range(4):
312            s = tuple(range(m))
313            for n in range(-3, 5):
314                self.assertEqual(self.type2test(s*n), self.type2test(s)*n)
315            self.assertEqual(self.type2test(s)*(-4), self.type2test([]))
316            self.assertEqual(id(s), id(s*1))
317
318    def test_subscript(self):
319        a = self.type2test([10, 11])
320        self.assertEqual(a.__getitem__(0), 10)
321        self.assertEqual(a.__getitem__(1), 11)
322        self.assertEqual(a.__getitem__(-2), 10)
323        self.assertEqual(a.__getitem__(-1), 11)
324        self.assertRaises(IndexError, a.__getitem__, -3)
325        self.assertRaises(IndexError, a.__getitem__, 3)
326        self.assertEqual(a.__getitem__(slice(0,1)), self.type2test([10]))
327        self.assertEqual(a.__getitem__(slice(1,2)), self.type2test([11]))
328        self.assertEqual(a.__getitem__(slice(0,2)), self.type2test([10, 11]))
329        self.assertEqual(a.__getitem__(slice(0,3)), self.type2test([10, 11]))
330        self.assertEqual(a.__getitem__(slice(3,5)), self.type2test([]))
331        self.assertRaises(ValueError, a.__getitem__, slice(0, 10, 0))
332        self.assertRaises(TypeError, a.__getitem__, 'x')
333