Back to index

plone3  3.1.7
testExtendedPathIndex.py
Go to the documentation of this file.
00001 # Copyright (c) 2004 Zope Corporation and Plone Solutions
00002 # ZPL 2.1 license
00003 
00004 import os, sys
00005 if __name__ == '__main__':
00006     execfile(os.path.join(sys.path[0], 'framework.py'))
00007 
00008 from Testing import ZopeTestCase
00009 from Products.ExtendedPathIndex.tests import epitc
00010 from Products.ExtendedPathIndex.ExtendedPathIndex import ExtendedPathIndex
00011 
00012 
00013 class TestPathIndex(epitc.PathIndexTestCase):
00014     """ Test ExtendedPathIndex objects """
00015 
00016     def testEmpty(self):
00017         self.assertEqual(self._index.numObjects() ,0)
00018         self.assertEqual(self._index.getEntryForObject(1234), None)
00019         self._index.unindex_object( 1234 ) # nothrow
00020         self.assertEqual(self._index._apply_index({"suxpath": "xxx"}), None)
00021 
00022     def testUnIndex(self):
00023         self._populateIndex()
00024         self.assertEqual(self._index.numObjects(), 18)
00025 
00026         for k in self._values.keys():
00027             self._index.unindex_object(k)
00028 
00029         self.assertEqual(self._index.numObjects(), 0)
00030         self.assertEqual(len(self._index._index), 0)
00031         self.assertEqual(len(self._index._unindex), 0)
00032 
00033     def testReindex(self):
00034         self._populateIndex()
00035         self.assertEqual(self._index.numObjects(), 18)
00036 
00037         o = epitc.Dummy('/foo/bar')
00038         self._index.index_object(19, o)
00039         self.assertEqual(self._index.numObjects(), 19)
00040         self._index.index_object(19, o)
00041         self.assertEqual(self._index.numObjects(), 19)
00042 
00043     def testUnIndexError(self):
00044         self._populateIndex()
00045         # this should not raise an error
00046         self._index.unindex_object(-1)
00047 
00048         # nor should this
00049         self._index._unindex[1] = "/broken/thing"
00050         self._index.unindex_object(1)
00051 
00052     def testRoot_1(self):
00053         self._populateIndex()
00054         tests = ( ("/", 0, range(1,19)), )
00055 
00056         for comp, level, results in tests:
00057             for path in [comp, "/"+comp, "/"+comp+"/"]:
00058                 res = self._index._apply_index(
00059                                     {"path": {'query': path, "level": level}})
00060                 lst = list(res[0].keys())
00061                 self.assertEqual(lst, results)
00062 
00063         for comp, level, results in tests:
00064             for path in [comp, "/"+comp, "/"+comp+"/"]:
00065                 res = self._index._apply_index(
00066                                     {"path": {'query': ((path, level),)}})
00067                 lst = list(res[0].keys())
00068                 self.assertEqual(lst, results)
00069 
00070     def testRoot_2(self):
00071         self._populateIndex()
00072         tests = ( ("/", 0, range(1,19)), )
00073 
00074         for comp,level,results in tests:
00075             for path in [comp, "/"+comp, "/"+comp+"/"]:
00076                 res = self._index._apply_index(
00077                                     {"path": {'query': path, "level": level}})
00078                 lst = list(res[0].keys())
00079                 self.assertEqual(lst, results)
00080 
00081         for comp, level, results in tests:
00082             for path in [comp, "/"+comp, "/"+comp+"/"]:
00083                 res = self._index._apply_index(
00084                                     {"path": {'query': ((path, level),)}})
00085                 lst = list(res[0].keys())
00086                 self.assertEqual(lst, results)
00087 
00088     def testSimpleTests(self):
00089         self._populateIndex()
00090         tests = [
00091             ("aa", 0, [1,2,3,4,5,6,7,8,9]),
00092             ("aa", 1, [1,2,3,10,11,12] ),
00093             ("bb", 0, [10,11,12,13,14,15,16,17,18]),
00094             ("bb", 1, [4,5,6,13,14,15]),
00095             ("bb/cc", 0, [16,17,18]),
00096             ("bb/cc", 1, [6,15]),
00097             ("bb/aa", 0, [10,11,12]),
00098             ("bb/aa", 1, [4,13]),
00099             ("aa/cc", -1, [3,7,8,9,12]),
00100             ("bb/bb", -1, [5,13,14,15]),
00101             ("18.html", 3, [18]),
00102             ("18.html", -1, [18]),
00103             ("cc/18.html", -1, [18]),
00104             ("cc/18.html", 2, [18]),
00105         ]
00106 
00107         for comp, level, results in tests:
00108             for path in [comp, "/"+comp, "/"+comp+"/"]:
00109                 res = self._index._apply_index(
00110                                     {"path": {'query': path, "level": level}})
00111                 lst = list(res[0].keys())
00112                 self.assertEqual(lst, results)
00113 
00114         for comp, level, results in tests:
00115             for path in [comp, "/"+comp, "/"+comp+"/"]:
00116                 res = self._index._apply_index(
00117                                     {"path": {'query': ((path, level),)}})
00118                 lst = list(res[0].keys())
00119                 self.assertEqual(lst, results)
00120 
00121     def testComplexOrTests(self):
00122         self._populateIndex()
00123         tests = [
00124             (['aa','bb'], 1, [1,2,3,4,5,6,10,11,12,13,14,15]),
00125             (['aa','bb','xx'], 1, [1,2,3,4,5,6,10,11,12,13,14,15]),
00126             ([('cc',1), ('cc',2)], 0, [3,6,7,8,9,12,15,16,17,18]),
00127         ]
00128 
00129         for lst, level, results in tests:
00130             res = self._index._apply_index(
00131                             {"path": {'query': lst, "level": level, "operator": "or"}})
00132             lst = list(res[0].keys())
00133             self.assertEqual(lst, results)
00134 
00135     def testComplexANDTests(self):
00136         self._populateIndex()
00137         tests = [
00138             (['aa','bb'], 1, []),
00139             ([('aa',0), ('bb',1)], 0, [4,5,6]),
00140             ([('aa',0), ('cc',2)], 0, [3,6,9]),
00141         ]
00142 
00143         for lst, level, results in tests:
00144             res = self._index._apply_index(
00145                             {"path": {'query': lst, "level": level, "operator": "and"}})
00146             lst = list(res[0].keys())
00147             self.assertEqual(lst, results)
00148 
00149 
00150 class TestExtendedPathIndex(epitc.ExtendedPathIndexTestCase):
00151     """ Test ExtendedPathIndex objects """
00152 
00153     def testIndexIntegrity(self):
00154         self._populateIndex()
00155         index = self._index._index
00156         self.assertEqual(list(index[None][0].keys()), [1,8,16])
00157         self.assertEqual(list(index[None][1].keys()), [2,9,10,17,18])
00158         self.assertEqual(list(index[None][2].keys()), [3,5,11,13])
00159         self.assertEqual(list(index[None][3].keys()), [4,6,7,12,14,15])
00160 
00161     def testUnIndexError(self):
00162         self._populateIndex()
00163         # this should not raise an error
00164         self._index.unindex_object(-1)
00165 
00166         # nor should this
00167         self._index._unindex[1] = "/broken/thing"
00168         self._index.unindex_object(1)
00169 
00170     def testDepthLimit(self):
00171         self._populateIndex()
00172         tests = [
00173             ('/', 0, 1, 0, [1,8,16]),
00174             ('/', 0, 2, 0, [1,2,8,9,10,16,17,18]),
00175             ('/', 0, 3, 0, [1,2,3,5,8,9,10,11,13,16,17,18]),
00176             ]
00177 
00178         for lst, level, depth, navtree, results in tests:
00179             res = self._index._apply_index(
00180                 {"path": {'query': lst, "level": level, "depth": depth, "navtree": navtree}})
00181             lst = list(res[0].keys())
00182             self.assertEqual(lst, results)
00183 
00184     def testDefaultNavtree(self):
00185         self._populateIndex()
00186         # depth = 1 by default when using navtree
00187         tests = [
00188             ('/'        ,0,1,1,[1,8,16]),
00189             ('/aa'      ,0,1,1,[1,2,8,9,16]),
00190             ('/aa'      ,1,1,1,[2,3,9,10,13,17,18]),
00191             ('/aa/aa'   ,0,1,1,[1,2,3,8,9,16]),
00192             ('/aa/aa/aa',0,1,1,[1,2,3,4,8,9,16]),
00193             ('/aa/bb'   ,0,1,1,[1,2,5,8,9,16]),
00194             ('/bb'      ,0,1,1,[1,8,10,16,17,18]),
00195             ('/bb/aa'   ,0,1,1,[1,8,10,13,16,17,18]),
00196             ('/bb/bb'   ,0,1,1,[1,8,10,11,16,17,18]),
00197             ]
00198         for lst, level, depth, navtree, results in tests:
00199             res = self._index._apply_index(
00200                 {"path": {'query': lst, "level": level, "depth": depth, "navtree": navtree}})
00201             lst = list(res[0].keys())
00202             self.assertEqual(lst,results)
00203 
00204     def testShallowNavtree(self):
00205         self._populateIndex()
00206         # With depth 0 we only get the parents
00207         tests = [
00208             ('/'        ,0,0,1,[]),
00209             ('/aa'      ,0,0,1,[8]),
00210             ('/aa'      ,1,0,1,[18]),
00211             ('/aa/aa'   ,0,0,1,[8]),
00212             ('/aa/aa/aa',0,0,1,[8]),
00213             ('/aa/bb'   ,0,0,1,[8,9]),
00214             ('/bb'      ,0,0,1,[16]),
00215             ('/bb/aa'   ,0,0,1,[16,18]),
00216             ('/bb/bb'   ,0,0,1,[16,17]),
00217             ('/bb/bb/aa'   ,0,0,1,[16,17]),
00218             ]
00219         for lst, level, depth, navtree, results in tests:
00220             res = self._index._apply_index(
00221                 {"path": {'query': lst, "level": level, "depth": depth, "navtree": navtree}})
00222             lst = list(res[0].keys())
00223             self.assertEqual(lst,results)
00224 
00225     def testNonexistingPaths(self):
00226         self._populateIndex()
00227         # With depth 0 we only get the parents
00228         # When getting non existing paths, 
00229         # we should get as many parents as possible when building navtree
00230         tests = [
00231             ('/'        ,0,0,1,[]),
00232             ('/aa'      ,0,0,1,[8]), # Exists
00233             ('/aa/x'    ,0,0,1,[8]), # Doesn't exist
00234             ('/aa'      ,1,0,1,[18]),
00235             ('/aa/x'    ,1,0,1,[18]),
00236             ('/aa/aa'   ,0,0,1,[8]),
00237             ('/aa/aa/x' ,0,0,1,[8]),
00238             ('/aa/bb'   ,0,0,1,[8,9]),
00239             ('/aa/bb/x' ,0,0,1,[8,9]),
00240             ]
00241         for lst, level, depth, navtree, results in tests:
00242             res = self._index._apply_index(
00243                 {"path": {'query': lst, "level": level, "depth": depth, "navtree": navtree}})
00244             lst = list(res[0].keys())
00245             self.assertEqual(lst,results)
00246 
00247     def testEmptyFolderDepthOne(self):
00248         # Shouldn't return folder when we want children of empty folder
00249         self._values = {
00250           1 : epitc.Dummy("/portal/emptyfolder"),
00251           2 : epitc.Dummy("/portal/folder"),
00252           3 : epitc.Dummy("/portal/folder/document"),
00253           4 : epitc.Dummy("/portal/folder/subfolder"),
00254           5 : epitc.Dummy("/portal/folder/subfolder/newsitem")
00255           }
00256         self._populateIndex()
00257         tests = [
00258             ('/portal/folder'                       ,0,1,0,[3,4]),
00259             ('/portal/emptyfolder'                  ,0,1,0,[]),
00260             ('/portal/folder/document'              ,0,1,0,[]),
00261             ('/portal/folder/subfolder'             ,0,1,0,[5]),
00262             ('/portal/folder/subfolder/newsitem'    ,0,1,0,[]),
00263             ]
00264         for lst, level, depth, navtree, results in tests:
00265             res = self._index._apply_index(
00266                 {"path": {'query': lst, "level": level, "depth": depth, "navtree": navtree}})
00267             lst = list(res[0].keys())
00268             self.assertEqual(lst,results)
00269 
00270     def testSiteMap(self):
00271         self._values = {
00272           1 : epitc.Dummy("/portal/emptyfolder"),
00273           2 : epitc.Dummy("/portal/folder"),
00274           3 : epitc.Dummy("/portal/folder/document"),
00275           4 : epitc.Dummy("/portal/folder/subfolder"),
00276           5 : epitc.Dummy("/portal/folder/subfolder/newsitem")
00277           }
00278         self._populateIndex()
00279         tests = [
00280             ('/' ,0,1,0,[]),
00281             ('/' ,0,2,0,[1,2]),
00282             ('/' ,0,3,0,[1,2,3,4]),
00283             ('/' ,0,4,0,[1,2,3,4,5]),
00284             ('/' ,0,5,0,[1,2,3,4,5]),
00285             ('/' ,0,6,0,[1,2,3,4,5]),
00286             ]
00287         for lst, level, depth, navtree, results in tests:
00288             res = self._index._apply_index(
00289                 {"path": {'query': lst, "level": level, "depth": depth, "navtree": navtree}})
00290             lst = list(res[0].keys())
00291             self.assertEqual(lst,results)
00292 
00293 
00294     def testBreadCrumbsWithStart(self):
00295         self._populateIndex()
00296         # Adding a navtree_start > 0 to a breadcrumb search should generate
00297         # breadcrumbs back to that level above the root.  The given path
00298         # will always be included, i.e. start > cur_level -> start = cur_level
00299         tests = [
00300             ('/'                   ,0,1,1,[]),
00301             ('/aa'                 ,0,1,1,[8]),
00302             ('/aa/aa'              ,0,1,1,[8]),
00303             ('/aa/aa/aa'           ,0,1,1,[8]),
00304             ('/aa/bb'              ,0,1,1,[8,9]),
00305             ('/bb'                 ,0,1,1,[16]),
00306             ('/bb/aa'              ,0,1,1,[16,18]),
00307             ('/bb/aa'              ,0,1,2,[18]),
00308             ('/bb/bb'              ,0,1,1,[16,17]),
00309             ('/bb/bb'              ,0,1,2,[17]),
00310             ('/bb/bb/bb/12.html'   ,0,1,1,[12,16,17]),
00311             ('/bb/bb/bb/12.html'   ,0,1,2,[12,17]),
00312             ('/bb/bb/bb/12.html'   ,0,1,3,[12]),
00313             ]
00314         for path, depth, navtree, navtree_start, results in tests:
00315             res = self._index._apply_index(
00316                 {"path": {'query': path,  "depth": depth, "navtree": navtree,
00317                                               "navtree_start":navtree_start}})
00318             lst = list(res[0].keys())
00319             self.assertEqual(lst,results,
00320                         '%s != %s Failed on %s start %s'%(
00321                                                lst,results,path,navtree_start))
00322 
00323     def testNegativeDepthQuery(self):
00324         self._populateIndex()
00325         tests = [
00326             ('/'                   ,0,-1,0,range(1,19)), # Depth -1
00327             ('/aa'                 ,0,-1,0,[2,3,4,5,6,7,8,9]),
00328             ('/aa/aa'              ,0,-1,0,[3,4]),
00329             ('/aa/bb'              ,0,-1,0,[5,6,7,9]),
00330             ('/bb'                 ,0,-1,0,[10,11,12,13,14,15,16,17,18]),
00331             ('/bb/aa'              ,0,-1,0,[13,14,18]),
00332             ('/bb/bb'              ,0,-1,0,[11,12,15,17]),
00333         ]
00334 
00335         for path, level, depth, navtree, results in tests:
00336             res = self._index._apply_index(
00337                 {"path": {'query': path, "level": level, "depth": depth, "navtree": navtree}})
00338             lst = list(res[0].keys())
00339             self.assertEqual(lst,results,
00340                         '%s != %s Failed on %s level %s depth %s navtree %s'%(
00341                                         lst,results,path,level,depth,navtree))
00342 
00343     def testPhysicalPathOptimization(self):
00344         self._populateIndex()
00345         # Fake a physical path for the index
00346         self._index.old_getPhysicalPath = self._index.getPhysicalPath
00347         self._index.getPhysicalPath = lambda: ('','aa')
00348         self.assertEqual(self._index.getPhysicalPath(), ('','aa'))
00349         # Test a variety of arguments
00350         tests = [
00351             ('/'                   ,0,1,0,[1,8,16]), # Sitemap
00352             ('/'                   ,0,0,1,[]), # Non-Existant
00353             ('/'                   ,0,0,1,[]), # Breadcrumb tests
00354             ('/aa'                 ,0,0,1,[8]),
00355             ('/aa/aa'              ,0,0,1,[8]),
00356             ('/'                   ,0,1,1,[1,8,16]), # Navtree tests
00357             ('/aa'                 ,0,1,1,[1,2,8,9,16]),
00358             ('/aa/aa'              ,0,1,1,[1,2,3,8,9,16]),
00359             ('/'                   ,0,0,0,[]), # Depth Zero tests
00360             ('/aa'                 ,0,0,0,[8]),
00361             ('/aa/aa'              ,0,0,0,[]),
00362             ('/'                   ,0,-1,0,range(1,19)), # Depth -1
00363             ('/aa'                 ,0,-1,0,range(1,19)), # Should assume that
00364                                                          # all paths are
00365                                                          # relevant
00366         ]
00367 
00368         for path, level, depth, navtree, results in tests:
00369             res = self._index._apply_index(
00370                 {"path": {'query': path, "level": level, "depth": depth, "navtree": navtree}})
00371             lst = list(res[0].keys())
00372             self.assertEqual(lst,results,
00373                         '%s != %s Failed on %s level %s depth %s navtree %s'%(
00374                                         lst,results,path,level,depth,navtree))
00375 
00376         self._index.getPhysicalPath = self._index.old_getPhysicalPath
00377         self.assertEqual(self._index.getPhysicalPath(), ('path',))
00378 
00379 
00380 def test_suite():
00381     from unittest import TestSuite, makeSuite
00382     suite = TestSuite()
00383     suite.addTest(makeSuite(TestPathIndex))
00384     suite.addTest(makeSuite(TestExtendedPathIndex))
00385     return suite
00386 
00387 if __name__ == '__main__':
00388     framework()