blob: b07360600a0ca84162b1a1efc670b70eb6b9ebee [file] [log] [blame]
Guido van Rossum7dab2422002-04-26 19:40:56 +00001import unittest
Raymond Hettingere8b0f042003-05-28 14:05:34 +00002from sets import Set
Guido van Rossum7dab2422002-04-26 19:40:56 +00003
Barry Warsaw04f357c2002-07-23 19:04:11 +00004from test import test_support
Guido van Rossum7dab2422002-04-26 19:40:56 +00005
Guido van Rossum7dab2422002-04-26 19:40:56 +00006class G:
7 'Sequence using __getitem__'
8 def __init__(self, seqn):
9 self.seqn = seqn
10 def __getitem__(self, i):
11 return self.seqn[i]
12
13class I:
14 'Sequence using iterator protocol'
15 def __init__(self, seqn):
16 self.seqn = seqn
17 self.i = 0
18 def __iter__(self):
19 return self
20 def next(self):
21 if self.i >= len(self.seqn): raise StopIteration
22 v = self.seqn[self.i]
23 self.i += 1
24 return v
25
26class Ig:
27 'Sequence using iterator protocol defined with a generator'
28 def __init__(self, seqn):
29 self.seqn = seqn
30 self.i = 0
31 def __iter__(self):
32 for val in self.seqn:
33 yield val
34
35class X:
36 'Missing __getitem__ and __iter__'
37 def __init__(self, seqn):
38 self.seqn = seqn
39 self.i = 0
40 def next(self):
41 if self.i >= len(self.seqn): raise StopIteration
42 v = self.seqn[self.i]
43 self.i += 1
44 return v
45
46class E:
47 'Test propagation of exceptions'
48 def __init__(self, seqn):
49 self.seqn = seqn
50 self.i = 0
51 def __iter__(self):
52 return self
53 def next(self):
54 3/0
55
56class N:
57 'Iterator missing next()'
58 def __init__(self, seqn):
59 self.seqn = seqn
60 self.i = 0
61 def __iter__(self):
62 return self
63
64class EnumerateTestCase(unittest.TestCase):
65
66 enum = enumerate
Raymond Hettingere8b0f042003-05-28 14:05:34 +000067 seq, res = 'abc', [(0,'a'), (1,'b'), (2,'c')]
Guido van Rossum7dab2422002-04-26 19:40:56 +000068
69 def test_basicfunction(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000070 self.assertEqual(type(self.enum(self.seq)), self.enum)
71 e = self.enum(self.seq)
Guido van Rossum7dab2422002-04-26 19:40:56 +000072 self.assertEqual(iter(e), e)
Raymond Hettingere8b0f042003-05-28 14:05:34 +000073 self.assertEqual(list(self.enum(self.seq)), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000074 self.enum.__doc__
75
76 def test_getitemseqn(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000077 self.assertEqual(list(self.enum(G(self.seq))), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000078 e = self.enum(G(''))
79 self.assertRaises(StopIteration, e.next)
80
81 def test_iteratorseqn(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000082 self.assertEqual(list(self.enum(I(self.seq))), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000083 e = self.enum(I(''))
84 self.assertRaises(StopIteration, e.next)
85
86 def test_iteratorgenerator(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000087 self.assertEqual(list(self.enum(Ig(self.seq))), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000088 e = self.enum(Ig(''))
89 self.assertRaises(StopIteration, e.next)
90
91 def test_noniterable(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000092 self.assertRaises(TypeError, self.enum, X(self.seq))
Guido van Rossum7dab2422002-04-26 19:40:56 +000093
94 def test_illformediterable(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000095 self.assertRaises(TypeError, list, self.enum(N(self.seq)))
Guido van Rossum7dab2422002-04-26 19:40:56 +000096
97 def test_exception_propagation(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000098 self.assertRaises(ZeroDivisionError, list, self.enum(E(self.seq)))
99
100 def test_argumentcheck(self):
101 self.assertRaises(TypeError, self.enum) # no arguments
102 self.assertRaises(TypeError, self.enum, 1) # wrong type (not iterable)
103 self.assertRaises(TypeError, self.enum, 'abc', 2) # too many arguments
104
105 def test_tuple_reuse(self):
106 # Tests an implementation detail where tuple is reused
107 # whenever nothing else holds a reference to it
Raymond Hettingerb25a52a2003-05-29 07:20:29 +0000108 self.assertEqual(len(Set(map(id, list(enumerate(self.seq))))), len(self.seq))
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000109 self.assertEqual(len(Set(map(id, enumerate(self.seq)))), min(1,len(self.seq)))
Guido van Rossum7dab2422002-04-26 19:40:56 +0000110
111class MyEnum(enumerate):
112 pass
113
114class SubclassTestCase(EnumerateTestCase):
115
116 enum = MyEnum
117
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000118class TestEmpty(EnumerateTestCase):
119
120 seq, res = '', []
121
122class TestBig(EnumerateTestCase):
123
124 seq = range(10,20000,2)
125 res = zip(range(20000), seq)
126
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000127class TestReversed(unittest.TestCase):
128
129 def test_simple(self):
130 class A:
131 def __getitem__(self, i):
132 if i < 5:
133 return str(i)
134 raise StopIteration
135 def __len__(self):
136 return 5
137 for data in 'abc', range(5), tuple(enumerate('abc')), A(), xrange(1,17,5):
138 self.assertEqual(list(data)[::-1], list(reversed(data)))
139 self.assertRaises(TypeError, reversed, {})
140
141 def test_xrange_optimization(self):
142 x = xrange(1)
143 self.assertEqual(type(reversed(x)), type(iter(x)))
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000144
145def test_main(verbose=None):
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000146 testclasses = (EnumerateTestCase, SubclassTestCase, TestEmpty, TestBig,
147 TestReversed)
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000148 test_support.run_unittest(*testclasses)
149
150 # verify reference counting
151 import sys
152 if verbose and hasattr(sys, "gettotalrefcount"):
153 counts = [None] * 5
154 for i in xrange(len(counts)):
155 test_support.run_unittest(*testclasses)
156 counts[i] = sys.gettotalrefcount()
157 print counts
Guido van Rossum7dab2422002-04-26 19:40:56 +0000158
159if __name__ == "__main__":
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000160 test_main(verbose=True)