[Checkins] SVN: z3c.autoinclude/trunk/ Better maintainability:

Ethan Jucovy ejucovy at openplans.org
Sat Dec 6 18:55:17 EST 2008


Log message for revision 93731:
  Better maintainability:
   * split apart doctests into multiple files organized by topic (README should be renamed to dependency.txt but that'll have to be a separate 
  commit)
   * factor out test infrastructure/setup (installation of dummy packages for test purposes) from doctests and into tests.py where they belong
  
  the latter required using tempfile directly instead of the weird tmpdir function zc.buildout.testing.BuildoutSetUp puts in the globs; that tmpdir 
  seems to be unreliably extant over the course of the test suite, resulting in sporadically missing eggs and confusing test breakage. (in its 
  defense, there's no reason whatsoever why anyone ought to expect it to be a reliable function to depend on, being both nested and undocumented)
  
  

Changed:
  U   z3c.autoinclude/trunk/CHANGES.txt
  U   z3c.autoinclude/trunk/setup.py
  U   z3c.autoinclude/trunk/src/z3c/autoinclude/README.txt
  A   z3c.autoinclude/trunk/src/z3c/autoinclude/plugin.txt
  U   z3c.autoinclude/trunk/src/z3c/autoinclude/tests/tests.py
  A   z3c.autoinclude/trunk/src/z3c/autoinclude/utils.txt

-=-
Modified: z3c.autoinclude/trunk/CHANGES.txt
===================================================================
--- z3c.autoinclude/trunk/CHANGES.txt	2008-12-06 23:52:23 UTC (rev 93730)
+++ z3c.autoinclude/trunk/CHANGES.txt	2008-12-06 23:55:17 UTC (rev 93731)
@@ -1,6 +1,10 @@
 Changes
 =======
 
+0.2.3 (unreleased)
+------------------
+
+
 0.2.2 (2008-04-22)
 ------------------
 

Modified: z3c.autoinclude/trunk/setup.py
===================================================================
--- z3c.autoinclude/trunk/setup.py	2008-12-06 23:52:23 UTC (rev 93730)
+++ z3c.autoinclude/trunk/setup.py	2008-12-06 23:55:17 UTC (rev 93731)
@@ -5,7 +5,7 @@
                     open('CHANGES.txt').read())
 
 setup(name='z3c.autoinclude',
-      version='0.2.2',
+      version='0.2.3dev',
       description="Automatically include ZCML for dependencies.",
       long_description=long_description,
       # Get more strings from http://www.python.org/pypi?%3Aaction=list_classifiers

Modified: z3c.autoinclude/trunk/src/z3c/autoinclude/README.txt
===================================================================
--- z3c.autoinclude/trunk/src/z3c/autoinclude/README.txt	2008-12-06 23:52:23 UTC (rev 93730)
+++ z3c.autoinclude/trunk/src/z3c/autoinclude/README.txt	2008-12-06 23:55:17 UTC (rev 93731)
@@ -1,3 +1,4 @@
+
 ============================
 Auto inclusion of zcml files
 ============================
@@ -39,41 +40,6 @@
 ``APackage`` depends on ``BCPackage``
 ``BCPackage`` depends on ``SiblingPackage``
 
-First, we need to have some infrastructure to install projects::
-
-    >>> from zc.buildout.easy_install import install
-    >>> from pkg_resources import working_set
-    >>> import os
-    >>> def install_projects(projects, target_dir):
-    ...  links = []
-    ...  for project in projects:
-    ...    project_dir = join(projects_dir, project)
-    ...    dist_dir = join(project_dir, 'dist')
-    ...    if os.path.isdir(dist_dir):
-    ...      rmdir(dist_dir)
-    ...    dummy = system(join('bin', 'buildout') + ' setup ' + \
-    ...              project_dir + ' bdist_egg')
-    ...    links.append(dist_dir)
-    ...
-    ...  return install(projects, target_dir, links=links,
-    ...                 working_set=working_set)
-
-We ensure the projects are installed into a temporary directory so
-that we can use them in our tests::
-
-    >>> target_dir = tmpdir('target_dir')
-    >>> ws = install_projects(['APackage', 'BCPackage', 'XYZPackage',
-    ...                        'SiblingPackage', 'TestDirective'],
-    ...                       target_dir)
-    >>> for dist in ws:
-    ...   dist.activate()
-    ...   if dist.project_name == 'APackage':
-    ...     a_dist = dist
-    ...   if dist.project_name == 'XYZPackage':
-    ...     xyz_dist = dist
-    ...   if dist.project_name == 'SiblingPackage':
-    ...	    sibling_dist = dist
-
 Given the distribution for the project named ``APackage``, we can ask
 for the requirements of that distribution::
 
@@ -214,140 +180,3 @@
     >>> pprint(test_log)
     []
 
-
-=========================================
-Automatic inclusion of extension packages
-=========================================
-
-There is additional functionality for registering and autoincluding
-extension packages for a particular platform.
-
-In this test environment, ``BasePackage`` provides the ``basepackage``
-module which we will treat as our platform.  ``FooPackage`` wants to
-broadcast itself as a plugin for ``basepackage`` and thereby register
-its ZCML as a candidate for automatic inclusion. ``TestDirective``
-also broadcasts itself as a plugin for ``basepackage``.
-
-So, once again, we must first set up our testing infrastructure::
-
-    >>> ws = install_projects(['BasePackage', 'FooPackage', 'TestDirective',
-    ...                        'base2', 'base2_plug'],
-    ...                       target_dir)
-    >>> for dist in ws:
-    ...   dist.activate()
-    ...   if dist.project_name == 'FooPackage':
-    ...     foo_dist = dist
-    ...   elif dist.project_name == 'BasePackage':
-    ...     base_dist = dist
-
-Given a module name, we can ask for distributions which have been broadcast
-themselves as plugging into that module via entry points::
-
-    >>> from z3c.autoinclude.plugin import find_plugins
-    >>> sorted(find_plugins('basepackage'))
-    [FooPackage 0.0 (...), TestDirective 0.0 (...)]
-
-Armed with a valid module name we can find the ZCML files within it
-which must be loaded::
-
-    >>> from z3c.autoinclude.plugin import zcml_to_include
-    >>> zcml_to_include('foo')
-    ['configure.zcml']
-
-By default the function looks for the standard ZCML files ``meta.zcml``,
-``configure.zcml``, and ``overrides.zcml`` but this behavior can be
-overridden::
-
-    >>> zcml_to_include('foo', ['meta.zcml'])
-    []
-
-Finally, we know how to get a list of all module dottednames within
-a distribution, through the DistributionManager adapter::
-
-    >>> from z3c.autoinclude.utils import DistributionManager
-    >>> DistributionManager(foo_dist).dottedNames()
-    ['foo']
-
-So between these functions we can now get a dictionary of all
-extension modules which must be loaded for each ZCML group given
-a base platform.
-
-For consistency, we use the same API as with dependency autoinclusion.
-This time we adapt a base platform (represented by a string referring
-to an importable dotted module name) to a PluginFinder and call its
-`includableInfo` method::
-
-    >>> from z3c.autoinclude.plugin import PluginFinder
-    >>> pprint(PluginFinder('basepackage').includableInfo(['configure.zcml',
-    ...                                                    'meta.zcml']))
-    {'configure.zcml': ['foo'], 'meta.zcml': ['testdirective']}
-
-``FooPackage`` has a test-logging directive in its configure.zcml
-which is defined in meta.zcml in ``TestDirective``.  ``FooPackage``
-does not know anything about ``TestDirective`` and does not explicitly
-include its ZCML; so for the test-logging directive to succeed when
-the ZCML of ``FooPackage`` is loaded, the meta.zcml from ``TestDirective``
-must be loaded first.  Since ``TestDirective`` offers itself as a
-plugin for ``BasePackage`` and zcmlgroups are loaded in the
-conventional order with all meta.zcml first, none of this should
-explode when we load the ZCML from ``BasePackage`` and the test log
-should accurately reflect that the ``FooPackage`` ZCML has been loaded::
-
-    >>> import basepackage
-    >>> dummy = xmlconfig.file(resource_filename('basepackage', 'configure.zcml'),
-    ...                        package=basepackage)
-    >>> pprint(test_log)
-    [u'foo has been loaded']
-
-``base2`` is a namespace package. ``base2.plug`` is a package that
-defines a plugin for base2; it extends ``base2``s namespace.
-
-    >>> clear_test_log()
-    >>> import base2
-    >>> from pkg_resources import Requirement, resource_filename
-    >>> req = Requirement.parse('base2')
-    >>> import os
-    >>> filename = resource_filename(req, os.path.join('base2', 'configure.zcml'))
-    >>> dummy = xmlconfig.file(filename, package=base2)
-    >>> pprint(test_log)
-    [u'base2.plug has been loaded']
-
-
-=================
-Utility functions
-=================
-
-Though this isn't the best place for these tests, I don't want to
-extract out the testing infrastructure right now; so let's just
-test the z3c.autoinclude.utils module right here.
-
-distributionForPackage is a function that takes a module object
-and returns the setuptools distribution object that contains
-the module.
-
-It should find the correct distribution for a package whose namespace
-is extended by other packages in the environment::
-
-    >>> from z3c.autoinclude.utils import distributionForPackage
-    >>> distributionForPackage(base2)
-    base2 0.0 (...base2-0.0...egg)
-
-It should also find the correct distribution for namespace packages,
-even if the namespace being extended is a module defined in another
-package in the environment::
-
-    >>> import base2.plug
-    >>> distributionForPackage(base2.plug)
-    base2-plug 0.0 (...base2_plug-0.0...egg)
-
-While we're at it, it should also find the correct distribution for
-packages whose distribution name has no bearing on the name of the
-package contained within it::
-
-    >>> import basepackage
-    >>> distributionForPackage(basepackage)
-    BasePackage 0.0 (...BasePackage-0.0...egg)
-
-    >>> import foo
-    >>> distributionForPackage(foo)
-    FooPackage 0.0 (...FooPackage-0.0...egg)

Added: z3c.autoinclude/trunk/src/z3c/autoinclude/plugin.txt
===================================================================
--- z3c.autoinclude/trunk/src/z3c/autoinclude/plugin.txt	                        (rev 0)
+++ z3c.autoinclude/trunk/src/z3c/autoinclude/plugin.txt	2008-12-06 23:55:17 UTC (rev 93731)
@@ -0,0 +1,90 @@
+=========================================
+Automatic inclusion of extension packages
+=========================================
+
+There is additional functionality for registering and autoincluding
+extension packages for a particular platform.
+
+In this test environment, ``BasePackage`` provides the ``basepackage``
+module which we will treat as our platform.  ``FooPackage`` wants to
+broadcast itself as a plugin for ``basepackage`` and thereby register
+its ZCML as a candidate for automatic inclusion. ``TestDirective``
+also broadcasts itself as a plugin for ``basepackage``.
+
+Given a module name, we can ask for distributions which have been broadcast
+themselves as plugging into that module via entry points::
+
+    >>> from z3c.autoinclude.plugin import find_plugins
+    >>> sorted(find_plugins('basepackage'))
+    [FooPackage 0.0 (...), TestDirective 0.0 (...)]
+
+Armed with a valid module name we can find the ZCML files within it
+which must be loaded::
+
+    >>> from z3c.autoinclude.plugin import zcml_to_include
+    >>> zcml_to_include('foo')
+    ['configure.zcml']
+
+By default the function looks for the standard ZCML files ``meta.zcml``,
+``configure.zcml``, and ``overrides.zcml`` but this behavior can be
+overridden::
+
+    >>> zcml_to_include('foo', ['meta.zcml'])
+    []
+
+Finally, we know how to get a list of all module dottednames within
+a distribution, through the DistributionManager adapter::
+
+    >>> from z3c.autoinclude.utils import DistributionManager
+    >>> DistributionManager(foo_dist).dottedNames()
+    ['foo']
+
+So between these functions we can now get a dictionary of all
+extension modules which must be loaded for each ZCML group given
+a base platform.
+
+For consistency, we use the same API as with dependency autoinclusion.
+This time we adapt a base platform (represented by a string referring
+to an importable dotted module name) to a PluginFinder and call its
+`includableInfo` method::
+
+    >>> from z3c.autoinclude.plugin import PluginFinder
+    >>> pprint(PluginFinder('basepackage').includableInfo(['configure.zcml',
+    ...                                                    'meta.zcml']))
+    {'configure.zcml': ['foo'], 'meta.zcml': ['testdirective']}
+
+``FooPackage`` has a test-logging directive in its configure.zcml
+which is defined in meta.zcml in ``TestDirective``.  ``FooPackage``
+does not know anything about ``TestDirective`` and does not explicitly
+include its ZCML; so for the test-logging directive to succeed when
+the ZCML of ``FooPackage`` is loaded, the meta.zcml from ``TestDirective``
+must be loaded first.  Since ``TestDirective`` offers itself as a
+plugin for ``BasePackage`` and zcmlgroups are loaded in the
+conventional order with all meta.zcml first, none of this should
+explode when we load the ZCML from ``BasePackage`` and the test log
+should accurately reflect that the ``FooPackage`` ZCML has been loaded::
+
+    >>> import basepackage
+    >>> from zope.configuration import xmlconfig
+    >>> from pkg_resources import resource_filename
+    >>> from testdirective.zcml import test_log
+
+    >>> dummy = xmlconfig.file(resource_filename('basepackage', 'configure.zcml'),
+    ...                        package=basepackage)
+    >>> pprint(test_log)
+    [u'foo has been loaded']
+
+``base2`` is a namespace package. ``base2.plug`` is a package that
+defines a plugin for base2; it extends ``base2``s namespace.
+
+    >>> from testdirective.zcml import clear_test_log
+    >>> clear_test_log()
+    >>> import base2
+    >>> from pkg_resources import Requirement, resource_filename
+    >>> req = Requirement.parse('base2')
+    >>> import os
+    >>> filename = resource_filename(req, os.path.join('base2', 'configure.zcml'))
+
+    >>> dummy = xmlconfig.file(filename, package=base2)
+    >>> pprint(test_log)
+    [u'base2.plug has been loaded']

Modified: z3c.autoinclude/trunk/src/z3c/autoinclude/tests/tests.py
===================================================================
--- z3c.autoinclude/trunk/src/z3c/autoinclude/tests/tests.py	2008-12-06 23:52:23 UTC (rev 93730)
+++ z3c.autoinclude/trunk/src/z3c/autoinclude/tests/tests.py	2008-12-06 23:55:17 UTC (rev 93731)
@@ -1,18 +1,71 @@
 import doctest
 import unittest
+
 import os
 from zc.buildout import testing
 from pprint import pprint
+projects_dir = os.path.dirname(__file__)
+from pkg_resources import working_set
 
+
+# this is the list of test packages that we'll temporarily install
+# for the duration of the tests; you MUST add your test package name
+# to this list if you want it to be available for import in doctests!
+test_packages = ['APackage', 'BCPackage', 'XYZPackage',
+                 'SiblingPackage', 'BasePackage', 'FooPackage',
+                 'base2', 'base2_plug', 'TestDirective']
+
+
+def install_projects(projects, target_dir):
+    from zc.buildout.easy_install import install
+
+    links = []
+    for project in projects:
+        project_dir = os.path.join(projects_dir, project)
+        dist_dir = os.path.join(project_dir, 'dist')
+        if os.path.isdir(dist_dir):
+            testing.rmdir(dist_dir)
+        dummy = testing.system("%s setup %s bdist_egg" % (
+                os.path.join('bin', 'buildout'), project_dir))
+        links.append(dist_dir)
+
+    return install(projects, target_dir, links=links,
+                   working_set=working_set)
+
+
+def testSetUp(test):
+
+    testing.buildoutSetUp(test)
+        
+    import tempfile
+    target_dir = tempfile.mkdtemp('.z3c.autoinclude.test-installs')
+    
+    ws = install_projects(test_packages, target_dir)
+
+    # we must perform a magical incantation on each distribution
+    for dist in ws:
+        dist.activate()
+        
+        if dist.project_name == 'APackage':
+            test.globs['a_dist'] = dist
+        elif dist.project_name == 'XYZPackage':
+            test.globs['xyz_dist'] = dist
+        elif dist.project_name == 'SiblingPackage':
+            test.globs['sibling_dist'] = dist
+        elif dist.project_name == 'FooPackage':
+            test.globs['foo_dist'] = dist
+        elif dist.project_name == 'BasePackage':
+            test.globs['base_dist'] = dist
+
+
 def test_suite():
-    projects_dir = os.path.dirname(__file__)
-    base_suite = doctest.DocFileSuite('../README.txt',
-                                      setUp=testing.buildoutSetUp,
-                                      tearDown=testing.buildoutTearDown,
-                                      globs=dict(projects_dir=projects_dir,
-                                                 pprint=pprint),
-                                      optionflags=doctest.ELLIPSIS)
-    return unittest.TestSuite((base_suite,
+    suite = doctest.DocFileSuite('../utils.txt', '../README.txt', '../plugin.txt',
+                                 setUp=testSetUp,
+                                 tearDown=testing.buildoutTearDown,
+                                 globs={'pprint':pprint},
+                                 optionflags=doctest.ELLIPSIS)
+
+    return unittest.TestSuite((suite,
                                ))
 
 if __name__ == '__main__':

Added: z3c.autoinclude/trunk/src/z3c/autoinclude/utils.txt
===================================================================
--- z3c.autoinclude/trunk/src/z3c/autoinclude/utils.txt	                        (rev 0)
+++ z3c.autoinclude/trunk/src/z3c/autoinclude/utils.txt	2008-12-06 23:55:17 UTC (rev 93731)
@@ -0,0 +1,35 @@
+=================
+Utility functions
+=================
+
+distributionForPackage is a function that takes a module object
+and returns the setuptools distribution object that contains
+the module.
+
+It should find the correct distribution for a package whose namespace
+is extended by other packages in the environment::
+
+    >>> from z3c.autoinclude.utils import distributionForPackage
+    >>> import base2
+    >>> distributionForPackage(base2)
+    base2 0.0 (...base2-0.0...egg)
+
+It should also find the correct distribution for namespace packages,
+even if the namespace being extended is a module defined in another
+package in the environment::
+
+    >>> import base2.plug
+    >>> distributionForPackage(base2.plug)
+    base2-plug 0.0 (...base2_plug-0.0...egg)
+
+While we're at it, it should also find the correct distribution for
+packages whose distribution name has no bearing on the name of the
+package contained within it::
+
+    >>> import basepackage
+    >>> distributionForPackage(basepackage)
+    BasePackage 0.0 (...BasePackage-0.0...egg)
+
+    >>> import foo
+    >>> distributionForPackage(foo)
+    FooPackage 0.0 (...FooPackage-0.0...egg)



More information about the Checkins mailing list