Commit bd6b4347 authored by Martijn Pieters's avatar Martijn Pieters

- Add a tests for the Lazy module, giving reasonable coverage.

- Fix collector# 1384: calculate correct length even when all items in the
  LazyCat have been enumerated.
parent 8add2f04
......@@ -117,9 +117,12 @@ class LazyCat(Lazy):
try:
return self._len
except:
l = 0
for s in self._seq:
l += len(s)
try:
l = 0
for s in self._seq:
l += len(s)
except AttributeError:
l = len(self._data)
self._len = l
return l
......@@ -203,11 +206,9 @@ class LazyFilter(Lazy):
class LazyMop(Lazy):
# Act like a sequence, but get data from a filtering process.
# Don't access data until necessary. Only data for which test(data)
# returns true will be considered part of the set. Exceptions raised
# in the test method are ignored and treated like test(data) return a
# false value.
# Don't access data until necessary. If the filter raises an exception
# for a given item, then that item isn't included in the sequence.
def __init__(self, test, seq):
self._seq=seq
self._data=[]
......
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Unittests for Lazy sequence classes
$Id$"""
import unittest
class BaseSequenceTest(unittest.TestCase):
def _compare(self, lseq, seq):
self.assertEqual(len(lseq), len(seq))
self.assertEqual(list(lseq), seq)
class TestLazyCat(BaseSequenceTest):
def _createLSeq(self, *sequences):
from Products.ZCatalog.Lazy import LazyCat
return LazyCat(sequences)
def testEmpty(self):
lcat = self._createLSeq([])
self._compare(lcat, [])
def testSingleSequence(self):
seq = range(10)
lcat = self._createLSeq(seq)
self._compare(lcat, seq)
def testMultipleSequences(self):
from string import hexdigits, letters
seq1 = range(10)
seq2 = list(hexdigits)
seq3 = list(letters)
lcat = self._createLSeq(seq1, seq2, seq3)
self._compare(lcat, seq1 + seq2 + seq3)
def testNestedLazySequences(self):
from string import hexdigits, letters
seq1 = range(10)
seq2 = list(hexdigits)
seq3 = list(letters)
lcat = apply(self._createLSeq,
[self._createLSeq(seq) for seq in (seq1, seq2, seq3)])
self._compare(lcat, seq1 + seq2 + seq3)
def testSlicedSequences(self):
from string import hexdigits, letters
seq1 = range(10)
seq2 = list(hexdigits)
seq3 = list(letters)
lcat = apply(self._createLSeq,
[self._createLSeq(seq) for seq in (seq1, seq2, seq3)])
self._compare(lcat[5:-5], seq1[5:] + seq2 + seq3[:-5])
def testConsistentLength(self):
# Unaccessed length
lcat = self._createLSeq(range(10))
self.assertEqual(len(lcat), 10)
# Accessed in the middle
lcat = self._createLSeq(range(10))
lcat[4]
self.assertEqual(len(lcat), 10)
# Accessed after the lcat is accessed over the whole range
lcat = self._createLSeq(range(10))
lcat[:]
self.assertEqual(len(lcat), 10)
class TestLazyMap(TestLazyCat):
def _createLSeq(self, *seq):
return self._createLMap(lambda x: x, *seq)
def _createLMap(self, mapfunc, *seq):
from Products.ZCatalog.Lazy import LazyMap
totalseq = []
for s in seq:
totalseq.extend(s)
return LazyMap(mapfunc, totalseq)
def testMap(self):
from string import hexdigits, letters
seq1 = range(10)
seq2 = list(hexdigits)
seq3 = list(letters)
filter = lambda x: str(x).lower()
lmap = self._createLMap(filter, seq1, seq2, seq3)
self._compare(lmap, [str(x).lower() for x in (seq1 + seq2 + seq3)])
class TestLazyFilter(TestLazyCat):
def _createLSeq(self, *seq):
return self._createLFilter(lambda x: True, *seq)
def _createLFilter(self, filter, *seq):
from Products.ZCatalog.Lazy import LazyFilter
totalseq = []
for s in seq:
totalseq.extend(s)
return LazyFilter(filter, totalseq)
def testFilter(self):
from string import hexdigits, letters
seq1 = range(10)
seq2 = list(hexdigits)
seq3 = list(letters)
filter = lambda x: str(x).isalpha()
lmap = self._createLFilter(filter, seq1, seq2, seq3)
self._compare(lmap, seq2[10:] + seq3)
def testConsistentLengthWithFilter(self):
from string import letters
# Unaccessed length
lfilter = self._createLFilter(lambda x: x.islower(), list(letters))
self.assertEqual(len(lfilter), 26)
# Accessed in the middle
lfilter = self._createLFilter(lambda x: x.islower(), list(letters))
lfilter[13]
self.assertEqual(len(lfilter), 26)
# Accessed after the lcat is accessed over the whole range
lfilter = self._createLFilter(lambda x: x.islower(), list(letters))
lfilter[:]
self.assertEqual(len(lfilter), 26)
class TestLazyMop(TestLazyCat):
def _createLSeq(self, *seq):
return self._createLMop(lambda x: x, *seq)
def _createLMop(self, mapfunc, *seq):
from Products.ZCatalog.Lazy import LazyMop
totalseq = []
for s in seq:
totalseq.extend(s)
return LazyMop(mapfunc, totalseq)
def testMop(self):
from string import hexdigits, letters
seq1 = range(10)
seq2 = list(hexdigits)
seq3 = list(letters)
def filter(x):
if isinstance(x, int):
raise ValueError
return x.lower()
lmop = self._createLMop(filter, seq1, seq2, seq3)
self._compare(lmop, [str(x).lower() for x in (seq2 + seq3)])
def testConsistentLengthWithMop(self):
from string import letters
seq = range(10) + list(letters)
def filter(x):
if isinstance(x, int):
raise ValueError
return x.lower()
# Unaccessed length
lmop = self._createLMop(filter, seq)
self.assertEqual(len(lmop), 52)
# Accessed in the middle
lmop = self._createLMop(filter, seq)
lmop[26]
self.assertEqual(len(lmop), 52)
# Accessed after the lcat is accessed over the whole range
lmop = self._createLMop(filter, letters)
lmop[:]
self.assertEqual(len(lmop), 52)
class TestLazyValues(BaseSequenceTest):
def _createLValues(self, seq):
from Products.ZCatalog.Lazy import LazyValues
return LazyValues(seq)
def testEmpty(self):
lvals = self._createLValues([])
self._compare(lvals, [])
def testValues(self):
from string import letters
seq = zip(letters, range(10))
lvals = self._createLValues(seq)
self._compare(lvals, range(10))
def testSlice(self):
from string import letters
seq = zip(letters, range(10))
lvals = self._createLValues(seq)
self._compare(lvals[2:-2], range(2, 8))
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestLazyCat))
suite.addTest(unittest.makeSuite(TestLazyMap))
suite.addTest(unittest.makeSuite(TestLazyFilter))
suite.addTest(unittest.makeSuite(TestLazyMop))
suite.addTest(unittest.makeSuite(TestLazyValues))
return suite
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment