[Checkins] SVN: zc.resourcelibrary/trunk/src/zc/resourcelibrary/
Bugfix: use a proper topological sort for pulling in resource
library
Marius Gedminas
marius at pov.lt
Mon Oct 23 11:07:39 EDT 2006
Log message for revision 70892:
Bugfix: use a proper topological sort for pulling in resource library
dependencies.
Changed:
U zc.resourcelibrary/trunk/src/zc/resourcelibrary/publication.py
U zc.resourcelibrary/trunk/src/zc/resourcelibrary/tests.py
-=-
Modified: zc.resourcelibrary/trunk/src/zc/resourcelibrary/publication.py
===================================================================
--- zc.resourcelibrary/trunk/src/zc/resourcelibrary/publication.py 2006-10-23 14:52:36 UTC (rev 70891)
+++ zc.resourcelibrary/trunk/src/zc/resourcelibrary/publication.py 2006-10-23 15:07:38 UTC (rev 70892)
@@ -109,26 +109,17 @@
return super(Response, self)._implicitResult(body)
def _addDependencies(self, resource_libraries):
- # avoid side effects by copying the list before modifying it
- resource_libraries = list(resource_libraries)
- # add any libraries that the explicitly referenced
- # libraries require
- libs = list(resource_libraries)
- while libs:
- lib = libs.pop()
+ result = []
+ def add_lib(lib):
+ if lib in result:
+ return # Nothing to do
try:
required = zc.resourcelibrary.getRequired(lib)
except KeyError:
raise RuntimeError('Unknown resource library: "%s"' % lib)
- for lib in required:
- if lib not in resource_libraries:
- resource_libraries.append(lib)
- libs.append(lib)
-
- # reverse the order of the libs in order to have the
- # dependencies first. TODO: this does not work if the
- # dependency is needed directly in the page before the
- # dependent lib is needed.
- resource_libraries.reverse()
- return resource_libraries
-
+ for other in required:
+ add_lib(other)
+ result.append(lib)
+ for lib in resource_libraries:
+ add_lib(lib)
+ return result
Modified: zc.resourcelibrary/trunk/src/zc/resourcelibrary/tests.py
===================================================================
--- zc.resourcelibrary/trunk/src/zc/resourcelibrary/tests.py 2006-10-23 14:52:36 UTC (rev 70891)
+++ zc.resourcelibrary/trunk/src/zc/resourcelibrary/tests.py 2006-10-23 15:07:38 UTC (rev 70892)
@@ -1,10 +1,71 @@
import doctest
import unittest
from zope.testing.doctestunit import DocTestSuite
+
+from zc.resourcelibrary import resourcelibrary
+from zc.resourcelibrary.resourcelibrary import LibraryInfo
+
+
+def setUp(test):
+ test.old_library_info = resourcelibrary.library_info
+ resourcelibrary.library_info = library_info = {}
+ # Dependencies:
+ #
+ # libA libD
+ # \ /
+ # libB /
+ # \/
+ # libC
+ #
+ library_info['libA'] = LibraryInfo()
+ library_info['libA'].required.append('libB')
+ library_info['libB'] = LibraryInfo()
+ library_info['libB'].required.append('libC')
+ library_info['libC'] = LibraryInfo()
+ library_info['libD'] = LibraryInfo()
+ library_info['libD'].required.append('libC')
+
+
+def tearDown(test):
+ resourcelibrary.library_info = test.old_library_info
+
+
+def doctest_dependency_resolution():
+ """Test Response._addDependencies
+
+ >>> from zc.resourcelibrary.publication import Response
+ >>> r = Response()
+
+ The method gets a list of libraries and adds all their dependencies
+ in the proper order
+
+ >>> r._addDependencies(['libA'])
+ ['libC', 'libB', 'libA']
+
+ Here's a tricky corner case that the old algorithm used to get wrong:
+
+ >>> r._addDependencies(['libA', 'libD'])
+ ['libC', 'libB', 'libA', 'libD']
+
+ No library is included more than once
+
+ >>> r._addDependencies(['libC', 'libA', 'libD', 'libA'])
+ ['libC', 'libB', 'libA', 'libD']
+
+ Unknown library names cause errors
+
+ >>> r._addDependencies(['libA', 'libZ'])
+ Traceback (most recent call last):
+ ...
+ RuntimeError: Unknown resource library: "libZ"
+
+ """
+
+
def test_suite():
-
return unittest.TestSuite(
(
+ DocTestSuite(setUp=setUp, tearDown=tearDown),
DocTestSuite('zc.resourcelibrary.publication',
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
),
More information about the Checkins
mailing list