############################################################################## # # Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (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. # ############################################################################## """TextIndex unit tests. $Id: testTextIndex.py 41217 2006-01-08 14:28:44Z andreasjung $ """ import unittest import Testing import Zope2 Zope2.startup() import ZODB from ZODB.MappingStorage import MappingStorage import transaction from Products.PluginIndexes.TextIndex import TextIndex from Products.PluginIndexes.TextIndex import GlobbingLexicon class Dummy: def __init__( self, text ): self._text = text def text( self ): return self._text def __str__( self ): return '' % self._text __repr__ = __str__ class Tests(unittest.TestCase): db = None jar = None def setUp(self): self.index=TextIndex.TextIndex('text') self.doc=Dummy(text='this is the time, when all good zopes') def dbopen(self): if self.db is None: s = MappingStorage() self.db = ZODB.DB(s) db = self.db if self.jar is not None: raise RuntimeError, 'test needs to dbclose() before dbopen()' jar = db.open() self.jar = jar if not jar.root().has_key('index'): jar.root()['index'] = TextIndex.TextIndex('text') transaction.commit() return jar.root()['index'] def dbclose(self): self.jar.close() self.jar = None def tearDown(self): transaction.abort() if self.jar is not None: self.dbclose() if self.db is not None: self.db.close() self.db = None def test_z3interfaces(self): from Products.PluginIndexes.interfaces import IPluggableIndex from Products.PluginIndexes.interfaces import ITextIndex from Products.PluginIndexes.TextIndex.TextIndex import TextIndex from zope.interface.verify import verifyClass verifyClass(IPluggableIndex, TextIndex) verifyClass(ITextIndex, TextIndex) def test_SimpleAddDelete(self): self.index.index_object(0, self.doc) self.index.index_object(1, self.doc) self.doc.text='spam is good, spam is fine, span span span' self.index.index_object(0, self.doc) self.index.unindex_object(0) def test_PersistentUpdate1(self): # Check simple persistent indexing index=self.dbopen() self.doc.text='this is the time, when all good zopes' index.index_object(0, self.doc) transaction.commit() self.doc.text='time waits for no one' index.index_object(1, self.doc) transaction.commit() self.dbclose() index=self.dbopen() r = index._apply_index({}) assert r==None r = index._apply_index({'text': 'python'}) assert len(r) == 2 and r[1]==('text',), 'incorrectly not used' assert not r[0], "should have no results" r = index._apply_index({'text': 'time'}) r=list(r[0].keys()) assert r == [0,1], r def test_PersistentUpdate2(self): # Check less simple persistent indexing index=self.dbopen() self.doc.text='this is the time, when all good zopes' index.index_object(0, self.doc) transaction.commit() self.doc.text='time waits for no one' index.index_object(1, self.doc) transaction.commit() self.doc.text='the next task is to test' index.index_object(3, self.doc) transaction.commit() self.doc.text='time time' index.index_object(2, self.doc) transaction.commit() self.dbclose() index=self.dbopen() r = index._apply_index({}) assert r==None r = index._apply_index({'text': 'python'}) assert len(r) == 2 and r[1]==('text',), 'incorrectly not used' assert not r[0], "should have no results" r = index._apply_index({'text': 'time'}) r=list(r[0].keys()) assert r == [0,1,2], r sample_texts = [ """This is the time for all good men to come to the aid of their country""", """ask not what your country can do for you, ask what you can do for your country""", """Man, I can't wait to get to Montross!""", """Zope Public License (ZPL) Version 1.0""", """Copyright (c) Digital Creations. All rights reserved.""", """This license has been certified as Open Source(tm).""", """I hope I get to work on time""", ] def globTest(self, qmap, rlist): "Check a glob query" index=self.dbopen() index._lexicon = GlobbingLexicon.GlobbingLexicon() for i in range(len(self.sample_texts)): self.doc.text=self.sample_texts[i] index.index_object(i, self.doc) transaction.commit() self.dbclose() index=self.dbopen() r = list(index._apply_index(qmap)[0].keys()) assert r == rlist, r return index._apply_index def test_StarQuery(self): self.globTest({'text':'m*n'}, [0,2]) def test_AndQuery(self): self.globTest({'text':'time and country'}, [0,]) def test_OrQuery(self): self.globTest({'text':'time or country'}, [0,1,6]) def test_DefaultOrQuery(self): self.globTest({'text':'time country'}, [0,1,6]) def test_NearQuery(self): # Check a NEAR query.. (NOTE:ACTUALLY AN 'AND' TEST!!) # NEAR never worked, so Zopes post-2.3.1b3 define near to mean AND self.globTest({'text':'time ... country'}, [0,]) def test_QuotesQuery(self): ai = self.globTest({'text':'"This is the time"'}, [0,]) r = list(ai({'text':'"now is the time"'})[0].keys()) assert r == [], r def test_AndNotQuery(self): self.globTest({'text':'time and not country'}, [6,]) def test_ParenMatchingQuery(self): ai = self.globTest({'text':'(time and country) men'}, [0,]) r = list(ai({'text':'(time and not country) or men'})[0].keys()) assert r == [0, 6], r def test_TextIndexOperatorQuery(self): self.globTest({'text': {'query': 'time men', 'operator':'and'}}, [0,]) def test_NonExistentWord(self): self.globTest({'text':'zop'}, []) def test_ComplexQuery1(self): self.globTest({'text':'((?ount* or get) and not wait) ' '"been *ert*"'}, [0, 1, 5, 6]) # same tests, unicode strings def test_StarQueryUnicode(self): self.globTest({'text':u'm*n'}, [0,2]) def test_AndQueryUnicode(self): self.globTest({'text':u'time and country'}, [0,]) def test_OrQueryUnicode(self): self.globTest({'text':u'time or country'}, [0,1,6]) def test_DefaultOrQueryUnicode(self): self.globTest({'text':u'time country'}, [0,1,6]) def test_NearQueryUnicode(self): # Check a NEAR query.. (NOTE:ACTUALLY AN 'AND' TEST!!) (unicode) # NEAR never worked, so Zopes post-2.3.1b3 define near to mean AND self.globTest({'text':u'time ... country'}, [0,]) def test_QuotesQueryUnicode(self): ai = self.globTest({'text':u'"This is the time"'}, [0,]) r = list(ai({'text':'"now is the time"'})[0].keys()) assert r == [], r def test_AndNotQueryUnicode(self): self.globTest({'text':u'time and not country'}, [6,]) def test_ParenMatchingQueryUnicode(self): ai = self.globTest({'text':u'(time and country) men'}, [0,]) r = list(ai({'text':u'(time and not country) or men'})[0].keys()) assert r == [0, 6], r def test_TextIndexOperatorQueryUnicode(self): self.globTest({'text': {u'query': u'time men', 'operator':'and'}}, [0,]) def test_NonExistentWordUnicode(self): self.globTest({'text':u'zop'}, []) def test_ComplexQuery1Unicode(self): self.globTest({'text':u'((?ount* or get) and not wait) ' '"been *ert*"'}, [0, 1, 5, 6]) def test_suite(): return unittest.makeSuite(Tests) if __name__=='__main__': unittest.main(defaultTest='test_suite')