blob: 6221c910ef5ed47cab2a6f2e9a17901ebffbeaab [file] [log] [blame]
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001from collections import deque
2import unittest
3from test import test_support
4import copy
5import cPickle as pickle
6from cStringIO import StringIO
7
8BIG = 100000
9
10class TestBasic(unittest.TestCase):
11
12 def test_basics(self):
13 d = deque(xrange(100))
14 d.__init__(xrange(100, 200))
15 for i in xrange(200, 400):
16 d.append(i)
17 for i in reversed(xrange(-200, 0)):
18 d.appendleft(i)
19 self.assertEqual(list(d), range(-200, 400))
20 self.assertEqual(len(d), 600)
21
22 left = [d.popleft() for i in xrange(250)]
23 self.assertEqual(left, range(-200, 50))
24 self.assertEqual(list(d), range(50, 400))
25
26 right = [d.pop() for i in xrange(250)]
27 right.reverse()
28 self.assertEqual(right, range(150, 400))
29 self.assertEqual(list(d), range(50, 150))
30
31 def test_len(self):
32 d = deque('ab')
33 self.assertEqual(len(d), 2)
34 d.popleft()
35 self.assertEqual(len(d), 1)
36 d.pop()
37 self.assertEqual(len(d), 0)
38 self.assertRaises(LookupError, d.pop)
39 self.assertEqual(len(d), 0)
40 d.append('c')
41 self.assertEqual(len(d), 1)
42 d.appendleft('d')
43 self.assertEqual(len(d), 2)
44 d.clear()
45 self.assertEqual(len(d), 0)
46
47 def test_underflow(self):
48 d = deque()
49 self.assertRaises(LookupError, d.pop)
50 self.assertRaises(LookupError, d.popleft)
51
52 def test_clear(self):
53 d = deque(xrange(100))
54 self.assertEqual(len(d), 100)
55 d.clear()
56 self.assertEqual(len(d), 0)
57 self.assertEqual(list(d), [])
58
59 def test_repr(self):
60 d = deque(xrange(200))
61 e = eval(repr(d))
62 self.assertEqual(list(d), list(e))
63 d.append(d)
64 self.assert_('...' in repr(d))
65
66 def test_print(self):
67 d = deque(xrange(200))
68 d.append(d)
69 f = StringIO()
70 print >> f, d,
71 self.assertEqual(f.getvalue(), repr(d))
72 f.close()
73
74 def test_hash(self):
75 self.assertRaises(TypeError, hash, deque('abc'))
76
77 def test_long_steadystate_queue_popleft(self):
78 for size in (0, 1, 2, 100, 1000):
79 d = deque(xrange(size))
80 append, pop = d.append, d.popleft
81 for i in xrange(size, BIG):
82 append(i)
83 x = pop()
84 if x != i - size:
85 self.assertEqual(x, i-size)
86 self.assertEqual(list(d), range(BIG-size, BIG))
87
88 def test_long_steadystate_queue_popright(self):
89 for size in (0, 1, 2, 100, 1000):
90 d = deque(reversed(xrange(size)))
91 append, pop = d.appendleft, d.pop
92 for i in xrange(size, BIG):
93 append(i)
94 x = pop()
95 if x != i - size:
96 self.assertEqual(x, i-size)
97 self.assertEqual(list(reversed(list(d))), range(BIG-size, BIG))
98
99 def test_big_queue_popleft(self):
100 pass
101 d = deque()
102 append, pop = d.append, d.popleft
103 for i in xrange(BIG):
104 append(i)
105 for i in xrange(BIG):
106 x = pop()
107 if x != i:
108 self.assertEqual(x, i)
109
110 def test_big_queue_popright(self):
111 d = deque()
112 append, pop = d.appendleft, d.pop
113 for i in xrange(BIG):
114 append(i)
115 for i in xrange(BIG):
116 x = pop()
117 if x != i:
118 self.assertEqual(x, i)
119
120 def test_big_stack_right(self):
121 d = deque()
122 append, pop = d.append, d.pop
123 for i in xrange(BIG):
124 append(i)
125 for i in reversed(xrange(BIG)):
126 x = pop()
127 if x != i:
128 self.assertEqual(x, i)
129 self.assertEqual(len(d), 0)
130
131 def test_big_stack_left(self):
132 d = deque()
133 append, pop = d.appendleft, d.popleft
134 for i in xrange(BIG):
135 append(i)
136 for i in reversed(xrange(BIG)):
137 x = pop()
138 if x != i:
139 self.assertEqual(x, i)
140 self.assertEqual(len(d), 0)
141
142 def test_roundtrip_iter_init(self):
143 d = deque(xrange(200))
144 e = deque(d)
145 self.assertNotEqual(id(d), id(e))
146 self.assertEqual(list(d), list(e))
147
148 def test_pickle(self):
149 d = deque(xrange(200))
150 s = pickle.dumps(d)
151 e = pickle.loads(s)
152 self.assertNotEqual(id(d), id(e))
153 self.assertEqual(list(d), list(e))
154
155 def test_deepcopy(self):
156 mut = [10]
157 d = deque([mut])
158 e = copy.deepcopy(d)
159 self.assertEqual(list(d), list(e))
160 mut[0] = 11
161 self.assertNotEqual(id(d), id(e))
162 self.assertNotEqual(list(d), list(e))
163
164 def test_copy(self):
165 mut = [10]
166 d = deque([mut])
167 e = copy.copy(d)
168 self.assertEqual(list(d), list(e))
169 mut[0] = 11
170 self.assertNotEqual(id(d), id(e))
171 self.assertEqual(list(d), list(e))
172
173def R(seqn):
174 'Regular generator'
175 for i in seqn:
176 yield i
177
178class G:
179 'Sequence using __getitem__'
180 def __init__(self, seqn):
181 self.seqn = seqn
182 def __getitem__(self, i):
183 return self.seqn[i]
184
185class I:
186 'Sequence using iterator protocol'
187 def __init__(self, seqn):
188 self.seqn = seqn
189 self.i = 0
190 def __iter__(self):
191 return self
192 def next(self):
193 if self.i >= len(self.seqn): raise StopIteration
194 v = self.seqn[self.i]
195 self.i += 1
196 return v
197
198class Ig:
199 'Sequence using iterator protocol defined with a generator'
200 def __init__(self, seqn):
201 self.seqn = seqn
202 self.i = 0
203 def __iter__(self):
204 for val in self.seqn:
205 yield val
206
207class X:
208 'Missing __getitem__ and __iter__'
209 def __init__(self, seqn):
210 self.seqn = seqn
211 self.i = 0
212 def next(self):
213 if self.i >= len(self.seqn): raise StopIteration
214 v = self.seqn[self.i]
215 self.i += 1
216 return v
217
218class N:
219 'Iterator missing next()'
220 def __init__(self, seqn):
221 self.seqn = seqn
222 self.i = 0
223 def __iter__(self):
224 return self
225
226class E:
227 'Test propagation of exceptions'
228 def __init__(self, seqn):
229 self.seqn = seqn
230 self.i = 0
231 def __iter__(self):
232 return self
233 def next(self):
234 3/0
235
236class S:
237 'Test immediate stop'
238 def __init__(self, seqn):
239 pass
240 def __iter__(self):
241 return self
242 def next(self):
243 raise StopIteration
244
245from itertools import chain, imap
246def L(seqn):
247 'Test multiple tiers of iterators'
248 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
249
250
251class TestVariousIteratorArgs(unittest.TestCase):
252
253 def test_constructor(self):
254 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
255 for g in (G, I, Ig, S, L, R):
256 self.assertEqual(list(deque(g(s))), list(g(s)))
257 self.assertRaises(TypeError, deque, X(s))
258 self.assertRaises(TypeError, deque, N(s))
259 self.assertRaises(ZeroDivisionError, deque, E(s))
260
261 def test_iter_with_altered_data(self):
262 d = deque('abcdefg')
263 it = iter(d)
264 d.pop()
265 self.assertRaises(RuntimeError, it.next)
266
267class Deque(deque):
268 pass
269
270class TestSubclass(unittest.TestCase):
271
272 def test_basics(self):
273 d = Deque(xrange(100))
274 d.__init__(xrange(100, 200))
275 for i in xrange(200, 400):
276 d.append(i)
277 for i in reversed(xrange(-200, 0)):
278 d.appendleft(i)
279 self.assertEqual(list(d), range(-200, 400))
280 self.assertEqual(len(d), 600)
281
282 left = [d.popleft() for i in xrange(250)]
283 self.assertEqual(left, range(-200, 50))
284 self.assertEqual(list(d), range(50, 400))
285
286 right = [d.pop() for i in xrange(250)]
287 right.reverse()
288 self.assertEqual(right, range(150, 400))
289 self.assertEqual(list(d), range(50, 150))
290
291 d.clear()
292 self.assertEqual(len(d), 0)
293
294 def test_copy_pickle(self):
295
296 d = Deque('abc')
297
298 e = d.__copy__()
299 self.assertEqual(type(d), type(e))
300 self.assertEqual(list(d), list(e))
301
302 e = Deque(d)
303 self.assertEqual(type(d), type(e))
304 self.assertEqual(list(d), list(e))
305
306 s = pickle.dumps(d)
307 e = pickle.loads(s)
308 self.assertNotEqual(id(d), id(e))
309 self.assertEqual(type(d), type(e))
310 self.assertEqual(list(d), list(e))
311
312
313#==============================================================================
314
315def test_main(verbose=None):
316 import sys
317 from test import test_sets
318 test_classes = (
319 TestBasic,
320 TestVariousIteratorArgs,
321 TestSubclass,
322 )
323
324 test_support.run_unittest(*test_classes)
325
326 # verify reference counting
327 if verbose and hasattr(sys, "gettotalrefcount"):
328 import gc
329 counts = [None] * 5
330 for i in xrange(len(counts)):
331 test_support.run_unittest(*test_classes)
332 gc.collect()
333 counts[i] = sys.gettotalrefcount()
334 print counts
335
336if __name__ == "__main__":
337 test_main(verbose=True)