[Checkins] SVN: zope.index/trunk/src/zope/index/keyword/ 100% coverage for zope.index.keyword.index module.
Tres Seaver
tseaver at palladion.com
Thu Jun 11 03:47:29 EDT 2009
Log message for revision 100844:
100% coverage for zope.index.keyword.index module.
Changed:
U zope.index/trunk/src/zope/index/keyword/index.py
U zope.index/trunk/src/zope/index/keyword/tests.py
-=-
Modified: zope.index/trunk/src/zope/index/keyword/index.py
===================================================================
--- zope.index/trunk/src/zope/index/keyword/index.py 2009-06-11 06:52:41 UTC (rev 100843)
+++ zope.index/trunk/src/zope/index/keyword/index.py 2009-06-11 07:47:28 UTC (rev 100844)
@@ -62,17 +62,17 @@
def normalize(self, seq):
"""Perform normalization on sequence of keywords.
-
+
Return normalized sequence. This method may be
overriden by subclasses.
-
+
"""
return seq
def index_doc(self, docid, seq):
if isinstance(seq, basestring):
raise TypeError('seq argument must be a list/tuple of strings')
-
+
if not seq:
return
@@ -93,12 +93,15 @@
# removed keywords are removed from the forward index
for word in kw_removed:
- self._fwd_index[word].remove(docid)
-
+ fwd = self._fwd_index[word]
+ fwd.remove(docid)
+ if len(fwd) == 0:
+ del self._fwd_index[word]
+
# now update reverse and forward indexes
self._insert_forward(docid, kw_added)
self._insert_reverse(docid, new_kw)
-
+
def unindex_doc(self, docid):
idx = self._fwd_index
@@ -106,14 +109,15 @@
for word in self._rev_index[docid]:
idx[word].remove(docid)
if not idx[word]:
- del idx[word]
+ del idx[word]
except KeyError:
+ msg = 'WAAA! Inconsistent'
return
-
+
try:
del self._rev_index[docid]
- except KeyError:
- pass
+ except KeyError: #pragma NO COVERAGE
+ msg = 'WAAA! Inconsistent'
self._num_docs.change(-1)
@@ -157,8 +161,9 @@
if not rs:
break
else:
- raise TypeError('Keyword index only supports `and` and `or` operators, not `%s`.' % operator)
-
+ raise TypeError('Keyword index only supports `and` and `or` '
+ 'operators, not `%s`.' % operator)
+
if rs:
return rs
else:
Modified: zope.index/trunk/src/zope/index/keyword/tests.py
===================================================================
--- zope.index/trunk/src/zope/index/keyword/tests.py 2009-06-11 06:52:41 UTC (rev 100843)
+++ zope.index/trunk/src/zope/index/keyword/tests.py 2009-06-11 07:47:28 UTC (rev 100844)
@@ -12,167 +12,370 @@
#
##############################################################################
-from unittest import TestCase, TestSuite, main, makeSuite
+import unittest
-import BTrees
+class _KeywordIndexTestsBase:
-from zope.index.keyword.index import CaseInsensitiveKeywordIndex
-from zope.index.interfaces import IInjection, IStatistics, IIndexSearch
-from zope.index.keyword.interfaces import IKeywordQuerying
-from zope.interface.verify import verifyClass
+ def _getTargetClass(self):
+ from zope.index.keyword.index import KeywordIndex
+ return KeywordIndex
-class KeywordIndexTest(TestCase):
+ def _populate(self, index):
- from BTrees.IFBTree import IFSet
+ index.index_doc(1, ('zope', 'CMF', 'Zope3'))
+ index.index_doc(2, ('the', 'quick', 'brown', 'FOX'))
+ index.index_doc(3, ('Zope',))
+ index.index_doc(4, ())
+ index.index_doc(5, ('cmf',))
- def setUp(self):
- self.index = CaseInsensitiveKeywordIndex()
+ _populated_doc_count = 4
+ _populated_word_count = 9
- def _populate_index(self):
+ def test_normalize(self):
+ index = self._makeOne()
+ self.assertEqual(index.normalize(['Foo']), ['Foo'])
- self.index.index_doc(1, ('zope', 'CMF', 'zope3', 'Zope3'))
- self.index.index_doc(2, ('the', 'quick', 'brown', 'FOX'))
- self.index.index_doc(3, ('Zope', 'zope'))
- self.index.index_doc(4, ())
- self.index.index_doc(5, ('cmf',))
+ def test_simplesearch(self):
+ index = self._makeOne()
+ self._populate(index)
+ self._search(index, [''], self.IFSet())
+ self._search(index, 'cmf', self.IFSet([5]))
+ self._search(index, ['cmf'], self.IFSet([5]))
+ self._search(index, ['Zope'], self.IFSet([3]))
+ self._search(index, ['Zope3'], self.IFSet([1]))
+ self._search(index, ['foo'], self.IFSet())
+ def test_search_and(self):
+ index = self._makeOne()
+ self._populate(index)
+ self._search_and(index, ('CMF', 'Zope3'), self.IFSet([1]))
+ self._search_and(index, ('CMF', 'zope'), self.IFSet([1]))
+ self._search_and(index, ('cmf', 'zope4'), self.IFSet())
+ self._search_and(index, ('quick', 'FOX'), self.IFSet([2]))
- def _search(self, query, expected, mode='and'):
- results = self.index.search(query, mode)
+ def test_search_or(self):
+ index = self._makeOne()
+ self._populate(index)
+ self._search_or(index, ('cmf', 'Zope3'), self.IFSet([1, 5]))
+ self._search_or(index, ('cmf', 'zope'), self.IFSet([1, 5]))
+ self._search_or(index, ('cmf', 'zope4'), self.IFSet([5]))
+ self._search_or(index, ('zope', 'Zope'), self.IFSet([1,3]))
+ def test_apply(self):
+ index = self._makeOne()
+ self._populate(index)
+ self._apply(index, ('CMF', 'Zope3'), self.IFSet([1]))
+ self._apply(index, ('CMF', 'zope'), self.IFSet([1]))
+ self._apply(index, ('cmf', 'zope4'), self.IFSet())
+ self._apply(index, ('quick', 'FOX'), self.IFSet([2]))
+
+ def test_apply_and(self):
+ index = self._makeOne()
+ self._populate(index)
+ self._apply_and(index, ('CMF', 'Zope3'), self.IFSet([1]))
+ self._apply_and(index, ('CMF', 'zope'), self.IFSet([1]))
+ self._apply_and(index, ('cmf', 'zope4'), self.IFSet())
+ self._apply_and(index, ('quick', 'FOX'), self.IFSet([2]))
+
+ def test_apply_or(self):
+ index = self._makeOne()
+ self._populate(index)
+ self._apply_or(index, ('cmf', 'Zope3'), self.IFSet([1, 5]))
+ self._apply_or(index, ('cmf', 'zope'), self.IFSet([1, 5]))
+ self._apply_or(index, ('cmf', 'zope4'), self.IFSet([5]))
+ self._apply_or(index, ('zope', 'Zope'), self.IFSet([1,3]))
+
+class CaseInsensitiveKeywordIndexTestsBase:
+
+ def _getTargetClass(self):
+ from zope.index.keyword.index import CaseInsensitiveKeywordIndex
+ return CaseInsensitiveKeywordIndex
+
+ def _populate(self, index):
+
+ index.index_doc(1, ('zope', 'CMF', 'zope3', 'Zope3'))
+ index.index_doc(2, ('the', 'quick', 'brown', 'FOX'))
+ index.index_doc(3, ('Zope', 'zope'))
+ index.index_doc(4, ())
+ index.index_doc(5, ('cmf',))
+
+ _populated_doc_count = 4
+ _populated_word_count = 7
+
+ def test_normalize(self):
+ index = self._makeOne()
+ self.assertEqual(index.normalize(['Foo']), ['foo'])
+
+ def test_simplesearch(self):
+ index = self._makeOne()
+ self._populate(index)
+ self._search(index, [''], self.IFSet())
+ self._search(index, 'cmf', self.IFSet([1, 5]))
+ self._search(index, ['cmf'], self.IFSet([1, 5]))
+ self._search(index, ['zope'], self.IFSet([1, 3]))
+ self._search(index, ['zope3'], self.IFSet([1]))
+ self._search(index, ['foo'], self.IFSet())
+
+ def test_search_and(self):
+ index = self._makeOne()
+ self._populate(index)
+ self._search_and(index, ('cmf', 'zope3'), self.IFSet([1]))
+ self._search_and(index, ('cmf', 'zope'), self.IFSet([1]))
+ self._search_and(index, ('cmf', 'zope4'), self.IFSet())
+ self._search_and(index, ('zope', 'ZOPE'), self.IFSet([1, 3]))
+
+ def test_search_or(self):
+ index = self._makeOne()
+ self._populate(index)
+ self._search_or(index, ('cmf', 'zope3'), self.IFSet([1, 5]))
+ self._search_or(index, ('cmf', 'zope'), self.IFSet([1, 3, 5]))
+ self._search_or(index, ('cmf', 'zope4'), self.IFSet([1, 5]))
+ self._search_or(index, ('zope', 'ZOPE'), self.IFSet([1,3]))
+
+ def test_apply(self):
+ index = self._makeOne()
+ self._populate(index)
+ self._apply(index, ('cmf', 'zope3'), self.IFSet([1]))
+ self._apply(index, ('cmf', 'zope'), self.IFSet([1]))
+ self._apply(index, ('cmf', 'zope4'), self.IFSet())
+ self._apply(index, ('zope', 'ZOPE'), self.IFSet([1, 3]))
+
+ def test_apply_and(self):
+ index = self._makeOne()
+ self._populate(index)
+ self._apply_and(index, ('cmf', 'zope3'), self.IFSet([1]))
+ self._apply_and(index, ('cmf', 'zope'), self.IFSet([1]))
+ self._apply_and(index, ('cmf', 'zope4'), self.IFSet())
+ self._apply_and(index, ('zope', 'ZOPE'), self.IFSet([1, 3]))
+
+ def test_apply_or(self):
+ index = self._makeOne()
+ self._populate(index)
+ self._apply_or(index, ('cmf', 'zope3'), self.IFSet([1, 5]))
+ self._apply_or(index, ('cmf', 'zope'), self.IFSet([1, 3, 5]))
+ self._apply_or(index, ('cmf', 'zope4'), self.IFSet([1, 5]))
+ self._apply_or(index, ('zope', 'ZOPE'), self.IFSet([1,3]))
+
+class _ThirtyTwoBitBase:
+
+ def _get_family(self):
+ import BTrees
+ return BTrees.family32
+
+ def IFSet(self, *args, **kw):
+ from BTrees.IFBTree import IFSet
+ return IFSet(*args, **kw)
+
+class _SixtyFourBitBase:
+
+ def _get_family(self):
+ import BTrees
+ return BTrees.family64
+
+ def IFSet(self, *args, **kw):
+ from BTrees.LFBTree import LFSet
+ return LFSet(*args, **kw)
+
+_marker = object()
+
+class _TestCaseBase:
+
+ def _makeOne(self, family=_marker):
+ if family is _marker:
+ return self._getTargetClass()(self._get_family())
+ return self._getTargetClass()(family)
+
+ def _search(self, index, query, expected, mode='and'):
+ results = index.search(query, mode)
+
# results and expected are IFSets() but we can not
# compare them directly since __eq__() does not seem
# to be implemented for BTrees
self.assertEqual(results.keys(), expected.keys())
- def _search_and(self, query, expected):
- return self._search(query, expected, 'and')
+ def _search_and(self, index, query, expected):
+ return self._search(index, query, expected, 'and')
- def _search_or(self, query, expected):
- return self._search(query, expected, 'or')
+ def _search_or(self, index, query, expected):
+ return self._search(index, query, expected, 'or')
- def _apply(self, query, expected, mode='and'):
- results = self.index.apply(query)
+ def _apply(self, index, query, expected, mode='and'):
+ results = index.apply(query)
self.assertEqual(results.keys(), expected.keys())
- def _apply_and(self, query, expected):
- results = self.index.apply({'operator': 'and', 'query': query})
+ def _apply_and(self, index, query, expected):
+ results = index.apply({'operator': 'and', 'query': query})
self.assertEqual(results.keys(), expected.keys())
- def _apply_or(self, query, expected):
- results = self.index.apply({'operator': 'or', 'query': query})
+ def _apply_or(self, index, query, expected):
+ results = index.apply({'operator': 'or', 'query': query})
self.assertEqual(results.keys(), expected.keys())
- def test_interface(self):
- verifyClass(IInjection, CaseInsensitiveKeywordIndex)
- verifyClass(IStatistics, CaseInsensitiveKeywordIndex)
- verifyClass(IIndexSearch, CaseInsensitiveKeywordIndex)
- verifyClass(IKeywordQuerying, CaseInsensitiveKeywordIndex)
+ def test_class_conforms_to_IInjection(self):
+ from zope.interface.verify import verifyClass
+ from zope.index.interfaces import IInjection
+ verifyClass(IInjection, self._getTargetClass())
+ def test_instance_conforms_to_IInjection(self):
+ from zope.interface.verify import verifyObject
+ from zope.index.interfaces import IInjection
+ verifyObject(IInjection, self._makeOne())
+
+ def test_class_conforms_to_IIndexSearch(self):
+ from zope.interface.verify import verifyClass
+ from zope.index.interfaces import IIndexSearch
+ verifyClass(IIndexSearch, self._getTargetClass())
+
+ def test_instance_conforms_to_IIndexSearch(self):
+ from zope.interface.verify import verifyObject
+ from zope.index.interfaces import IIndexSearch
+ verifyObject(IIndexSearch, self._makeOne())
+
+ def test_class_conforms_to_IStatistics(self):
+ from zope.interface.verify import verifyClass
+ from zope.index.interfaces import IStatistics
+ verifyClass(IStatistics, self._getTargetClass())
+
+ def test_instance_conforms_to_IStatistics(self):
+ from zope.interface.verify import verifyObject
+ from zope.index.interfaces import IStatistics
+ verifyObject(IStatistics, self._makeOne())
+
+ def test_class_conforms_to_IKeywordQuerying(self):
+ from zope.interface.verify import verifyClass
+ from zope.index.keyword.interfaces import IKeywordQuerying
+ verifyClass(IKeywordQuerying, self._getTargetClass())
+
+ def test_instance_conforms_to_IKeywordQuerying(self):
+ from zope.interface.verify import verifyObject
+ from zope.index.keyword.interfaces import IKeywordQuerying
+ verifyObject(IKeywordQuerying, self._makeOne())
+
+ def test_ctor_defaults(self):
+ index = self._makeOne()
+ self.failUnless(index.family is self._get_family())
+
+ def test_ctor_explicit_family(self):
+ import BTrees
+ index = self._makeOne(family=BTrees.family64)
+ self.failUnless(index.family is BTrees.family64)
+
def test_empty_index(self):
- self.assertEqual(self.index.documentCount(), 0)
- self.assertEqual(self.index.wordCount(), 0)
- self._populate_index()
- self.assertEqual(self.index.documentCount(), 4)
- self.assertEqual(self.index.wordCount(), 7)
- self.index.clear()
- self.assertEqual(self.index.documentCount(), 0)
- self.assertEqual(self.index.wordCount(), 0)
+ index = self._makeOne()
+ self.assertEqual(index.documentCount(), 0)
+ self.assertEqual(index.wordCount(), 0)
+ self.failIf(index.has_doc(1))
- def test_unindex(self):
- self._populate_index()
- self.assertEqual(self.index.documentCount(), 4)
- self.index.unindex_doc(1)
- self.index.unindex_doc(2)
- self.assertEqual(self.index.documentCount(), 2)
- self.index.unindex_doc(-99999) # no exception should be raised
- self.assertEqual(self.index.documentCount(), 2)
+ def test_index_doc_string_value_raises(self):
+ index = self._makeOne()
+ self.assertRaises(TypeError, index.index_doc, 1, 'albatross')
- def test_reindex(self):
- self._populate_index()
- self.assertEqual(self.index.documentCount(), 4)
- self.index.unindex_doc(1)
- self.index.unindex_doc(2)
- self.index.index_doc(1, ('foo', 'bar', 'doom'))
- self.index.index_doc(1, ('bar', 'blabla'))
- self.assertEqual(self.index.documentCount(), 3)
- self._search('quick', self.IFSet())
- self._search('foo', self.IFSet())
- self._search('bar', self.IFSet([1]))
- self._search(['doom'], self.IFSet())
- self._search(['blabla'], self.IFSet([1]))
- self._search_and(('bar', 'blabla'), self.IFSet([1]))
- self._search(['cmf'], self.IFSet([5]))
+ def test_index_doc_single(self):
+ index = self._makeOne()
+ index.index_doc(1, ('albatross', 'cormorant'))
+ self.assertEqual(index.documentCount(), 1)
+ self.assertEqual(index.wordCount(), 2)
+ self.failUnless(index.has_doc(1))
+ self.failUnless('albatross' in index._fwd_index)
+ self.failUnless('cormorant' in index._fwd_index)
- def test_hasdoc(self):
- self._populate_index()
- self.assertEqual(self.index.has_doc(1), 1)
- self.assertEqual(self.index.has_doc(2), 1)
- self.assertEqual(self.index.has_doc(3), 1)
- self.assertEqual(self.index.has_doc(4), 0)
- self.assertEqual(self.index.has_doc(5), 1)
- self.assertEqual(self.index.has_doc(6), 0)
+ def test_index_doc_existing(self):
+ index = self._makeOne()
+ index.index_doc(1, ('albatross', 'cormorant'))
+ index.index_doc(1, ('buzzard', 'cormorant'))
+ self.assertEqual(index.documentCount(), 1)
+ self.assertEqual(index.wordCount(), 2)
+ self.failUnless(index.has_doc(1))
+ self.failIf('albatross' in index._fwd_index)
+ self.failUnless('buzzard' in index._fwd_index)
+ self.failUnless('cormorant' in index._fwd_index)
- def test_simplesearch(self):
- self._populate_index()
- self._search([''], self.IFSet())
- self._search(['cmf'], self.IFSet([1, 5]))
- self._search(['zope'], self.IFSet([1, 3]))
- self._search(['zope3'], self.IFSet([1]))
- self._search(['foo'], self.IFSet())
+ def test_index_doc_many(self):
+ index = self._makeOne()
+ self._populate(index)
+ self.assertEqual(index.documentCount(), self._populated_doc_count)
+ self.assertEqual(index.wordCount(), self._populated_word_count)
+ for docid in range(1, 6):
+ if docid == 4:
+ self.failIf(index.has_doc(docid))
+ else:
+ self.failUnless(index.has_doc(docid))
- def test_search_and(self):
- self._populate_index()
- self._search_and(('cmf', 'zope3'), self.IFSet([1]))
- self._search_and(('cmf', 'zope'), self.IFSet([1]))
- self._search_and(('cmf', 'zope4'), self.IFSet())
- self._search_and(('zope', 'ZOPE'), self.IFSet([1, 3]))
+ def test_clear(self):
+ index = self._makeOne()
+ self._populate(index)
+ index.clear()
+ self.assertEqual(index.documentCount(), 0)
+ self.assertEqual(index.wordCount(), 0)
+ for docid in range(1, 6):
+ self.failIf(index.has_doc(docid))
- def test_search_or(self):
- self._populate_index()
- self._search_or(('cmf', 'zope3'), self.IFSet([1, 5]))
- self._search_or(('cmf', 'zope'), self.IFSet([1, 3, 5]))
- self._search_or(('cmf', 'zope4'), self.IFSet([1, 5]))
- self._search_or(('zope', 'ZOPE'), self.IFSet([1,3]))
+ def test_unindex_doc_missing(self):
+ index = self._makeOne()
+ index.unindex_doc(1) # doesn't raise
- def test_apply(self):
- self._populate_index()
- self._apply(('cmf', 'zope3'), self.IFSet([1]))
- self._apply(('cmf', 'zope'), self.IFSet([1]))
- self._apply(('cmf', 'zope4'), self.IFSet())
- self._apply(('zope', 'ZOPE'), self.IFSet([1, 3]))
+ def test_unindex_no_residue(self):
+ index = self._makeOne()
+ index.index_doc(1, ('albatross', ))
+ index.unindex_doc(1)
+ self.assertEqual(index.documentCount(), 0)
+ self.assertEqual(index.wordCount(), 0)
+ self.failIf(index.has_doc(1))
- def test_apply_and(self):
- self._populate_index()
- self._apply_and(('cmf', 'zope3'), self.IFSet([1]))
- self._apply_and(('cmf', 'zope'), self.IFSet([1]))
- self._apply_and(('cmf', 'zope4'), self.IFSet())
- self._apply_and(('zope', 'ZOPE'), self.IFSet([1, 3]))
+ def test_unindex_w_residue(self):
+ index = self._makeOne()
+ index.index_doc(1, ('albatross', ))
+ index.index_doc(2, ('albatross', 'cormorant'))
+ index.unindex_doc(1)
+ self.assertEqual(index.documentCount(), 1)
+ self.assertEqual(index.wordCount(), 2)
+ self.failIf(index.has_doc(1))
- def test_apply_or(self):
- self._populate_index()
- self._apply_or(('cmf', 'zope3'), self.IFSet([1, 5]))
- self._apply_or(('cmf', 'zope'), self.IFSet([1, 3, 5]))
- self._apply_or(('cmf', 'zope4'), self.IFSet([1, 5]))
- self._apply_or(('zope', 'ZOPE'), self.IFSet([1,3]))
+ def test_hasdoc(self):
+ index = self._makeOne()
+ self._populate(index)
+ self.assertEqual(index.has_doc(1), 1)
+ self.assertEqual(index.has_doc(2), 1)
+ self.assertEqual(index.has_doc(3), 1)
+ self.assertEqual(index.has_doc(4), 0)
+ self.assertEqual(index.has_doc(5), 1)
+ self.assertEqual(index.has_doc(6), 0)
- def test_index_input(self):
- self.assertRaises(
- TypeError, self.index.index_doc, 1, "non-sequence-string")
+ def test_search_bad_operator(self):
+ index = self._makeOne()
+ self.assertRaises(TypeError, index.search, 'whatever', 'maybe')
-class KeywordIndexTest64(KeywordIndexTest):
+class KeywordIndexTests32(_KeywordIndexTestsBase,
+ _ThirtyTwoBitBase,
+ _TestCaseBase,
+ unittest.TestCase):
+ pass
- from BTrees.LFBTree import LFSet as IFSet
+class CaseInsensitiveKeywordIndexTests32(CaseInsensitiveKeywordIndexTestsBase,
+ _ThirtyTwoBitBase,
+ _TestCaseBase,
+ unittest.TestCase):
+ pass
- def setUp(self):
- self.index = CaseInsensitiveKeywordIndex(family=BTrees.family64)
+class KeywordIndexTests64(_KeywordIndexTestsBase,
+ _SixtyFourBitBase,
+ _TestCaseBase,
+ unittest.TestCase):
+ pass
+class CaseInsensitiveKeywordIndexTests64(CaseInsensitiveKeywordIndexTestsBase,
+ _SixtyFourBitBase,
+ _TestCaseBase,
+ unittest.TestCase):
+ pass
+
+
def test_suite():
- return TestSuite((makeSuite(KeywordIndexTest),
- makeSuite(KeywordIndexTest64),
- ))
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
+ return unittest.TestSuite((
+ unittest.makeSuite(KeywordIndexTests32),
+ unittest.makeSuite(KeywordIndexTests64),
+ unittest.makeSuite(CaseInsensitiveKeywordIndexTests32),
+ unittest.makeSuite(CaseInsensitiveKeywordIndexTests64),
+ ))
More information about the Checkins
mailing list