[Zope-Checkins]
SVN: Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/
reverting old state - latest EPI integration should have gone a
Andreas Jung
andreas at andreas-jung.com
Fri Apr 8 10:07:42 EDT 2005
Log message for revision 29911:
reverting old state - latest EPI integration should have gone a
branch but no to the trunk
Changed:
U Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/PathIndex.py
D Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/README.txt
D Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/tests/epitc.py
D Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/tests/testIndexedAttrs.py
D Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/tests/testPathIndex2.py
-=-
Modified: Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/PathIndex.py
===================================================================
--- Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/PathIndex.py 2005-04-08 13:55:31 UTC (rev 29910)
+++ Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/PathIndex.py 2005-04-08 14:07:42 UTC (rev 29911)
@@ -55,9 +55,9 @@
'help': ('PathIndex','PathIndex_Settings.stx')},
)
- query_options = ("query", "level", "operator", "depth", "navtree")
+ query_options = ("query", "level", "operator")
- def ___init__(self,id,caller=None):
+ def __init__(self,id,caller=None):
self.id = id
self.operators = ('or','and')
self.useOperator = 'or'
@@ -87,77 +87,10 @@
if level > self._depth:
self._depth = level
-
- def numObjects(self):
- """ return the number distinct values """
- return len(self._unindex)
-
- def indexSize(self):
- """ return the number of indexed objects"""
- return len(self)
-
- def __len__(self):
- return self._length()
-
- def hasUniqueValuesFor(self, name):
- """has unique values for column name"""
- return name == self.id
-
- def uniqueValues(self, name=None, withLength=0):
- """ needed to be consistent with the interface """
- return self._index.keys()
-
- def getEntryForObject(self, docid, default=_marker):
- """ Takes a document ID and returns all the information
- we have on that specific object.
- """
- try:
- return self._unindex[docid]
- except KeyError:
- # XXX Why is default ignored?
- return None
-
-
-
-
-
-
- def __init__(self, id, extra=None, caller=None):
- """ ExtendedPathIndex supports indexed_attrs """
- self.___init__( id, caller)
-
- def get(o, k, default):
- if isinstance(o, dict):
- return o.get(k, default)
- else:
- return getattr(o, k, default)
-
- attrs = get(extra, 'indexed_attrs', None)
- if attrs is None:
- return
- if isinstance(attrs, str):
- attrs = attrs.split(',')
- attrs = filter(None, [a.strip() for a in attrs])
-
- if attrs:
- # We only index the first attribute so snip off the rest
- self.indexed_attrs = tuple(attrs[:1])
-
def index_object(self, docid, obj ,threshold=100):
""" hook for (Z)Catalog """
- # PathIndex first checks for an attribute matching its id and
- # falls back to getPhysicalPath only when failing to get one.
- # The presence of 'indexed_attrs' overrides this behavior and
- # causes indexing of the custom attribute.
-
- attrs = getattr(self, 'indexed_attrs', None)
- if attrs:
- index = attrs[0]
- else:
- index = self.id
-
- f = getattr(obj, index, None)
+ f = getattr(obj, self.id, None)
if f is not None:
if safe_callable(f):
try:
@@ -167,7 +100,7 @@
else:
path = f
- if not isinstance(path, (str, tuple)):
+ if not isinstance(path, (StringType, TupleType)):
raise TypeError('path value must be string or tuple of strings')
else:
try:
@@ -175,25 +108,15 @@
except AttributeError:
return 0
- if isinstance(path, (list, tuple)):
+ if isinstance(path, (ListType, TupleType)):
path = '/'+ '/'.join(path[1:])
comps = filter(None, path.split('/'))
-
- # Make sure we reindex properly when path change
- if self._unindex.has_key(docid) and self._unindex.get(docid) != path:
- self.unindex_object(docid)
-
+
if not self._unindex.has_key(docid):
- if hasattr(self, '_migrate_length'):
- self._migrate_length()
self._length.change(1)
for i in range(len(comps)):
self.insertEntry(comps[i], docid, i)
-
- # Add terminator
- self.insertEntry(None, docid, len(comps)-1)
-
self._unindex[docid] = path
return 1
@@ -201,17 +124,15 @@
""" hook for (Z)Catalog """
if not self._unindex.has_key(docid):
- LOG.error('Attempt to unindex nonexistent document'
- ' with id %s' % docid)
+ LOG.error('Attempt to unindex nonexistent document with id %s'
+ % docid)
return
- # There is an assumption that paths start with /
- path = self._unindex[docid]
- if not path.startswith('/'):
- path = '/'+path
- comps = path.split('/')
+ comps = self._unindex[docid].split('/')
- def unindex(comp, level, docid=docid):
+ for level in range(len(comps[1:])):
+ comp = comps[level+1]
+
try:
self._index[comp][level].remove(docid)
@@ -221,26 +142,13 @@
if not self._index[comp]:
del self._index[comp]
except KeyError:
- LOG.error('Attempt to unindex document'
- ' with id %s failed' % docid)
- return
+ LOG.error('Attempt to unindex document with id %s failed'
+ % docid)
- for level in range(len(comps[1:])):
- comp = comps[level+1]
- unindex(comp, level)
-
- # Remove the terminator
- level = len(comps[1:])
- comp = None
- unindex(comp, level-1)
-
- if hasattr(self, '_migrate_length'):
- self._migrate_length()
-
self._length.change(-1)
del self._unindex[docid]
- def search(self, path, default_level=0, depth=-1, navtree=0):
+ def search(self, path, default_level=0):
"""
path is either a string representing a
relative URL or a part of a relative URL or
@@ -250,59 +158,30 @@
level < 0 not implemented yet
"""
- if isinstance(path, str):
- startlevel = default_level
+ if isinstance(path, StringType):
+ level = default_level
else:
- startlevel = int(path[1])
+ level = int(path[1])
path = path[0]
comps = filter(None, path.split('/'))
- # Make sure that we get depth = 1 if in navtree mode
- # unless specified otherwise
-
- if depth == -1:
- depth = 0 or navtree
-
if len(comps) == 0:
- if not depth and not navtree:
- return IISet(self._unindex.keys())
+ return IISet(self._unindex.keys())
- if startlevel >= 0:
+ if level >= 0:
+ results = []
+ for i in range(len(comps)):
+ comp = comps[i]
+ if not self._index.has_key(comp): return IISet()
+ if not self._index[comp].has_key(level+i): return IISet()
+ results.append( self._index[comp][level+i] )
- pathset = None # Same as pathindex
- navset = None # For collecting siblings along the way
- depthset = None # For limiting depth
+ res = results[0]
+ for i in range(1,len(results)):
+ res = intersection(res,results[i])
+ return res
- if navtree and depth and \
- self._index.has_key(None) and \
- self._index[None].has_key(startlevel):
- navset = self._index[None][startlevel]
-
- for level in range(startlevel, startlevel+len(comps) + depth):
- if level-startlevel < len(comps):
- comp = comps[level-startlevel]
- if not self._index.has_key(comp) or not self._index[comp].has_key(level):
- # Navtree is inverse, keep going even for nonexisting paths
- if navtree:
- pathset = IISet()
- else:
- return IISet()
- else:
- pathset = intersection(pathset, self._index[comp][level])
- if navtree and depth and \
- self._index.has_key(None) and \
- self._index[None].has_key(level+depth):
- navset = union(navset, intersection(pathset, self._index[None][level+depth]))
- if level-startlevel >= len(comps) or navtree:
- if self._index.has_key(None) and self._index[None].has_key(level):
- depthset = union(depthset, intersection(pathset, self._index[None][level]))
-
- if navtree:
- return union(depthset, navset) or IISet()
- else:
- return intersection(pathset,depthset) or IISet()
-
else:
results = IISet()
for level in range(0,self._depth + 1):
@@ -318,6 +197,17 @@
results = union(results,ids)
return results
+ def numObjects(self):
+ """ return the number distinct values """
+ return len(self._unindex)
+
+ def indexSize(self):
+ """ return the number of indexed objects"""
+ return len(self)
+
+ def __len__(self):
+ return self._length()
+
def _apply_index(self, request, cid=''):
""" hook for (Z)Catalog
'request' -- mapping type (usually {"path": "..." }
@@ -332,8 +222,6 @@
level = record.get("level",0)
operator = record.get('operator',self.useOperator).lower()
- depth = getattr(record, 'depth',-1) # Set to 0 or navtree in search - use getattr to get 0 value
- navtree = record.get('navtree',0)
# depending on the operator we use intersection of union
if operator == "or": set_func = union
@@ -341,7 +229,7 @@
res = None
for k in record.keys:
- rows = self.search(k,level, depth, navtree)
+ rows = self.search(k,level)
res = set_func(res,rows)
if res:
@@ -349,21 +237,32 @@
else:
return IISet(), (self.id,)
+ def hasUniqueValuesFor(self, name):
+ """has unique values for column name"""
+ return name == self.id
+
+ def uniqueValues(self, name=None, withLength=0):
+ """ needed to be consistent with the interface """
+ return self._index.keys()
+
def getIndexSourceNames(self):
""" return names of indexed attributes """
+ return ('getPhysicalPath', )
- # By default PathIndex advertises getPhysicalPath even
- # though the logic in index_object is different.
-
+ def getEntryForObject(self, docid, default=_marker):
+ """ Takes a document ID and returns all the information
+ we have on that specific object.
+ """
try:
- return tuple(self.indexed_attrs)
- except AttributeError:
- return ('getPhysicalPath',)
+ return self._unindex[docid]
+ except KeyError:
+ # XXX Why is default ignored?
+ return None
-
index_html = DTMLFile('dtml/index', globals())
manage_workspace = DTMLFile('dtml/managePathIndex', globals())
+
manage_addPathIndexForm = DTMLFile('dtml/addPathIndex', globals())
def manage_addPathIndex(self, id, REQUEST=None, RESPONSE=None, URL3=None):
Deleted: Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/README.txt
===================================================================
--- Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/README.txt 2005-04-08 13:55:31 UTC (rev 29910)
+++ Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/README.txt 2005-04-08 14:07:42 UTC (rev 29911)
@@ -1,34 +0,0 @@
-PathIndex by Zope Corporation +
-extensions by Plone Solutions (former ExtendedPathIndex)
-
- This is an index that supports depth limiting, and the ability to build a
- structure usable for navtrees and sitemaps. The actual navtree implementations
- are not (and should not) be in this Product, this is the index implementation
- only.
-
-Features
-
- - Can construct a site map with a single catalog query
-
- - Can construct a navigation tree with a single catalog query
-
-Usage:
-
- - catalog(path='some/path') - search for all objects below some/path
-
- - catalog(path={'query' : 'some/path', 'depth' : 2 ) - search for all
- objects below some/path but only down to a depth of 2
-
- - catalog(path={'query' : 'some/path', 'navtree' : 1 ) - search for all
- objects below some/path for rendering a navigation tree. This includes
- all objects below some/path up to a depth of 1 and all parent objects.
-
-Credits
-
- - Zope Corporation for the initial PathIndex code
-
- - Helge Tesdal from Plone Solutions for the ExtendedPathIndex implementation
-
-License
-
- This software is released under the ZPL license.
Deleted: Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/tests/epitc.py
===================================================================
--- Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/tests/epitc.py 2005-04-08 13:55:31 UTC (rev 29910)
+++ Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/tests/epitc.py 2005-04-08 14:07:42 UTC (rev 29911)
@@ -1,75 +0,0 @@
-from Testing import ZopeTestCase
-from Products.PluginIndexes.PathIndex.PathIndex import PathIndex
-
-
-class Dummy:
-
- meta_type="foo"
-
- def __init__(self, path):
- self.path = path
-
- def getPhysicalPath(self):
- return self.path.split('/')
-
- def __str__(self):
- return '<Dummy: %s>' % self.path
-
- __repr__ = __str__
-
-
-class PathIndexTestCase(ZopeTestCase.ZopeTestCase):
-
- def _setup(self):
- self._index = PathIndex( 'path' )
- self._values = {
- 1 : Dummy("/aa/aa/aa/1.html"),
- 2 : Dummy("/aa/aa/bb/2.html"),
- 3 : Dummy("/aa/aa/cc/3.html"),
- 4 : Dummy("/aa/bb/aa/4.html"),
- 5 : Dummy("/aa/bb/bb/5.html"),
- 6 : Dummy("/aa/bb/cc/6.html"),
- 7 : Dummy("/aa/cc/aa/7.html"),
- 8 : Dummy("/aa/cc/bb/8.html"),
- 9 : Dummy("/aa/cc/cc/9.html"),
- 10 : Dummy("/bb/aa/aa/10.html"),
- 11 : Dummy("/bb/aa/bb/11.html"),
- 12 : Dummy("/bb/aa/cc/12.html"),
- 13 : Dummy("/bb/bb/aa/13.html"),
- 14 : Dummy("/bb/bb/bb/14.html"),
- 15 : Dummy("/bb/bb/cc/15.html"),
- 16 : Dummy("/bb/cc/aa/16.html"),
- 17 : Dummy("/bb/cc/bb/17.html"),
- 18 : Dummy("/bb/cc/cc/18.html")
- }
-
- def _populateIndex(self):
- for k, v in self._values.items():
- self._index.index_object( k, v )
-
-
-class ExtendedPathIndexTestCase(PathIndexTestCase):
-
- def _setup(self):
- self._index = PathIndex( 'path' )
- self._values = {
- 1 : Dummy("/1.html"),
- 2 : Dummy("/aa/2.html"),
- 3 : Dummy("/aa/aa/3.html"),
- 4 : Dummy("/aa/aa/aa/4.html"),
- 5 : Dummy("/aa/bb/5.html"),
- 6 : Dummy("/aa/bb/aa/6.html"),
- 7 : Dummy("/aa/bb/bb/7.html"),
- 8 : Dummy("/aa"),
- 9 : Dummy("/aa/bb"),
- 10 : Dummy("/bb/10.html"),
- 11 : Dummy("/bb/bb/11.html"),
- 12 : Dummy("/bb/bb/bb/12.html"),
- 13 : Dummy("/bb/aa/13.html"),
- 14 : Dummy("/bb/aa/aa/14.html"),
- 15 : Dummy("/bb/bb/aa/15.html"),
- 16 : Dummy("/bb"),
- 17 : Dummy("/bb/bb"),
- 18 : Dummy("/bb/aa")
- }
-
Deleted: Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/tests/testIndexedAttrs.py
===================================================================
--- Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/tests/testIndexedAttrs.py 2005-04-08 13:55:31 UTC (rev 29910)
+++ Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/tests/testIndexedAttrs.py 2005-04-08 14:07:42 UTC (rev 29911)
@@ -1,159 +0,0 @@
-#
-# IndexedAttrs tests
-#
-
-import os, sys
-if __name__ == '__main__':
- execfile(os.path.join(sys.path[0], 'framework.py'))
-
-from Testing import ZopeTestCase
-
-
-from Products.ZCatalog.ZCatalog import ZCatalog
-from OFS.SimpleItem import SimpleItem
-
-
-class Record:
- def __init__(self, **kw):
- self.__dict__.update(kw)
-
-class Dummy(SimpleItem):
- def __init__(self, id):
- self.id = id
- def getCustomPath(self):
- return ('', 'custom', 'path')
- def getStringPath(self):
- return '/string/path'
-
-
-class TestIndexedAttrs(ZopeTestCase.ZopeTestCase):
-
- def afterSetUp(self):
- self.catalog = ZCatalog('catalog')
- self.folder._setObject('dummy', Dummy('dummy'))
- self.dummy = self.folder.dummy
- self.physical_path = '/'.join(self.dummy.getPhysicalPath())
- self.custom_path = '/'.join(self.dummy.getCustomPath())
- self.string_path = self.dummy.getStringPath()
-
- def addIndex(self, id='path', extra=None):
- self.catalog.addIndex(id, 'PathIndex', extra)
- return self.catalog.Indexes[id]
-
- def testAddIndex(self):
- self.catalog.addIndex('path', 'PathIndex')
- try:
- self.catalog.Indexes['path']
- except KeyError:
- self.fail('Failed to create index')
-
- def testDefaultIndexedAttrs(self):
- # By default we don't have indexed_attrs at all
- idx = self.addIndex()
- self.failIf(hasattr(idx, 'indexed_attrs'))
-
- def testDefaultIndexSourceNames(self):
- # However, getIndexSourceName returns 'getPhysicalPath'
- idx = self.addIndex()
- self.assertEqual(idx.getIndexSourceNames(), ('getPhysicalPath',))
-
- def testDefaultIndexObject(self):
- # By default PathIndex indexes getPhysicalPath
- idx = self.addIndex()
- idx.index_object(123, self.dummy)
- self.assertEqual(idx.getEntryForObject(123), self.physical_path)
-
- def testDefaultSearchObject(self):
- # We can find the object in the catalog by physical path
- self.addIndex()
- self.catalog.catalog_object(self.dummy)
- self.assertEqual(len(self.catalog(path=self.physical_path)), 1)
-
- def testDefaultSearchDictSyntax(self):
- # PathIndex supports dictionary syntax for queries
- self.addIndex()
- self.catalog.catalog_object(self.dummy)
- self.assertEqual(len(self.catalog(path={'query': self.physical_path})), 1)
-
- def testExtraAsRecord(self):
- # 'extra' can be a record type object
- idx = self.addIndex(extra=Record(indexed_attrs='getCustomPath'))
- self.assertEqual(idx.indexed_attrs, ('getCustomPath',))
-
- def testExtraAsMapping(self):
- # or a dictionary
- idx = self.addIndex(extra={'indexed_attrs': 'getCustomPath'})
- self.assertEqual(idx.indexed_attrs, ('getCustomPath',))
-
- def testCustomIndexSourceNames(self):
- # getIndexSourceName returns the indexed_attrs
- idx = self.addIndex(extra={'indexed_attrs': 'getCustomPath'})
- self.assertEqual(idx.getIndexSourceNames(), ('getCustomPath',))
-
- def testCustomIndexObject(self):
- # PathIndex indexes getCustomPath
- idx = self.addIndex(extra={'indexed_attrs': 'getCustomPath'})
- idx.index_object(123, self.dummy)
- self.assertEqual(idx.getEntryForObject(123), self.custom_path)
-
- def testCustomSearchObject(self):
- # We can find the object in the catalog by custom path
- self.addIndex(extra={'indexed_attrs': 'getCustomPath'})
- self.catalog.catalog_object(self.dummy)
- self.assertEqual(len(self.catalog(path=self.custom_path)), 1)
-
- def testStringIndexObject(self):
- # PathIndex accepts a path as tuple or string
- idx = self.addIndex(extra={'indexed_attrs': 'getStringPath'})
- idx.index_object(123, self.dummy)
- self.assertEqual(idx.getEntryForObject(123), self.string_path)
-
- def testStringSearchObject(self):
- # And we can find the object in the catalog again
- self.addIndex(extra={'indexed_attrs': 'getStringPath'})
- self.catalog.catalog_object(self.dummy)
- self.assertEqual(len(self.catalog(path=self.string_path)), 1)
-
- def testIdIndexObject(self):
- # PathIndex prefers an attribute matching its id over getPhysicalPath
- idx = self.addIndex(id='getId')
- idx.index_object(123, self.dummy)
- self.assertEqual(idx.getEntryForObject(123), 'dummy')
-
- def testIdIndexObject(self):
- # Using indexed_attr overrides this behavior
- idx = self.addIndex(id='getId', extra={'indexed_attrs': 'getCustomPath'})
- idx.index_object(123, self.dummy)
- self.assertEqual(idx.getEntryForObject(123), self.custom_path)
-
- def testListIndexedAttr(self):
- # indexed_attrs can be a list
- idx = self.addIndex(id='getId', extra={'indexed_attrs': ['getCustomPath', 'foo']})
- # only the first attribute is used
- self.assertEqual(idx.getIndexSourceNames(), ('getCustomPath',))
-
- def testStringIndexedAttr(self):
- # indexed_attrs can also be a comma separated string
- idx = self.addIndex(id='getId', extra={'indexed_attrs': 'getCustomPath, foo'})
- # only the first attribute is used
- self.assertEqual(idx.getIndexSourceNames(), ('getCustomPath',))
-
- def testEmtpyListAttr(self):
- # Empty indexed_attrs falls back to defaults
- idx = self.addIndex(extra={'indexed_attrs': []})
- self.assertEqual(idx.getIndexSourceNames(), ('getPhysicalPath',))
-
- def testEmtpyStringAttr(self):
- # Empty indexed_attrs falls back to defaults
- idx = self.addIndex(extra={'indexed_attrs': ''})
- self.assertEqual(idx.getIndexSourceNames(), ('getPhysicalPath',))
-
-
-def test_suite():
- from unittest import TestSuite, makeSuite
- suite = TestSuite()
- suite.addTest(makeSuite(TestIndexedAttrs))
- return suite
-
-if __name__ == '__main__':
- framework()
Deleted: Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/tests/testPathIndex2.py
===================================================================
--- Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/tests/testPathIndex2.py 2005-04-08 13:55:31 UTC (rev 29910)
+++ Zope/trunk/lib/python/Products/PluginIndexes/PathIndex/tests/testPathIndex2.py 2005-04-08 14:07:42 UTC (rev 29911)
@@ -1,253 +0,0 @@
-# Copyright (c) 2004 Zope Corporation and Plone Solutions
-# BSD license
-
-import os, sys
-if __name__ == '__main__':
- execfile(os.path.join(sys.path[0], 'framework.py'))
-
-from Products.PluginIndexes.PathIndex.tests import epitc
-
-class TestPathIndex(epitc.PathIndexTestCase):
- """ Test ExtendedPathIndex objects """
-
- def testEmpty(self):
- self.assertEqual(self._index.numObjects() ,0)
- self.assertEqual(self._index.getEntryForObject(1234), None)
- self._index.unindex_object( 1234 ) # nothrow
- self.assertEqual(self._index._apply_index({"suxpath": "xxx"}), None)
-
- def testUnIndex(self):
- self._populateIndex()
- self.assertEqual(self._index.numObjects(), 18)
-
- for k in self._values.keys():
- self._index.unindex_object(k)
-
- self.assertEqual(self._index.numObjects(), 0)
- self.assertEqual(len(self._index._index), 0)
- self.assertEqual(len(self._index._unindex), 0)
-
- def testReindex(self):
- self._populateIndex()
- self.assertEqual(self._index.numObjects(), 18)
-
- o = epitc.Dummy('/foo/bar')
- self._index.index_object(19, o)
- self.assertEqual(self._index.numObjects(), 19)
- self._index.index_object(19, o)
- self.assertEqual(self._index.numObjects(), 19)
-
- def testUnIndexError(self):
- self._populateIndex()
- # this should not raise an error
- self._index.unindex_object(-1)
-
- # nor should this
- self._index._unindex[1] = "/broken/thing"
- self._index.unindex_object(1)
-
- def testRoot_1(self):
- self._populateIndex()
- tests = ( ("/", 0, range(1,19)), )
-
- for comp, level, results in tests:
- for path in [comp, "/"+comp, "/"+comp+"/"]:
- res = self._index._apply_index(
- {"path": {'query': path, "level": level}})
- lst = list(res[0].keys())
- self.assertEqual(lst, results)
-
- for comp, level, results in tests:
- for path in [comp, "/"+comp, "/"+comp+"/"]:
- res = self._index._apply_index(
- {"path": {'query': ((path, level),)}})
- lst = list(res[0].keys())
- self.assertEqual(lst, results)
-
- def testRoot_2(self):
- self._populateIndex()
- tests = ( ("/", 0, range(1,19)), )
-
- for comp,level,results in tests:
- for path in [comp, "/"+comp, "/"+comp+"/"]:
- res = self._index._apply_index(
- {"path": {'query': path, "level": level}})
- lst = list(res[0].keys())
- self.assertEqual(lst, results)
-
- for comp, level, results in tests:
- for path in [comp, "/"+comp, "/"+comp+"/"]:
- res = self._index._apply_index(
- {"path": {'query': ((path, level),)}})
- lst = list(res[0].keys())
- self.assertEqual(lst, results)
-
- def testSimpleTests(self):
- self._populateIndex()
- tests = [
- ("aa", 0, [1,2,3,4,5,6,7,8,9]),
- ("aa", 1, [1,2,3,10,11,12] ),
- ("bb", 0, [10,11,12,13,14,15,16,17,18]),
- ("bb", 1, [4,5,6,13,14,15]),
- ("bb/cc", 0, [16,17,18]),
- ("bb/cc", 1, [6,15]),
- ("bb/aa", 0, [10,11,12]),
- ("bb/aa", 1, [4,13]),
- ("aa/cc", -1, [3,7,8,9,12]),
- ("bb/bb", -1, [5,13,14,15]),
- ("18.html", 3, [18]),
- ("18.html", -1, [18]),
- ("cc/18.html", -1, [18]),
- ("cc/18.html", 2, [18]),
- ]
-
- for comp, level, results in tests:
- for path in [comp, "/"+comp, "/"+comp+"/"]:
- res = self._index._apply_index(
- {"path": {'query': path, "level": level}})
- lst = list(res[0].keys())
- self.assertEqual(lst, results)
-
- for comp, level, results in tests:
- for path in [comp, "/"+comp, "/"+comp+"/"]:
- res = self._index._apply_index(
- {"path": {'query': ((path, level),)}})
- lst = list(res[0].keys())
- self.assertEqual(lst, results)
-
- def testComplexOrTests(self):
- self._populateIndex()
- tests = [
- (['aa','bb'], 1, [1,2,3,4,5,6,10,11,12,13,14,15]),
- (['aa','bb','xx'], 1, [1,2,3,4,5,6,10,11,12,13,14,15]),
- ([('cc',1), ('cc',2)], 0, [3,6,7,8,9,12,15,16,17,18]),
- ]
-
- for lst, level, results in tests:
- res = self._index._apply_index(
- {"path": {'query': lst, "level": level, "operator": "or"}})
- lst = list(res[0].keys())
- self.assertEqual(lst, results)
-
- def testComplexANDTests(self):
- self._populateIndex()
- tests = [
- (['aa','bb'], 1, []),
- ([('aa',0), ('bb',1)], 0, [4,5,6]),
- ([('aa',0), ('cc',2)], 0, [3,6,9]),
- ]
-
- for lst, level, results in tests:
- res = self._index._apply_index(
- {"path": {'query': lst, "level": level, "operator": "and"}})
- lst = list(res[0].keys())
- self.assertEqual(lst, results)
-
-
-class TestExtendedPathIndex(epitc.ExtendedPathIndexTestCase):
- """ Test ExtendedPathIndex objects """
-
- def testIndexIntegrity(self):
- self._populateIndex()
- index = self._index._index
- self.assertEqual(list(index[None][0].keys()), [1,8,16])
- self.assertEqual(list(index[None][1].keys()), [2,9,10,17,18])
- self.assertEqual(list(index[None][2].keys()), [3,5,11,13])
- self.assertEqual(list(index[None][3].keys()), [4,6,7,12,14,15])
-
- def testUnIndexError(self):
- self._populateIndex()
- # this should not raise an error
- self._index.unindex_object(-1)
-
- # nor should this
- self._index._unindex[1] = "/broken/thing"
- self._index.unindex_object(1)
-
- def testDepthLimit(self):
- self._populateIndex()
- tests = [
- ('/', 0, 1, 0, [1,8,16]),
- ('/', 0, 2, 0, [1,2,8,9,10,16,17,18]),
- ('/', 0, 3, 0, [1,2,3,5,8,9,10,11,13,16,17,18]),
- ]
-
- for lst, level, depth, navtree, results in tests:
- res = self._index._apply_index(
- {"path": {'query': lst, "level": level, "depth": depth, "navtree": navtree}})
- lst = list(res[0].keys())
- self.assertEqual(lst, results)
-
- def testDefaultNavtree(self):
- self._populateIndex()
- # depth = 1 by default when using navtree
- tests = [
- ('/' ,0,1,1,[1,8,16]),
- ('/aa' ,0,1,1,[1,2,8,9,16]),
- ('/aa' ,1,1,1,[2,3,9,10,13,17,18]),
- ('/aa/aa' ,0,1,1,[1,2,3,8,9,16]),
- ('/aa/aa/aa',0,1,1,[1,2,3,4,8,9,16]),
- ('/aa/bb' ,0,1,1,[1,2,5,8,9,16]),
- ('/bb' ,0,1,1,[1,8,10,16,17,18]),
- ('/bb/aa' ,0,1,1,[1,8,10,13,16,17,18]),
- ('/bb/bb' ,0,1,1,[1,8,10,11,16,17,18]),
- ]
- for lst, level, depth, navtree, results in tests:
- res = self._index._apply_index(
- {"path": {'query': lst, "level": level, "depth": depth, "navtree": navtree}})
- lst = list(res[0].keys())
- self.assertEqual(lst,results)
-
- def testShallowNavtree(self):
- self._populateIndex()
- # With depth 0 we only get the parents
- tests = [
- ('/' ,0,0,1,[]),
- ('/aa' ,0,0,1,[8]),
- ('/aa' ,1,0,1,[18]),
- ('/aa/aa' ,0,0,1,[8]),
- ('/aa/aa/aa',0,0,1,[8]),
- ('/aa/bb' ,0,0,1,[8,9]),
- ('/bb' ,0,0,1,[16]),
- ('/bb/aa' ,0,0,1,[16,18]),
- ('/bb/bb' ,0,0,1,[16,17]),
- ('/bb/bb/aa' ,0,0,1,[16,17]),
- ]
- for lst, level, depth, navtree, results in tests:
- res = self._index._apply_index(
- {"path": {'query': lst, "level": level, "depth": depth, "navtree": navtree}})
- lst = list(res[0].keys())
- self.assertEqual(lst,results)
-
- def testNonexistingPaths(self):
- self._populateIndex()
- # With depth 0 we only get the parents
- # When getting non existing paths,
- # we should get as many parents as possible when building navtree
- tests = [
- ('/' ,0,0,1,[]),
- ('/aa' ,0,0,1,[8]), # Exists
- ('/aa/x' ,0,0,1,[8]), # Doesn't exist
- ('/aa' ,1,0,1,[18]),
- ('/aa/x' ,1,0,1,[18]),
- ('/aa/aa' ,0,0,1,[8]),
- ('/aa/aa/x' ,0,0,1,[8]),
- ('/aa/bb' ,0,0,1,[8,9]),
- ('/aa/bb/x' ,0,0,1,[8,9]),
- ]
- for lst, level, depth, navtree, results in tests:
- res = self._index._apply_index(
- {"path": {'query': lst, "level": level, "depth": depth, "navtree": navtree}})
- lst = list(res[0].keys())
- self.assertEqual(lst,results)
-
-
-def test_suite():
- from unittest import TestSuite, makeSuite
- suite = TestSuite()
- suite.addTest(makeSuite(TestPathIndex))
- suite.addTest(makeSuite(TestExtendedPathIndex))
- return suite
-
-if __name__ == '__main__':
- framework()
More information about the Zope-Checkins
mailing list