8
8
class Iterators(unittest.TestCase):
9
one_to_100 = lambda s: iter(range(1, 101))
10
evens = lambda s: iter(range(2, 101, 2))
11
odds = lambda s: iter(range(1, 100, 2))
12
empty = lambda s: iter([])
14
def __init__(self, *args):
15
apply (unittest.TestCase.__init__, (self,) + args)
16
self.falseerror = self.falseerror_maker()
17
self.trueerror = self.trueerror_maker()
18
self.emptygen = self.emptygen_maker()
19
self.typeerror = self.typeerror_maker()
20
self.nameerror = self.nameerror_maker()
22
def falseerror_maker(self):
28
def trueerror_maker(self):
34
def nameerror_maker(self):
38
def typeerror_maker(self):
43
def alwayserror(self, x):
46
def emptygen_maker(self):
9
one_to_100 = lambda s: iter(range(1, 101))
10
evens = lambda s: iter(range(2, 101, 2))
11
odds = lambda s: iter(range(1, 100, 2))
12
empty = lambda s: iter([])
14
def __init__(self, *args):
15
apply (unittest.TestCase.__init__, (self,) + args)
16
self.falseerror = self.falseerror_maker()
17
self.trueerror = self.trueerror_maker()
18
self.emptygen = self.emptygen_maker()
19
self.typeerror = self.typeerror_maker()
20
self.nameerror = self.nameerror_maker()
22
def falseerror_maker(self):
28
def trueerror_maker(self):
34
def nameerror_maker(self):
38
def typeerror_maker(self):
43
def alwayserror(self, x):
46
def emptygen_maker(self):
50
50
class IterEqualTestCase(Iterators):
51
"""Tests for iter_equal function"""
53
"""Empty iterators should be equal"""
54
assert Iter.equal(self.empty(), iter([]))
57
"""See if normal iterators are equal"""
58
assert Iter.equal(iter((1,2,3)), iter((1,2,3)))
59
assert Iter.equal(self.odds(), iter(range(1, 100, 2)))
60
assert Iter.equal(iter((1,2,3)), iter(range(1, 4)))
62
def testNormalInequality(self):
63
"""See if normal unequals work"""
64
assert not Iter.equal(iter((1,2,3)), iter((1,2,4)))
65
assert not Iter.equal(self.odds(), iter(["hello", "there"]))
67
def testGenerators(self):
68
"""equals works for generators"""
75
assert Iter.equal(f(), g())
78
"""Differently sized iterators"""
79
assert not Iter.equal(iter((1,2,3)), iter((1,2)))
80
assert not Iter.equal(iter((1,2)), iter((1,2,3)))
51
"""Tests for iter_equal function"""
53
"""Empty iterators should be equal"""
54
assert Iter.equal(self.empty(), iter([]))
57
"""See if normal iterators are equal"""
58
assert Iter.equal(iter((1,2,3)), iter((1,2,3)))
59
assert Iter.equal(self.odds(), iter(range(1, 100, 2)))
60
assert Iter.equal(iter((1,2,3)), iter(range(1, 4)))
62
def testNormalInequality(self):
63
"""See if normal unequals work"""
64
assert not Iter.equal(iter((1,2,3)), iter((1,2,4)))
65
assert not Iter.equal(self.odds(), iter(["hello", "there"]))
67
def testGenerators(self):
68
"""equals works for generators"""
75
assert Iter.equal(f(), g())
78
"""Differently sized iterators"""
79
assert not Iter.equal(iter((1,2,3)), iter((1,2)))
80
assert not Iter.equal(iter((1,2)), iter((1,2,3)))
83
83
class FilterTestCase(Iterators):
84
"""Tests for lazy_filter function"""
86
"""empty iterators -> empty iterators"""
87
assert Iter.empty(Iter.filter(self.alwayserror,
89
"Filtering an empty iterator should result in empty iterator"
92
"""Test numbers 1 - 100 #1"""
93
assert Iter.equal(Iter.filter(lambda x: x % 2 == 0,
96
assert Iter.equal(Iter.filter(lambda x: x % 2,
101
"""Should raise appropriate error"""
102
i = Iter.filter(lambda x: x, self.falseerror_maker())
103
self.assertRaises(Exception, i.next)
84
"""Tests for lazy_filter function"""
86
"""empty iterators -> empty iterators"""
87
assert Iter.empty(Iter.filter(self.alwayserror,
89
"Filtering an empty iterator should result in empty iterator"
92
"""Test numbers 1 - 100 #1"""
93
assert Iter.equal(Iter.filter(lambda x: x % 2 == 0,
96
assert Iter.equal(Iter.filter(lambda x: x % 2,
101
"""Should raise appropriate error"""
102
i = Iter.filter(lambda x: x, self.falseerror_maker())
103
self.assertRaises(Exception, i.next)
106
106
class MapTestCase(Iterators):
107
"""Test mapping of iterators"""
108
def testNumbers(self):
109
"""1 to 100 * 2 = 2 to 200"""
110
assert Iter.equal(Iter.map(lambda x: 2*x, self.one_to_100()),
111
iter(range(2, 201, 2)))
113
def testShortcut(self):
114
"""Map should go in order"""
118
i = Iter.map(f, self.trueerror_maker())
120
self.assertRaises(NameError, i.next)
123
"""Map of an empty iterator is empty"""
124
assert Iter.empty(Iter.map(lambda x: x, iter([])))
107
"""Test mapping of iterators"""
108
def testNumbers(self):
109
"""1 to 100 * 2 = 2 to 200"""
110
assert Iter.equal(Iter.map(lambda x: 2*x, self.one_to_100()),
111
iter(range(2, 201, 2)))
113
def testShortcut(self):
114
"""Map should go in order"""
118
i = Iter.map(f, self.trueerror_maker())
120
self.assertRaises(NameError, i.next)
123
"""Map of an empty iterator is empty"""
124
assert Iter.empty(Iter.map(lambda x: x, iter([])))
127
127
class CatTestCase(Iterators):
128
"""Test concatenation of iterators"""
130
"""Empty + empty = empty"""
131
assert Iter.empty(Iter.cat(iter([]), iter([])))
133
def testNumbers(self):
134
"""1 to 50 + 51 to 100 = 1 to 100"""
135
assert Iter.equal(Iter.cat(iter(range(1, 51)), iter(range(51, 101))),
138
def testShortcut(self):
139
"""Process iterators in order"""
140
i = Iter.cat(self.typeerror_maker(), self.nameerror_maker())
143
self.assertRaises(TypeError, i.next)
128
"""Test concatenation of iterators"""
130
"""Empty + empty = empty"""
131
assert Iter.empty(Iter.cat(iter([]), iter([])))
133
def testNumbers(self):
134
"""1 to 50 + 51 to 100 = 1 to 100"""
135
assert Iter.equal(Iter.cat(iter(range(1, 51)), iter(range(51, 101))),
138
def testShortcut(self):
139
"""Process iterators in order"""
140
i = Iter.cat(self.typeerror_maker(), self.nameerror_maker())
143
self.assertRaises(TypeError, i.next)
146
146
class AndOrTestCase(Iterators):
147
"""Test And and Or"""
149
"""And() -> true, Or() -> false"""
150
assert Iter.And(self.empty())
151
assert not Iter.Or(self.empty())
153
def testAndShortcut(self):
154
"""And should return if any false"""
155
assert Iter.And(self.falseerror_maker()) is None
157
def testOrShortcut(self):
158
"""Or should return if any true"""
159
assert Iter.Or(self.trueerror_maker()) == 1
161
def testNormalAnd(self):
162
"""And should go through true iterators, picking last"""
163
assert Iter.And(iter([1,2,3,4])) == 4
164
self.assertRaises(Exception, Iter.And, self.trueerror_maker())
166
def testNormalOr(self):
167
"""Or goes through false iterators, picking last"""
168
assert Iter.Or(iter([0, None, []])) == []
169
self.assertRaises(Exception, Iter.Or, self.falseerror_maker())
147
"""Test And and Or"""
149
"""And() -> true, Or() -> false"""
150
assert Iter.And(self.empty())
151
assert not Iter.Or(self.empty())
153
def testAndShortcut(self):
154
"""And should return if any false"""
155
assert Iter.And(self.falseerror_maker()) is None
157
def testOrShortcut(self):
158
"""Or should return if any true"""
159
assert Iter.Or(self.trueerror_maker()) == 1
161
def testNormalAnd(self):
162
"""And should go through true iterators, picking last"""
163
assert Iter.And(iter([1,2,3,4])) == 4
164
self.assertRaises(Exception, Iter.And, self.trueerror_maker())
166
def testNormalOr(self):
167
"""Or goes through false iterators, picking last"""
168
assert Iter.Or(iter([0, None, []])) == []
169
self.assertRaises(Exception, Iter.Or, self.falseerror_maker())
172
172
class FoldingTest(Iterators):
173
"""Test folding operations"""
174
def f(self, x, y): return x + y
177
"""Folds of empty iterators should produce defaults"""
178
assert Iter.foldl(self.f, 23, self.empty()) == 23
179
assert Iter.foldr(self.f, 32, self.empty()) == 32
181
def testAddition(self):
182
"""Use folds to sum lists"""
183
assert Iter.foldl(self.f, 0, self.one_to_100()) == 5050
184
assert Iter.foldr(self.f, 0, self.one_to_100()) == 5050
186
def testLargeAddition(self):
187
"""Folds on 10000 element iterators"""
188
assert Iter.foldl(self.f, 0, iter(range(1, 10001))) == 50005000
189
self.assertRaises(RuntimeError,
190
Iter.foldr, self.f, 0, iter(range(1, 10001)))
193
"""Use folds to calculate length of lists"""
194
assert Iter.foldl(lambda x, y: x+1, 0, self.evens()) == 50
195
assert Iter.foldr(lambda x, y: y+1, 0, self.odds()) == 50
173
"""Test folding operations"""
174
def f(self, x, y): return x + y
177
"""Folds of empty iterators should produce defaults"""
178
assert Iter.foldl(self.f, 23, self.empty()) == 23
179
assert Iter.foldr(self.f, 32, self.empty()) == 32
181
def testAddition(self):
182
"""Use folds to sum lists"""
183
assert Iter.foldl(self.f, 0, self.one_to_100()) == 5050
184
assert Iter.foldr(self.f, 0, self.one_to_100()) == 5050
186
def testLargeAddition(self):
187
"""Folds on 10000 element iterators"""
188
assert Iter.foldl(self.f, 0, iter(range(1, 10001))) == 50005000
189
self.assertRaises(RuntimeError,
190
Iter.foldr, self.f, 0, iter(range(1, 10001)))
193
"""Use folds to calculate length of lists"""
194
assert Iter.foldl(lambda x, y: x+1, 0, self.evens()) == 50
195
assert Iter.foldr(lambda x, y: y+1, 0, self.odds()) == 50
197
197
class MultiplexTest(Iterators):
198
def testSingle(self):
199
"""Test multiplex single stream"""
200
i_orig = self.one_to_100()
201
i2_orig = self.one_to_100()
202
i = Iter.multiplex(i_orig, 1)[0]
203
assert Iter.equal(i, i2_orig)
205
def testTrible(self):
206
"""Test splitting iterator into three"""
208
def ff(x): counter[0] += 1
209
i_orig = self.one_to_100()
210
i2_orig = self.one_to_100()
211
i1, i2, i3 = Iter.multiplex(i_orig, 3, ff)
212
assert Iter.equal(i1, i2)
213
assert Iter.equal(i3, i2_orig)
214
assert counter[0] == 100, counter
216
def testDouble(self):
217
"""Test splitting into two..."""
218
i1, i2 = Iter.multiplex(self.one_to_100(), 2)
219
assert Iter.equal(i1, self.one_to_100())
220
assert Iter.equal(i2, self.one_to_100())
198
def testSingle(self):
199
"""Test multiplex single stream"""
200
i_orig = self.one_to_100()
201
i2_orig = self.one_to_100()
202
i = Iter.multiplex(i_orig, 1)[0]
203
assert Iter.equal(i, i2_orig)
205
def testTrible(self):
206
"""Test splitting iterator into three"""
208
def ff(x): counter[0] += 1
209
i_orig = self.one_to_100()
210
i2_orig = self.one_to_100()
211
i1, i2, i3 = Iter.multiplex(i_orig, 3, ff)
212
assert Iter.equal(i1, i2)
213
assert Iter.equal(i3, i2_orig)
214
assert counter[0] == 100, counter
216
def testDouble(self):
217
"""Test splitting into two..."""
218
i1, i2 = Iter.multiplex(self.one_to_100(), 2)
219
assert Iter.equal(i1, self.one_to_100())
220
assert Iter.equal(i2, self.one_to_100())
223
223
class ITRBadder(ITRBranch):
224
def start_process(self, index):
227
def end_process(self):
229
summand = self.base_index[-1]
230
#print "Adding ", summand
231
self.total += summand
233
def branch_process(self, subinstance):
234
#print "Adding subinstance ", subinstance.total
235
self.total += subinstance.total
224
def start_process(self, index):
227
def end_process(self):
229
summand = self.base_index[-1]
230
#print "Adding ", summand
231
self.total += summand
233
def branch_process(self, subinstance):
234
#print "Adding subinstance ", subinstance.total
235
self.total += subinstance.total
237
237
class ITRBadder2(ITRBranch):
238
def start_process(self, index):
241
def end_process(self):
242
#print "Adding ", self.base_index
243
self.total += reduce(lambda x,y: x+y, self.base_index, 0)
245
def can_fast_process(self, index):
246
if len(index) == 3: return 1
249
def fast_process(self, index):
250
self.total += index[0] + index[1] + index[2]
252
def branch_process(self, subinstance):
253
#print "Adding branch ", subinstance.total
254
self.total += subinstance.total
238
def start_process(self, index):
241
def end_process(self):
242
#print "Adding ", self.base_index
243
self.total += reduce(lambda x,y: x+y, self.base_index, 0)
245
def can_fast_process(self, index):
246
if len(index) == 3: return 1
249
def fast_process(self, index):
250
self.total += index[0] + index[1] + index[2]
252
def branch_process(self, subinstance):
253
#print "Adding branch ", subinstance.total
254
self.total += subinstance.total
256
256
class TreeReducerTest(unittest.TestCase):
258
self.i1 = [(), (1,), (2,), (3,)]
259
self.i2 = [(0,), (0,1), (0,1,0), (0,1,1), (0,2), (0,2,1), (0,3)]
261
self.i1a = [(), (1,)]
262
self.i1b = [(2,), (3,)]
263
self.i2a = [(0,), (0,1), (0,1,0)]
264
self.i2b = [(0,1,1), (0,2)]
265
self.i2c = [(0,2,1), (0,3)]
267
def testTreeReducer(self):
268
"""testing IterTreeReducer"""
269
itm = IterTreeReducer(ITRBadder, [])
270
for index in self.i1:
272
assert val, (val, index)
274
assert itm.root_branch.total == 6, itm.root_branch.total
276
itm2 = IterTreeReducer(ITRBadder2, [])
277
for index in self.i2:
279
if index == (): assert not val
282
assert itm2.root_branch.total == 12, itm2.root_branch.total
284
def testTreeReducerState(self):
285
"""Test saving and recreation of an IterTreeReducer"""
286
itm1a = IterTreeReducer(ITRBadder, [])
287
for index in self.i1a:
290
itm1b = pickle.loads(pickle.dumps(itm1a))
291
for index in self.i1b:
295
assert itm1b.root_branch.total == 6, itm1b.root_branch.total
297
itm2a = IterTreeReducer(ITRBadder2, [])
298
for index in self.i2a:
300
if index == (): assert not val
302
itm2b = pickle.loads(pickle.dumps(itm2a))
303
for index in self.i2b:
305
if index == (): assert not val
307
itm2c = pickle.loads(pickle.dumps(itm2b))
308
for index in self.i2c:
310
if index == (): assert not val
313
assert itm2c.root_branch.total == 12, itm2c.root_branch.total
258
self.i1 = [(), (1,), (2,), (3,)]
259
self.i2 = [(0,), (0,1), (0,1,0), (0,1,1), (0,2), (0,2,1), (0,3)]
261
self.i1a = [(), (1,)]
262
self.i1b = [(2,), (3,)]
263
self.i2a = [(0,), (0,1), (0,1,0)]
264
self.i2b = [(0,1,1), (0,2)]
265
self.i2c = [(0,2,1), (0,3)]
267
def testTreeReducer(self):
268
"""testing IterTreeReducer"""
269
itm = IterTreeReducer(ITRBadder, [])
270
for index in self.i1:
272
assert val, (val, index)
274
assert itm.root_branch.total == 6, itm.root_branch.total
276
itm2 = IterTreeReducer(ITRBadder2, [])
277
for index in self.i2:
279
if index == (): assert not val
282
assert itm2.root_branch.total == 12, itm2.root_branch.total
284
def testTreeReducerState(self):
285
"""Test saving and recreation of an IterTreeReducer"""
286
itm1a = IterTreeReducer(ITRBadder, [])
287
for index in self.i1a:
290
itm1b = pickle.loads(pickle.dumps(itm1a))
291
for index in self.i1b:
295
assert itm1b.root_branch.total == 6, itm1b.root_branch.total
297
itm2a = IterTreeReducer(ITRBadder2, [])
298
for index in self.i2a:
300
if index == (): assert not val
302
itm2b = pickle.loads(pickle.dumps(itm2a))
303
for index in self.i2b:
305
if index == (): assert not val
307
itm2c = pickle.loads(pickle.dumps(itm2b))
308
for index in self.i2c:
310
if index == (): assert not val
313
assert itm2c.root_branch.total == 12, itm2c.root_branch.total
316
316
if __name__ == "__main__":