blob: 200779fb98775da92d1a8c28c3f825aaa1a49b1b [file] [log] [blame]
Guido van Rossum7dab2422002-04-26 19:40:56 +00001import unittest
2
Barry Warsaw04f357c2002-07-23 19:04:11 +00003from test import test_support
Guido van Rossum7dab2422002-04-26 19:40:56 +00004
Guido van Rossum7dab2422002-04-26 19:40:56 +00005class G:
6 'Sequence using __getitem__'
7 def __init__(self, seqn):
8 self.seqn = seqn
9 def __getitem__(self, i):
10 return self.seqn[i]
11
12class I:
13 'Sequence using iterator protocol'
14 def __init__(self, seqn):
15 self.seqn = seqn
16 self.i = 0
17 def __iter__(self):
18 return self
19 def next(self):
20 if self.i >= len(self.seqn): raise StopIteration
21 v = self.seqn[self.i]
22 self.i += 1
23 return v
24
25class Ig:
26 'Sequence using iterator protocol defined with a generator'
27 def __init__(self, seqn):
28 self.seqn = seqn
29 self.i = 0
30 def __iter__(self):
31 for val in self.seqn:
32 yield val
33
34class X:
35 'Missing __getitem__ and __iter__'
36 def __init__(self, seqn):
37 self.seqn = seqn
38 self.i = 0
39 def next(self):
40 if self.i >= len(self.seqn): raise StopIteration
41 v = self.seqn[self.i]
42 self.i += 1
43 return v
44
45class E:
46 'Test propagation of exceptions'
47 def __init__(self, seqn):
48 self.seqn = seqn
49 self.i = 0
50 def __iter__(self):
51 return self
52 def next(self):
53 3/0
54
55class N:
56 'Iterator missing next()'
57 def __init__(self, seqn):
58 self.seqn = seqn
59 self.i = 0
60 def __iter__(self):
61 return self
62
63class EnumerateTestCase(unittest.TestCase):
64
65 enum = enumerate
Raymond Hettingere8b0f042003-05-28 14:05:34 +000066 seq, res = 'abc', [(0,'a'), (1,'b'), (2,'c')]
Guido van Rossum7dab2422002-04-26 19:40:56 +000067
68 def test_basicfunction(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000069 self.assertEqual(type(self.enum(self.seq)), self.enum)
70 e = self.enum(self.seq)
Guido van Rossum7dab2422002-04-26 19:40:56 +000071 self.assertEqual(iter(e), e)
Raymond Hettingere8b0f042003-05-28 14:05:34 +000072 self.assertEqual(list(self.enum(self.seq)), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000073 self.enum.__doc__
74
75 def test_getitemseqn(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000076 self.assertEqual(list(self.enum(G(self.seq))), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000077 e = self.enum(G(''))
78 self.assertRaises(StopIteration, e.next)
79
80 def test_iteratorseqn(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000081 self.assertEqual(list(self.enum(I(self.seq))), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000082 e = self.enum(I(''))
83 self.assertRaises(StopIteration, e.next)
84
85 def test_iteratorgenerator(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000086 self.assertEqual(list(self.enum(Ig(self.seq))), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000087 e = self.enum(Ig(''))
88 self.assertRaises(StopIteration, e.next)
89
90 def test_noniterable(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000091 self.assertRaises(TypeError, self.enum, X(self.seq))
Guido van Rossum7dab2422002-04-26 19:40:56 +000092
93 def test_illformediterable(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000094 self.assertRaises(TypeError, list, self.enum(N(self.seq)))
Guido van Rossum7dab2422002-04-26 19:40:56 +000095
96 def test_exception_propagation(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000097 self.assertRaises(ZeroDivisionError, list, self.enum(E(self.seq)))
98
99 def test_argumentcheck(self):
100 self.assertRaises(TypeError, self.enum) # no arguments
101 self.assertRaises(TypeError, self.enum, 1) # wrong type (not iterable)
102 self.assertRaises(TypeError, self.enum, 'abc', 2) # too many arguments
103
104 def test_tuple_reuse(self):
105 # Tests an implementation detail where tuple is reused
106 # whenever nothing else holds a reference to it
Raymond Hettingera690a992003-11-16 16:17:49 +0000107 self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq))
108 self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self.seq)))
Guido van Rossum7dab2422002-04-26 19:40:56 +0000109
110class MyEnum(enumerate):
111 pass
112
113class SubclassTestCase(EnumerateTestCase):
114
115 enum = MyEnum
116
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000117class TestEmpty(EnumerateTestCase):
118
119 seq, res = '', []
120
121class TestBig(EnumerateTestCase):
122
123 seq = range(10,20000,2)
124 res = zip(range(20000), seq)
125
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000126class TestReversed(unittest.TestCase):
127
128 def test_simple(self):
129 class A:
130 def __getitem__(self, i):
131 if i < 5:
132 return str(i)
133 raise StopIteration
134 def __len__(self):
135 return 5
136 for data in 'abc', range(5), tuple(enumerate('abc')), A(), xrange(1,17,5):
137 self.assertEqual(list(data)[::-1], list(reversed(data)))
138 self.assertRaises(TypeError, reversed, {})
139
140 def test_xrange_optimization(self):
141 x = xrange(1)
142 self.assertEqual(type(reversed(x)), type(iter(x)))
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000143
Raymond Hettinger029dba52004-02-10 09:33:39 +0000144 def test_len(self):
Raymond Hettingerd2c36262004-03-10 08:32:47 +0000145 # This is an implementation detail, not an interface requirement
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000146 for s in ('hello', tuple('hello'), list('hello'), xrange(5)):
147 self.assertEqual(len(reversed(s)), len(s))
Raymond Hettinger029dba52004-02-10 09:33:39 +0000148
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000149def test_main(verbose=None):
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000150 testclasses = (EnumerateTestCase, SubclassTestCase, TestEmpty, TestBig,
151 TestReversed)
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000152 test_support.run_unittest(*testclasses)
153
154 # verify reference counting
155 import sys
156 if verbose and hasattr(sys, "gettotalrefcount"):
157 counts = [None] * 5
158 for i in xrange(len(counts)):
159 test_support.run_unittest(*testclasses)
160 counts[i] = sys.gettotalrefcount()
161 print counts
Guido van Rossum7dab2422002-04-26 19:40:56 +0000162
163if __name__ == "__main__":
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000164 test_main(verbose=True)