[Checkins] SVN: Sandbox/ulif/grok-with-testing/src/grok/ Added module support.

Uli Fouquet uli at gnufix.de
Wed Aug 15 23:41:16 EDT 2007


Log message for revision 78866:
  Added module support.

Changed:
  U   Sandbox/ulif/grok-with-testing/src/grok/admin/app.py
  A   Sandbox/ulif/grok-with-testing/src/grok/admin/modtest.txt
  U   Sandbox/ulif/grok-with-testing/src/grok/meta.py
  U   Sandbox/ulif/grok-with-testing/src/grok/testing.py
  A   Sandbox/ulif/grok-with-testing/src/grok/tests/testing/AnotherSampleTest.txt
  D   Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive.py
  A   Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive_in_class.py
  A   Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive_in_module.py

-=-
Modified: Sandbox/ulif/grok-with-testing/src/grok/admin/app.py
===================================================================
--- Sandbox/ulif/grok-with-testing/src/grok/admin/app.py	2007-08-16 03:09:32 UTC (rev 78865)
+++ Sandbox/ulif/grok-with-testing/src/grok/admin/app.py	2007-08-16 03:41:15 UTC (rev 78866)
@@ -21,3 +21,7 @@
 class MyTest3(grok.testing.FunctionalDocTest):
     # This is currently not supported...
     grok.context(SampleApp)
+
+grok.testing.file('modtest.txt')
+#grok.testing.file('')
+#grok.testing.file('Another.txt')

Added: Sandbox/ulif/grok-with-testing/src/grok/admin/modtest.txt
===================================================================
--- Sandbox/ulif/grok-with-testing/src/grok/admin/modtest.txt	                        (rev 0)
+++ Sandbox/ulif/grok-with-testing/src/grok/admin/modtest.txt	2007-08-16 03:41:15 UTC (rev 78866)
@@ -0,0 +1,5 @@
+
+This is a simple doctest:
+
+  >>> 1+1
+  1

Modified: Sandbox/ulif/grok-with-testing/src/grok/meta.py
===================================================================
--- Sandbox/ulif/grok-with-testing/src/grok/meta.py	2007-08-16 03:09:32 UTC (rev 78865)
+++ Sandbox/ulif/grok-with-testing/src/grok/meta.py	2007-08-16 03:41:15 UTC (rev 78866)
@@ -632,10 +632,22 @@
         return intids
 
 class FunctionalDocTestGrokker(martian.ClassGrokker):
+    """This grokker is called, when ``grok.testing.file`` appears in a class.
+
+    It checks for existance of files given in a directive and adds
+    the 'surrounding' class to a list in ``grok.testing``.
+    """
     component_class = grok.testing.FunctionalDocTest
 
     def grok(self, name, factory, context, module_info, templates):
+        # Check whether the file given exists...
         docfilelist = getattr(factory, '__grok_testing_file__', [])
+
+        # Avoid duplicates...
+        docfileset = set()
+        docfileset.update(docfilelist)
+        docfilelist = list(docfileset)
+
         for docfile in docfilelist:
             docfilepath = module_info.getResourcePath(docfile)
             if not os.path.isfile(docfilepath):
@@ -645,9 +657,38 @@
                     (docfile, module_info.dotted_name,
                      module_info.getResourcePath('')),
                     None)
-            if not hasattr(factory, '__grok_testing_filepath__'):
-                factory.__grok_testing_filepath__ = []
-            factory.__grok_testing_filepath__.append(docfilepath)
+            # Add test class to global list...
             grok.testing.add_functional_doctest(factory)
         return True
 
+
+class FunctionalDocTestModuleGrokker(martian.GlobalGrokker):
+    """This grokker is called, when ``grok.testing.file`` appears in a module.
+
+    It checks for existance of files given in a directive and adds
+    the 'surrounding' module to a list in ``grok.testing``.
+    """
+
+    def grok(self, name, module, context, module_info, templates):
+        docfilelist = module_info.getAnnotation('grok.testing.file', [])
+        if docfilelist == []:
+            return True
+
+        # Avoid duplicates...
+        docfileset = set()
+        docfileset.update(docfilelist)
+        docfilelist = list(docfileset)
+        for docfile in docfilelist:
+            if docfile == '':
+                docfile = "%s.py" % (module_info.name,)
+            docfilepath = module_info.getResourcePath(docfile)
+            if not os.path.isfile(docfilepath):
+                raise GrokError(
+                    "Doctest file '%r' declared in %r does not exist "
+                    "in %r." %
+                    (docfile, module_info.dotted_name,
+                     module_info.getResourcePath('')),
+                    None)
+        grok.testing.add_functional_doctest_location(docfilelist,
+                                                     module_info.dotted_name)
+        return True

Modified: Sandbox/ulif/grok-with-testing/src/grok/testing.py
===================================================================
--- Sandbox/ulif/grok-with-testing/src/grok/testing.py	2007-08-16 03:09:32 UTC (rev 78865)
+++ Sandbox/ulif/grok-with-testing/src/grok/testing.py	2007-08-16 03:41:15 UTC (rev 78866)
@@ -13,7 +13,6 @@
                                ClassDirectiveContext,
                                ClassOrModuleDirectiveContext)
 from martian import util
-#from martian.scan import ModuleInfo
 
 from pkg_resources import resource_listdir
 from zope.testing import doctest
@@ -21,23 +20,15 @@
                                          FunctionalTestSetup, sync, ZCMLLayer,
                                          FunctionalDocFileSuite)
 
-
-
-
 class FunctionalDocTest(object):
-    """A functional doc test, that will automatically executed.
-
+    """A functional doc test, that will be automatically executed.
     """
 
     ftesting_zcml = os.path.join(os.path.dirname(grok.__file__),
                                  'ftesting.zcml')
     FunctionalLayer = ZCMLLayer(ftesting_zcml, __name__,
                                 'FunctionalLayer')
-    
-    def __init__(self):
-        # print "FUNCDOCTEST CREATED: ", self
-        pass
-    
+
     def setUp(self, test):
         FunctionalTestSetup().setUp()
 
@@ -49,7 +40,6 @@
         suite = unittest.TestSuite()
         # We must get the pkg of the target test...
         pkg = self.__module__.rsplit('.', 1)[0].replace('.', '/')
-            
         test = FunctionalDocFileSuite(
             filepath, setUp=self.setUp, tearDown=self.tearDown,
             module_relative = True, package = pkg,
@@ -65,35 +55,88 @@
         suite.addTest(test)
         return suite
         
-    def test_suite(self):
+    def __grok_test_suite__(self):
         suite = unittest.TestSuite()
         for name in getattr(self, '__grok_testing_file__', []):
             suite.addTest(self.suiteFromFile(name))
         return suite
         
 
-# Setup for the grok.testing.file directive...
-all_func_doc_tests = []
+class FunctionalDocTestForModule(FunctionalDocTest):
+    """A doctest with a given pkg and docfile path.
+    """
+    pkg = None
+    filepath = None
+    
+    def __init__(self, pkg, filepath):
+        self.pkg = pkg
+        self.filepath = filepath
 
+    def __grok_test_suite__(self):
+        suite = unittest.TestSuite()
+        for path in self.filepath:
+            test = FunctionalDocFileSuite(
+                path, setUp=self.setUp, tearDown=self.tearDown,
+                module_relative = True, package = self.pkg,
+                globs = dict(http=HTTPCaller(),
+                             getRootFolder=getRootFolder,
+                             sync=sync
+                             ),
+                optionflags = (doctest.ELLIPSIS+
+                               doctest.NORMALIZE_WHITESPACE+
+                               doctest.REPORT_NDIFF)
+                )
+            test.layer = self.FunctionalLayer
+            suite.addTest(test)
+        return suite
+
+
+# Setup for the grok.testing.file directive.
+#
+# This is a list of FunctionalDocTest classes and tuples containing a
+# dotted pkg name and a filepath. The first is injected by the testing
+# class grokker, while the latter is injected by module wide
+# directives.
+all_func_doc_tests = set()
+all_func_doc_test_locations = []
+
 def add_functional_doctest(doctest):
-    all_func_doc_tests.append(doctest)
+    # TODO: a set does not check hard enough for existing tests.
+    all_func_doc_tests.add(doctest)
 
+def add_functional_doctest_location(pkg, subpath):
+    # TODO: check harder for existing tests.
+    if subpath == []:
+        return
+    if (pkg, subpath) in all_func_doc_test_locations:
+        return
+    all_func_doc_test_locations.append((pkg, subpath))
+
+
 class TestingFileDirective(MultipleTextDirective):
     def check_arguments(self, filename = None):
         if filename is None or filename == '':
             raise GrokImportError("You must give a valid filename when using "
-                                  "grok.testing.file() (invalid: %s)." % self.filename)
+                                  "grok.testing.file() (invalid: '%s')." % (
+                filename,))
 
 file = TestingFileDirective('grok.testing.file',
                             ClassOrModuleDirectiveContext())
 
 
 def test_suite():
-
     suite = unittest.TestSuite()
+    # First handle doctests registered on module level...
+    for elem in all_func_doc_test_locations:
+        pkg, path = elem
+        ftest = FunctionalDocTestForModule(pkg, path)
+    # Then handle doctests registered on class level...
     for klass in all_func_doc_tests:
+        # This klass describes a class, which is derived from
+        # ``FunctionalDocTest`` and brings all neccessary methods
+        # to extract tests with it.
         ftest = klass()
-        suite.addTest(ftest.test_suite())
+        suite.addTest(ftest.__grok_test_suite__())
     return suite
 
 if __name__ == '__main__':

Added: Sandbox/ulif/grok-with-testing/src/grok/tests/testing/AnotherSampleTest.txt
===================================================================
--- Sandbox/ulif/grok-with-testing/src/grok/tests/testing/AnotherSampleTest.txt	                        (rev 0)
+++ Sandbox/ulif/grok-with-testing/src/grok/tests/testing/AnotherSampleTest.txt	2007-08-16 03:41:15 UTC (rev 78866)
@@ -0,0 +1,4 @@
+
+Just a pseudo doctest.
+
+  >>> 1 == 1

Deleted: Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive.py
===================================================================
--- Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive.py	2007-08-16 03:09:32 UTC (rev 78865)
+++ Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive.py	2007-08-16 03:41:15 UTC (rev 78866)
@@ -1,89 +0,0 @@
-"""
-Tests for the ``grok.testing.file`` directive.
-
-Declaring a not existent file makes Grok unhappy:
-
-   >>> grok.grok(__name__)
-   Traceback (most recent call last):
-   ...
-   GrokError: Doctest file ''Not existent file name'' declared in 'grok.tests.testing.file_directive' does not exist in '.../grok/tests/testing/'.
-
-We don't *have* to use the ``grok.testing.file`` directive:
-
-   >>> klass = DoctestWithoutFileDirective
-   >>> hasattr(klass, '__grok_testing_file__')
-   False
-
-We can declare one or more doctest files per FunctionalDoctest. By
-default doctestfiles are assumed to reside in the package of the
-module in which the doctest was defined:
-
-   >>> klass = DoctestInCurrentDir
-   >>> hasattr(klass, '__grok_testing_file__')
-   True
-
-   >>> klassdoctests = getattr(klass, '__grok_testing_file__', [])
-   >>> 'SampleDocTest.txt' in klassdoctests
-   True
-
-We can register doctests in subdirectories relative to the package of
-the module, where the ``FunctionalDocTest`` was defined. To make use
-of this feature, split path elements by the simple slash ('/').
-
-The subdirectories do not have to be Python packages (although they
-can), which is handy for functional tests, that should not be grokked
-when running in non-testing mode:
-
-   >>> klass = DoctestInSubDir
-   >>> klassdoctests = getattr(klass, '__grok_testing_file__', [])
-   >>> 'subdir/empty_doc_test.txt' in klassdoctests
-   True
-
-We can also register several docfiles per ``FunctionalDocTest``:
-
-   >>> klass = DoctestWithSeveralTests
-   >>> klassdoctests = getattr(klass, '__grok_testing_file__', [])
-   >>> 'SampleDocTest.txt' in klassdoctests
-   True
-
-   >>> 'subdir/empty_doc_test.txt' in klassdoctests
-   True
-
-Make sure, that doctest paths are looked up relative to the package,
-where the declaring ``FunctionalDocTest`` was defined. To test this,
-we grok the module in the subpackage and expect no ``GrokError`` to be
-raised. This means, that the doctestfile was found, although it
-resides in a different package and its path was declared relative to
-the subpackage module.
-
-   >>> dotted_subpkg_path = __name__.rsplit('.', 1)[0] + '.subpkg'
-   >>> grok.grok(dotted_subpkg_path)
-
-No output here is good. Just to make sure, the class was really
-grokked:
-
-   >>> from grok.tests.testing.subpkg.mod_declaring_a_doctest import DoctestDeclaredInSubpkg
-   >>> klass = DoctestDeclaredInSubpkg
-   >>> klassdoctests = getattr(klass, '__grok_testing_file__', [])
-   >>> 'doctest_in_subpkg.txt' in klassdoctests
-   True
-
-"""
-
-import grok
-
-class DoctestWithoutFileDirective(grok.testing.FunctionalDocTest):
-    pass
-
-class NotExistentTestFile(grok.testing.FunctionalDocTest):
-    grok.testing.file('Not existent file name')
-
-class DoctestInCurrentDir(grok.testing.FunctionalDocTest):
-    grok.testing.file('SampleDocTest.txt')
-
-class DoctestInSubDir(grok.testing.FunctionalDocTest):
-    grok.testing.file('subdir/empty_doc_test.txt')
-
-class DoctestWithSeveralTests(grok.testing.FunctionalDocTest):
-    grok.testing.file('SampleDocTest.txt')
-    grok.testing.file('subdir/empty_doc_test.txt')

Copied: Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive_in_class.py (from rev 78847, Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive.py)
===================================================================
--- Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive_in_class.py	                        (rev 0)
+++ Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive_in_class.py	2007-08-16 03:41:15 UTC (rev 78866)
@@ -0,0 +1,106 @@
+"""
+Tests for the ``grok.testing.file`` directive in class context.
+
+Declaring a not existent file makes Grok unhappy:
+
+   >>> grok.grok(__name__)
+   Traceback (most recent call last):
+   ...
+   GrokError: Doctest file ''Not existent file name'' declared in 'grok.tests.testing.file_directive_in_class' does not exist in '.../grok/tests/testing/'.
+
+We don't *have* to use the ``grok.testing.file`` directive:
+
+   >>> klass = DoctestWithoutFileDirective
+   >>> hasattr(klass, '__grok_testing_file__')
+   False
+
+We can declare one or more doctest files per FunctionalDoctest. By
+default doctestfiles are assumed to reside in the package of the
+module in which the doctest was defined:
+
+   >>> klass = DoctestInCurrentDir
+   >>> hasattr(klass, '__grok_testing_file__')
+   True
+
+   >>> klassdoctests = getattr(klass, '__grok_testing_file__', [])
+   >>> 'SampleDocTest.txt' in klassdoctests
+   True
+
+We can register doctests in subdirectories relative to the package of
+the module, where the ``FunctionalDocTest`` was defined. To make use
+of this feature, split path elements by the simple slash ('/').
+
+The subdirectories do not have to be Python packages (although they
+can), which is handy for functional tests, that should not be grokked
+when running in non-testing mode:
+
+   >>> klass = DoctestInSubDir
+   >>> klassdoctests = getattr(klass, '__grok_testing_file__', [])
+   >>> 'subdir/empty_doc_test.txt' in klassdoctests
+   True
+
+We can also register several docfiles per ``FunctionalDocTest``:
+
+   >>> klass = DoctestWithSeveralTests
+   >>> klassdoctests = getattr(klass, '__grok_testing_file__', [])
+   >>> 'SampleDocTest.txt' in klassdoctests
+   True
+
+   >>> 'subdir/empty_doc_test.txt' in klassdoctests
+   True
+
+But if we try to register the same file several time, it will only be
+registered once:
+
+   >>> len(grok.testing.all_func_doc_tests)
+   6
+
+This is less than the amount of ``grok.testing.file`` directives seen
+below.
+
+Make sure, that doctest paths are looked up relative to the package,
+where the declaring ``FunctionalDocTest`` was defined. To test this,
+we grok the module in the subpackage and expect no ``GrokError`` to be
+raised. This means, that the doctestfile was found, although it
+resides in a different package and its path was declared relative to
+the subpackage module.
+
+   >>> dotted_subpkg_path = __name__.rsplit('.', 1)[0] + '.subpkg'
+   >>> grok.grok(dotted_subpkg_path)
+
+No output here is good. Just to make sure, the class was really
+grokked:
+
+   >>> from grok.tests.testing.subpkg.mod_declaring_a_doctest import DoctestDeclaredInSubpkg
+   >>> klass = DoctestDeclaredInSubpkg
+   >>> klassdoctests = getattr(klass, '__grok_testing_file__', [])
+   >>> 'doctest_in_subpkg.txt' in klassdoctests
+   True
+
+
+"""
+
+import grok
+
+class DoctestWithoutFileDirective(grok.testing.FunctionalDocTest):
+    pass
+
+class NotExistentTestFile(grok.testing.FunctionalDocTest):
+    grok.testing.file('Not existent file name')
+
+class DoctestInCurrentDir(grok.testing.FunctionalDocTest):
+    grok.testing.file('SampleDocTest.txt')
+
+class DoctestInSubDir(grok.testing.FunctionalDocTest):
+    grok.testing.file('subdir/empty_doc_test.txt')
+
+class DoctestWithSeveralTests(grok.testing.FunctionalDocTest):
+    grok.testing.file('SampleDocTest.txt')
+    grok.testing.file('subdir/empty_doc_test.txt')
+
+class DoctestWithOneTestSeveralTimes(grok.testing.FunctionalDocTest):
+    grok.testing.file('SampleDocTest.txt')
+    grok.testing.file('SampleDocTest.txt')
+    grok.testing.file('SampleDocTest.txt')
+    grok.testing.file('SampleDocTest.txt')
+

Added: Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive_in_module.py
===================================================================
--- Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive_in_module.py	                        (rev 0)
+++ Sandbox/ulif/grok-with-testing/src/grok/tests/testing/file_directive_in_module.py	2007-08-16 03:41:15 UTC (rev 78866)
@@ -0,0 +1,61 @@
+"""
+Tests for the ``grok.testing.file`` directive in module context.
+
+
+   >>> import grok
+   >>> grok.grok(__name__)
+
+We can declare one or more doctest files per module. By default
+doctestfiles are assumed to reside in the package of the module in
+which the doctest was declared:
+
+   >>> 'SampleDocTest.txt' in __grok_testing_file__
+   True
+
+   >>> 'AnotherSampleTest.txt' in  __grok_testing_file__
+   True
+
+The registered tests are stored in
+``grok.testing.all_func_doc_test_locations``. This is where we can
+look for what really got registered.
+
+   >>> registered_tuple = [x for x in grok.testing.all_func_doc_test_locations if x[1] == 'grok.tests.testing.file_directive_in_module'][0]
+   
+   >>> pathlist, mod_path = registered_tuple
+   >>> 'AnotherSampleTest.txt' in pathlist
+   True
+
+
+We can register doctests in subdirectories relative to the package of
+the module, where the file was declared. To make use
+of this feature, split path elements by the simple slash ('/').
+
+   >>> 'subpkg/doctest_in_subpkg.txt' in pathlist
+   True
+
+The subdirectories do not have to be Python packages (although they
+can), which is handy for functional tests, that should not be grokked
+when running in non-testing mode:
+
+   >>> 'subdir/empty_doc_test.txt' in pathlist
+   True
+
+We can also register several docfiles per module. But if we try to
+register the same file several time, it will only be registered
+once. We declared ``SampleDocTest.txt`` several times below, but:
+
+   >>> len([x for x in pathlist if x == 'SampleDocTest.txt'])
+   1
+
+
+"""
+
+import grok
+
+grok.testing.file('SampleDocTest.txt')
+grok.testing.file('SampleDocTest.txt')
+grok.testing.file('AnotherSampleTest.txt')
+grok.testing.file('subdir/empty_doc_test.txt')
+grok.testing.file('subpkg/doctest_in_subpkg.txt')
+
+



More information about the Checkins mailing list