r370 - / python-zope.testing python-zope.testing/branches python-zope.testing/branches/upstream python-zope.testing/branches/upstream/current python-zope.testing/branches/upstream/current/src python-zope.testing/branches/upstream/current/src/zope python-zope.testing/branches/upstream/current/src/zope/testing python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample11 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample12 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample13 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/do-not-enter python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/donotenter python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample22 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample23 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample31 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample32 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample33 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/package python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4 python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/products python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/more python-zope.testing/branches/upstream/current/src/zope.testing.egg-info python-zope.testing/branches/upstream/current/workspace

Brian Sutherland jinty-guest at alioth.debian.org
Sun Oct 29 20:26:06 CET 2006


Author: jinty-guest
Date: 2006-10-29 20:24:26 +0100 (Sun, 29 Oct 2006)
New Revision: 370

Added:
   python-zope.testing/
   python-zope.testing/branches/
   python-zope.testing/branches/upstream/
   python-zope.testing/branches/upstream/current/
   python-zope.testing/branches/upstream/current/CHANGES.txt
   python-zope.testing/branches/upstream/current/INSTALL.txt
   python-zope.testing/branches/upstream/current/MANIFEST.in
   python-zope.testing/branches/upstream/current/PKG-INFO
   python-zope.testing/branches/upstream/current/README.txt
   python-zope.testing/branches/upstream/current/develop.py
   python-zope.testing/branches/upstream/current/setup.cfg.in
   python-zope.testing/branches/upstream/current/setup.py
   python-zope.testing/branches/upstream/current/src/
   python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/
   python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/PKG-INFO
   python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/SOURCES.txt
   python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/namespace_packages.txt
   python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/not-zip-safe
   python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/requires.txt
   python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/top_level.txt
   python-zope.testing/branches/upstream/current/src/zope/
   python-zope.testing/branches/upstream/current/src/zope/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/
   python-zope.testing/branches/upstream/current/src/zope/testing/DEPENDENCIES.cfg
   python-zope.testing/branches/upstream/current/src/zope/testing/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/cleanup.py
   python-zope.testing/branches/upstream/current/src/zope/testing/doctest.py
   python-zope.testing/branches/upstream/current/src/zope/testing/doctestunit.py
   python-zope.testing/branches/upstream/current/src/zope/testing/formparser.py
   python-zope.testing/branches/upstream/current/src/zope/testing/formparser.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/loggingsupport.py
   python-zope.testing/branches/upstream/current/src/zope/testing/loghandler.py
   python-zope.testing/branches/upstream/current/src/zope/testing/module.py
   python-zope.testing/branches/upstream/current/src/zope/testing/renormalizing.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-arguments.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-coverage.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-debugging.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-edge-cases.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-errors.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/products/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/products/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/more/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/more/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/more/sampletests.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/sampletests.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/README.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gc0.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gc1.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gcset.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gcstats.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/leak.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/pledge.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample11/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample11/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample11/sampletests.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample12/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample12/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample13/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample13/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample13/sampletests.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test1.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test11.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test111.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test112.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test12.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test121.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test122.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test_one.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_none_suite.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_none_test.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_ntd.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_ntds.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletestsf.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/do-not-enter/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/do-not-enter/sampletests.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/donotenter/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/donotenter/sampletests.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/e.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/sampletests.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/sampletests_i.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample22/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample22/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample22/sampletests_i.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample23/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample23/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample23/sampletests_i.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/test_1.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/testone.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_1.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_e.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_f.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_ntd.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_ntds.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem5.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem6.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem_failure.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample31/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample31/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample32/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample32/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample33/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample33/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests_d.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests_ntd.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/set_trace5.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/set_trace6.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/samplelayers.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test1.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test11.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test111.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test112.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test12.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test121.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test122.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test_one.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletestsf.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletestsl.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/README.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/compiletest.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/package/
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/package/__init__.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/package/compiletest.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-gc.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-knit.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-layers-ntd.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-layers.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-leaks-err.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-leaks.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-profiling.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-progress.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-repeat.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-simple.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-test-selection.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-verbose.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-wo-source.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner.py
   python-zope.testing/branches/upstream/current/src/zope/testing/testrunner.txt
   python-zope.testing/branches/upstream/current/src/zope/testing/tests.py
   python-zope.testing/branches/upstream/current/test.py
   python-zope.testing/branches/upstream/current/workspace/
   python-zope.testing/branches/upstream/current/workspace/__init__.py
   python-zope.testing/branches/upstream/current/workspace/develop.py
   python-zope.testing/tags/
Log:
[svn-inject] Installing original source of python-zope.testing

Added: python-zope.testing/branches/upstream/current/CHANGES.txt
===================================================================
--- python-zope.testing/branches/upstream/current/CHANGES.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/CHANGES.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,19 @@
+zope.testing Package Changelog
+=============================
+
+zope.testing version 2.0.2 (2006/04/15)
+---------------------------------------
+
+- Fix packaging bug:  'package_dir' must be a *relative* path.
+
+zope.testing version 2.0.1 (2006/04/14)
+---------------------------------------
+
+- Packaging change:  suppress inclusion of 'setup.cfg' in 'sdist' builds.
+
+zope.testing version 2.0 (2006/01/05)
+--------------------------------------
+
+- Corresponds to the verison of the zope.testing package shipped as part of
+  the Zope 3.2.0 release.
+


Property changes on: python-zope.testing/branches/upstream/current/CHANGES.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/INSTALL.txt
===================================================================
--- python-zope.testing/branches/upstream/current/INSTALL.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/INSTALL.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,72 @@
+Installing This Package
+=======================
+
+Prerequisites
+-------------
+
+The installation steps below assume that you have the cool new 'setuptools'
+package installed in your Python.  Here is where to get it:
+
+  $ wget http://peak.telecommunity.com/dist/ez_setup.py
+  $ /path/to/your/python ez_setup.py # req. write access to 'site-packages'
+
+
+  - Docs for EasyInstall:
+    http://peak.telecommunity.com/DevCenter/EasyInstall
+
+  - Docs for setuptools:
+    http://peak.telecommunity.com/DevCenter/setuptools
+
+  - Docs for eggs:
+    http://peak.telecommunity.com/DevCenter/PythonEggs
+
+
+Installing a Development Checkout
+---------------------------------
+
+Check out the package from subversion:
+
+  $ svn co svn+ssh://svn.zope.org/repos/main/zope.testing/trunk \
+    src/zope.testing
+  $ cd src/zope.testing
+
+Install it as a "devlopment egg" (which also installs its "hard"
+dependencies):
+
+  $ /path/to/your/python setup.py devel
+
+The installation of dependency eggs uses the 'setup.cfg' file in
+the checkout.  You can supply '--find-links' on the command line to
+point it at a non-standard package repository.
+
+
+Running the Tests
+-----------------
+
+You can then run the tests from the checkout directory:
+
+  $ /path/to/your/python test.py
+    Running:
+      .............
+    Ran 13 tests with 0 failures and 0 errors in 0.094 seconds.
+
+
+Installing a Source Distribution
+--------------------------------
+
+You can also install it from a source distribution:
+
+  $ /path/to/easy_install --find-links="...." -eb src zope.testing
+  $ cd src/zope.testing
+  $ /path/to/your/python setup.py devel
+
+
+Installing a Binary Egg
+-----------------------
+
+Install the package as a "binary egg" (which also installs its "hard"
+dependencies):
+
+  $ /path/to/easy_install --find-links="...." zope.testing
+
+


Property changes on: python-zope.testing/branches/upstream/current/INSTALL.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/MANIFEST.in
===================================================================
--- python-zope.testing/branches/upstream/current/MANIFEST.in	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/MANIFEST.in	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+exclude setup.cfg

Added: python-zope.testing/branches/upstream/current/PKG-INFO
===================================================================
--- python-zope.testing/branches/upstream/current/PKG-INFO	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/PKG-INFO	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,10 @@
+Metadata-Version: 1.0
+Name: zope.testing
+Version: 2.0.2
+Summary: Zope3 Testrunner
+Home-page: http://svn.zope.org/zope.testing
+Author: Zope Corporation and Contributors
+Author-email: zope3-dev at zope.org
+License: ZPL 2.1
+Description: UNKNOWN
+Platform: UNKNOWN

Added: python-zope.testing/branches/upstream/current/README.txt
===================================================================
--- python-zope.testing/branches/upstream/current/README.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/README.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,37 @@
+zope.testing Package Readme
+==========================
+
+Overview
+--------
+
+See 'src/zope/testing/README.txt' for more information.
+
+Changes
+-------
+
+See CHANGES.txt.
+
+Installation
+------------
+
+See INSTALL.txt.
+
+
+Developer Resources
+-------------------
+
+- Subversion browser:
+
+  http://svn.zope.org/zope.testing/
+
+- Read-only Subversion checkout:
+
+  $ svn co svn://svn.zope.org/repos/main/zope.testing/trunk
+
+- Writable Subversion checkout:
+
+  $ svn co svn://svn.zope.org/repos/main/zope.testing/trunk
+
+- Note that the 'src/zope/testing' package is acutally a 'svn:externals' link
+  to the corresponding package in the Zope3 trunk (or to a specific tag,
+  for released versions of the package).


Property changes on: python-zope.testing/branches/upstream/current/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/develop.py
===================================================================
--- python-zope.testing/branches/upstream/current/develop.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/develop.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,21 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Workspace configuration wrapper script
+
+$Id: develop.py 66450 2006-04-04 21:09:30Z tseaver $
+"""
+
+import workspace.develop
+
+workspace.develop.main()


Property changes on: python-zope.testing/branches/upstream/current/develop.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/setup.cfg.in
===================================================================
--- python-zope.testing/branches/upstream/current/setup.cfg.in	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/setup.cfg.in	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,6 @@
+[development]
+depends = 
+
+[egg_info]
+tag_build = .dev
+tag_svn_revision = 1

Added: python-zope.testing/branches/upstream/current/setup.py
===================================================================
--- python-zope.testing/branches/upstream/current/setup.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/setup.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,42 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Setup for zope.testing package
+
+$Id: setup.py 66994 2006-04-15 00:52:17Z tseaver $
+"""
+
+import os
+
+try:
+    from setuptools import setup, Extension
+except ImportError, e:
+    from distutils.core import setup, Extension
+
+setup(name='zope.testing',
+      version='2.0.2',
+      url='http://svn.zope.org/zope.testing',
+      license='ZPL 2.1',
+      description='Zope3 Testrunner',
+      author='Zope Corporation and Contributors',
+      author_email='zope3-dev at zope.org',
+      
+      packages=['zope', 'zope.testing'],
+      package_dir = {'': 'src'},
+
+      namespace_packages=['zope',],
+      install_requires=['zope.exceptions'],
+      include_package_data = True,
+
+      zip_safe = False,
+      )


Property changes on: python-zope.testing/branches/upstream/current/setup.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,7 @@
+# namespace package boilerplate
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError, e:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)
+


Property changes on: python-zope.testing/branches/upstream/current/src/zope/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/DEPENDENCIES.cfg
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/DEPENDENCIES.cfg	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/DEPENDENCIES.cfg	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+zope.exceptions

Added: python-zope.testing/branches/upstream/current/src/zope/testing/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,30 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Set up testing environment
+
+$Id: __init__.py 26567 2004-07-16 06:58:27Z srichter $
+"""
+import os
+
+def patchTracebackModule():
+    """Use the ExceptionFormatter to show more info in tracebacks.
+    """
+    from zope.exceptions.exceptionformatter import format_exception
+    import traceback
+    traceback.format_exception = format_exception
+
+# Don't use the new exception formatter by default, since it
+# doesn't show filenames.
+if os.environ.get('NEW_ZOPE_EXCEPTION_FORMATTER', 0):
+    patchTracebackModule()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/cleanup.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/cleanup.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/cleanup.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,65 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Provide a standard cleanup registry
+
+Unit tests that change global data should include the CleanUp base
+class, which provides simpler setUp and tearDown methods that call
+global-data cleanup routines::
+
+  class Test(CleanUp, unittest.TestCase):
+
+      ....
+
+If custom setUp or tearDown are needed, then the base routines should
+be called, as in::
+
+  def tearDown(self):
+      super(Test, self).tearDown()
+      ....
+
+Cleanup routines for global data should be registered by passing them to
+addCleanup::
+
+
+  addCleanUp(pigRegistry._clear)
+
+
+$Id: cleanup.py 29143 2005-02-14 22:43:16Z srichter $
+"""
+_cleanups = []
+
+def addCleanUp(func, args=(), kw={}):
+    """Register a cleanup routines
+
+    Pass a function to be called to cleanup global data.
+    Optional argument tuple and keyword arguments may be passed.
+    """
+    _cleanups.append((func, args, kw))
+
+class CleanUp(object):
+    """Mix-in class providing clean-up setUp and tearDown routines."""
+
+    def cleanUp(self):
+        """Clean up global data."""
+        cleanUp()
+
+    setUp = tearDown = cleanUp
+
+
+def cleanUp():
+    """Clean up global data."""
+    for func, args, kw in _cleanups:
+        func(*args, **kw)
+
+setUp = tearDown = cleanUp


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/cleanup.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/doctest.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/doctest.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/doctest.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,2713 @@
+# Module doctest.
+# Released to the public domain 16-Jan-2001, by Tim Peters (tim at python.org).
+# Major enhancements and refactoring by:
+#     Jim Fulton
+#     Edward Loper
+
+# Provided as-is; use at your own risk; no warranty; no promises; enjoy!
+
+r"""Module doctest -- a framework for running examples in docstrings.
+
+In simplest use, end each module M to be tested with:
+
+def _test():
+    import doctest
+    doctest.testmod()
+
+if __name__ == "__main__":
+    _test()
+
+Then running the module as a script will cause the examples in the
+docstrings to get executed and verified:
+
+python M.py
+
+This won't display anything unless an example fails, in which case the
+failing example(s) and the cause(s) of the failure(s) are printed to stdout
+(why not stderr? because stderr is a lame hack <0.2 wink>), and the final
+line of output is "Test failed.".
+
+Run it with the -v switch instead:
+
+python M.py -v
+
+and a detailed report of all examples tried is printed to stdout, along
+with assorted summaries at the end.
+
+You can force verbose mode by passing "verbose=True" to testmod, or prohibit
+it by passing "verbose=False".  In either of those cases, sys.argv is not
+examined by testmod.
+
+There are a variety of other ways to run doctests, including integration
+with the unittest framework, and support for running non-Python text
+files containing doctests.  There are also many ways to override parts
+of doctest's default behaviors.  See the Library Reference Manual for
+details.
+"""
+
+__docformat__ = 'reStructuredText en'
+
+__all__ = [
+    # 0, Option Flags
+    'register_optionflag',
+    'DONT_ACCEPT_TRUE_FOR_1',
+    'DONT_ACCEPT_BLANKLINE',
+    'NORMALIZE_WHITESPACE',
+    'ELLIPSIS',
+    'IGNORE_EXCEPTION_DETAIL',
+    'COMPARISON_FLAGS',
+    'REPORT_UDIFF',
+    'REPORT_CDIFF',
+    'REPORT_NDIFF',
+    'REPORT_ONLY_FIRST_FAILURE',
+    'REPORTING_FLAGS',
+    # 1. Utility Functions
+    'is_private',
+    # 2. Example & DocTest
+    'Example',
+    'DocTest',
+    # 3. Doctest Parser
+    'DocTestParser',
+    # 4. Doctest Finder
+    'DocTestFinder',
+    # 5. Doctest Runner
+    'DocTestRunner',
+    'OutputChecker',
+    'DocTestFailure',
+    'UnexpectedException',
+    'DebugRunner',
+    # 6. Test Functions
+    'testmod',
+    'testfile',
+    'run_docstring_examples',
+    # 7. Tester
+    'Tester',
+    # 8. Unittest Support
+    'DocTestSuite',
+    'DocFileSuite',
+    'set_unittest_reportflags',
+    # 9. Debugging Support
+    'script_from_examples',
+    'testsource',
+    'debug_src',
+    'debug',
+]
+
+import __future__
+
+import sys, traceback, inspect, linecache, os, re, types
+import unittest, difflib, pdb, tempfile
+import warnings
+from StringIO import StringIO
+
+# Don't whine about the deprecated is_private function in this
+# module's tests.
+warnings.filterwarnings("ignore", "is_private", DeprecationWarning,
+                        __name__, 0)
+
+real_pdb_set_trace = pdb.set_trace
+
+# There are 4 basic classes:
+#  - Example: a <source, want> pair, plus an intra-docstring line number.
+#  - DocTest: a collection of examples, parsed from a docstring, plus
+#    info about where the docstring came from (name, filename, lineno).
+#  - DocTestFinder: extracts DocTests from a given object's docstring and
+#    its contained objects' docstrings.
+#  - DocTestRunner: runs DocTest cases, and accumulates statistics.
+#
+# So the basic picture is:
+#
+#                             list of:
+# +------+                   +---------+                   +-------+
+# |object| --DocTestFinder-> | DocTest | --DocTestRunner-> |results|
+# +------+                   +---------+                   +-------+
+#                            | Example |
+#                            |   ...   |
+#                            | Example |
+#                            +---------+
+
+# Option constants.
+
+OPTIONFLAGS_BY_NAME = {}
+def register_optionflag(name):
+    flag = 1 << len(OPTIONFLAGS_BY_NAME)
+    OPTIONFLAGS_BY_NAME[name] = flag
+    return flag
+
+DONT_ACCEPT_TRUE_FOR_1 = register_optionflag('DONT_ACCEPT_TRUE_FOR_1')
+DONT_ACCEPT_BLANKLINE = register_optionflag('DONT_ACCEPT_BLANKLINE')
+NORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE')
+ELLIPSIS = register_optionflag('ELLIPSIS')
+IGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL')
+
+COMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 |
+                    DONT_ACCEPT_BLANKLINE |
+                    NORMALIZE_WHITESPACE |
+                    ELLIPSIS |
+                    IGNORE_EXCEPTION_DETAIL)
+
+REPORT_UDIFF = register_optionflag('REPORT_UDIFF')
+REPORT_CDIFF = register_optionflag('REPORT_CDIFF')
+REPORT_NDIFF = register_optionflag('REPORT_NDIFF')
+REPORT_ONLY_FIRST_FAILURE = register_optionflag('REPORT_ONLY_FIRST_FAILURE')
+
+REPORTING_FLAGS = (REPORT_UDIFF |
+                   REPORT_CDIFF |
+                   REPORT_NDIFF |
+                   REPORT_ONLY_FIRST_FAILURE)
+
+# Special string markers for use in `want` strings:
+BLANKLINE_MARKER = '<BLANKLINE>'
+ELLIPSIS_MARKER = '...'
+
+######################################################################
+## Table of Contents
+######################################################################
+#  1. Utility Functions
+#  2. Example & DocTest -- store test cases
+#  3. DocTest Parser -- extracts examples from strings
+#  4. DocTest Finder -- extracts test cases from objects
+#  5. DocTest Runner -- runs test cases
+#  6. Test Functions -- convenient wrappers for testing
+#  7. Tester Class -- for backwards compatibility
+#  8. Unittest Support
+#  9. Debugging Support
+# 10. Example Usage
+
+######################################################################
+## 1. Utility Functions
+######################################################################
+
+def is_private(prefix, base):
+    """prefix, base -> true iff name prefix + "." + base is "private".
+
+    Prefix may be an empty string, and base does not contain a period.
+    Prefix is ignored (although functions you write conforming to this
+    protocol may make use of it).
+    Return true iff base begins with an (at least one) underscore, but
+    does not both begin and end with (at least) two underscores.
+
+    >>> is_private("a.b", "my_func")
+    False
+    >>> is_private("____", "_my_func")
+    True
+    >>> is_private("someclass", "__init__")
+    False
+    >>> is_private("sometypo", "__init_")
+    True
+    >>> is_private("x.y.z", "_")
+    True
+    >>> is_private("_x.y.z", "__")
+    False
+    >>> is_private("", "")  # senseless but consistent
+    False
+    """
+    warnings.warn("is_private is deprecated; it wasn't useful; "
+                  "examine DocTestFinder.find() lists instead",
+                  DeprecationWarning, stacklevel=2)
+    return base[:1] == "_" and not base[:2] == "__" == base[-2:]
+
+def _extract_future_flags(globs):
+    """
+    Return the compiler-flags associated with the future features that
+    have been imported into the given namespace (globs).
+    """
+    flags = 0
+    for fname in __future__.all_feature_names:
+        feature = globs.get(fname, None)
+        if feature is getattr(__future__, fname):
+            flags |= feature.compiler_flag
+    return flags
+
+def _normalize_module(module, depth=2):
+    """
+    Return the module specified by `module`.  In particular:
+      - If `module` is a module, then return module.
+      - If `module` is a string, then import and return the
+        module with that name.
+      - If `module` is None, then return the calling module.
+        The calling module is assumed to be the module of
+        the stack frame at the given depth in the call stack.
+    """
+    if inspect.ismodule(module):
+        return module
+    elif isinstance(module, (str, unicode)):
+        return __import__(module, globals(), locals(), ["*"])
+    elif module is None:
+        return sys.modules[sys._getframe(depth).f_globals['__name__']]
+    else:
+        raise TypeError("Expected a module, string, or None")
+
+def _indent(s, indent=4):
+    """
+    Add the given number of space characters to the beginning every
+    non-blank line in `s`, and return the result.
+    """
+    # This regexp matches the start of non-blank lines:
+    return re.sub('(?m)^(?!$)', indent*' ', s)
+
+def _exception_traceback(exc_info):
+    """
+    Return a string containing a traceback message for the given
+    exc_info tuple (as returned by sys.exc_info()).
+    """
+    # Get a traceback message.
+    excout = StringIO()
+    exc_type, exc_val, exc_tb = exc_info
+    traceback.print_exception(exc_type, exc_val, exc_tb, file=excout)
+    return excout.getvalue()
+
+# Override some StringIO methods.
+class _SpoofOut(StringIO):
+    def getvalue(self):
+        result = StringIO.getvalue(self)
+        # If anything at all was written, make sure there's a trailing
+        # newline.  There's no way for the expected output to indicate
+        # that a trailing newline is missing.
+        if result and not result.endswith("\n"):
+            result += "\n"
+        # Prevent softspace from screwing up the next test case, in
+        # case they used print with a trailing comma in an example.
+        if hasattr(self, "softspace"):
+            del self.softspace
+        return result
+
+    def truncate(self,   size=None):
+        StringIO.truncate(self, size)
+        if hasattr(self, "softspace"):
+            del self.softspace
+
+# Worst-case linear-time ellipsis matching.
+def _ellipsis_match(want, got):
+    """
+    Essentially the only subtle case:
+    >>> _ellipsis_match('aa...aa', 'aaa')
+    False
+    """
+    if ELLIPSIS_MARKER not in want:
+        return want == got
+
+    # Find "the real" strings.
+    ws = want.split(ELLIPSIS_MARKER)
+    assert len(ws) >= 2
+
+    # Deal with exact matches possibly needed at one or both ends.
+    startpos, endpos = 0, len(got)
+    w = ws[0]
+    if w:   # starts with exact match
+        if got.startswith(w):
+            startpos = len(w)
+            del ws[0]
+        else:
+            return False
+    w = ws[-1]
+    if w:   # ends with exact match
+        if got.endswith(w):
+            endpos -= len(w)
+            del ws[-1]
+        else:
+            return False
+
+    if startpos > endpos:
+        # Exact end matches required more characters than we have, as in
+        # _ellipsis_match('aa...aa', 'aaa')
+        return False
+
+    # For the rest, we only need to find the leftmost non-overlapping
+    # match for each piece.  If there's no overall match that way alone,
+    # there's no overall match period.
+    for w in ws:
+        # w may be '' at times, if there are consecutive ellipses, or
+        # due to an ellipsis at the start or end of `want`.  That's OK.
+        # Search for an empty string succeeds, and doesn't change startpos.
+        startpos = got.find(w, startpos, endpos)
+        if startpos < 0:
+            return False
+        startpos += len(w)
+
+    return True
+
+def _comment_line(line):
+    "Return a commented form of the given line"
+    line = line.rstrip()
+    if line:
+        return '# '+line
+    else:
+        return '#'
+
+class _OutputRedirectingPdb(pdb.Pdb):
+    """
+    A specialized version of the python debugger that redirects stdout
+    to a given stream when interacting with the user.  Stdout is *not*
+    redirected when traced code is executed.
+    """
+    def __init__(self, out):
+        self.__out = out
+        self.__debugger_used = False
+        pdb.Pdb.__init__(self)
+
+    def set_trace(self):
+        self.__debugger_used = True
+        pdb.Pdb.set_trace(self)
+
+    def set_continue(self):
+        # Calling set_continue unconditionally would break unit test coverage
+        # reporting, as Bdb.set_continue calls sys.settrace(None).
+        if self.__debugger_used:
+            pdb.Pdb.set_continue(self)
+
+    def trace_dispatch(self, *args):
+        # Redirect stdout to the given stream.
+        save_stdout = sys.stdout
+        sys.stdout = self.__out
+        # Call Pdb's trace dispatch method.
+        result = pdb.Pdb.trace_dispatch(self, *args)
+        # Restore stdout.
+        sys.stdout = save_stdout
+        return result
+
+# [XX] Normalize with respect to os.path.pardir?
+def _module_relative_path(module, path):
+    if not inspect.ismodule(module):
+        raise TypeError('Expected a module: %r' % module)
+    if path.startswith('/'):
+        raise ValueError('Module-relative files may not have absolute paths')
+
+    # Find the base directory for the path.
+    if hasattr(module, '__file__'):
+        # A normal module/package
+        basedir = os.path.split(module.__file__)[0]
+    elif module.__name__ == '__main__':
+        # An interactive session.
+        if len(sys.argv)>0 and sys.argv[0] != '':
+            basedir = os.path.split(sys.argv[0])[0]
+        else:
+            basedir = os.curdir
+    else:
+        # A module w/o __file__ (this includes builtins)
+        raise ValueError("Can't resolve paths relative to the module " +
+                         module + " (it has no __file__)")
+
+    # Combine the base directory and the path.
+    return os.path.join(basedir, *(path.split('/')))
+
+######################################################################
+## 2. Example & DocTest
+######################################################################
+## - An "example" is a <source, want> pair, where "source" is a
+##   fragment of source code, and "want" is the expected output for
+##   "source."  The Example class also includes information about
+##   where the example was extracted from.
+##
+## - A "doctest" is a collection of examples, typically extracted from
+##   a string (such as an object's docstring).  The DocTest class also
+##   includes information about where the string was extracted from.
+
+class Example:
+    """
+    A single doctest example, consisting of source code and expected
+    output.  `Example` defines the following attributes:
+
+      - source: A single Python statement, always ending with a newline.
+        The constructor adds a newline if needed.
+
+      - want: The expected output from running the source code (either
+        from stdout, or a traceback in case of exception).  `want` ends
+        with a newline unless it's empty, in which case it's an empty
+        string.  The constructor adds a newline if needed.
+
+      - exc_msg: The exception message generated by the example, if
+        the example is expected to generate an exception; or `None` if
+        it is not expected to generate an exception.  This exception
+        message is compared against the return value of
+        `traceback.format_exception_only()`.  `exc_msg` ends with a
+        newline unless it's `None`.  The constructor adds a newline
+        if needed.
+
+      - lineno: The line number within the DocTest string containing
+        this Example where the Example begins.  This line number is
+        zero-based, with respect to the beginning of the DocTest.
+
+      - indent: The example's indentation in the DocTest string.
+        I.e., the number of space characters that preceed the
+        example's first prompt.
+
+      - options: A dictionary mapping from option flags to True or
+        False, which is used to override default options for this
+        example.  Any option flags not contained in this dictionary
+        are left at their default value (as specified by the
+        DocTestRunner's optionflags).  By default, no options are set.
+    """
+    def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
+                 options=None):
+        # Normalize inputs.
+        if not source.endswith('\n'):
+            source += '\n'
+        if want and not want.endswith('\n'):
+            want += '\n'
+        if exc_msg is not None and not exc_msg.endswith('\n'):
+            exc_msg += '\n'
+        # Store properties.
+        self.source = source
+        self.want = want
+        self.lineno = lineno
+        self.indent = indent
+        if options is None: options = {}
+        self.options = options
+        self.exc_msg = exc_msg
+
+class DocTest:
+    """
+    A collection of doctest examples that should be run in a single
+    namespace.  Each `DocTest` defines the following attributes:
+
+      - examples: the list of examples.
+
+      - globs: The namespace (aka globals) that the examples should
+        be run in.
+
+      - name: A name identifying the DocTest (typically, the name of
+        the object whose docstring this DocTest was extracted from).
+
+      - filename: The name of the file that this DocTest was extracted
+        from, or `None` if the filename is unknown.
+
+      - lineno: The line number within filename where this DocTest
+        begins, or `None` if the line number is unavailable.  This
+        line number is zero-based, with respect to the beginning of
+        the file.
+
+      - docstring: The string that the examples were extracted from,
+        or `None` if the string is unavailable.
+    """
+    def __init__(self, examples, globs, name, filename, lineno, docstring):
+        """
+        Create a new DocTest containing the given examples.  The
+        DocTest's globals are initialized with a copy of `globs`.
+        """
+        assert not isinstance(examples, basestring), \
+               "DocTest no longer accepts str; use DocTestParser instead"
+        self.examples = examples
+        self.docstring = docstring
+        self.globs = globs.copy()
+        self.name = name
+        self.filename = filename
+        self.lineno = lineno
+
+    def __repr__(self):
+        if len(self.examples) == 0:
+            examples = 'no examples'
+        elif len(self.examples) == 1:
+            examples = '1 example'
+        else:
+            examples = '%d examples' % len(self.examples)
+        return ('<DocTest %s from %s:%s (%s)>' %
+                (self.name, self.filename, self.lineno, examples))
+
+
+    # This lets us sort tests by name:
+    def __cmp__(self, other):
+        if not isinstance(other, DocTest):
+            return -1
+        return cmp((self.name, self.filename, self.lineno, id(self)),
+                   (other.name, other.filename, other.lineno, id(other)))
+
+######################################################################
+## 3. DocTestParser
+######################################################################
+
+class DocTestParser:
+    """
+    A class used to parse strings containing doctest examples.
+    """
+    # This regular expression is used to find doctest examples in a
+    # string.  It defines three groups: `source` is the source code
+    # (including leading indentation and prompts); `indent` is the
+    # indentation of the first (PS1) line of the source code; and
+    # `want` is the expected output (including leading indentation).
+    _EXAMPLE_RE = re.compile(r'''
+        # Source consists of a PS1 line followed by zero or more PS2 lines.
+        (?P<source>
+            (?:^(?P<indent> [ ]*) >>>    .*)    # PS1 line
+            (?:\n           [ ]*  \.\.\. .*)*)  # PS2 lines
+        \n?
+        # Want consists of any non-blank lines that do not start with PS1.
+        (?P<want> (?:(?![ ]*$)    # Not a blank line
+                     (?![ ]*>>>)  # Not a line starting with PS1
+                     .*$\n?       # But any other line
+                  )*)
+        ''', re.MULTILINE | re.VERBOSE)
+
+    # A regular expression for handling `want` strings that contain
+    # expected exceptions.  It divides `want` into three pieces:
+    #    - the traceback header line (`hdr`)
+    #    - the traceback stack (`stack`)
+    #    - the exception message (`msg`), as generated by
+    #      traceback.format_exception_only()
+    # `msg` may have multiple lines.  We assume/require that the
+    # exception message is the first non-indented line starting with a word
+    # character following the traceback header line.
+    _EXCEPTION_RE = re.compile(r"""
+        # Grab the traceback header.  Different versions of Python have
+        # said different things on the first traceback line.
+        ^(?P<hdr> Traceback\ \(
+            (?: most\ recent\ call\ last
+            |   innermost\ last
+            ) \) :
+        )
+        \s* $                # toss trailing whitespace on the header.
+        (?P<stack> .*?)      # don't blink: absorb stuff until...
+        ^ (?P<msg> \w+ .*)   #     a line *starts* with alphanum.
+        """, re.VERBOSE | re.MULTILINE | re.DOTALL)
+
+    # A callable returning a true value iff its argument is a blank line
+    # or contains a single comment.
+    _IS_BLANK_OR_COMMENT = re.compile(r'^[ ]*(#.*)?$').match
+
+    def parse(self, string, name='<string>'):
+        """
+        Divide the given string into examples and intervening text,
+        and return them as a list of alternating Examples and strings.
+        Line numbers for the Examples are 0-based.  The optional
+        argument `name` is a name identifying this string, and is only
+        used for error messages.
+        """
+        string = string.expandtabs()
+        # If all lines begin with the same indentation, then strip it.
+        min_indent = self._min_indent(string)
+        if min_indent > 0:
+            string = '\n'.join([l[min_indent:] for l in string.split('\n')])
+
+        output = []
+        charno, lineno = 0, 0
+        # Find all doctest examples in the string:
+        for m in self._EXAMPLE_RE.finditer(string):
+            # Add the pre-example text to `output`.
+            output.append(string[charno:m.start()])
+            # Update lineno (lines before this example)
+            lineno += string.count('\n', charno, m.start())
+            # Extract info from the regexp match.
+            (source, options, want, exc_msg) = \
+                     self._parse_example(m, name, lineno)
+            # Create an Example, and add it to the list.
+            if not self._IS_BLANK_OR_COMMENT(source):
+                output.append( Example(source, want, exc_msg,
+                                    lineno=lineno,
+                                    indent=min_indent+len(m.group('indent')),
+                                    options=options) )
+            # Update lineno (lines inside this example)
+            lineno += string.count('\n', m.start(), m.end())
+            # Update charno.
+            charno = m.end()
+        # Add any remaining post-example text to `output`.
+        output.append(string[charno:])
+        return output
+
+    def get_doctest(self, string, globs, name, filename, lineno):
+        """
+        Extract all doctest examples from the given string, and
+        collect them into a `DocTest` object.
+
+        `globs`, `name`, `filename`, and `lineno` are attributes for
+        the new `DocTest` object.  See the documentation for `DocTest`
+        for more information.
+        """
+        return DocTest(self.get_examples(string, name), globs,
+                       name, filename, lineno, string)
+
+    def get_examples(self, string, name='<string>'):
+        """
+        Extract all doctest examples from the given string, and return
+        them as a list of `Example` objects.  Line numbers are
+        0-based, because it's most common in doctests that nothing
+        interesting appears on the same line as opening triple-quote,
+        and so the first interesting line is called \"line 1\" then.
+
+        The optional argument `name` is a name identifying this
+        string, and is only used for error messages.
+        """
+        return [x for x in self.parse(string, name)
+                if isinstance(x, Example)]
+
+    def _parse_example(self, m, name, lineno):
+        """
+        Given a regular expression match from `_EXAMPLE_RE` (`m`),
+        return a pair `(source, want)`, where `source` is the matched
+        example's source code (with prompts and indentation stripped);
+        and `want` is the example's expected output (with indentation
+        stripped).
+
+        `name` is the string's name, and `lineno` is the line number
+        where the example starts; both are used for error messages.
+        """
+        # Get the example's indentation level.
+        indent = len(m.group('indent'))
+
+        # Divide source into lines; check that they're properly
+        # indented; and then strip their indentation & prompts.
+        source_lines = m.group('source').split('\n')
+        self._check_prompt_blank(source_lines, indent, name, lineno)
+        self._check_prefix(source_lines[1:], ' '*indent + '.', name, lineno)
+        source = '\n'.join([sl[indent+4:] for sl in source_lines])
+
+        # Divide want into lines; check that it's properly indented; and
+        # then strip the indentation.  Spaces before the last newline should
+        # be preserved, so plain rstrip() isn't good enough.
+        want = m.group('want')
+        want_lines = want.split('\n')
+        if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
+            del want_lines[-1]  # forget final newline & spaces after it
+        self._check_prefix(want_lines, ' '*indent, name,
+                           lineno + len(source_lines))
+        want = '\n'.join([wl[indent:] for wl in want_lines])
+
+        # If `want` contains a traceback message, then extract it.
+        m = self._EXCEPTION_RE.match(want)
+        if m:
+            exc_msg = m.group('msg')
+        else:
+            exc_msg = None
+
+        # Extract options from the source.
+        options = self._find_options(source, name, lineno)
+
+        return source, options, want, exc_msg
+
+    # This regular expression looks for option directives in the
+    # source code of an example.  Option directives are comments
+    # starting with "doctest:".  Warning: this may give false
+    # positives for string-literals that contain the string
+    # "#doctest:".  Eliminating these false positives would require
+    # actually parsing the string; but we limit them by ignoring any
+    # line containing "#doctest:" that is *followed* by a quote mark.
+    _OPTION_DIRECTIVE_RE = re.compile(r'#\s*doctest:\s*([^\n\'"]*)$',
+                                      re.MULTILINE)
+
+    def _find_options(self, source, name, lineno):
+        """
+        Return a dictionary containing option overrides extracted from
+        option directives in the given source string.
+
+        `name` is the string's name, and `lineno` is the line number
+        where the example starts; both are used for error messages.
+        """
+        options = {}
+        # (note: with the current regexp, this will match at most once:)
+        for m in self._OPTION_DIRECTIVE_RE.finditer(source):
+            option_strings = m.group(1).replace(',', ' ').split()
+            for option in option_strings:
+                if (option[0] not in '+-' or
+                    option[1:] not in OPTIONFLAGS_BY_NAME):
+                    raise ValueError('line %r of the doctest for %s '
+                                     'has an invalid option: %r' %
+                                     (lineno+1, name, option))
+                flag = OPTIONFLAGS_BY_NAME[option[1:]]
+                options[flag] = (option[0] == '+')
+        if options and self._IS_BLANK_OR_COMMENT(source):
+            raise ValueError('line %r of the doctest for %s has an option '
+                             'directive on a line with no example: %r' %
+                             (lineno, name, source))
+        return options
+
+    # This regular expression finds the indentation of every non-blank
+    # line in a string.
+    _INDENT_RE = re.compile('^([ ]*)(?=\S)', re.MULTILINE)
+
+    def _min_indent(self, s):
+        "Return the minimum indentation of any non-blank line in `s`"
+        indents = [len(indent) for indent in self._INDENT_RE.findall(s)]
+        if len(indents) > 0:
+            return min(indents)
+        else:
+            return 0
+
+    def _check_prompt_blank(self, lines, indent, name, lineno):
+        """
+        Given the lines of a source string (including prompts and
+        leading indentation), check to make sure that every prompt is
+        followed by a space character.  If any line is not followed by
+        a space character, then raise ValueError.
+        """
+        for i, line in enumerate(lines):
+            if len(line) >= indent+4 and line[indent+3] != ' ':
+                raise ValueError('line %r of the docstring for %s '
+                                 'lacks blank after %s: %r' %
+                                 (lineno+i+1, name,
+                                  line[indent:indent+3], line))
+
+    def _check_prefix(self, lines, prefix, name, lineno):
+        """
+        Check that every line in the given list starts with the given
+        prefix; if any line does not, then raise a ValueError.
+        """
+        for i, line in enumerate(lines):
+            if line and not line.startswith(prefix):
+                raise ValueError('line %r of the docstring for %s has '
+                                 'inconsistent leading whitespace: %r' %
+                                 (lineno+i+1, name, line))
+
+
+######################################################################
+## 4. DocTest Finder
+######################################################################
+
+class DocTestFinder:
+    """
+    A class used to extract the DocTests that are relevant to a given
+    object, from its docstring and the docstrings of its contained
+    objects.  Doctests can currently be extracted from the following
+    object types: modules, functions, classes, methods, staticmethods,
+    classmethods, and properties.
+    """
+
+    def __init__(self, verbose=False, parser=DocTestParser(),
+                 recurse=True, _namefilter=None, exclude_empty=True):
+        """
+        Create a new doctest finder.
+
+        The optional argument `parser` specifies a class or
+        function that should be used to create new DocTest objects (or
+        objects that implement the same interface as DocTest).  The
+        signature for this factory function should match the signature
+        of the DocTest constructor.
+
+        If the optional argument `recurse` is false, then `find` will
+        only examine the given object, and not any contained objects.
+
+        If the optional argument `exclude_empty` is false, then `find`
+        will include tests for objects with empty docstrings.
+        """
+        self._parser = parser
+        self._verbose = verbose
+        self._recurse = recurse
+        self._exclude_empty = exclude_empty
+        # _namefilter is undocumented, and exists only for temporary backward-
+        # compatibility support of testmod's deprecated isprivate mess.
+        self._namefilter = _namefilter
+
+    def find(self, obj, name=None, module=None, globs=None,
+             extraglobs=None):
+        """
+        Return a list of the DocTests that are defined by the given
+        object's docstring, or by any of its contained objects'
+        docstrings.
+
+        The optional parameter `module` is the module that contains
+        the given object.  If the module is not specified or is None, then
+        the test finder will attempt to automatically determine the
+        correct module.  The object's module is used:
+
+            - As a default namespace, if `globs` is not specified.
+            - To prevent the DocTestFinder from extracting DocTests
+              from objects that are imported from other modules.
+            - To find the name of the file containing the object.
+            - To help find the line number of the object within its
+              file.
+
+        Contained objects whose module does not match `module` are ignored.
+
+        If `module` is False, no attempt to find the module will be made.
+        This is obscure, of use mostly in tests:  if `module` is False, or
+        is None but cannot be found automatically, then all objects are
+        considered to belong to the (non-existent) module, so all contained
+        objects will (recursively) be searched for doctests.
+
+        The globals for each DocTest is formed by combining `globs`
+        and `extraglobs` (bindings in `extraglobs` override bindings
+        in `globs`).  A new copy of the globals dictionary is created
+        for each DocTest.  If `globs` is not specified, then it
+        defaults to the module's `__dict__`, if specified, or {}
+        otherwise.  If `extraglobs` is not specified, then it defaults
+        to {}.
+
+        """
+        # If name was not specified, then extract it from the object.
+        if name is None:
+            name = getattr(obj, '__name__', None)
+            if name is None:
+                raise ValueError("DocTestFinder.find: name must be given "
+                        "when obj.__name__ doesn't exist: %r" %
+                                 (type(obj),))
+
+        # Find the module that contains the given object (if obj is
+        # a module, then module=obj.).  Note: this may fail, in which
+        # case module will be None.
+        if module is False:
+            module = None
+        elif module is None:
+            module = inspect.getmodule(obj)
+
+        # Read the module's source code.  This is used by
+        # DocTestFinder._find_lineno to find the line number for a
+        # given object's docstring.
+        try:
+            file = inspect.getsourcefile(obj) or inspect.getfile(obj)
+            source_lines = linecache.getlines(file)
+            if not source_lines:
+                source_lines = None
+        except TypeError:
+            source_lines = None
+
+        # Initialize globals, and merge in extraglobs.
+        if globs is None:
+            if module is None:
+                globs = {}
+            else:
+                globs = module.__dict__.copy()
+        else:
+            globs = globs.copy()
+        if extraglobs is not None:
+            globs.update(extraglobs)
+
+        # Recursively expore `obj`, extracting DocTests.
+        tests = []
+        self._find(tests, obj, name, module, source_lines, globs, {})
+        return tests
+
+    def _filter(self, obj, prefix, base):
+        """
+        Return true if the given object should not be examined.
+        """
+        return (self._namefilter is not None and
+                self._namefilter(prefix, base))
+
+    def _from_module(self, module, object):
+        """
+        Return true if the given object is defined in the given
+        module.
+        """
+        if module is None:
+            return True
+        elif inspect.isfunction(object):
+            return module.__dict__ is object.func_globals
+        elif inspect.isclass(object):
+            return module.__name__ == object.__module__
+        elif inspect.getmodule(object) is not None:
+            return module is inspect.getmodule(object)
+        elif hasattr(object, '__module__'):
+            return module.__name__ == object.__module__
+        elif isinstance(object, property):
+            return True # [XX] no way not be sure.
+        else:
+            raise ValueError("object must be a class or function")
+
+    def _find(self, tests, obj, name, module, source_lines, globs, seen):
+        """
+        Find tests for the given object and any contained objects, and
+        add them to `tests`.
+        """
+        if self._verbose:
+            print 'Finding tests in %s' % name
+
+        # If we've already processed this object, then ignore it.
+        if id(obj) in seen:
+            return
+        seen[id(obj)] = 1
+
+        # Find a test for this object, and add it to the list of tests.
+        test = self._get_test(obj, name, module, globs, source_lines)
+        if test is not None:
+            tests.append(test)
+
+        # Look for tests in a module's contained objects.
+        if inspect.ismodule(obj) and self._recurse:
+            for valname, val in obj.__dict__.items():
+                # Check if this contained object should be ignored.
+                if self._filter(val, name, valname):
+                    continue
+                valname = '%s.%s' % (name, valname)
+                # Recurse to functions & classes.
+                if ((inspect.isfunction(val) or inspect.isclass(val)) and
+                    self._from_module(module, val)):
+                    self._find(tests, val, valname, module, source_lines,
+                               globs, seen)
+
+        # Look for tests in a module's __test__ dictionary.
+        if inspect.ismodule(obj) and self._recurse:
+            for valname, val in getattr(obj, '__test__', {}).items():
+                if not isinstance(valname, basestring):
+                    raise ValueError("DocTestFinder.find: __test__ keys "
+                                     "must be strings: %r" %
+                                     (type(valname),))
+                if not (inspect.isfunction(val) or inspect.isclass(val) or
+                        inspect.ismethod(val) or inspect.ismodule(val) or
+                        isinstance(val, basestring)):
+                    raise ValueError("DocTestFinder.find: __test__ values "
+                                     "must be strings, functions, methods, "
+                                     "classes, or modules: %r" %
+                                     (type(val),))
+                valname = '%s.__test__.%s' % (name, valname)
+                self._find(tests, val, valname, module, source_lines,
+                           globs, seen)
+
+        # Look for tests in a class's contained objects.
+        if inspect.isclass(obj) and self._recurse:
+            for valname, val in obj.__dict__.items():
+                # Check if this contained object should be ignored.
+                if self._filter(val, name, valname):
+                    continue
+                # Special handling for staticmethod/classmethod.
+                if isinstance(val, staticmethod):
+                    val = getattr(obj, valname)
+                if isinstance(val, classmethod):
+                    val = getattr(obj, valname).im_func
+
+                # Recurse to methods, properties, and nested classes.
+                if ((inspect.isfunction(val) or inspect.isclass(val) or
+                      isinstance(val, property)) and
+                      self._from_module(module, val)):
+                    valname = '%s.%s' % (name, valname)
+                    self._find(tests, val, valname, module, source_lines,
+                               globs, seen)
+
+    def _get_test(self, obj, name, module, globs, source_lines):
+        """
+        Return a DocTest for the given object, if it defines a docstring;
+        otherwise, return None.
+        """
+        # Extract the object's docstring.  If it doesn't have one,
+        # then return None (no test for this object).
+        if isinstance(obj, basestring):
+            docstring = obj
+        else:
+            try:
+                if obj.__doc__ is None:
+                    docstring = ''
+                else:
+                    docstring = obj.__doc__
+                    if not isinstance(docstring, basestring):
+                        docstring = str(docstring)
+            except (TypeError, AttributeError):
+                docstring = ''
+
+        # Find the docstring's location in the file.
+        lineno = self._find_lineno(obj, source_lines)
+
+        # Don't bother if the docstring is empty.
+        if self._exclude_empty and not docstring:
+            return None
+
+        # Return a DocTest for this object.
+        if module is None:
+            filename = None
+        else:
+            filename = getattr(module, '__file__', module.__name__)
+            if filename[-4:] in (".pyc", ".pyo"):
+                filename = filename[:-1]
+        return self._parser.get_doctest(docstring, globs, name,
+                                        filename, lineno)
+
+    def _find_lineno(self, obj, source_lines):
+        """
+        Return a line number of the given object's docstring.  Note:
+        this method assumes that the object has a docstring.
+        """
+        lineno = None
+
+        # Find the line number for modules.
+        if inspect.ismodule(obj):
+            lineno = 0
+
+        # Find the line number for classes.
+        # Note: this could be fooled if a class is defined multiple
+        # times in a single file.
+        if inspect.isclass(obj):
+            if source_lines is None:
+                return None
+            pat = re.compile(r'^\s*class\s*%s\b' %
+                             getattr(obj, '__name__', '-'))
+            for i, line in enumerate(source_lines):
+                if pat.match(line):
+                    lineno = i
+                    break
+
+        # Find the line number for functions & methods.
+        if inspect.ismethod(obj): obj = obj.im_func
+        if inspect.isfunction(obj): obj = obj.func_code
+        if inspect.istraceback(obj): obj = obj.tb_frame
+        if inspect.isframe(obj): obj = obj.f_code
+        if inspect.iscode(obj):
+            lineno = getattr(obj, 'co_firstlineno', None)-1
+
+        # Find the line number where the docstring starts.  Assume
+        # that it's the first line that begins with a quote mark.
+        # Note: this could be fooled by a multiline function
+        # signature, where a continuation line begins with a quote
+        # mark.
+        if lineno is not None:
+            if source_lines is None:
+                return lineno+1
+            pat = re.compile('(^|.*:)\s*\w*("|\')')
+            for lineno in range(lineno, len(source_lines)):
+                if pat.match(source_lines[lineno]):
+                    return lineno
+
+        # We couldn't find the line number.
+        return None
+
+######################################################################
+## 5. DocTest Runner
+######################################################################
+
+class DocTestRunner:
+    """
+    A class used to run DocTest test cases, and accumulate statistics.
+    The `run` method is used to process a single DocTest case.  It
+    returns a tuple `(f, t)`, where `t` is the number of test cases
+    tried, and `f` is the number of test cases that failed.
+
+        >>> tests = DocTestFinder().find(_TestClass)
+        >>> runner = DocTestRunner(verbose=False)
+        >>> for test in tests:
+        ...     print runner.run(test)
+        (0, 2)
+        (0, 1)
+        (0, 2)
+        (0, 2)
+
+    The `summarize` method prints a summary of all the test cases that
+    have been run by the runner, and returns an aggregated `(f, t)`
+    tuple:
+
+        >>> runner.summarize(verbose=1)
+        4 items passed all tests:
+           2 tests in _TestClass
+           2 tests in _TestClass.__init__
+           2 tests in _TestClass.get
+           1 tests in _TestClass.square
+        7 tests in 4 items.
+        7 passed and 0 failed.
+        Test passed.
+        (0, 7)
+
+    The aggregated number of tried examples and failed examples is
+    also available via the `tries` and `failures` attributes:
+
+        >>> runner.tries
+        7
+        >>> runner.failures
+        0
+
+    The comparison between expected outputs and actual outputs is done
+    by an `OutputChecker`.  This comparison may be customized with a
+    number of option flags; see the documentation for `testmod` for
+    more information.  If the option flags are insufficient, then the
+    comparison may also be customized by passing a subclass of
+    `OutputChecker` to the constructor.
+
+    The test runner's display output can be controlled in two ways.
+    First, an output function (`out) can be passed to
+    `TestRunner.run`; this function will be called with strings that
+    should be displayed.  It defaults to `sys.stdout.write`.  If
+    capturing the output is not sufficient, then the display output
+    can be also customized by subclassing DocTestRunner, and
+    overriding the methods `report_start`, `report_success`,
+    `report_unexpected_exception`, and `report_failure`.
+    """
+    # This divider string is used to separate failure messages, and to
+    # separate sections of the summary.
+    DIVIDER = "*" * 70
+
+    def __init__(self, checker=None, verbose=None, optionflags=0):
+        """
+        Create a new test runner.
+
+        Optional keyword arg `checker` is the `OutputChecker` that
+        should be used to compare the expected outputs and actual
+        outputs of doctest examples.
+
+        Optional keyword arg 'verbose' prints lots of stuff if true,
+        only failures if false; by default, it's true iff '-v' is in
+        sys.argv.
+
+        Optional argument `optionflags` can be used to control how the
+        test runner compares expected output to actual output, and how
+        it displays failures.  See the documentation for `testmod` for
+        more information.
+        """
+        self._checker = checker or OutputChecker()
+        if verbose is None:
+            verbose = '-v' in sys.argv
+        self._verbose = verbose
+        self.optionflags = optionflags
+        self.original_optionflags = optionflags
+
+        # Keep track of the examples we've run.
+        self.tries = 0
+        self.failures = 0
+        self._name2ft = {}
+
+        # Create a fake output target for capturing doctest output.
+        self._fakeout = _SpoofOut()
+
+    #/////////////////////////////////////////////////////////////////
+    # Reporting methods
+    #/////////////////////////////////////////////////////////////////
+
+    def report_start(self, out, test, example):
+        """
+        Report that the test runner is about to process the given
+        example.  (Only displays a message if verbose=True)
+        """
+        if self._verbose:
+            if example.want:
+                out('Trying:\n' + _indent(example.source) +
+                    'Expecting:\n' + _indent(example.want))
+            else:
+                out('Trying:\n' + _indent(example.source) +
+                    'Expecting nothing\n')
+
+    def report_success(self, out, test, example, got):
+        """
+        Report that the given example ran successfully.  (Only
+        displays a message if verbose=True)
+        """
+        if self._verbose:
+            out("ok\n")
+
+    def report_failure(self, out, test, example, got):
+        """
+        Report that the given example failed.
+        """
+        out(self._failure_header(test, example) +
+            self._checker.output_difference(example, got, self.optionflags))
+
+    def report_unexpected_exception(self, out, test, example, exc_info):
+        """
+        Report that the given example raised an unexpected exception.
+        """
+        out(self._failure_header(test, example) +
+            'Exception raised:\n' + _indent(_exception_traceback(exc_info)))
+
+    def _failure_header(self, test, example):
+        out = [self.DIVIDER]
+        if test.filename:
+            if test.lineno is not None and example.lineno is not None:
+                lineno = test.lineno + example.lineno + 1
+            else:
+                lineno = '?'
+            out.append('File "%s", line %s, in %s' %
+                       (test.filename, lineno, test.name))
+        else:
+            out.append('Line %s, in %s' % (example.lineno+1, test.name))
+        out.append('Failed example:')
+        source = example.source
+        out.append(_indent(source))
+        return '\n'.join(out)
+
+    #/////////////////////////////////////////////////////////////////
+    # DocTest Running
+    #/////////////////////////////////////////////////////////////////
+
+    def __run(self, test, compileflags, out):
+        """
+        Run the examples in `test`.  Write the outcome of each example
+        with one of the `DocTestRunner.report_*` methods, using the
+        writer function `out`.  `compileflags` is the set of compiler
+        flags that should be used to execute examples.  Return a tuple
+        `(f, t)`, where `t` is the number of examples tried, and `f`
+        is the number of examples that failed.  The examples are run
+        in the namespace `test.globs`.
+        """
+        # Keep track of the number of failures and tries.
+        failures = tries = 0
+
+        # Save the option flags (since option directives can be used
+        # to modify them).
+        original_optionflags = self.optionflags
+
+        SUCCESS, FAILURE, BOOM = range(3) # `outcome` state
+
+        check = self._checker.check_output
+
+        # Process each example.
+        for examplenum, example in enumerate(test.examples):
+
+            # If REPORT_ONLY_FIRST_FAILURE is set, then supress
+            # reporting after the first failure.
+            quiet = (self.optionflags & REPORT_ONLY_FIRST_FAILURE and
+                     failures > 0)
+
+            # Merge in the example's options.
+            self.optionflags = original_optionflags
+            if example.options:
+                for (optionflag, val) in example.options.items():
+                    if val:
+                        self.optionflags |= optionflag
+                    else:
+                        self.optionflags &= ~optionflag
+
+            # Record that we started this example.
+            tries += 1
+            if not quiet:
+                self.report_start(out, test, example)
+
+            # Use a special filename for compile(), so we can retrieve
+            # the source code during interactive debugging (see
+            # __patched_linecache_getlines).
+            filename = '<doctest %s[%d]>' % (test.name, examplenum)
+
+            # Run the example in the given context (globs), and record
+            # any exception that gets raised.  (But don't intercept
+            # keyboard interrupts.)
+            try:
+                # Don't blink!  This is where the user's code gets run.
+                exec compile(example.source, filename, "single",
+                             compileflags, 1) in test.globs
+                self.debugger.set_continue() # ==== Example Finished ====
+                exception = None
+            except KeyboardInterrupt:
+                raise
+            except:
+                exception = sys.exc_info()
+                self.debugger.set_continue() # ==== Example Finished ====
+
+            got = self._fakeout.getvalue()  # the actual output
+            self._fakeout.truncate(0)
+            outcome = FAILURE   # guilty until proved innocent or insane
+
+            # If the example executed without raising any exceptions,
+            # verify its output.
+            if exception is None:
+                if check(example.want, got, self.optionflags):
+                    outcome = SUCCESS
+
+            # The example raised an exception:  check if it was expected.
+            else:
+                exc_info = sys.exc_info()
+                exc_msg = traceback.format_exception_only(*exc_info[:2])[-1]
+                if not quiet:
+                    got += _exception_traceback(exc_info)
+
+                # If `example.exc_msg` is None, then we weren't expecting
+                # an exception.
+                if example.exc_msg is None:
+                    outcome = BOOM
+
+                # We expected an exception:  see whether it matches.
+                elif check(example.exc_msg, exc_msg, self.optionflags):
+                    outcome = SUCCESS
+
+                # Another chance if they didn't care about the detail.
+                elif self.optionflags & IGNORE_EXCEPTION_DETAIL:
+                    m1 = re.match(r'[^:]*:', example.exc_msg)
+                    m2 = re.match(r'[^:]*:', exc_msg)
+                    if m1 and m2 and check(m1.group(0), m2.group(0),
+                                           self.optionflags):
+                        outcome = SUCCESS
+
+            # Report the outcome.
+            if outcome is SUCCESS:
+                if not quiet:
+                    self.report_success(out, test, example, got)
+            elif outcome is FAILURE:
+                if not quiet:
+                    self.report_failure(out, test, example, got)
+                failures += 1
+            elif outcome is BOOM:
+                if not quiet:
+                    self.report_unexpected_exception(out, test, example,
+                                                     exc_info)
+                failures += 1
+            else:
+                assert False, ("unknown outcome", outcome)
+
+        # Restore the option flags (in case they were modified)
+        self.optionflags = original_optionflags
+
+        # Record and return the number of failures and tries.
+        self.__record_outcome(test, failures, tries)
+        return failures, tries
+
+    def __record_outcome(self, test, f, t):
+        """
+        Record the fact that the given DocTest (`test`) generated `f`
+        failures out of `t` tried examples.
+        """
+        f2, t2 = self._name2ft.get(test.name, (0,0))
+        self._name2ft[test.name] = (f+f2, t+t2)
+        self.failures += f
+        self.tries += t
+
+    __LINECACHE_FILENAME_RE = re.compile(r'<doctest '
+                                         r'(?P<name>[\w\.]+)'
+                                         r'\[(?P<examplenum>\d+)\]>$')
+    def __patched_linecache_getlines(self, filename):
+        m = self.__LINECACHE_FILENAME_RE.match(filename)
+        if m and m.group('name') == self.test.name:
+            example = self.test.examples[int(m.group('examplenum'))]
+            return example.source.splitlines(True)
+        else:
+            return self.save_linecache_getlines(filename)
+
+    def run(self, test, compileflags=None, out=None, clear_globs=True):
+        """
+        Run the examples in `test`, and display the results using the
+        writer function `out`.
+
+        The examples are run in the namespace `test.globs`.  If
+        `clear_globs` is true (the default), then this namespace will
+        be cleared after the test runs, to help with garbage
+        collection.  If you would like to examine the namespace after
+        the test completes, then use `clear_globs=False`.
+
+        `compileflags` gives the set of flags that should be used by
+        the Python compiler when running the examples.  If not
+        specified, then it will default to the set of future-import
+        flags that apply to `globs`.
+
+        The output of each example is checked using
+        `DocTestRunner.check_output`, and the results are formatted by
+        the `DocTestRunner.report_*` methods.
+        """
+        self.test = test
+
+        if compileflags is None:
+            compileflags = _extract_future_flags(test.globs)
+
+        save_stdout = sys.stdout
+        if out is None:
+            out = save_stdout.write
+        sys.stdout = self._fakeout
+
+        # Patch pdb.set_trace to restore sys.stdout during interactive
+        # debugging (so it's not still redirected to self._fakeout).
+        # Note that the interactive output will go to *our*
+        # save_stdout, even if that's not the real sys.stdout; this
+        # allows us to write test cases for the set_trace behavior.
+        save_set_trace = pdb.set_trace
+        self.debugger = _OutputRedirectingPdb(save_stdout)
+        self.debugger.reset()
+        pdb.set_trace = self.debugger.set_trace
+
+        # Patch linecache.getlines, so we can see the example's source
+        # when we're inside the debugger.
+        self.save_linecache_getlines = linecache.getlines
+        linecache.getlines = self.__patched_linecache_getlines
+
+        try:
+            return self.__run(test, compileflags, out)
+        finally:
+            sys.stdout = save_stdout
+            pdb.set_trace = save_set_trace
+            linecache.getlines = self.save_linecache_getlines
+            if clear_globs:
+                test.globs.clear()
+
+    #/////////////////////////////////////////////////////////////////
+    # Summarization
+    #/////////////////////////////////////////////////////////////////
+    def summarize(self, verbose=None):
+        """
+        Print a summary of all the test cases that have been run by
+        this DocTestRunner, and return a tuple `(f, t)`, where `f` is
+        the total number of failed examples, and `t` is the total
+        number of tried examples.
+
+        The optional `verbose` argument controls how detailed the
+        summary is.  If the verbosity is not specified, then the
+        DocTestRunner's verbosity is used.
+        """
+        if verbose is None:
+            verbose = self._verbose
+        notests = []
+        passed = []
+        failed = []
+        totalt = totalf = 0
+        for x in self._name2ft.items():
+            name, (f, t) = x
+            assert f <= t
+            totalt += t
+            totalf += f
+            if t == 0:
+                notests.append(name)
+            elif f == 0:
+                passed.append( (name, t) )
+            else:
+                failed.append(x)
+        if verbose:
+            if notests:
+                print len(notests), "items had no tests:"
+                notests.sort()
+                for thing in notests:
+                    print "   ", thing
+            if passed:
+                print len(passed), "items passed all tests:"
+                passed.sort()
+                for thing, count in passed:
+                    print " %3d tests in %s" % (count, thing)
+        if failed:
+            print self.DIVIDER
+            print len(failed), "items had failures:"
+            failed.sort()
+            for thing, (f, t) in failed:
+                print " %3d of %3d in %s" % (f, t, thing)
+        if verbose:
+            print totalt, "tests in", len(self._name2ft), "items."
+            print totalt - totalf, "passed and", totalf, "failed."
+        if totalf:
+            print "***Test Failed***", totalf, "failures."
+        elif verbose:
+            print "Test passed."
+        return totalf, totalt
+
+    #/////////////////////////////////////////////////////////////////
+    # Backward compatibility cruft to maintain doctest.master.
+    #/////////////////////////////////////////////////////////////////
+    def merge(self, other):
+        d = self._name2ft
+        for name, (f, t) in other._name2ft.items():
+            if name in d:
+                print "*** DocTestRunner.merge: '" + name + "' in both" \
+                    " testers; summing outcomes."
+                f2, t2 = d[name]
+                f = f + f2
+                t = t + t2
+            d[name] = f, t
+
+class OutputChecker:
+    """
+    A class used to check the whether the actual output from a doctest
+    example matches the expected output.  `OutputChecker` defines two
+    methods: `check_output`, which compares a given pair of outputs,
+    and returns true if they match; and `output_difference`, which
+    returns a string describing the differences between two outputs.
+    """
+    def check_output(self, want, got, optionflags):
+        """
+        Return True iff the actual output from an example (`got`)
+        matches the expected output (`want`).  These strings are
+        always considered to match if they are identical; but
+        depending on what option flags the test runner is using,
+        several non-exact match types are also possible.  See the
+        documentation for `TestRunner` for more information about
+        option flags.
+        """
+        # Handle the common case first, for efficiency:
+        # if they're string-identical, always return true.
+        if got == want:
+            return True
+
+        # The values True and False replaced 1 and 0 as the return
+        # value for boolean comparisons in Python 2.3.
+        if not (optionflags & DONT_ACCEPT_TRUE_FOR_1):
+            if (got,want) == ("True\n", "1\n"):
+                return True
+            if (got,want) == ("False\n", "0\n"):
+                return True
+
+        # <BLANKLINE> can be used as a special sequence to signify a
+        # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used.
+        if not (optionflags & DONT_ACCEPT_BLANKLINE):
+            # Replace <BLANKLINE> in want with a blank line.
+            want = re.sub('(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER),
+                          '', want)
+            # If a line in got contains only spaces, then remove the
+            # spaces.
+            got = re.sub('(?m)^\s*?$', '', got)
+            if got == want:
+                return True
+
+        # This flag causes doctest to ignore any differences in the
+        # contents of whitespace strings.  Note that this can be used
+        # in conjunction with the ELLIPSIS flag.
+        if optionflags & NORMALIZE_WHITESPACE:
+            got = ' '.join(got.split())
+            want = ' '.join(want.split())
+            if got == want:
+                return True
+
+        # The ELLIPSIS flag says to let the sequence "..." in `want`
+        # match any substring in `got`.
+        if optionflags & ELLIPSIS:
+            if _ellipsis_match(want, got):
+                return True
+
+        # We didn't find any match; return false.
+        return False
+
+    # Should we do a fancy diff?
+    def _do_a_fancy_diff(self, want, got, optionflags):
+        # Not unless they asked for a fancy diff.
+        if not optionflags & (REPORT_UDIFF |
+                              REPORT_CDIFF |
+                              REPORT_NDIFF):
+            return False
+
+        # If expected output uses ellipsis, a meaningful fancy diff is
+        # too hard ... or maybe not.  In two real-life failures Tim saw,
+        # a diff was a major help anyway, so this is commented out.
+        # [todo] _ellipsis_match() knows which pieces do and don't match,
+        # and could be the basis for a kick-ass diff in this case.
+        ##if optionflags & ELLIPSIS and ELLIPSIS_MARKER in want:
+        ##    return False
+
+        # ndiff does intraline difference marking, so can be useful even
+        # for 1-line differences.
+        if optionflags & REPORT_NDIFF:
+            return True
+
+        # The other diff types need at least a few lines to be helpful.
+        return want.count('\n') > 2 and got.count('\n') > 2
+
+    def output_difference(self, example, got, optionflags):
+        """
+        Return a string describing the differences between the
+        expected output for a given example (`example`) and the actual
+        output (`got`).  `optionflags` is the set of option flags used
+        to compare `want` and `got`.
+        """
+        want = example.want
+        # If <BLANKLINE>s are being used, then replace blank lines
+        # with <BLANKLINE> in the actual output string.
+        if not (optionflags & DONT_ACCEPT_BLANKLINE):
+            got = re.sub('(?m)^[ ]*(?=\n)', BLANKLINE_MARKER, got)
+
+        # Check if we should use diff.
+        if self._do_a_fancy_diff(want, got, optionflags):
+            # Split want & got into lines.
+            want_lines = want.splitlines(True)  # True == keep line ends
+            got_lines = got.splitlines(True)
+            # Use difflib to find their differences.
+            if optionflags & REPORT_UDIFF:
+                diff = difflib.unified_diff(want_lines, got_lines, n=2)
+                diff = list(diff)[2:] # strip the diff header
+                kind = 'unified diff with -expected +actual'
+            elif optionflags & REPORT_CDIFF:
+                diff = difflib.context_diff(want_lines, got_lines, n=2)
+                diff = list(diff)[2:] # strip the diff header
+                kind = 'context diff with expected followed by actual'
+            elif optionflags & REPORT_NDIFF:
+                engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK)
+                diff = list(engine.compare(want_lines, got_lines))
+                kind = 'ndiff with -expected +actual'
+            else:
+                assert 0, 'Bad diff option'
+            # Remove trailing whitespace on diff output.
+            diff = [line.rstrip() + '\n' for line in diff]
+            return 'Differences (%s):\n' % kind + _indent(''.join(diff))
+
+        # If we're not using diff, then simply list the expected
+        # output followed by the actual output.
+        if want and got:
+            return 'Expected:\n%sGot:\n%s' % (_indent(want), _indent(got))
+        elif want:
+            return 'Expected:\n%sGot nothing\n' % _indent(want)
+        elif got:
+            return 'Expected nothing\nGot:\n%s' % _indent(got)
+        else:
+            return 'Expected nothing\nGot nothing\n'
+
+class DocTestFailure(Exception):
+    """A DocTest example has failed in debugging mode.
+
+    The exception instance has variables:
+
+    - test: the DocTest object being run
+
+    - excample: the Example object that failed
+
+    - got: the actual output
+    """
+    def __init__(self, test, example, got):
+        self.test = test
+        self.example = example
+        self.got = got
+
+    def __str__(self):
+        return str(self.test)
+
+class UnexpectedException(Exception):
+    """A DocTest example has encountered an unexpected exception
+
+    The exception instance has variables:
+
+    - test: the DocTest object being run
+
+    - excample: the Example object that failed
+
+    - exc_info: the exception info
+    """
+    def __init__(self, test, example, exc_info):
+        self.test = test
+        self.example = example
+        self.exc_info = exc_info
+
+    def __str__(self):
+        return str(self.test)
+
+class DebugRunner(DocTestRunner):
+    r"""Run doc tests but raise an exception as soon as there is a failure.
+
+       If an unexpected exception occurs, an UnexpectedException is raised.
+       It contains the test, the example, and the original exception:
+
+         >>> runner = DebugRunner(verbose=False)
+         >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42',
+         ...                                    {}, 'foo', 'foo.py', 0)
+         >>> try:
+         ...     runner.run(test)
+         ... except UnexpectedException, failure:
+         ...     pass
+
+         >>> failure.test is test
+         True
+
+         >>> failure.example.want
+         '42\n'
+
+         >>> exc_info = failure.exc_info
+         >>> raise exc_info[0], exc_info[1], exc_info[2]
+         Traceback (most recent call last):
+         ...
+         KeyError
+
+       We wrap the original exception to give the calling application
+       access to the test and example information.
+
+       If the output doesn't match, then a DocTestFailure is raised:
+
+         >>> test = DocTestParser().get_doctest('''
+         ...      >>> x = 1
+         ...      >>> x
+         ...      2
+         ...      ''', {}, 'foo', 'foo.py', 0)
+
+         >>> try:
+         ...    runner.run(test)
+         ... except DocTestFailure, failure:
+         ...    pass
+
+       DocTestFailure objects provide access to the test:
+
+         >>> failure.test is test
+         True
+
+       As well as to the example:
+
+         >>> failure.example.want
+         '2\n'
+
+       and the actual output:
+
+         >>> failure.got
+         '1\n'
+
+       If a failure or error occurs, the globals are left intact:
+
+         >>> del test.globs['__builtins__']
+         >>> test.globs
+         {'x': 1}
+
+         >>> test = DocTestParser().get_doctest('''
+         ...      >>> x = 2
+         ...      >>> raise KeyError
+         ...      ''', {}, 'foo', 'foo.py', 0)
+
+         >>> runner.run(test)
+         Traceback (most recent call last):
+         ...
+         UnexpectedException: <DocTest foo from foo.py:0 (2 examples)>
+
+         >>> del test.globs['__builtins__']
+         >>> test.globs
+         {'x': 2}
+
+       But the globals are cleared if there is no error:
+
+         >>> test = DocTestParser().get_doctest('''
+         ...      >>> x = 2
+         ...      ''', {}, 'foo', 'foo.py', 0)
+
+         >>> runner.run(test)
+         (0, 1)
+
+         >>> test.globs
+         {}
+
+       """
+
+    def run(self, test, compileflags=None, out=None, clear_globs=True):
+        r = DocTestRunner.run(self, test, compileflags, out, False)
+        if clear_globs:
+            test.globs.clear()
+        return r
+
+    def report_unexpected_exception(self, out, test, example, exc_info):
+        raise UnexpectedException(test, example, exc_info)
+
+    def report_failure(self, out, test, example, got):
+        raise DocTestFailure(test, example, got)
+
+######################################################################
+## 6. Test Functions
+######################################################################
+# These should be backwards compatible.
+
+# For backward compatibility, a global instance of a DocTestRunner
+# class, updated by testmod.
+master = None
+
+def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None,
+            report=True, optionflags=0, extraglobs=None,
+            raise_on_error=False, exclude_empty=False):
+    """m=None, name=None, globs=None, verbose=None, isprivate=None,
+       report=True, optionflags=0, extraglobs=None, raise_on_error=False,
+       exclude_empty=False
+
+    Test examples in docstrings in functions and classes reachable
+    from module m (or the current module if m is not supplied), starting
+    with m.__doc__.  Unless isprivate is specified, private names
+    are not skipped.
+
+    Also test examples reachable from dict m.__test__ if it exists and is
+    not None.  m.__test__ maps names to functions, classes and strings;
+    function and class docstrings are tested even if the name is private;
+    strings are tested directly, as if they were docstrings.
+
+    Return (#failures, #tests).
+
+    See doctest.__doc__ for an overview.
+
+    Optional keyword arg "name" gives the name of the module; by default
+    use m.__name__.
+
+    Optional keyword arg "globs" gives a dict to be used as the globals
+    when executing examples; by default, use m.__dict__.  A copy of this
+    dict is actually used for each docstring, so that each docstring's
+    examples start with a clean slate.
+
+    Optional keyword arg "extraglobs" gives a dictionary that should be
+    merged into the globals that are used to execute examples.  By
+    default, no extra globals are used.  This is new in 2.4.
+
+    Optional keyword arg "verbose" prints lots of stuff if true, prints
+    only failures if false; by default, it's true iff "-v" is in sys.argv.
+
+    Optional keyword arg "report" prints a summary at the end when true,
+    else prints nothing at the end.  In verbose mode, the summary is
+    detailed, else very brief (in fact, empty if all tests passed).
+
+    Optional keyword arg "optionflags" or's together module constants,
+    and defaults to 0.  This is new in 2.3.  Possible values (see the
+    docs for details):
+
+        DONT_ACCEPT_TRUE_FOR_1
+        DONT_ACCEPT_BLANKLINE
+        NORMALIZE_WHITESPACE
+        ELLIPSIS
+        IGNORE_EXCEPTION_DETAIL
+        REPORT_UDIFF
+        REPORT_CDIFF
+        REPORT_NDIFF
+        REPORT_ONLY_FIRST_FAILURE
+
+    Optional keyword arg "raise_on_error" raises an exception on the
+    first unexpected exception or failure. This allows failures to be
+    post-mortem debugged.
+
+    Deprecated in Python 2.4:
+    Optional keyword arg "isprivate" specifies a function used to
+    determine whether a name is private.  The default function is
+    treat all functions as public.  Optionally, "isprivate" can be
+    set to doctest.is_private to skip over functions marked as private
+    using the underscore naming convention; see its docs for details.
+
+    Advanced tomfoolery:  testmod runs methods of a local instance of
+    class doctest.Tester, then merges the results into (or creates)
+    global Tester instance doctest.master.  Methods of doctest.master
+    can be called directly too, if you want to do something unusual.
+    Passing report=0 to testmod is especially useful then, to delay
+    displaying a summary.  Invoke doctest.master.summarize(verbose)
+    when you're done fiddling.
+    """
+    global master
+
+    if isprivate is not None:
+        warnings.warn("the isprivate argument is deprecated; "
+                      "examine DocTestFinder.find() lists instead",
+                      DeprecationWarning)
+
+    # If no module was given, then use __main__.
+    if m is None:
+        # DWA - m will still be None if this wasn't invoked from the command
+        # line, in which case the following TypeError is about as good an error
+        # as we should expect
+        m = sys.modules.get('__main__')
+
+    # Check that we were actually given a module.
+    if not inspect.ismodule(m):
+        raise TypeError("testmod: module required; %r" % (m,))
+
+    # If no name was given, then use the module's name.
+    if name is None:
+        name = m.__name__
+
+    # Find, parse, and run all tests in the given module.
+    finder = DocTestFinder(_namefilter=isprivate, exclude_empty=exclude_empty)
+
+    if raise_on_error:
+        runner = DebugRunner(verbose=verbose, optionflags=optionflags)
+    else:
+        runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
+
+    for test in finder.find(m, name, globs=globs, extraglobs=extraglobs):
+        runner.run(test)
+
+    if report:
+        runner.summarize()
+
+    if master is None:
+        master = runner
+    else:
+        master.merge(runner)
+
+    return runner.failures, runner.tries
+
+def testfile(filename, module_relative=True, name=None, package=None,
+             globs=None, verbose=None, report=True, optionflags=0,
+             extraglobs=None, raise_on_error=False, parser=DocTestParser()):
+    """
+    Test examples in the given file.  Return (#failures, #tests).
+
+    Optional keyword arg "module_relative" specifies how filenames
+    should be interpreted:
+
+      - If "module_relative" is True (the default), then "filename"
+         specifies a module-relative path.  By default, this path is
+         relative to the calling module's directory; but if the
+         "package" argument is specified, then it is relative to that
+         package.  To ensure os-independence, "filename" should use
+         "/" characters to separate path segments, and should not
+         be an absolute path (i.e., it may not begin with "/").
+
+      - If "module_relative" is False, then "filename" specifies an
+        os-specific path.  The path may be absolute or relative (to
+        the current working directory).
+
+    Optional keyword arg "name" gives the name of the test; by default
+    use the file's basename.
+
+    Optional keyword argument "package" is a Python package or the
+    name of a Python package whose directory should be used as the
+    base directory for a module relative filename.  If no package is
+    specified, then the calling module's directory is used as the base
+    directory for module relative filenames.  It is an error to
+    specify "package" if "module_relative" is False.
+
+    Optional keyword arg "globs" gives a dict to be used as the globals
+    when executing examples; by default, use {}.  A copy of this dict
+    is actually used for each docstring, so that each docstring's
+    examples start with a clean slate.
+
+    Optional keyword arg "extraglobs" gives a dictionary that should be
+    merged into the globals that are used to execute examples.  By
+    default, no extra globals are used.
+
+    Optional keyword arg "verbose" prints lots of stuff if true, prints
+    only failures if false; by default, it's true iff "-v" is in sys.argv.
+
+    Optional keyword arg "report" prints a summary at the end when true,
+    else prints nothing at the end.  In verbose mode, the summary is
+    detailed, else very brief (in fact, empty if all tests passed).
+
+    Optional keyword arg "optionflags" or's together module constants,
+    and defaults to 0.  Possible values (see the docs for details):
+
+        DONT_ACCEPT_TRUE_FOR_1
+        DONT_ACCEPT_BLANKLINE
+        NORMALIZE_WHITESPACE
+        ELLIPSIS
+        IGNORE_EXCEPTION_DETAIL
+        REPORT_UDIFF
+        REPORT_CDIFF
+        REPORT_NDIFF
+        REPORT_ONLY_FIRST_FAILURE
+
+    Optional keyword arg "raise_on_error" raises an exception on the
+    first unexpected exception or failure. This allows failures to be
+    post-mortem debugged.
+
+    Optional keyword arg "parser" specifies a DocTestParser (or
+    subclass) that should be used to extract tests from the files.
+
+    Advanced tomfoolery:  testmod runs methods of a local instance of
+    class doctest.Tester, then merges the results into (or creates)
+    global Tester instance doctest.master.  Methods of doctest.master
+    can be called directly too, if you want to do something unusual.
+    Passing report=0 to testmod is especially useful then, to delay
+    displaying a summary.  Invoke doctest.master.summarize(verbose)
+    when you're done fiddling.
+    """
+    global master
+
+    if package and not module_relative:
+        raise ValueError("Package may only be specified for module-"
+                         "relative paths.")
+
+    # Relativize the path
+    if module_relative:
+        package = _normalize_module(package)
+        filename = _module_relative_path(package, filename)
+
+    # If no name was given, then use the file's name.
+    if name is None:
+        name = os.path.basename(filename)
+
+    # Assemble the globals.
+    if globs is None:
+        globs = {}
+    else:
+        globs = globs.copy()
+    if extraglobs is not None:
+        globs.update(extraglobs)
+
+    if raise_on_error:
+        runner = DebugRunner(verbose=verbose, optionflags=optionflags)
+    else:
+        runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
+
+    # Read the file, convert it to a test, and run it.
+    s = open(filename).read()
+    test = parser.get_doctest(s, globs, name, filename, 0)
+    runner.run(test)
+
+    if report:
+        runner.summarize()
+
+    if master is None:
+        master = runner
+    else:
+        master.merge(runner)
+
+    return runner.failures, runner.tries
+
+def run_docstring_examples(f, globs, verbose=False, name="NoName",
+                           compileflags=None, optionflags=0):
+    """
+    Test examples in the given object's docstring (`f`), using `globs`
+    as globals.  Optional argument `name` is used in failure messages.
+    If the optional argument `verbose` is true, then generate output
+    even if there are no failures.
+
+    `compileflags` gives the set of flags that should be used by the
+    Python compiler when running the examples.  If not specified, then
+    it will default to the set of future-import flags that apply to
+    `globs`.
+
+    Optional keyword arg `optionflags` specifies options for the
+    testing and output.  See the documentation for `testmod` for more
+    information.
+    """
+    # Find, parse, and run all tests in the given module.
+    finder = DocTestFinder(verbose=verbose, recurse=False)
+    runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
+    for test in finder.find(f, name, globs=globs):
+        runner.run(test, compileflags=compileflags)
+
+######################################################################
+## 7. Tester
+######################################################################
+# This is provided only for backwards compatibility.  It's not
+# actually used in any way.
+
+class Tester:
+    def __init__(self, mod=None, globs=None, verbose=None,
+                 isprivate=None, optionflags=0):
+
+        warnings.warn("class Tester is deprecated; "
+                      "use class doctest.DocTestRunner instead",
+                      DeprecationWarning, stacklevel=2)
+        if mod is None and globs is None:
+            raise TypeError("Tester.__init__: must specify mod or globs")
+        if mod is not None and not inspect.ismodule(mod):
+            raise TypeError("Tester.__init__: mod must be a module; %r" %
+                            (mod,))
+        if globs is None:
+            globs = mod.__dict__
+        self.globs = globs
+
+        self.verbose = verbose
+        self.isprivate = isprivate
+        self.optionflags = optionflags
+        self.testfinder = DocTestFinder(_namefilter=isprivate)
+        self.testrunner = DocTestRunner(verbose=verbose,
+                                        optionflags=optionflags)
+
+    def runstring(self, s, name):
+        test = DocTestParser().get_doctest(s, self.globs, name, None, None)
+        if self.verbose:
+            print "Running string", name
+        (f,t) = self.testrunner.run(test)
+        if self.verbose:
+            print f, "of", t, "examples failed in string", name
+        return (f,t)
+
+    def rundoc(self, object, name=None, module=None):
+        f = t = 0
+        tests = self.testfinder.find(object, name, module=module,
+                                     globs=self.globs)
+        for test in tests:
+            (f2, t2) = self.testrunner.run(test)
+            (f,t) = (f+f2, t+t2)
+        return (f,t)
+
+    def rundict(self, d, name, module=None):
+        import new
+        m = new.module(name)
+        m.__dict__.update(d)
+        if module is None:
+            module = False
+        return self.rundoc(m, name, module)
+
+    def run__test__(self, d, name):
+        import new
+        m = new.module(name)
+        m.__test__ = d
+        return self.rundoc(m, name)
+
+    def summarize(self, verbose=None):
+        return self.testrunner.summarize(verbose)
+
+    def merge(self, other):
+        self.testrunner.merge(other.testrunner)
+
+######################################################################
+## 8. Unittest Support
+######################################################################
+
+_unittest_reportflags = 0
+
+def set_unittest_reportflags(flags):
+    """Sets the unittest option flags.
+
+    The old flag is returned so that a runner could restore the old
+    value if it wished to:
+
+      >>> old = _unittest_reportflags
+      >>> set_unittest_reportflags(REPORT_NDIFF |
+      ...                          REPORT_ONLY_FIRST_FAILURE) == old
+      True
+
+      >>> import doctest
+      >>> doctest._unittest_reportflags == (REPORT_NDIFF |
+      ...                                   REPORT_ONLY_FIRST_FAILURE)
+      True
+
+    Only reporting flags can be set:
+
+      >>> set_unittest_reportflags(ELLIPSIS)
+      Traceback (most recent call last):
+      ...
+      ValueError: ('Only reporting flags allowed', 8)
+
+      >>> set_unittest_reportflags(old) == (REPORT_NDIFF |
+      ...                                   REPORT_ONLY_FIRST_FAILURE)
+      True
+    """
+    global _unittest_reportflags
+
+    if (flags & REPORTING_FLAGS) != flags:
+        raise ValueError("Only reporting flags allowed", flags)
+    old = _unittest_reportflags
+    _unittest_reportflags = flags
+    return old
+
+_para_re = re.compile(r'\s*\n\s*\n\s*')
+def _unittest_count(docstring):
+    words = 0
+    count = 0
+    for p in _para_re.split(docstring):
+        p = p.strip()
+        if not p:
+            continue
+        if p.startswith('>>> '):
+            if words:
+                count += 1
+                words = 0
+        else:
+            words = 1
+
+    return count or 1
+
+
+class DocTestFailureException(AssertionError):
+    """Use custom exception for doctest unit test failures
+    """
+
+class DocTestCase(unittest.TestCase):
+
+    def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
+                 checker=None):
+
+        unittest.TestCase.__init__(self)
+        self._dt_optionflags = optionflags
+        self._dt_checker = checker
+        self._dt_test = test
+        self._dt_globs = test.globs.copy()
+        self._dt_setUp = setUp
+        self._dt_tearDown = tearDown
+
+        self._dt_count = _unittest_count(test.docstring)
+
+    def countTestCases(self):
+        return self._dt_count
+
+    def setUp(self):
+        test = self._dt_test
+
+        if self._dt_setUp is not None:
+            self._dt_setUp(test)
+
+    def tearDown(self):
+        test = self._dt_test
+
+        if self._dt_tearDown is not None:
+            self._dt_tearDown(test)
+
+        # restore the original globs
+        test.globs.clear()
+        test.globs.update(self._dt_globs)
+
+    failureException = DocTestFailureException
+
+    def runTest(self):
+        test = self._dt_test
+        old = sys.stdout
+        new = StringIO()
+        optionflags = self._dt_optionflags
+
+        if not (optionflags & REPORTING_FLAGS):
+            # The option flags don't include any reporting flags,
+            # so add the default reporting flags
+            optionflags |= _unittest_reportflags
+
+        runner = DocTestRunner(optionflags=optionflags,
+                               checker=self._dt_checker, verbose=False)
+
+        try:
+            runner.DIVIDER = "-"*70
+            failures, tries = runner.run(
+                test, out=new.write, clear_globs=False)
+        finally:
+            sys.stdout = old
+
+        if failures:
+            raise self.failureException(self.format_failure(new.getvalue()))
+
+    def format_failure(self, err):
+        test = self._dt_test
+        if test.lineno is None:
+            lineno = 'unknown line number'
+        else:
+            lineno = '%s' % test.lineno
+        lname = '.'.join(test.name.split('.')[-1:])
+        return ('Failed doctest test for %s\n'
+                '  File "%s", line %s, in %s\n\n%s'
+                % (test.name, test.filename, lineno, lname, err)
+                )
+
+    def debug(self):
+        r"""Run the test case without results and without catching exceptions
+
+           The unit test framework includes a debug method on test cases
+           and test suites to support post-mortem debugging.  The test code
+           is run in such a way that errors are not caught.  This way a
+           caller can catch the errors and initiate post-mortem debugging.
+
+           The DocTestCase provides a debug method that raises
+           UnexpectedException errors if there is an unexepcted
+           exception:
+
+             >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42',
+             ...                {}, 'foo', 'foo.py', 0)
+             >>> case = DocTestCase(test)
+             >>> try:
+             ...     case.debug()
+             ... except UnexpectedException, failure:
+             ...     pass
+
+           The UnexpectedException contains the test, the example, and
+           the original exception:
+
+             >>> failure.test is test
+             True
+
+             >>> failure.example.want
+             '42\n'
+
+             >>> exc_info = failure.exc_info
+             >>> raise exc_info[0], exc_info[1], exc_info[2]
+             Traceback (most recent call last):
+             ...
+             KeyError
+
+           If the output doesn't match, then a DocTestFailure is raised:
+
+             >>> test = DocTestParser().get_doctest('''
+             ...      >>> x = 1
+             ...      >>> x
+             ...      2
+             ...      ''', {}, 'foo', 'foo.py', 0)
+             >>> case = DocTestCase(test)
+
+             >>> try:
+             ...    case.debug()
+             ... except DocTestFailure, failure:
+             ...    pass
+
+           DocTestFailure objects provide access to the test:
+
+             >>> failure.test is test
+             True
+
+           As well as to the example:
+
+             >>> failure.example.want
+             '2\n'
+
+           and the actual output:
+
+             >>> failure.got
+             '1\n'
+
+           """
+
+        self.setUp()
+        runner = DebugRunner(optionflags=self._dt_optionflags,
+                             checker=self._dt_checker, verbose=False)
+        runner.run(self._dt_test, clear_globs=False)
+        self.tearDown()
+
+    def id(self):
+        return self._dt_test.name
+
+    def __repr__(self):
+        name = self._dt_test.name.split('.')
+        return "%s (%s)" % (name[-1], '.'.join(name[:-1]))
+
+    __str__ = __repr__
+
+    def shortDescription(self):
+        return "Doctest: " + self._dt_test.name
+
+def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None,
+                 **options):
+    """
+    Convert doctest tests for a module to a unittest test suite.
+
+    This converts each documentation string in a module that
+    contains doctest tests to a unittest test case.  If any of the
+    tests in a doc string fail, then the test case fails.  An exception
+    is raised showing the name of the file containing the test and a
+    (sometimes approximate) line number.
+
+    The `module` argument provides the module to be tested.  The argument
+    can be either a module or a module name.
+
+    If no argument is given, the calling module is used.
+
+    A number of options may be provided as keyword arguments:
+
+    setUp
+      A set-up function.  This is called before running the
+      tests in each file. The setUp function will be passed a DocTest
+      object.  The setUp function can access the test globals as the
+      globs attribute of the test passed.
+
+    tearDown
+      A tear-down function.  This is called after running the
+      tests in each file.  The tearDown function will be passed a DocTest
+      object.  The tearDown function can access the test globals as the
+      globs attribute of the test passed.
+
+    globs
+      A dictionary containing initial global variables for the tests.
+
+    optionflags
+       A set of doctest option flags expressed as an integer.
+    """
+
+    if test_finder is None:
+        test_finder = DocTestFinder()
+
+    module = _normalize_module(module)
+    tests = test_finder.find(module, globs=globs, extraglobs=extraglobs)
+    if globs is None:
+        globs = module.__dict__
+    if not tests:
+        # Why do we want to do this? Because it reveals a bug that might
+        # otherwise be hidden.
+        raise ValueError(module, "has no tests")
+
+    tests.sort()
+    suite = unittest.TestSuite()
+    for test in tests:
+        if len(test.examples) == 0:
+            continue
+        if not test.filename:
+            filename = module.__file__
+            if filename[-4:] in (".pyc", ".pyo"):
+                filename = filename[:-1]
+            test.filename = filename
+        suite.addTest(DocTestCase(test, **options))
+
+    return suite
+
+class DocFileCase(DocTestCase):
+
+    def id(self):
+        return '_'.join(self._dt_test.name.split('.'))
+
+    def __repr__(self):
+        return self._dt_test.filename
+    __str__ = __repr__
+
+    def format_failure(self, err):
+        return ('Failed doctest test for %s\n  File "%s", line 0\n\n%s'
+                % (self._dt_test.name, self._dt_test.filename, err)
+                )
+
+def DocFileTest(path, module_relative=True, package=None,
+                globs=None, parser=DocTestParser(), **options):
+    if globs is None:
+        globs = {}
+    else:
+        globs = globs.copy()
+
+    if package and not module_relative:
+        raise ValueError("Package may only be specified for module-"
+                         "relative paths.")
+
+    # Relativize the path.
+    if module_relative:
+        package = _normalize_module(package)
+        path = _module_relative_path(package, path)
+    if "__file__" not in globs:
+        globs["__file__"] = path
+
+    # Find the file and read it.
+    name = os.path.basename(path)
+    doc = open(path).read()
+
+    # Convert it to a test, and wrap it in a DocFileCase.
+    test = parser.get_doctest(doc, globs, name, path, 0)
+    return DocFileCase(test, **options)
+
+def DocFileSuite(*paths, **kw):
+    """A unittest suite for one or more doctest files.
+
+    The path to each doctest file is given as a string; the
+    interpretation of that string depends on the keyword argument
+    "module_relative".
+
+    A number of options may be provided as keyword arguments:
+
+    module_relative
+      If "module_relative" is True, then the given file paths are
+      interpreted as os-independent module-relative paths.  By
+      default, these paths are relative to the calling module's
+      directory; but if the "package" argument is specified, then
+      they are relative to that package.  To ensure os-independence,
+      "filename" should use "/" characters to separate path
+      segments, and may not be an absolute path (i.e., it may not
+      begin with "/").
+
+      If "module_relative" is False, then the given file paths are
+      interpreted as os-specific paths.  These paths may be absolute
+      or relative (to the current working directory).
+
+    package
+      A Python package or the name of a Python package whose directory
+      should be used as the base directory for module relative paths.
+      If "package" is not specified, then the calling module's
+      directory is used as the base directory for module relative
+      filenames.  It is an error to specify "package" if
+      "module_relative" is False.
+
+    setUp
+      A set-up function.  This is called before running the
+      tests in each file. The setUp function will be passed a DocTest
+      object.  The setUp function can access the test globals as the
+      globs attribute of the test passed.
+
+    tearDown
+      A tear-down function.  This is called after running the
+      tests in each file.  The tearDown function will be passed a DocTest
+      object.  The tearDown function can access the test globals as the
+      globs attribute of the test passed.
+
+    globs
+      A dictionary containing initial global variables for the tests.
+
+    optionflags
+      A set of doctest option flags expressed as an integer.
+
+    parser
+      A DocTestParser (or subclass) that should be used to extract
+      tests from the files.
+    """
+    suite = unittest.TestSuite()
+
+    # We do this here so that _normalize_module is called at the right
+    # level.  If it were called in DocFileTest, then this function
+    # would be the caller and we might guess the package incorrectly.
+    if kw.get('module_relative', True):
+        kw['package'] = _normalize_module(kw.get('package'))
+
+    for path in paths:
+        suite.addTest(DocFileTest(path, **kw))
+
+    return suite
+
+######################################################################
+## 9. Debugging Support
+######################################################################
+
+def script_from_examples(s):
+    r"""Extract script from text with examples.
+
+       Converts text with examples to a Python script.  Example input is
+       converted to regular code.  Example output and all other words
+       are converted to comments:
+
+       >>> text = '''
+       ...       Here are examples of simple math.
+       ...
+       ...           Python has super accurate integer addition
+       ...
+       ...           >>> 2 + 2
+       ...           5
+       ...
+       ...           And very friendly error messages:
+       ...
+       ...           >>> 1/0
+       ...           To Infinity
+       ...           And
+       ...           Beyond
+       ...
+       ...           You can use logic if you want:
+       ...
+       ...           >>> if 0:
+       ...           ...    blah
+       ...           ...    blah
+       ...           ...
+       ...
+       ...           Ho hum
+       ...           '''
+
+       >>> print script_from_examples(text)
+       # Here are examples of simple math.
+       #
+       #     Python has super accurate integer addition
+       #
+       2 + 2
+       # Expected:
+       ## 5
+       #
+       #     And very friendly error messages:
+       #
+       1/0
+       # Expected:
+       ## To Infinity
+       ## And
+       ## Beyond
+       #
+       #     You can use logic if you want:
+       #
+       if 0:
+          blah
+          blah
+       #
+       #     Ho hum
+       """
+    output = []
+    for piece in DocTestParser().parse(s):
+        if isinstance(piece, Example):
+            # Add the example's source code (strip trailing NL)
+            output.append(piece.source[:-1])
+            # Add the expected output:
+            want = piece.want
+            if want:
+                output.append('# Expected:')
+                output += ['## '+l for l in want.split('\n')[:-1]]
+        else:
+            # Add non-example text.
+            output += [_comment_line(l)
+                       for l in piece.split('\n')[:-1]]
+
+    # Trim junk on both ends.
+    while output and output[-1] == '#':
+        output.pop()
+    while output and output[0] == '#':
+        output.pop(0)
+    # Combine the output, and return it.
+    return '\n'.join(output)
+
+def testsource(module, name):
+    """Extract the test sources from a doctest docstring as a script.
+
+    Provide the module (or dotted name of the module) containing the
+    test to be debugged and the name (within the module) of the object
+    with the doc string with tests to be debugged.
+    """
+    module = _normalize_module(module)
+    tests = DocTestFinder().find(module)
+    test = [t for t in tests if t.name == name]
+    if not test:
+        raise ValueError(name, "not found in tests")
+    test = test[0]
+    testsrc = script_from_examples(test.docstring)
+    return testsrc
+
+def debug_src(src, pm=False, globs=None):
+    """Debug a single doctest docstring, in argument `src`'"""
+    testsrc = script_from_examples(src)
+    debug_script(testsrc, pm, globs)
+
+def debug_script(src, pm=False, globs=None):
+    "Debug a test script.  `src` is the script, as a string."
+    import pdb
+
+    # Note that tempfile.NameTemporaryFile() cannot be used.  As the
+    # docs say, a file so created cannot be opened by name a second time
+    # on modern Windows boxes, and execfile() needs to open it.
+    srcfilename = tempfile.mktemp(".py", "doctestdebug")
+    f = open(srcfilename, 'w')
+    f.write(src)
+    f.close()
+
+    try:
+        if globs:
+            globs = globs.copy()
+        else:
+            globs = {}
+
+        if pm:
+            try:
+                execfile(srcfilename, globs, globs)
+            except:
+                print sys.exc_info()[1]
+                pdb.post_mortem(sys.exc_info()[2])
+        else:
+            # Note that %r is vital here.  '%s' instead can, e.g., cause
+            # backslashes to get treated as metacharacters on Windows.
+            pdb.run("execfile(%r)" % srcfilename, globs, globs)
+
+    finally:
+        os.remove(srcfilename)
+
+def debug(module, name, pm=False):
+    """Debug a single doctest docstring.
+
+    Provide the module (or dotted name of the module) containing the
+    test to be debugged and the name (within the module) of the object
+    with the docstring with tests to be debugged.
+    """
+    module = _normalize_module(module)
+    testsrc = testsource(module, name)
+    debug_script(testsrc, pm, module.__dict__)
+
+######################################################################
+## 10. Example Usage
+######################################################################
+class _TestClass:
+    """
+    A pointless class, for sanity-checking of docstring testing.
+
+    Methods:
+        square()
+        get()
+
+    >>> _TestClass(13).get() + _TestClass(-12).get()
+    1
+    >>> hex(_TestClass(13).square().get())
+    '0xa9'
+    """
+
+    def __init__(self, val):
+        """val -> _TestClass object with associated value val.
+
+        >>> t = _TestClass(123)
+        >>> print t.get()
+        123
+        """
+
+        self.val = val
+
+    def square(self):
+        """square() -> square TestClass's associated value
+
+        >>> _TestClass(13).square().get()
+        169
+        """
+
+        self.val = self.val ** 2
+        return self
+
+    def get(self):
+        """get() -> return TestClass's associated value.
+
+        >>> x = _TestClass(-42)
+        >>> print x.get()
+        -42
+        """
+
+        return self.val
+
+__test__ = {"_TestClass": _TestClass,
+            "string": r"""
+                      Example of a string object, searched as-is.
+                      >>> x = 1; y = 2
+                      >>> x + y, x * y
+                      (3, 2)
+                      """,
+
+            "bool-int equivalence": r"""
+                                    In 2.2, boolean expressions displayed
+                                    0 or 1.  By default, we still accept
+                                    them.  This can be disabled by passing
+                                    DONT_ACCEPT_TRUE_FOR_1 to the new
+                                    optionflags argument.
+                                    >>> 4 == 4
+                                    1
+                                    >>> 4 == 4
+                                    True
+                                    >>> 4 > 4
+                                    0
+                                    >>> 4 > 4
+                                    False
+                                    """,
+
+            "blank lines": r"""
+                Blank lines can be marked with <BLANKLINE>:
+                    >>> print 'foo\n\nbar\n'
+                    foo
+                    <BLANKLINE>
+                    bar
+                    <BLANKLINE>
+            """,
+
+            "ellipsis": r"""
+                If the ellipsis flag is used, then '...' can be used to
+                elide substrings in the desired output:
+                    >>> print range(1000) #doctest: +ELLIPSIS
+                    [0, 1, 2, ..., 999]
+            """,
+
+            "whitespace normalization": r"""
+                If the whitespace normalization flag is used, then
+                differences in whitespace are ignored.
+                    >>> print range(30) #doctest: +NORMALIZE_WHITESPACE
+                    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+                     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+                     27, 28, 29]
+            """,
+           }
+
+def _test():
+    r = unittest.TextTestRunner()
+    r.run(DocTestSuite())
+
+if __name__ == "__main__":
+    _test()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/doctest.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/doctestunit.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/doctestunit.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/doctestunit.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,33 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Extension to use doctest tests as unit tests
+
+This module provides a DocTestSuite contructor for converting doctest
+tests to unit tests.
+
+$Id: doctestunit.py 28304 2004-10-31 17:59:45Z jim $
+"""
+
+from doctest import DocFileSuite, DocTestSuite
+from doctest import debug_src, debug
+
+def pprint():
+    from pprint import PrettyPrinter
+    def pprint(ob, **opts):
+        if 'width' not in opts:
+            opts['width'] = 1
+        return PrettyPrinter(**opts).pprint(ob)
+    return pprint
+
+pprint = pprint()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/doctestunit.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/formparser.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/formparser.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/formparser.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,234 @@
+"""HTML parser that extracts form information.
+
+This is intended to support functional tests that need to extract
+information from HTML forms returned by the publisher.
+
+See *formparser.txt* for documentation.
+
+This isn't intended to simulate a browser session; that's provided by
+the `zope.testbrowser` package.
+
+"""
+__docformat__ = "reStructuredText"
+
+import HTMLParser
+import urlparse
+
+
+def parse(data, base=None):
+    """Return a form collection parsed from `data`.
+
+    `base` should be the URL from which `data` was retrieved.
+
+    """
+    parser = FormParser(data, base)
+    return parser.parse()
+
+
+class FormParser(object):
+
+    def __init__(self, data, base=None):
+        self.data = data
+        self.base = base
+        self._parser = HTMLParser.HTMLParser()
+        self._parser.handle_data = self._handle_data
+        self._parser.handle_endtag = self._handle_endtag
+        self._parser.handle_starttag = self._handle_starttag
+        self._parser.handle_startendtag = self._handle_starttag
+        self._buffer = []
+        self.current = None # current form
+        self.forms = FormCollection()
+
+    def parse(self):
+        """Parse the document, returning the collection of forms."""
+        self._parser.feed(self.data)
+        self._parser.close()
+        return self.forms
+
+    # HTMLParser handlers
+
+    def _handle_data(self, data):
+        self._buffer.append(data)
+
+    def _handle_endtag(self, tag):
+        if tag == "textarea":
+            self.textarea.value = "".join(self._buffer)
+            self.textarea = None
+        elif tag == "select":
+            self.select = None
+        elif tag == "option":
+            option = self.select.options[-1]
+            label = "".join(self._buffer)
+            if not option.label:
+                option.label = label
+            if not option.value:
+                option.value = label
+            if option.selected:
+                if self.select.multiple:
+                    self.select.value.append(option.value)
+                else:
+                    self.select.value = option.value
+
+    def _handle_starttag(self, tag, attrs):
+        del self._buffer[:]
+        d = {}
+        for name, value in attrs:
+            d[name] = value
+        name = d.get("name")
+        id = d.get("id") or d.get("xml:id")
+        if tag == "form":
+            method = kwattr(d, "method", "get")
+            action = d.get("action", "").strip() or None
+            if self.base and action:
+                action = urlparse.urljoin(self.base, action)
+            enctype = kwattr(d, "enctype", "application/x-www-form-urlencoded")
+            self.current = Form(name, id, method, action, enctype)
+            self.forms.append(self.current)
+        elif tag == "input":
+            type = kwattr(d, "type", "text")
+            checked = "checked" in d
+            disabled = "disabled" in d
+            readonly = "readonly" in d
+            src = d.get("src", "").strip() or None
+            if self.base and src:
+                src = urlparse.urljoin(self.base, src)
+            value = d.get("value")
+            size = intattr(d, "size")
+            maxlength = intattr(d, "maxlength")
+            self._add_field(
+                Input(name, id, type, value, checked,
+                      disabled, readonly, src, size, maxlength))
+        elif tag == "button":
+            pass
+        elif tag == "textarea":
+            disabled = "disabled" in d
+            readonly = "readonly" in d
+            self.textarea = Input(name, id, "textarea", None,
+                                  None, disabled, readonly,
+                                  None, None, None)
+            self.textarea.rows = intattr(d, "rows")
+            self.textarea.cols = intattr(d, "cols")
+            self._add_field(self.textarea)
+            # The value will be set when the </textarea> is seen.
+        elif tag == "base":
+            href = d.get("href", "").strip()
+            if href and self.base:
+                href = urlparse.urljoin(self.base, href)
+            self.base = href
+        elif tag == "select":
+            disabled = "disabled" in d
+            multiple = "multiple" in d
+            size = intattr(d, "size")
+            self.select = Select(name, id, disabled, multiple, size)
+            self._add_field(self.select)
+        elif tag == "option":
+            disabled = "disabled" in d
+            selected = "selected" in d
+            value = d.get("value")
+            label = d.get("label")
+            option = Option(id, value, selected, label, disabled)
+            self.select.options.append(option)
+
+    # Helpers:
+
+    def _add_field(self, field):
+        if field.name in self.current:
+            ob = self.current[field.name]
+            if isinstance(ob, list):
+                ob.append(field)
+            else:
+                self.current[field.name] = [ob, field]
+        else:
+            self.current[field.name] = field
+
+
+def kwattr(d, name, default=None):
+    """Return attribute, converted to lowercase."""
+    v = d.get(name, default)
+    if v != default and v is not None:
+        v = v.strip().lower()
+        v = v or default
+    return v
+
+
+def intattr(d, name):
+    """Return attribute as an integer, or None."""
+    if name in d:
+        v = d[name].strip()
+        return int(v)
+    else:
+        return None
+
+
+class FormCollection(list):
+    """Collection of all forms from a page."""
+
+    def __getattr__(self, name):
+        for form in self:
+            if form.name == name:
+                return form
+        raise AttributeError(name)
+
+
+class Form(dict):
+    """A specific form within a page."""
+
+    # This object should provide some method to prepare a dictionary
+    # that can be passed directly as the value of the `form` argument
+    # to the `http()` function of the Zope functional test.
+    #
+    # This is probably a low priority given the availability of the
+    # `zope.testbrowser` package.
+
+    def __init__(self, name, id, method, action, enctype):
+        super(Form, self).__init__()
+        self.name = name
+        self.id = id
+        self.method = method
+        self.action = action
+        self.enctype = enctype
+
+
+class Input(object):
+    """Input element."""
+
+    rows = None
+    cols = None
+
+    def __init__(self, name, id, type, value, checked, disabled, readonly,
+                 src, size, maxlength):
+        super(Input, self).__init__()
+        self.name = name
+        self.id = id
+        self.type = type
+        self.value = value
+        self.checked = checked
+        self.disabled = disabled
+        self.readonly = readonly
+        self.src = src
+        self.size = size
+        self.maxlength = maxlength
+
+
+class Select(Input):
+    """Select element."""
+
+    def __init__(self, name, id, disabled, multiple, size):
+        super(Select, self).__init__(name, id, "select", None, None,
+                                     disabled, None, None, size, None)
+        self.options = []
+        self.multiple = multiple
+        if multiple:
+            self.value = []
+
+
+class Option(object):
+    """Individual value representation for a select element."""
+
+    def __init__(self, id, value, selected, label, disabled):
+        super(Option, self).__init__()
+        self.id = id
+        self.value = value
+        self.selected = selected
+        self.label = label
+        self.disabled = disabled


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/formparser.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/formparser.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/formparser.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/formparser.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,143 @@
+==================
+Parsing HTML Forms
+==================
+
+Sometimes in functional tests, information from a generated form must
+be extracted in order to re-submit it as part of a subsequent request.
+The `zope.testing.formparser` module can be used for this purpose.
+
+The scanner is implemented using the `FormParser` class.  The
+constructor arguments are the page data containing the form and
+(optionally) the URL from which the page was retrieved:
+
+  >>> import zope.testing.formparser
+
+  >>> page_text = '''\
+  ... <html><body>
+  ...   <form name="form1" action="/cgi-bin/foobar.py" method="POST">
+  ...     <input type="hidden" name="f1" value="today" />
+  ...     <input type="submit" name="do-it-now" value="Go for it!" />
+  ...     <input type="IMAGE" name="not-really" value="Don't."
+  ...            src="dont.png" />
+  ...     <select name="pick-two" size="3" multiple>
+  ...       <option value="one" selected>First</option>
+  ...       <option value="two" label="Second">Another</option>
+  ...       <optgroup>
+  ...         <option value="three">Third</option>
+  ...         <option selected="selected">Fourth</option>
+  ...       </optgroup>
+  ...     </select>
+  ...   </form>
+  ...
+  ...   Just for fun, a second form, after specifying a base:
+  ...   <base href="http://www.example.com/base/" />
+  ...   <form action = 'sproing/sprung.html' enctype="multipart/form">
+  ...     <textarea name="sometext" rows="5">Some text.</textarea>
+  ...     <input type="Image" name="action" value="Do something."
+  ...            src="else.png" />
+  ...     <input type="text" value="" name="multi" size="2" />
+  ...     <input type="text" value="" name="multi" size="3" />
+  ...   </form>
+  ... </body></html>
+  ... '''
+
+  >>> parser = zope.testing.formparser.FormParser(page_text)
+  >>> forms = parser.parse()
+
+  >>> len(forms)
+  2
+  >>> forms.form1 is forms[0]
+  True
+  >>> forms.form1 is forms[1]
+  False
+
+More often, the `parse()` convenience function is all that's needed:
+
+  >>> forms = zope.testing.formparser.parse(
+  ...     page_text, "http://cgi.example.com/somewhere/form.html")
+
+  >>> len(forms)
+  2
+  >>> forms.form1 is forms[0]
+  True
+  >>> forms.form1 is forms[1]
+  False
+
+Once we have the form we're interested in, we can check form
+attributes and individual field values:
+
+  >>> form = forms.form1
+  >>> form.enctype
+  'application/x-www-form-urlencoded'
+  >>> form.method
+  'post'
+
+  >>> keys = form.keys()
+  >>> keys.sort()
+  >>> keys
+  ['do-it-now', 'f1', 'not-really', 'pick-two']
+
+  >>> not_really = form["not-really"]
+  >>> not_really.type
+  'image'
+  >>> not_really.value
+  "Don't."
+  >>> not_really.readonly
+  False
+  >>> not_really.disabled
+  False
+
+Note that relative URLs are converted to absolute URLs based on the
+``<base>`` element (if present) or using the base passed in to the
+constructor.
+
+  >>> form.action
+  'http://cgi.example.com/cgi-bin/foobar.py'
+  >>> not_really.src
+  'http://cgi.example.com/somewhere/dont.png'
+
+  >>> forms[1].action
+  'http://www.example.com/base/sproing/sprung.html'
+  >>> forms[1]["action"].src
+  'http://www.example.com/base/else.png'
+
+Fields which are repeated are reported as lists of objects that
+represent each instance of the field::
+
+  >>> field = forms[1]["multi"]
+  >>> type(field)
+  <type 'list'>
+  >>> [o.value for o in field]
+  ['', '']
+  >>> [o.size for o in field]
+  [2, 3]
+
+The ``<textarea>`` element provides some additional attributes:
+
+  >>> ta = forms[1]["sometext"]
+  >>> print ta.rows
+  5
+  >>> print ta.cols
+  None
+  >>> ta.value
+  'Some text.'
+
+The ``<select>`` element provides access to the options as well:
+
+  >>> select = form["pick-two"]
+  >>> select.multiple
+  True
+  >>> select.size
+  3
+  >>> select.type
+  'select'
+  >>> select.value
+  ['one', 'Fourth']
+
+  >>> options = select.options
+  >>> len(options)
+  4
+  >>> [opt.label for opt in options]
+  ['First', 'Second', 'Third', 'Fourth']
+  >>> [opt.value for opt in options]
+  ['one', 'two', 'three', 'Fourth']


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/formparser.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/loggingsupport.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/loggingsupport.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/loggingsupport.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,121 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Support for testing logging code
+
+If you want to test that your code generates proper log output, you
+can create and install a handler that collects output:
+
+  >>> handler = InstalledHandler('foo.bar')
+
+The handler is installed into loggers for all of the names passed. In
+addition, the logger level is set to 1, which means, log
+everything. If you want to log less than everything, you can provide a
+level keyword argument.  The level setting effects only the named
+loggers.
+
+Then, any log output is collected in the handler:
+
+  >>> logging.getLogger('foo.bar').exception('eek')
+  >>> logging.getLogger('foo.bar').info('blah blah')
+
+  >>> for record in handler.records:
+  ...     print record.name, record.levelname
+  ...     print ' ', record.getMessage()
+  foo.bar ERROR
+    eek
+  foo.bar INFO
+    blah blah
+
+A similar effect can be gotten by just printing the handler:
+
+  >>> print handler
+  foo.bar ERROR
+    eek
+  foo.bar INFO
+    blah blah
+
+After checking the log output, you need to uninstall the handler:
+
+  >>> handler.uninstall()
+
+At which point, the handler won't get any more log output.
+Let's clear the handler:
+
+  >>> handler.clear()
+  >>> handler.records
+  []
+
+And then log something:
+
+  >>> logging.getLogger('foo.bar').info('blah')
+
+and, sure enough, we still have no output:
+
+  >>> handler.records
+  []
+
+$Id: loggingsupport.py 30499 2005-05-25 17:08:28Z tim_one $
+"""
+
+import logging
+
+class Handler(logging.Handler):
+
+    def __init__(self, *names, **kw):
+        logging.Handler.__init__(self)
+        self.names = names
+        self.records = []
+        self.setLoggerLevel(**kw)
+
+    def setLoggerLevel(self, level=1):
+        self.level = level
+        self.oldlevels = {}
+
+    def emit(self, record):
+        self.records.append(record)
+
+    def clear(self):
+        del self.records[:]
+
+    def install(self):
+        for name in self.names:
+            logger = logging.getLogger(name)
+            self.oldlevels[name] = logger.level
+            logger.setLevel(self.level)
+            logger.addHandler(self)
+
+    def uninstall(self):
+        for name in self.names:
+            logger = logging.getLogger(name)
+            logger.setLevel(self.oldlevels[name])
+            logger.removeHandler(self)
+
+    def __str__(self):
+        return '\n'.join(
+            [("%s %s\n  %s" %
+              (record.name, record.levelname,
+               '\n'.join([line
+                          for line in record.getMessage().split('\n')
+                          if line.strip()])
+               )
+              )
+              for record in self.records]
+              )
+
+
+class InstalledHandler(Handler):
+
+    def __init__(self, *names):
+        Handler.__init__(self, *names)
+        self.install()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/loggingsupport.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/loghandler.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/loghandler.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/loghandler.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,77 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""logging handler for tests that check logging output.
+
+$Id: loghandler.py 27164 2004-08-17 11:16:39Z hdima $
+"""
+import logging
+
+class Handler(logging.Handler):
+    """Handler for use with unittest.TestCase objects.
+
+    The handler takes a TestCase instance as a constructor argument.
+    It can be registered with one or more loggers and collects log
+    records they generate.
+
+    The assertLogsMessage() and failIfLogsMessage() methods can be
+    used to check the logger output and causes the test to fail as
+    appropriate.
+    """
+
+    def __init__(self, testcase, propagate=False):
+        logging.Handler.__init__(self)
+        self.records = []
+        # loggers stores (logger, propagate) tuples
+        self.loggers = []
+        self.closed = False
+        self.propagate = propagate
+        self.testcase = testcase
+
+    def close(self):
+        """Remove handler from any loggers it was added to."""
+        if self.closed:
+            return
+        for logger, propagate in self.loggers:
+            logger.removeHandler(self)
+            logger.propagate = propagate
+        self.closed = True
+
+    def add(self, name):
+        """Add handler to logger named name."""
+        logger = logging.getLogger(name)
+        old_prop = logger.propagate
+        logger.addHandler(self)
+        if self.propagate:
+            logger.propagate = 1
+        else:
+            logger.propagate = 0
+        self.loggers.append((logger, old_prop))
+
+    def emit(self, record):
+        self.records.append(record)
+
+    def assertLogsMessage(self, msg, level=None):
+        for r in self.records:
+            if r.getMessage() == msg:
+                if level is not None and r.levelno == level:
+                    return
+        msg = "No log message contained %r" % msg
+        if level is not None:
+            msg += " at level %d" % level
+        self.testcase.fail(msg)
+
+    def failIfLogsMessage(self, msg):
+        for r in self.records:
+            if r.getMessage() == msg:
+                self.testcase.fail("Found log message %r" % msg)


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/loghandler.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/module.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/module.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/module.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,47 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Fake module support
+
+$Id: module.py 38684 2005-09-29 09:21:32Z jim $
+"""
+
+import sys
+
+class FakeModule:
+    def __init__(self, dict):
+        self.__dict = dict
+    def __getattr__(self, name):
+        try:
+            return self.__dict[name]
+        except KeyError:
+            raise AttributeError(name)
+
+def setUp(test, name='README.txt'):
+    dict = test.globs
+    dict['__name__'] = name
+    module = FakeModule(dict)
+    sys.modules[name] = module
+    if '.' in name:
+        name = name.split('.')
+        parent = sys.modules['.'.join(name[:-1])]
+        setattr(parent, name[-1], module)
+
+def tearDown(test, name=None):
+    if name is None:
+        name = test.globs['__name__']
+    del sys.modules[name]
+    if '.' in name:
+        name = name.split('.')
+        parent = sys.modules['.'.join(name[:-1])]
+        delattr(parent, name[-1])


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/module.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/renormalizing.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/renormalizing.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/renormalizing.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,221 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+r"""Regular expression pattern normalizing output checker
+
+The pattern-normalizing output checker extends the default output checker with
+an option to normalize expected an actual output.
+
+You specify a sequence of patterns and replacements.  The replacements are
+applied to the expected and actual outputs before calling the default outputs
+checker.  Let's look at an example.  In this example, we have some times and
+addresses:
+
+    >>> want = '''\
+    ... <object object at 0xb7f14438>
+    ... completed in 1.234 seconds.
+    ... <BLANKLINE>
+    ... <object object at 0xb7f14440>
+    ... completed in 123.234 seconds.
+    ... <BLANKLINE>
+    ... <object object at 0xb7f14448>
+    ... completed in .234 seconds.
+    ... <BLANKLINE>
+    ... <object object at 0xb7f14450>
+    ... completed in 1.234 seconds.
+    ... <BLANKLINE>
+    ... '''
+
+    >>> got = '''\
+    ... <object object at 0xb7f14458>
+    ... completed in 1.235 seconds.
+    ...
+    ... <object object at 0xb7f14460>
+    ... completed in 123.233 seconds.
+    ...
+    ... <object object at 0xb7f14468>
+    ... completed in .231 seconds.
+    ...
+    ... <object object at 0xb7f14470>
+    ... completed in 1.23 seconds.
+    ...
+    ... '''
+
+We may wish to consider these two strings to match, even though they differ in
+actual addresses and times.  The default output checker will consider them
+different:
+
+    >>> doctest.OutputChecker().check_output(want, got, 0)
+    False
+
+We'll use the RENormalizing to normalize both the wanted and gotten strings to
+ignore differences in times and addresses:
+
+    >>> import re
+    >>> checker = RENormalizing([
+    ...    (re.compile('[0-9]*[.][0-9]* seconds'), '<SOME NUMBER OF> seconds'),
+    ...    (re.compile('at 0x[0-9a-f]+'), 'at <SOME ADDRESS>'),
+    ...    ])
+
+    >>> checker.check_output(want, got, 0)
+    True
+
+Usual OutputChecker options work as expected:
+
+    >>> want_ellided = '''\
+    ... <object object at 0xb7f14438>
+    ... completed in 1.234 seconds.
+    ... ...
+    ... <object object at 0xb7f14450>
+    ... completed in 1.234 seconds.
+    ... <BLANKLINE>
+    ... '''
+
+    >>> checker.check_output(want_ellided, got, 0)
+    False
+
+    >>> checker.check_output(want, got, doctest.ELLIPSIS)
+    True
+
+When we get differencs, we output them with normalized text:
+
+    >>> source = '''\
+    ... >>> do_something()
+    ... <object object at 0xb7f14438>
+    ... completed in 1.234 seconds.
+    ... ...
+    ... <object object at 0xb7f14450>
+    ... completed in 1.234 seconds.
+    ... <BLANKLINE>
+    ... '''
+
+    >>> example = doctest.Example(source, want_ellided)
+
+    >>> print checker.output_difference(example, got, 0)
+    Expected:
+        <object object at <SOME ADDRESS>>
+        completed in <SOME NUMBER OF> seconds.
+        ...
+        <object object at <SOME ADDRESS>>
+        completed in <SOME NUMBER OF> seconds.
+        <BLANKLINE>
+    Got:
+        <object object at <SOME ADDRESS>>
+        completed in <SOME NUMBER OF> seconds.
+        <BLANKLINE>
+        <object object at <SOME ADDRESS>>
+        completed in <SOME NUMBER OF> seconds.
+        <BLANKLINE>
+        <object object at <SOME ADDRESS>>
+        completed in <SOME NUMBER OF> seconds.
+        <BLANKLINE>
+        <object object at <SOME ADDRESS>>
+        completed in <SOME NUMBER OF> seconds.
+        <BLANKLINE>
+    <BLANKLINE>
+
+    >>> print checker.output_difference(example, got,
+    ...                                 doctest.REPORT_NDIFF)
+    Differences (ndiff with -expected +actual):
+        - <object object at <SOME ADDRESS>>
+        - completed in <SOME NUMBER OF> seconds.
+        - ...
+          <object object at <SOME ADDRESS>>
+          completed in <SOME NUMBER OF> seconds.
+          <BLANKLINE>
+        + <object object at <SOME ADDRESS>>
+        + completed in <SOME NUMBER OF> seconds.
+        + <BLANKLINE>
+        + <object object at <SOME ADDRESS>>
+        + completed in <SOME NUMBER OF> seconds.
+        + <BLANKLINE>
+        + <object object at <SOME ADDRESS>>
+        + completed in <SOME NUMBER OF> seconds.
+        + <BLANKLINE>
+    <BLANKLINE>
+
+    If the wanted text is empty, however, we don't transform the actual output.
+    This is usful when writing tests.  We leave the expected output empty, run
+    the test, and use the actual output as expected, after reviewing it.
+
+    >>> source = '''\
+    ... >>> do_something()
+    ... '''
+
+    >>> example = doctest.Example(source, '\n')
+    >>> print checker.output_difference(example, got, 0)
+    Expected:
+    <BLANKLINE>
+    Got:
+        <object object at 0xb7f14458>
+        completed in 1.235 seconds.
+        <BLANKLINE>
+        <object object at 0xb7f14460>
+        completed in 123.233 seconds.
+        <BLANKLINE>
+        <object object at 0xb7f14468>
+        completed in .231 seconds.
+        <BLANKLINE>
+        <object object at 0xb7f14470>
+        completed in 1.23 seconds.
+        <BLANKLINE>
+    <BLANKLINE>
+
+$Id: renormalizing.py 30915 2005-06-24 22:20:42Z benji_york $
+"""
+
+import doctest
+
+class RENormalizing(doctest.OutputChecker):
+    """Pattern-normalizing outout checker
+    """
+
+    def __init__(self, patterns):
+        self.patterns = patterns
+
+    def check_output(self, want, got, optionflags):
+        if got == want:
+            return True
+
+        for pattern, repl in self.patterns:
+            want = pattern.sub(repl, want)
+            got = pattern.sub(repl, got)
+
+        return doctest.OutputChecker.check_output(self, want, got, optionflags)
+
+    def output_difference(self, example, got, optionflags):
+
+        want = example.want
+
+        # If want is empty, use original outputter. This is useful
+        # when setting up tests for the first time.  In that case, we
+        # generally use the differencer to display output, which we evaluate
+        # by hand.
+        if not want.strip():
+            return doctest.OutputChecker.output_difference(
+                self, example, got, optionflags)
+
+        # Dang, this isn't as easy to override as we might wish
+        original = want
+
+        for pattern, repl in self.patterns:
+            want = pattern.sub(repl, want)
+            got = pattern.sub(repl, got)
+
+        # temporarily hack example with normalized want:
+        example.want = want
+        result = doctest.OutputChecker.output_difference(
+            self, example, got, optionflags)
+        example.want = original
+
+        return result


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/renormalizing.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-arguments.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-arguments.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-arguments.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,30 @@
+Test Runner
+===========
+
+Passing arguments explicitly
+----------------------------
+
+In most of the examples here, we set up `sys.argv`.  In normal usage,
+the testrunner just uses `sys.argv`.  It is possible to pass arguments
+explicitly.
+
+    >>> import os.path
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+    >>> from zope.testing import testrunner
+    >>> testrunner.run(defaults, 'test --layer 111'.split())
+    Running samplelayers.Layer111 tests:
+      Set up samplelayers.Layerx in N.NNN seconds.
+      Set up samplelayers.Layer1 in N.NNN seconds.
+      Set up samplelayers.Layer11 in N.NNN seconds.
+      Set up samplelayers.Layer111 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer111 in N.NNN seconds.
+      Tear down samplelayers.Layerx in N.NNN seconds.
+      Tear down samplelayers.Layer11 in N.NNN seconds.
+      Tear down samplelayers.Layer1 in N.NNN seconds.
+    False


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-arguments.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-coverage.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-coverage.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-coverage.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,94 @@
+Test Runner
+===========
+Code Coverage
+-------------
+
+If the --coverage option is used, test coverage reports will be generated.  The
+directory name given as the parameter will be used to hold the reports.
+
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+
+    >>> sys.argv = 'test --coverage=coverage_dir'.split()
+
+    >>> from zope.testing import testrunner
+    >>> testrunner.run(defaults)
+    Running unit tests:
+      Ran 192 tests with 0 failures and 0 errors in 0.125 seconds.
+    Running samplelayers.Layer1 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Ran 9 tests with 0 failures and 0 errors in 0.003 seconds.
+    Running samplelayers.Layer11 tests:
+      Set up samplelayers.Layer11 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.029 seconds.
+    Running samplelayers.Layer111 tests:
+      Set up samplelayers.Layerx in 0.000 seconds.
+      Set up samplelayers.Layer111 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.024 seconds.
+    Running samplelayers.Layer112 tests:
+      Tear down samplelayers.Layer111 in 0.000 seconds.
+      Set up samplelayers.Layer112 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.024 seconds.
+    Running samplelayers.Layer12 tests:
+      Tear down samplelayers.Layer112 in 0.000 seconds.
+      Tear down samplelayers.Layerx in 0.000 seconds.
+      Tear down samplelayers.Layer11 in 0.000 seconds.
+      Set up samplelayers.Layer12 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.026 seconds.
+    Running samplelayers.Layer121 tests:
+      Set up samplelayers.Layer121 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.025 seconds.
+    Running samplelayers.Layer122 tests:
+      Tear down samplelayers.Layer121 in 0.000 seconds.
+      Set up samplelayers.Layer122 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.025 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in 0.000 seconds.
+      Tear down samplelayers.Layer12 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    Total: 405 tests, 0 failures, 0 errors
+    lines   cov%   module   (path)
+       82    78%   sample1.sample11.sampletests   (testrunner-ex/sample1/sample11/sampletests.py)
+       52    92%   sample1.sample13.sampletests   (testrunner-ex/sample1/sample13/sampletests.py)
+       52    92%   sample1.sampletests.test1   (testrunner-ex/sample1/sampletests/test1.py)
+       78    94%   sample1.sampletests.test11   (testrunner-ex/sample1/sampletests/test11.py)
+       78    94%   sample1.sampletests.test111   (testrunner-ex/sample1/sampletests/test111.py)
+       78    94%   sample1.sampletests.test112   (testrunner-ex/sample1/sampletests/test112.py)
+       78    94%   sample1.sampletests.test12   (testrunner-ex/sample1/sampletests/test12.py)
+       78    94%   sample1.sampletests.test121   (testrunner-ex/sample1/sampletests/test121.py)
+       78    94%   sample1.sampletests.test122   (testrunner-ex/sample1/sampletests/test122.py)
+       52    92%   sample1.sampletests.test_one   (testrunner-ex/sample1/sampletests/test_one.py)
+       52    92%   sample1.sampletestsf   (testrunner-ex/sample1/sampletestsf.py)
+       52    92%   sample2.sample21.sampletests   (testrunner-ex/sample2/sample21/sampletests.py)
+       52    92%   sample2.sampletests.test_1   (testrunner-ex/sample2/sampletests/test_1.py)
+       52    92%   sample2.sampletests.testone   (testrunner-ex/sample2/sampletests/testone.py)
+       52    92%   sample3.sampletests   (testrunner-ex/sample3/sampletests.py)
+       96    75%   samplelayers   (testrunner-ex/samplelayers.py)
+       52    92%   sampletests.test1   (testrunner-ex/sampletests/test1.py)
+       78    94%   sampletests.test11   (testrunner-ex/sampletests/test11.py)
+       78    94%   sampletests.test111   (testrunner-ex/sampletests/test111.py)
+       80    95%   sampletests.test112   (testrunner-ex/sampletests/test112.py)
+       78    94%   sampletests.test12   (testrunner-ex/sampletests/test12.py)
+       78    94%   sampletests.test121   (testrunner-ex/sampletests/test121.py)
+       78    94%   sampletests.test122   (testrunner-ex/sampletests/test122.py)
+       52    92%   sampletests.test_one   (testrunner-ex/sampletests/test_one.py)
+      122    87%   sampletestsf   (testrunner-ex/sampletestsf.py)
+    False
+
+The directory specified with the --coverage option will have been created and
+will hold the coverage reports.
+
+    >>> os.path.exists('coverage_dir')
+    True
+    >>> os.listdir('coverage_dir')
+    [...]
+
+(We should clean up after ourselves.)
+
+    >>> import shutil
+    >>> shutil.rmtree('coverage_dir')


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-coverage.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-debugging.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-debugging.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-debugging.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,121 @@
+Test Runner
+===========
+
+Debugging
+---------
+
+The testrunner module supports post-mortem debugging and debugging
+using `pdb.set_trace`.  Let's look first at using `pdb.set_trace`.
+To demonstrate this, we'll provide input via helper Input objects:
+
+    >>> class Input:
+    ...     def __init__(self, src):
+    ...         self.lines = src.split('\n')
+    ...     def readline(self):
+    ...         line = self.lines.pop(0)
+    ...         print line
+    ...         return line+'\n'
+
+If a test or code called by a test calls pdb.set_trace, then the
+runner will enter pdb at that point:
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> from zope.testing import testrunner
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+
+    >>> real_stdin = sys.stdin
+    >>> if sys.version_info[:2] == (2, 3):
+    ...     sys.stdin = Input('n\np x\nc')
+    ... else:
+    ...     sys.stdin = Input('p x\nc')
+
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t set_trace1').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    ... # doctest: +ELLIPSIS
+    Running unit tests:...
+    > testrunner-ex/sample3/sampletests_d.py(27)test_set_trace1()
+    -> y = x
+    (Pdb) p x
+    1
+    (Pdb) c
+      Ran 1 tests with 0 failures and 0 errors in 0.001 seconds.
+    False
+
+Note that, prior to Python 2.4, calling pdb.set_trace caused pdb to
+break in the pdb.set_trace function.  It was necessary to use 'next'
+or 'up' to get to the application code that called pdb.set_trace.  In
+Python 2.4, pdb.set_trace causes pdb to stop right after the call to
+pdb.set_trace.
+
+You can also do post-mortem debugging, using the --post-mortem (-D)
+option:
+
+    >>> sys.stdin = Input('p x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t post_mortem1 -D').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    ... # doctest: +NORMALIZE_WHITESPACE +REPORT_NDIFF
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test test_post_mortem1 (sample3.sampletests_d.TestSomething)
+    Traceback (most recent call last):
+      File "testrunner-ex/sample3/sampletests_d.py",
+              line 34, in test_post_mortem1
+        raise ValueError
+    ValueError
+    <BLANKLINE>
+    exceptions.ValueError:
+    <BLANKLINE>
+    > testrunner-ex/sample3/sampletests_d.py(34)test_post_mortem1()
+    -> raise ValueError
+    (Pdb) p x
+    1
+    (Pdb) c
+    True
+
+Note that the test runner exits after post-mortem debugging.
+
+In the example above, we debugged an error.  Failures are actually
+converted to errors and can be debugged the same way:
+
+    >>> sys.stdin = Input('up\np x\np y\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t post_mortem_failure1 -D').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    ... # doctest: +NORMALIZE_WHITESPACE +REPORT_NDIFF
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test test_post_mortem_failure1 (sample3.sampletests_d.TestSomething)
+    Traceback (most recent call last):
+      File ".../unittest.py",  line 252, in debug
+        getattr(self, self.__testMethodName)()
+      File "testrunner-ex/sample3/sampletests_d.py",
+        line 42, in test_post_mortem_failure1
+        self.assertEqual(x, y)
+      File ".../unittest.py", line 302, in failUnlessEqual
+        raise self.failureException, \
+    AssertionError: 1 != 2
+    <BLANKLINE>
+    exceptions.AssertionError:
+    1 != 2
+    > .../unittest.py(302)failUnlessEqual()
+    -> raise self.failureException, \
+    (Pdb) up
+    > testrunner-ex/sample3/sampletests_d.py(42)test_post_mortem_failure1()
+    -> self.assertEqual(x, y)
+    (Pdb) p x
+    1
+    (Pdb) p y
+    2
+    (Pdb) c
+    True


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-debugging.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-edge-cases.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-edge-cases.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-edge-cases.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,477 @@
+testrunner Edge Cases
+=====================
+
+This document has some edge-case examples to test various aspects of
+the test runner.
+
+Separating Python path and test directories
+-------------------------------------------
+
+The --path option defines a directory to be searched for tests *and* a
+directory to be added to Python's search path.  The --test-path option
+can be used when you want to set a test search path without also
+affecting the Python path:
+
+    >>> import os, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+
+    >>> from zope.testing import testrunner
+
+    >>> defaults = [
+    ...     '--test-path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+    >>> sys.argv = ['test']
+    >>> testrunner.run(defaults)
+    ... # doctest: +ELLIPSIS
+    Test-module import failures:
+    <BLANKLINE>
+    Module: sampletestsf
+    <BLANKLINE>
+    ImportError: No module named sampletestsf
+    ...
+
+    >>> sys.path.append(directory_with_tests)
+    >>> sys.argv = ['test']
+    >>> testrunner.run(defaults)
+    ... # doctest: +ELLIPSIS
+    Running unit tests:
+      Ran 192 tests with 0 failures and 0 errors in 0.028 seconds.
+    Running samplelayers.Layer1 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Ran 9 tests with 0 failures and 0 errors in 0.000 seconds.
+    ...
+
+Debugging Edge Cases
+--------------------
+
+    >>> class Input:
+    ...     def __init__(self, src):
+    ...         self.lines = src.split('\n')
+    ...     def readline(self):
+    ...         line = self.lines.pop(0)
+    ...         print line
+    ...         return line+'\n'
+
+    >>> real_stdin = sys.stdin
+
+Using pdb.set_trace in a function called by an ordinary test:
+
+    >>> if sys.version_info[:2] == (2, 3):
+    ...     sys.stdin = Input('n\np x\nc')
+    ... else:
+    ...     sys.stdin = Input('p x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t set_trace2').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    ... # doctest: +ELLIPSIS
+    Running unit tests:...
+    > testrunner-ex/sample3/sampletests_d.py(47)f()
+    -> y = x
+    (Pdb) p x
+    1
+    (Pdb) c
+      Ran 1 tests with 0 failures and 0 errors in 0.001 seconds.
+    False
+
+Using pdb.set_trace in a function called by a doctest in a doc string:
+
+    >>> sys.stdin = Input('n\np x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t set_trace4').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    Running unit tests:
+    --Return--
+    > doctest.py(351)set_trace()->None
+    -> pdb.Pdb.set_trace(self)
+    (Pdb) n
+    > testrunner-ex/sample3/sampletests_d.py(42)f()
+    -> y = x
+    (Pdb) p x
+    1
+    (Pdb) c
+      Ran 1 tests with 0 failures and 0 errors in 0.002 seconds.
+    False
+
+Using pdb in a docstring-based doctest
+
+    >>> sys.stdin = Input('n\np x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t set_trace3').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    Running unit tests:
+    --Return--
+    > doctest.py(351)set_trace()->None
+    -> pdb.Pdb.set_trace(self)
+    (Pdb) n
+    > <doctest sample3.sampletests_d.set_trace3[1]>(3)?()
+    -> y = x
+    (Pdb) p x
+    1
+    (Pdb) c
+      Ran 1 tests with 0 failures and 0 errors in 0.002 seconds.
+    False
+
+Using pdb.set_trace in a doc file:
+
+
+    >>> sys.stdin = Input('n\np x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t set_trace5').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    Running unit tests:
+    --Return--
+    > doctest.py(351)set_trace()->None
+    -> pdb.Pdb.set_trace(self)
+    (Pdb) n
+    > <doctest set_trace5.txt[1]>(3)?()
+    -> y = x
+    (Pdb) p x
+    1
+    (Pdb) c
+      Ran 1 tests with 0 failures and 0 errors in 0.002 seconds.
+    False
+
+
+Using pdb.set_trace in a function called by a doctest in a doc file:
+
+
+    >>> sys.stdin = Input('n\np x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t set_trace6').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    Running unit tests:
+    --Return--
+    > doctest.py(351)set_trace()->None
+    -> pdb.Pdb.set_trace(self)
+    (Pdb) n
+    > testrunner-ex/sample3/sampletests_d.py(42)f()
+    -> y = x
+    (Pdb) p x
+    1
+    (Pdb) c
+      Ran 1 tests with 0 failures and 0 errors in 0.002 seconds.
+    False
+
+Post-mortem debugging function called from ordinary test:
+
+    >>> sys.stdin = Input('p x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t post_mortem2 -D').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    ... # doctest: +NORMALIZE_WHITESPACE
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test test_post_mortem2 (sample3.sampletests_d.TestSomething)
+    Traceback (most recent call last):
+      File "testrunner-ex/sample3/sampletests_d.py",
+           line 37, in test_post_mortem2
+        g()
+      File "testrunner-ex/sample3/sampletests_d.py", line 46, in g
+        raise ValueError
+    ValueError
+    <BLANKLINE>
+    exceptions.ValueError:
+    <BLANKLINE>
+    > testrunner-ex/sample3/sampletests_d.py(46)g()
+    -> raise ValueError
+    (Pdb) p x
+    1
+    (Pdb) c
+    True
+
+
+Post-mortem debugging docstring-based doctest:
+
+    >>> sys.stdin = Input('p x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t post_mortem3 -D').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    ... # doctest: +NORMALIZE_WHITESPACE
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test post_mortem3 (sample3.sampletests_d)
+    Traceback (most recent call last):
+      File "zope/testing/doctest.py", line 2276, in debug
+        runner.run(self._dt_test)
+      File "zope/testing/doctest.py", line 1731, in run
+        r = DocTestRunner.run(self, test, compileflags, out, False)
+      File "zope/testing/doctest.py", line 1389, in run
+        return self.__run(test, compileflags, out)
+      File "zope/testing/doctest.py", line 1310, in __run
+        exc_info)
+      File "zope/testing/doctest.py", line 1737, in report_unexpected_exception
+        raise UnexpectedException(test, example, exc_info)
+    UnexpectedException:
+       from testrunner-ex/sample3/sampletests_d.py:61 (2 examples)>
+    <BLANKLINE>
+    exceptions.ValueError:
+    <BLANKLINE>
+    > <doctest sample3.sampletests_d.post_mortem3[1]>(1)?()
+    (Pdb) p x
+    1
+    (Pdb) c
+    True
+
+Post-mortem debugging function called from docstring-based doctest:
+
+    >>> sys.stdin = Input('p x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t post_mortem4 -D').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    ... # doctest: +NORMALIZE_WHITESPACE
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test post_mortem4 (sample3.sampletests_d)
+    Traceback (most recent call last):
+      File "zope/testing/doctest.py", line 2276, in debug
+        runner.run(self._dt_test)
+      File "zope/testing/doctest.py", line 1731, in run
+        r = DocTestRunner.run(self, test, compileflags, out, False)
+      File "zope/testing/doctest.py", line 1389, in run
+        return self.__run(test, compileflags, out)
+      File "zope/testing/doctest.py", line 1310, in __run
+        exc_info)
+      File "zope/testing/doctest.py", line 1737, in report_unexpected_exception
+        raise UnexpectedException(test, example, exc_info)
+    UnexpectedException: testrunner-ex/sample3/sampletests_d.py:67 (1 example)>
+    <BLANKLINE>
+    exceptions.ValueError:
+    <BLANKLINE>
+    > testrunner-ex/sample3/sampletests_d.py(46)g()
+    -> raise ValueError
+    (Pdb) p x
+    1
+    (Pdb) c
+    True
+
+Post-mortem debugging file-based doctest:
+
+    >>> sys.stdin = Input('p x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t post_mortem5 -D').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    ... # doctest: +NORMALIZE_WHITESPACE
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test zope/testing/testrunner-ex/sample3/post_mortem5.txt
+    Traceback (most recent call last):
+      File "zope/testing/doctest.py", line 2276, in debug
+        runner.run(self._dt_test)
+      File "zope/testing/doctest.py", line 1731, in run
+        r = DocTestRunner.run(self, test, compileflags, out, False)
+      File "zope/testing/doctest.py", line 1389, in run
+        return self.__run(test, compileflags, out)
+      File "zope/testing/doctest.py", line 1310, in __run
+        exc_info)
+      File "zope/testing/doctest.py", line 1737, in report_unexpected_exception
+        raise UnexpectedException(test, example, exc_info)
+    UnexpectedException: testrunner-ex/sample3/post_mortem5.txt:0 (2 examples)>
+    <BLANKLINE>
+    exceptions.ValueError:
+    <BLANKLINE>
+    > <doctest post_mortem5.txt[1]>(1)?()
+    (Pdb) p x
+    1
+    (Pdb) c
+    True
+
+
+Post-mortem debugging function called from file-based doctest:
+
+    >>> sys.stdin = Input('p x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t post_mortem6 -D').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    ... # doctest: +NORMALIZE_WHITESPACE
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test zope/testing/testrunner-ex/sample3/post_mortem6.txt
+    Traceback (most recent call last):
+      File "zope/testing/doctest.py", line 2276, in debug
+        runner.run(self._dt_test)
+      File "zope/testing/doctest.py", line 1731, in run
+        r = DocTestRunner.run(self, test, compileflags, out, False)
+      File "zope/testing/doctest.py", line 1389, in run
+        return self.__run(test, compileflags, out)
+      File "zope/testing/doctest.py", line 1310, in __run
+        exc_info)
+      File "zope/testing/doctest.py", line 1737, in report_unexpected_exception
+        raise UnexpectedException(test, example, exc_info)
+    UnexpectedException: testrunner-ex/sample3/post_mortem6.txt:0 (2 examples)>
+    <BLANKLINE>
+    exceptions.ValueError:
+    <BLANKLINE>
+    > testrunner-ex/sample3/sampletests_d.py(46)g()
+    -> raise ValueError
+    (Pdb) p x
+    1
+    (Pdb) c
+    True
+
+Post-mortem debugging of a docstring doctest failure:
+
+    >>> sys.stdin = Input('p x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t post_mortem_failure2 -D').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    ... # doctest: +NORMALIZE_WHITESPACE
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test post_mortem_failure2 (sample3.sampletests_d)
+    <BLANKLINE>
+    File "testrunner-ex/sample3/sampletests_d.py",
+                   line 81, in sample3.sampletests_d.post_mortem_failure2
+    <BLANKLINE>
+    x
+    <BLANKLINE>
+    Want:
+    2
+    <BLANKLINE>
+    Got:
+    1
+    <BLANKLINE>
+    <BLANKLINE>
+    > testrunner-ex/sample3/sampletests_d.py(81)_()
+    exceptions.ValueError:
+    Expected and actual output are different
+    > <string>(1)?()
+    (Pdb) p x
+    1
+    (Pdb) c
+    True
+
+
+Post-mortem debugging of a docfile doctest failure:
+
+    >>> sys.stdin = Input('p x\nc')
+    >>> sys.argv = ('test -ssample3 --tests-pattern ^sampletests_d$'
+    ...             ' -t post_mortem_failure.txt -D').split()
+    >>> try: testrunner.run(defaults)
+    ... finally: sys.stdin = real_stdin
+    ... # doctest: +NORMALIZE_WHITESPACE
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test /home/jim/z3/zope.testing/src/zope/testing/testrunner-ex/sample3/post_mortem_failure.txt
+    <BLANKLINE>
+    File "testrunner-ex/sample3/post_mortem_failure.txt",
+                                      line 2, in post_mortem_failure.txt
+    <BLANKLINE>
+    x
+    <BLANKLINE>
+    Want:
+    2
+    <BLANKLINE>
+    Got:
+    1
+    <BLANKLINE>
+    <BLANKLINE>
+    > testrunner-ex/sample3/post_mortem_failure.txt(2)_()
+    exceptions.ValueError:
+    Expected and actual output are different
+    > <string>(1)?()
+    (Pdb) p x
+    1
+    (Pdb) c
+    True
+
+Post-mortem debugging with triple verbosity
+
+    >>> sys.argv = 'test --layer samplelayers.Layer1$ -vvv -D'.split()
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running samplelayers.Layer1 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Running:
+        test_x1 (sampletestsf.TestA1) (0.000 ms)
+        test_y0 (sampletestsf.TestA1) (0.000 ms)
+        test_z0 (sampletestsf.TestA1) (0.000 ms)
+        test_x0 (sampletestsf.TestB1) (0.000 ms)
+        test_y1 (sampletestsf.TestB1) (0.000 ms)
+        test_z0 (sampletestsf.TestB1) (0.000 ms)
+        test_1 (sampletestsf.TestNotMuch1) (0.000 ms)
+        test_2 (sampletestsf.TestNotMuch1) (0.000 ms)
+        test_3 (sampletestsf.TestNotMuch1) (0.000 ms)
+      Ran 9 tests with 0 failures and 0 errors in 0.001 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    False
+
+Test Suites with None for suites or tests
+-----------------------------------------
+
+    >>> sys.argv = ['test', 
+    ...             '--tests-pattern', '^sampletests_none_suite$',
+    ...     ]
+    >>> testrunner.run(defaults)
+    Test-module import failures:
+    <BLANKLINE>
+    Module: sample1.sampletests_none_suite
+    <BLANKLINE>
+    TypeError: Invalid test_suite, None, in sample1.sampletests_none_suite
+    <BLANKLINE>
+    <BLANKLINE>
+    Total: 0 tests, 0 failures, 0 errors
+    <BLANKLINE>
+    Test-modules with import problems:
+      sample1.sampletests_none_suite
+    True
+
+
+    >>> sys.argv = ['test', 
+    ...             '--tests-pattern', '^sampletests_none_test$',
+    ...     ]
+    >>> testrunner.run(defaults)
+    Test-module import failures:
+    <BLANKLINE>
+    Module: sample1.sampletests_none_test
+    <BLANKLINE>
+    TypeError: Invalid test, None,
+    in test_suite from sample1.sampletests_none_test
+    <BLANKLINE>
+    <BLANKLINE>
+    Total: 0 tests, 0 failures, 0 errors
+    <BLANKLINE>
+    Test-modules with import problems:
+      sample1.sampletests_none_test
+    True
+
+You must use --repeat with --report-refcounts
+---------------------------------------------
+
+It is an error to specify --report-refcounts (-r) without specifying a
+repeat count greater than 1
+
+    >>> sys.argv = 'test -r'.split() 
+    >>> testrunner.run(defaults)
+            You must use the --repeat (-N) option to specify a repeat
+            count greater than 1 when using the --report_refcounts (-r)
+            option.
+    <BLANKLINE>
+    True
+
+    >>> sys.argv = 'test -r -N1'.split() 
+    >>> testrunner.run(defaults)
+            You must use the --repeat (-N) option to specify a repeat
+            count greater than 1 when using the --report_refcounts (-r)
+            option.
+    <BLANKLINE>
+    True


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-edge-cases.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-errors.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-errors.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-errors.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,804 @@
+Test Runner
+===========
+
+Errors and Failures
+-------------------
+
+Let's look at tests that have errors and failures:
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> from zope.testing import testrunner
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+
+    >>> sys.argv = 'test --tests-pattern ^sampletests(f|_e|_f)?$ '.split()
+    >>> testrunner.run(defaults)
+    ... # doctest: +NORMALIZE_WHITESPACE
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Failure in test eek (sample2.sampletests_e)
+    Failed doctest test for sample2.sampletests_e.eek
+      File "testrunner-ex/sample2/sampletests_e.py", line 28, in eek
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/sample2/sampletests_e.py", line 30, in sample2.sampletests_e.eek
+    Failed example:
+        f()
+    Exception raised:
+        Traceback (most recent call last):
+          File ".../doctest.py", line 1256, in __run
+            compileflags, 1) in test.globs
+          File "<doctest sample2.sampletests_e.eek[0]>", line 1, in ?
+            f()
+          File "testrunner-ex/sample2/sampletests_e.py", line 19, in f
+            g()
+          File "testrunner-ex/sample2/sampletests_e.py", line 24, in g
+            x = y + 1
+        NameError: global name 'y' is not defined
+    <BLANKLINE>
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test test3 (sample2.sampletests_e.Test)
+    Traceback (most recent call last):
+      File "testrunner-ex/sample2/sampletests_e.py", line 43, in test3
+        f()
+      File "testrunner-ex/sample2/sampletests_e.py", line 19, in f
+        g()
+      File "testrunner-ex/sample2/sampletests_e.py", line 24, in g
+        x = y + 1
+    NameError: global name 'y' is not defined
+    <BLANKLINE>
+    <BLANKLINE>
+    <BLANKLINE>
+    Failure in test testrunner-ex/sample2/e.txt
+    Failed doctest test for e.txt
+      File "testrunner-ex/sample2/e.txt", line 0
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/sample2/e.txt", line 4, in e.txt
+    Failed example:
+        f()
+    Exception raised:
+        Traceback (most recent call last):
+          File ".../doctest.py", line 1256, in __run
+            compileflags, 1) in test.globs
+          File "<doctest e.txt[1]>", line 1, in ?
+            f()
+          File "<doctest e.txt[0]>", line 2, in f
+            return x
+        NameError: global name 'x' is not defined
+    <BLANKLINE>
+    <BLANKLINE>
+    <BLANKLINE>
+    Failure in test test (sample2.sampletests_f.Test)
+    Traceback (most recent call last):
+      File "testrunner-ex/sample2/sampletests_f.py", line 21, in test
+        self.assertEqual(1,0)
+      File "/usr/local/python/2.3/lib/python2.3/unittest.py", line 302, in failUnlessEqual
+        raise self.failureException, \
+    AssertionError: 1 != 0
+    <BLANKLINE>
+      Ran 200 tests with 3 failures and 1 errors in 0.038 seconds.
+    Running samplelayers.Layer1 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Ran 9 tests with 0 failures and 0 errors in 0.000 seconds.
+    Running samplelayers.Layer11 tests:
+      Set up samplelayers.Layer11 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.007 seconds.
+    Running samplelayers.Layer111 tests:
+      Set up samplelayers.Layerx in 0.000 seconds.
+      Set up samplelayers.Layer111 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.007 seconds.
+    Running samplelayers.Layer112 tests:
+      Tear down samplelayers.Layer111 in 0.000 seconds.
+      Set up samplelayers.Layer112 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.006 seconds.
+    Running samplelayers.Layer12 tests:
+      Tear down samplelayers.Layer112 in 0.000 seconds.
+      Tear down samplelayers.Layerx in 0.000 seconds.
+      Tear down samplelayers.Layer11 in 0.000 seconds.
+      Set up samplelayers.Layer12 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.007 seconds.
+    Running samplelayers.Layer121 tests:
+      Set up samplelayers.Layer121 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.006 seconds.
+    Running samplelayers.Layer122 tests:
+      Tear down samplelayers.Layer121 in 0.000 seconds.
+      Set up samplelayers.Layer122 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.007 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in 0.000 seconds.
+      Tear down samplelayers.Layer12 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    Total: 413 tests, 3 failures, 1 errors
+    True
+
+We see that we get an error report and a traceback for the failing
+test.  In addition, the test runner returned True, indicating that
+there was an error.
+
+If we ask for single verbosity, the dotted output will be interrupted:
+
+    >>> sys.argv = 'test --tests-pattern ^sampletests(f|_e|_f)?$ -uv'.split()
+    >>> testrunner.run(defaults)
+    ... # doctest: +NORMALIZE_WHITESPACE +REPORT_NDIFF
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        ..................................................
+        ...............................................
+    <BLANKLINE>
+    Failure in test eek (sample2.sampletests_e)
+    Failed doctest test for sample2.sampletests_e.eek
+      File "testrunner-ex/sample2/sampletests_e.py", line 28, in eek
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/sample2/sampletests_e.py", line 30,
+        in sample2.sampletests_e.eek
+    Failed example:
+        f()
+    Exception raised:
+        Traceback (most recent call last):
+          File ".../doctest.py", line 1256, in __run
+            compileflags, 1) in test.globs
+          File "<doctest sample2.sampletests_e.eek[0]>", line 1, in ?
+            f()
+          File "testrunner-ex/sample2/sampletests_e.py", line 19, in f
+            g()
+          File "testrunner-ex/sample2/sampletests_e.py", line 24, in g
+            x = y + 1
+        NameError: global name 'y' is not defined
+    <BLANKLINE>
+    ...
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test test3 (sample2.sampletests_e.Test)
+    Traceback (most recent call last):
+      File "testrunner-ex/sample2/sampletests_e.py", line 43, in test3
+        f()
+      File "testrunner-ex/sample2/sampletests_e.py", line 19, in f
+        g()
+      File "testrunner-ex/sample2/sampletests_e.py", line 24, in g
+        x = y + 1
+    NameError: global name 'y' is not defined
+    <BLANKLINE>
+    ...
+    <BLANKLINE>
+    Failure in test testrunner-ex/sample2/e.txt
+    Failed doctest test for e.txt
+      File "testrunner-ex/sample2/e.txt", line 0
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/sample2/e.txt", line 4, in e.txt
+    Failed example:
+        f()
+    Exception raised:
+        Traceback (most recent call last):
+          File ".../doctest.py", line 1256, in __run
+            compileflags, 1) in test.globs
+          File "<doctest e.txt[1]>", line 1, in ?
+            f()
+          File "<doctest e.txt[0]>", line 2, in f
+            return x
+        NameError: global name 'x' is not defined
+    <BLANKLINE>
+    .
+    <BLANKLINE>
+    Failure in test test (sample2.sampletests_f.Test)
+    Traceback (most recent call last):
+      File "testrunner-ex/sample2/sampletests_f.py", line 21, in test
+        self.assertEqual(1,0)
+      File ".../unittest.py", line 302, in failUnlessEqual
+        raise self.failureException, \
+    AssertionError: 1 != 0
+    <BLANKLINE>
+    ..............................................
+        ..................................................
+    <BLANKLINE>
+      Ran 200 tests with 3 failures and 1 errors in 0.040 seconds.
+    True
+
+Similarly for progress output:
+
+    >>> sys.argv = ('test --tests-pattern ^sampletests(f|_e|_f)?$ -u -ssample2'
+    ...             ' -p').split()
+    >>> testrunner.run(defaults)
+    ... # doctest: +NORMALIZE_WHITESPACE +REPORT_NDIFF
+    Running unit tests:
+      Running:
+        1/56 (1.8%)
+    <BLANKLINE>
+    Failure in test eek (sample2.sampletests_e)
+    Failed doctest test for sample2.sampletests_e.eek
+      File "testrunner-ex/sample2/sampletests_e.py", line 28, in eek
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/sample2/sampletests_e.py", line 30,
+           in sample2.sampletests_e.eek
+    Failed example:
+        f()
+    Exception raised:
+        Traceback (most recent call last):
+          File ".../doctest.py", line 1256, in __run
+            compileflags, 1) in test.globs
+          File "<doctest sample2.sampletests_e.eek[0]>", line 1, in ?
+            f()
+          File "testrunner-ex/sample2/sampletests_e.py", line 19, in f
+            g()
+          File "testrunner-ex/sample2/sampletests_e.py", line 24, in g
+            x = y + 1
+        NameError: global name 'y' is not defined
+    <BLANKLINE>
+        2/56 (3.6%)\r
+                   \r
+        3/56 (5.4%)\r
+                   \r
+        4/56 (7.1%)
+    <BLANKLINE>
+    Error in test test3 (sample2.sampletests_e.Test)
+    Traceback (most recent call last):
+      File "testrunner-ex/sample2/sampletests_e.py", line 43, in test3
+        f()
+      File "testrunner-ex/sample2/sampletests_e.py", line 19, in f
+        g()
+      File "testrunner-ex/sample2/sampletests_e.py", line 24, in g
+        x = y + 1
+    NameError: global name 'y' is not defined
+    <BLANKLINE>
+        5/56 (8.9%)\r
+                   \r
+        6/56 (10.7%)\r
+                    \r
+        7/56 (12.5%)
+    <BLANKLINE>
+    Failure in test testrunner-ex/sample2/e.txt
+    Failed doctest test for e.txt
+      File "testrunner-ex/sample2/e.txt", line 0
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/sample2/e.txt", line 4, in e.txt
+    Failed example:
+        f()
+    Exception raised:
+        Traceback (most recent call last):
+          File ".../doctest.py", line 1256, in __run
+            compileflags, 1) in test.globs
+          File "<doctest e.txt[1]>", line 1, in ?
+            f()
+          File "<doctest e.txt[0]>", line 2, in f
+            return x
+        NameError: global name 'x' is not defined
+    <BLANKLINE>
+        8/56 (14.3%)
+    <BLANKLINE>
+    Failure in test test (sample2.sampletests_f.Test)
+    Traceback (most recent call last):
+      File "testrunner-ex/sample2/sampletests_f.py", line 21, in test
+        self.assertEqual(1,0)
+      File ".../unittest.py", line 302, in failUnlessEqual
+        raise self.failureException, \
+    AssertionError: 1 != 0
+    <BLANKLINE>
+        9/56 (16.1%)\r
+                    \r
+        10/56 (17.9%)\r
+                     \r
+        11/56 (19.6%)\r
+                     \r
+        12/56 (21.4%)\r
+                     \r
+        13/56 (23.2%)\r
+                     \r
+        14/56 (25.0%)\r
+                     \r
+        15/56 (26.8%)\r
+                     \r
+        16/56 (28.6%)\r
+                     \r
+        17/56 (30.4%)\r
+                     \r
+        18/56 (32.1%)\r
+                     \r
+        19/56 (33.9%)\r
+                     \r
+        20/56 (35.7%)\r
+                     \r
+        24/56 (42.9%)\r
+                     \r
+        25/56 (44.6%)\r
+                     \r
+        26/56 (46.4%)\r
+                     \r
+        27/56 (48.2%)\r
+                     \r
+        28/56 (50.0%)\r
+                     \r
+        29/56 (51.8%)\r
+                     \r
+        30/56 (53.6%)\r
+                     \r
+        31/56 (55.4%)\r
+                     \r
+        32/56 (57.1%)\r
+                     \r
+        33/56 (58.9%)\r
+                     \r
+        34/56 (60.7%)\r
+                     \r
+        35/56 (62.5%)\r
+                     \r
+        36/56 (64.3%)\r
+                     \r
+        40/56 (71.4%)\r
+                     \r
+        41/56 (73.2%)\r
+                     \r
+        42/56 (75.0%)\r
+                     \r
+        43/56 (76.8%)\r
+                     \r
+        44/56 (78.6%)\r
+                     \r
+        45/56 (80.4%)\r
+                     \r
+        46/56 (82.1%)\r
+                     \r
+        47/56 (83.9%)\r
+                     \r
+        48/56 (85.7%)\r
+                     \r
+        49/56 (87.5%)\r
+                     \r
+        50/56 (89.3%)\r
+                     \r
+        51/56 (91.1%)\r
+                     \r
+        52/56 (92.9%)\r
+                     \r
+        56/56 (100.0%)\r
+                      \r
+    <BLANKLINE>
+      Ran 56 tests with 3 failures and 1 errors in 0.054 seconds.
+    True
+
+For greater levels of verbosity, we summarize the errors at the end of
+the test
+
+    >>> sys.argv = ('test --tests-pattern ^sampletests(f|_e|_f)?$ -u -ssample2'
+    ...             ' -vv').split()
+    >>> testrunner.run(defaults)
+    ... # doctest: +NORMALIZE_WHITESPACE
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        eek (sample2.sampletests_e)
+    <BLANKLINE>
+    Failure in test eek (sample2.sampletests_e)
+    Failed doctest test for sample2.sampletests_e.eek
+      File "testrunner-ex/sample2/sampletests_e.py", line 28, in eek
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/sample2/sampletests_e.py", line 30,
+           in sample2.sampletests_e.eek
+    Failed example:
+        f()
+    Exception raised:
+        Traceback (most recent call last):
+          File ".../doctest.py", line 1256, in __run
+            compileflags, 1) in test.globs
+          File "<doctest sample2.sampletests_e.eek[0]>", line 1, in ?
+            f()
+          File "testrunner-ex/sample2/sampletests_e.py", line 19, in f
+            g()
+          File "testrunner-ex/sample2/sampletests_e.py", line 24, in g
+            x = y + 1
+        NameError: global name 'y' is not defined
+    <BLANKLINE>
+    <BLANKLINE>
+        test1 (sample2.sampletests_e.Test)
+        test2 (sample2.sampletests_e.Test)
+        test3 (sample2.sampletests_e.Test)
+    <BLANKLINE>
+    Error in test test3 (sample2.sampletests_e.Test)
+    Traceback (most recent call last):
+      File "testrunner-ex/sample2/sampletests_e.py", line 43, in test3
+        f()
+      File "testrunner-ex/sample2/sampletests_e.py", line 19, in f
+        g()
+      File "testrunner-ex/sample2/sampletests_e.py", line 24, in g
+        x = y + 1
+    NameError: global name 'y' is not defined
+    <BLANKLINE>
+    <BLANKLINE>
+        test4 (sample2.sampletests_e.Test)
+        test5 (sample2.sampletests_e.Test)
+        testrunner-ex/sample2/e.txt
+    <BLANKLINE>
+    Failure in test testrunner-ex/sample2/e.txt
+    Failed doctest test for e.txt
+      File "testrunner-ex/sample2/e.txt", line 0
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/sample2/e.txt", line 4, in e.txt
+    Failed example:
+        f()
+    Exception raised:
+        Traceback (most recent call last):
+          File ".../doctest.py", line 1256, in __run
+            compileflags, 1) in test.globs
+          File "<doctest e.txt[1]>", line 1, in ?
+            f()
+          File "<doctest e.txt[0]>", line 2, in f
+            return x
+        NameError: global name 'x' is not defined
+    <BLANKLINE>
+    <BLANKLINE>
+        test (sample2.sampletests_f.Test)
+    <BLANKLINE>
+    Failure in test test (sample2.sampletests_f.Test)
+    Traceback (most recent call last):
+      File "testrunner-ex/sample2/sampletests_f.py", line 21, in test
+        self.assertEqual(1,0)
+      File ".../unittest.py", line 302, in failUnlessEqual
+        raise self.failureException, \
+    AssertionError: 1 != 0
+    <BLANKLINE>
+    <BLANKLINE>
+        test_x1 (sample2.sample21.sampletests.TestA)
+        test_y0 (sample2.sample21.sampletests.TestA)
+        test_z0 (sample2.sample21.sampletests.TestA)
+        test_x0 (sample2.sample21.sampletests.TestB)
+        test_y1 (sample2.sample21.sampletests.TestB)
+        test_z0 (sample2.sample21.sampletests.TestB)
+        test_1 (sample2.sample21.sampletests.TestNotMuch)
+        test_2 (sample2.sample21.sampletests.TestNotMuch)
+        test_3 (sample2.sample21.sampletests.TestNotMuch)
+        test_x0 (sample2.sample21.sampletests)
+        test_y0 (sample2.sample21.sampletests)
+        test_z1 (sample2.sample21.sampletests)
+        testrunner-ex/sample2/sample21/../../sampletests.txt
+        test_x1 (sample2.sampletests.test_1.TestA)
+        test_y0 (sample2.sampletests.test_1.TestA)
+        test_z0 (sample2.sampletests.test_1.TestA)
+        test_x0 (sample2.sampletests.test_1.TestB)
+        test_y1 (sample2.sampletests.test_1.TestB)
+        test_z0 (sample2.sampletests.test_1.TestB)
+        test_1 (sample2.sampletests.test_1.TestNotMuch)
+        test_2 (sample2.sampletests.test_1.TestNotMuch)
+        test_3 (sample2.sampletests.test_1.TestNotMuch)
+        test_x0 (sample2.sampletests.test_1)
+        test_y0 (sample2.sampletests.test_1)
+        test_z1 (sample2.sampletests.test_1)
+        testrunner-ex/sample2/sampletests/../../sampletests.txt
+        test_x1 (sample2.sampletests.testone.TestA)
+        test_y0 (sample2.sampletests.testone.TestA)
+        test_z0 (sample2.sampletests.testone.TestA)
+        test_x0 (sample2.sampletests.testone.TestB)
+        test_y1 (sample2.sampletests.testone.TestB)
+        test_z0 (sample2.sampletests.testone.TestB)
+        test_1 (sample2.sampletests.testone.TestNotMuch)
+        test_2 (sample2.sampletests.testone.TestNotMuch)
+        test_3 (sample2.sampletests.testone.TestNotMuch)
+        test_x0 (sample2.sampletests.testone)
+        test_y0 (sample2.sampletests.testone)
+        test_z1 (sample2.sampletests.testone)
+        testrunner-ex/sample2/sampletests/../../sampletests.txt
+      Ran 56 tests with 3 failures and 1 errors in 0.060 seconds.
+    <BLANKLINE>
+    Tests with errors:
+       test3 (sample2.sampletests_e.Test)
+    <BLANKLINE>
+    Tests with failures:
+       eek (sample2.sampletests_e)
+       testrunner-ex/sample2/e.txt
+       test (sample2.sampletests_f.Test)
+    True
+
+Suppressing multiple doctest errors
+-----------------------------------
+
+Often, when a doctest example fails, the failure will cause later
+examples in the same test to fail.  Each failure is reported:
+
+    >>> sys.argv = 'test --tests-pattern ^sampletests_1$'.split()
+    >>> testrunner.run(defaults) # doctest: +NORMALIZE_WHITESPACE
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Failure in test eek (sample2.sampletests_1)
+    Failed doctest test for sample2.sampletests_1.eek
+      File "testrunner-ex/sample2/sampletests_1.py", line 17, in eek
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/sample2/sampletests_1.py", line 19,
+         in sample2.sampletests_1.eek
+    Failed example:
+        x = y
+    Exception raised:
+        Traceback (most recent call last):
+          File ".../doctest.py", line 1256, in __run
+            compileflags, 1) in test.globs
+          File "<doctest sample2.sampletests_1.eek[0]>", line 1, in ?
+            x = y
+        NameError: name 'y' is not defined
+    ----------------------------------------------------------------------
+    File "testrunner-ex/sample2/sampletests_1.py", line 21,
+         in sample2.sampletests_1.eek
+    Failed example:
+        x
+    Exception raised:
+        Traceback (most recent call last):
+          File ".../doctest.py", line 1256, in __run
+            compileflags, 1) in test.globs
+          File "<doctest sample2.sampletests_1.eek[1]>", line 1, in ?
+            x
+        NameError: name 'x' is not defined
+    ----------------------------------------------------------------------
+    File "testrunner-ex/sample2/sampletests_1.py", line 24,
+         in sample2.sampletests_1.eek
+    Failed example:
+        z = x + 1
+    Exception raised:
+        Traceback (most recent call last):
+          File ".../doctest.py", line 1256, in __run
+            compileflags, 1) in test.globs
+          File "<doctest sample2.sampletests_1.eek[2]>", line 1, in ?
+            z = x + 1
+        NameError: name 'x' is not defined
+    <BLANKLINE>
+      Ran 1 tests with 1 failures and 0 errors in 0.002 seconds.
+    True
+
+This can be a bit confusing, especially when there are enough tests
+that they scroll off a screen.  Often you just want to see the first
+failure.  This can be accomplished with the -1 option (for "just show
+me the first failed example in a doctest" :)
+
+    >>> sys.argv = 'test --tests-pattern ^sampletests_1$ -1'.split()
+    >>> testrunner.run(defaults) # doctest:
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Failure in test eek (sample2.sampletests_1)
+    Failed doctest test for sample2.sampletests_1.eek
+      File "testrunner-ex/sample2/sampletests_1.py", line 17, in eek
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/sample2/sampletests_1.py", line 19,
+         in sample2.sampletests_1.eek
+    Failed example:
+        x = y
+    Exception raised:
+        Traceback (most recent call last):
+          File ".../doctest.py", line 1256, in __run
+            compileflags, 1) in test.globs
+          File "<doctest sample2.sampletests_1.eek[0]>", line 1, in ?
+            x = y
+        NameError: name 'y' is not defined
+    <BLANKLINE>
+      Ran 1 tests with 1 failures and 0 errors in 0.001 seconds.
+    True
+
+Getting diff output for doctest failures
+----------------------------------------
+
+If a doctest has large expected and actual output, it can be hard to
+see differences when expected and actual output differ.  The --ndiff,
+--udiff, and --cdiff options can be used to get diff output pf various
+kinds.
+
+    >>> sys.argv = 'test --tests-pattern ^pledge$'.split()
+    >>> _ = testrunner.run(defaults)
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Failure in test pledge (pledge)
+    Failed doctest test for pledge.pledge
+      File "testrunner-ex/pledge.py", line 24, in pledge
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/pledge.py", line 26, in pledge.pledge
+    Failed example:
+        print pledge_template % ('and earthling', 'planet'),
+    Expected:
+        I give my pledge, as an earthling,
+        to save, and faithfully, to defend from waste,
+        the natural resources of my planet.
+        It's soils, minerals, forests, waters, and wildlife.
+    Got:
+        I give my pledge, as and earthling,
+        to save, and faithfully, to defend from waste,
+        the natural resources of my planet.
+        It's soils, minerals, forests, waters, and wildlife.
+    <BLANKLINE>
+      Ran 1 tests with 1 failures and 0 errors in 0.002 seconds.
+
+Here, the actual output uses the word "and" rather than the word "an",
+but it's a bit hard to pick this out.  Wr can use the various diff
+outputs to see this better. We could modify the test to ask for diff
+output, but it's easier to use one of the diff options.
+
+The --ndiff option requests a diff using Python's ndiff utility. This
+is the only method that marks differences within lines as well as
+across lines. For example, if a line of expected output contains digit
+1 where actual output contains letter l, a line is inserted with a
+caret marking the mismatching column positions.
+
+    >>> sys.argv = 'test --tests-pattern ^pledge$ --ndiff'.split()
+    >>> _ = testrunner.run(defaults)
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Failure in test pledge (pledge)
+    Failed doctest test for pledge.pledge
+      File "testrunner-ex/pledge.py", line 24, in pledge
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/pledge.py", line 26, in pledge.pledge
+    Failed example:
+        print pledge_template % ('and earthling', 'planet'),
+    Differences (ndiff with -expected +actual):
+        - I give my pledge, as an earthling,
+        + I give my pledge, as and earthling,
+        ?                        +
+          to save, and faithfully, to defend from waste,
+          the natural resources of my planet.
+          It's soils, minerals, forests, waters, and wildlife.
+    <BLANKLINE>
+      Ran 1 tests with 1 failures and 0 errors in 0.003 seconds.
+
+The -udiff option requests a standard "unified" diff:
+
+    >>> sys.argv = 'test --tests-pattern ^pledge$ --udiff'.split()
+    >>> _ = testrunner.run(defaults)
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Failure in test pledge (pledge)
+    Failed doctest test for pledge.pledge
+      File "testrunner-ex/pledge.py", line 24, in pledge
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/pledge.py", line 26, in pledge.pledge
+    Failed example:
+        print pledge_template % ('and earthling', 'planet'),
+    Differences (unified diff with -expected +actual):
+        @@ -1,3 +1,3 @@
+        -I give my pledge, as an earthling,
+        +I give my pledge, as and earthling,
+         to save, and faithfully, to defend from waste,
+         the natural resources of my planet.
+    <BLANKLINE>
+      Ran 1 tests with 1 failures and 0 errors in 0.002 seconds.
+
+The -cdiff option requests a standard "context" diff:
+
+    >>> sys.argv = 'test --tests-pattern ^pledge$ --cdiff'.split()
+    >>> _ = testrunner.run(defaults)
+    Running unit tests:
+    <BLANKLINE>
+    <BLANKLINE>
+    Failure in test pledge (pledge)
+    Failed doctest test for pledge.pledge
+      File "testrunner-ex/pledge.py", line 24, in pledge
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    File "testrunner-ex/pledge.py", line 26, in pledge.pledge
+    Failed example:
+        print pledge_template % ('and earthling', 'planet'),
+    Differences (context diff with expected followed by actual):
+        ***************
+        *** 1,3 ****
+        ! I give my pledge, as an earthling,
+          to save, and faithfully, to defend from waste,
+          the natural resources of my planet.
+        --- 1,3 ----
+        ! I give my pledge, as and earthling,
+          to save, and faithfully, to defend from waste,
+          the natural resources of my planet.
+    <BLANKLINE>
+      Ran 1 tests with 1 failures and 0 errors in 0.002 seconds.
+
+
+Testing-Module Import Errors
+----------------------------
+
+If there are errors when importing a test module, these errors are
+reported.  In order to illustrate a module with a syntax error, we create
+one now:  this module used to be checked in to the project, but then it was
+included in distributions of projects using zope.testing too, and distutils
+complained about the syntax error when it compiled Python files during
+installation of such projects.  So first we create a module with bad syntax:
+
+    >>> badsyntax_path = os.path.join(directory_with_tests,
+    ...                               "sample2", "sampletests_i.py")
+    >>> f = open(badsyntax_path, "w")
+    >>> print >> f, "importx unittest"  # syntax error
+    >>> f.close()
+
+Then run the tests:
+
+    >>> sys.argv = ('test --tests-pattern ^sampletests(f|_i)?$ --layer 1 '
+    ...            ).split()
+    >>> testrunner.run(defaults)
+    ... # doctest: +NORMALIZE_WHITESPACE
+    Test-module import failures:
+    <BLANKLINE>
+    Module: sample2.sampletests_i
+    <BLANKLINE>
+      File "testrunner-ex/sample2/sampletests_i.py", line 1
+        importx unittest
+                       ^
+    SyntaxError: invalid syntax
+    <BLANKLINE>
+    <BLANKLINE>
+    Module: sample2.sample21.sampletests_i
+    <BLANKLINE>
+    Traceback (most recent call last):
+      File "testrunner-ex/sample2/sample21/sampletests_i.py", line 15, in ?
+        import zope.testing.huh
+    ImportError: No module named huh
+    <BLANKLINE>
+    <BLANKLINE>
+    Module: sample2.sample22.sampletests_i
+    <BLANKLINE>
+    AttributeError: 'module' object has no attribute 'test_suite'
+    <BLANKLINE>
+    <BLANKLINE>
+    Module: sample2.sample23.sampletests_i
+    <BLANKLINE>
+    Traceback (most recent call last):
+      File "testrunner-ex/sample2/sample23/sampletests_i.py", line 18, in ?
+        class Test(unittest.TestCase):
+      File "testrunner-ex/sample2/sample23/sampletests_i.py", line 23, in Test
+        raise TypeError('eek')
+    TypeError: eek
+    <BLANKLINE>
+    <BLANKLINE>
+    Running samplelayers.Layer1 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Ran 9 tests with 0 failures and 0 errors in 0.000 seconds.
+    Running samplelayers.Layer11 tests:
+      Set up samplelayers.Layer11 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.007 seconds.
+    Running samplelayers.Layer111 tests:
+      Set up samplelayers.Layerx in 0.000 seconds.
+      Set up samplelayers.Layer111 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.007 seconds.
+    Running samplelayers.Layer112 tests:
+      Tear down samplelayers.Layer111 in 0.000 seconds.
+      Set up samplelayers.Layer112 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.007 seconds.
+    Running samplelayers.Layer12 tests:
+      Tear down samplelayers.Layer112 in 0.000 seconds.
+      Tear down samplelayers.Layerx in 0.000 seconds.
+      Tear down samplelayers.Layer11 in 0.000 seconds.
+      Set up samplelayers.Layer12 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.007 seconds.
+    Running samplelayers.Layer121 tests:
+      Set up samplelayers.Layer121 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.007 seconds.
+    Running samplelayers.Layer122 tests:
+      Tear down samplelayers.Layer121 in 0.000 seconds.
+      Set up samplelayers.Layer122 in 0.000 seconds.
+      Ran 34 tests with 0 failures and 0 errors in 0.006 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in 0.000 seconds.
+      Tear down samplelayers.Layer12 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    Total: 213 tests, 0 failures, 0 errors
+    <BLANKLINE>
+    Test-modules with import problems:
+      sample2.sampletests_i
+      sample2.sample21.sampletests_i
+      sample2.sample22.sampletests_i
+      sample2.sample23.sampletests_i
+    True
+
+And remove the file with bad syntax:
+
+    >>> os.remove(badsyntax_path)


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-errors.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/README.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/README.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/README.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,2 @@
+This directory and its subdirectories contain example tests for
+testing the test runner, testrunner.py.


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gc0.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gc0.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gc0.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import unittest
+from zope.testing import doctest
+
+def make_sure_gc_is_disabled():
+    """
+    >>> import gc
+    >>> gc.get_threshold()[0]
+    0
+    """
+
+def test_suite():
+    return doctest.DocTestSuite()
+


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gc0.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gc1.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gc1.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gc1.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import unittest
+from zope.testing import doctest
+
+def make_sure_gc_threshold_is_one():
+    """
+    >>> import gc
+    >>> gc.get_threshold()[0]
+    1
+    """
+
+def test_suite():
+    return doctest.DocTestSuite()
+


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gc1.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gcset.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gcset.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gcset.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import unittest
+from zope.testing import doctest
+
+def make_sure_gc_threshold_is_701_11_9():
+    """
+    >>> import gc
+    >>> gc.get_threshold()
+    (701, 11, 9)
+    """
+
+def test_suite():
+    return doctest.DocTestSuite()
+


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gcset.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gcstats.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gcstats.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gcstats.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import unittest
+from zope.testing import doctest
+
+def generate_some_gc_statistics():
+    """
+    >>> import gc
+    >>> l = []; l.append(l); del l
+    >>> _ = gc.collect()
+    """
+
+def test_suite():
+    return doctest.DocTestSuite()
+


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/gcstats.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/leak.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/leak.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/leak.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,39 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest, sys, time
+
+class ClassicLeakable:
+    def __init__(self):
+        self.x = 'x'
+
+class Leakable(object):
+    def __init__(self):
+        self.x = 'x'
+
+leaked = []
+
+class TestSomething(unittest.TestCase):
+
+    def testleak(self):
+        leaked.append((ClassicLeakable(), Leakable(), time.time()))
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestSomething))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/leak.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/pledge.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/pledge.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/pledge.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,35 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import unittest
+from zope.testing import doctest
+
+pledge_template = """\
+I give my pledge, as %s,
+to save, and faithfully, to defend from waste,
+the natural resources of my %s.
+It's soils, minerals, forests, waters, and wildlife.
+"""
+
+def pledge():
+    """
+    >>> print pledge_template % ('and earthling', 'planet'),
+    I give my pledge, as an earthling,
+    to save, and faithfully, to defend from waste,
+    the natural resources of my planet.
+    It's soils, minerals, forests, waters, and wildlife.
+    """
+
+def test_suite():
+    return doctest.DocTestSuite()
+


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/pledge.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample11/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample11/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample11/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample11/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample11/sampletests.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample11/sampletests.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample11/sampletests.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,123 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestA3(unittest.TestCase):
+
+    level = 3
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB(unittest.TestCase):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB2(unittest.TestCase):
+    level = 2
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+
+class TestNotMuch(unittest.TestCase):
+    def test_1(self):
+        pass
+    def test_2(self):
+        pass
+    def test_3(self):
+        pass
+
+def setUp(test):
+    test.globs['z'] = 1
+
+def test_y0(self):
+    """
+    >>> y
+    0
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestA3))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestB2))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    suite.addTest(doctest.DocTestSuite(setUp=setUp))
+    suite.addTest(doctest.DocFileSuite('../../sampletests.txt',
+                                       setUp=setUp))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample11/sampletests.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample12/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample12/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample12/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample12/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample13/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample13/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample13/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample13/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample13/sampletests.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample13/sampletests.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample13/sampletests.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,88 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB(unittest.TestCase):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+
+class TestNotMuch(unittest.TestCase):
+    def test_1(self):
+        pass
+    def test_2(self):
+        pass
+    def test_3(self):
+        pass
+
+def setUp(test):
+    test.globs['z'] = 1
+
+def test_y0(self):
+    """
+    >>> y
+    0
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    suite.addTest(doctest.DocTestSuite(setUp=setUp))
+    suite.addTest(doctest.DocFileSuite('../../sampletests.txt',
+                                       setUp=setUp))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sample13/sampletests.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test1.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test1.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test1.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,88 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB(unittest.TestCase):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+
+class TestNotMuch(unittest.TestCase):
+    def test_1(self):
+        pass
+    def test_2(self):
+        pass
+    def test_3(self):
+        pass
+
+def setUp(test):
+    test.globs['z'] = 1
+
+def test_y0(self):
+    """
+    >>> y
+    0
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    suite.addTest(doctest.DocTestSuite(setUp=setUp))
+    suite.addTest(doctest.DocFileSuite('../../sampletests.txt',
+                                       setUp=setUp))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test1.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test11.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test11.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test11.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+import samplelayers
+
+layername = 'samplelayers.Layer11'
+layer = samplelayers.Layer11
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+class TestB(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+
+class TestNotMuch(unittest.TestCase):
+    layer = layername
+
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+def setUp(test):
+    test.globs['z'] = 1
+    test.globs['layer'] = layer.layer
+    test.globs['layerx'] = layer.layerx
+
+def test_y0(self):
+    """
+    >>> y
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    s = doctest.DocTestSuite(setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    s = doctest.DocFileSuite('../../sampletestsl.txt', setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test11.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test111.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test111.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test111.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+import samplelayers
+
+layername = 'samplelayers.Layer111'
+layer = samplelayers.Layer111
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+class TestB(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+
+class TestNotMuch(unittest.TestCase):
+    layer = layername
+
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+def setUp(test):
+    test.globs['z'] = 1
+    test.globs['layer'] = layer.layer
+    test.globs['layerx'] = layer.layerx
+
+def test_y0(self):
+    """
+    >>> y
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    s = doctest.DocTestSuite(setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    s = doctest.DocFileSuite('../../sampletestsl.txt', setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test111.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test112.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test112.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test112.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,128 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+import samplelayers
+
+layername = 'samplelayers.Layer112'
+layer = samplelayers.Layer112
+
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+class TestB(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+
+class TestNotMuch(unittest.TestCase):
+    layer = layername
+
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+def setUp(test):
+    test.globs['z'] = 1
+    test.globs['layer'] = layer.layer
+    test.globs['layerx'] = layer.layerx
+
+def test_y0(self):
+    """
+    >>> y
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    s = doctest.DocTestSuite(setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    s = doctest.DocFileSuite('../../sampletestsl.txt', setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test112.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test12.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test12.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test12.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+import samplelayers
+
+layername = 'samplelayers.Layer12'
+layer = samplelayers.Layer12
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+class TestB(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+
+class TestNotMuch(unittest.TestCase):
+    layer = layername
+
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+def setUp(test):
+    test.globs['z'] = 1
+    test.globs['layer'] = layer.layer
+    test.globs['layerx'] = layer.layerx
+
+def test_y0(self):
+    """
+    >>> y
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    s = doctest.DocTestSuite(setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    s = doctest.DocFileSuite('../../sampletestsl.txt', setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test12.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test121.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test121.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test121.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+import samplelayers
+
+layername = 'samplelayers.Layer121'
+layer = samplelayers.Layer121
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+class TestB(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+
+class TestNotMuch(unittest.TestCase):
+    layer = layername
+
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+def setUp(test):
+    test.globs['z'] = 1
+    test.globs['layer'] = layer.layer
+    test.globs['layerx'] = layer.layerx
+
+def test_y0(self):
+    """
+    >>> y
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    s = doctest.DocTestSuite(setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    s = doctest.DocFileSuite('../../sampletestsl.txt', setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test121.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test122.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test122.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test122.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+import samplelayers
+
+layername = 'samplelayers.Layer122'
+layer = samplelayers.Layer122
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+class TestB(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+
+class TestNotMuch(unittest.TestCase):
+    layer = layername
+
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+def setUp(test):
+    test.globs['z'] = 1
+    test.globs['layer'] = layer.layer
+    test.globs['layerx'] = layer.layerx
+
+def test_y0(self):
+    """
+    >>> y
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    s = doctest.DocTestSuite(setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    s = doctest.DocFileSuite('../../sampletestsl.txt', setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test122.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test_one.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test_one.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test_one.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,88 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB(unittest.TestCase):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+
+class TestNotMuch(unittest.TestCase):
+    def test_1(self):
+        pass
+    def test_2(self):
+        pass
+    def test_3(self):
+        pass
+
+def setUp(test):
+    test.globs['z'] = 1
+
+def test_y0(self):
+    """
+    >>> y
+    0
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    suite.addTest(doctest.DocTestSuite(setUp=setUp))
+    suite.addTest(doctest.DocFileSuite('../../sampletests.txt',
+                                       setUp=setUp))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests/test_one.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_none_suite.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_none_suite.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_none_suite.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,20 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Sample tests with a layer that can't be torn down
+
+$Id: sampletests_none_suite.py 39021 2005-10-09 18:38:33Z jim $
+"""
+
+def test_suite():
+    pass


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_none_suite.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_none_test.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_none_test.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_none_test.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,24 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Sample tests with a layer that can't be torn down
+
+$Id: sampletests_none_test.py 39021 2005-10-09 18:38:33Z jim $
+"""
+
+import unittest
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(None)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_none_test.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_ntd.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_ntd.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_ntd.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Sample tests with a layer that can't be torn down
+
+$Id: sampletests_ntd.py 33278 2005-07-12 11:45:54Z jim $
+"""
+
+import unittest
+
+class Layer:
+
+    def setUp(self):
+        pass
+    setUp = classmethod(setUp)
+
+    def tearDown(self):
+        raise NotImplementedError
+    tearDown = classmethod(tearDown)
+
+class TestSomething(unittest.TestCase):
+
+    layer = Layer
+
+    def test_something(self):
+        pass
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestSomething))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_ntd.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_ntds.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_ntds.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_ntds.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Sample tests with a layer that can't be torn down
+
+$Id: sampletests_ntds.py 33295 2005-07-13 12:02:58Z jim $
+"""
+
+import unittest
+
+class Layer:
+
+    def setUp(self):
+        pass
+    setUp = classmethod(setUp)
+
+    def tearDown(self):
+        raise NotImplementedError
+    tearDown = classmethod(tearDown)
+
+class TestSomething(unittest.TestCase):
+
+    layer = Layer
+
+    def test_something(self):
+        pass
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestSomething))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletests_ntds.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletestsf.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletestsf.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletestsf.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,88 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB(unittest.TestCase):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+
+class TestNotMuch(unittest.TestCase):
+    def test_1(self):
+        pass
+    def test_2(self):
+        pass
+    def test_3(self):
+        pass
+
+def setUp(test):
+    test.globs['z'] = 1
+
+def test_y0(self):
+    """
+    >>> y
+    0
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    suite.addTest(doctest.DocTestSuite(setUp=setUp))
+    suite.addTest(doctest.DocFileSuite('../sampletests.txt',
+                                       setUp=setUp))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample1/sampletestsf.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/do-not-enter/sampletests.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/do-not-enter/sampletests.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/do-not-enter/sampletests.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,56 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+def f():
+    g()
+
+def g():
+    x = 1
+    x = x + 1
+    x = y + 1
+    x = x + 1
+
+
+def eek(self):
+    """
+    >>> f()
+    1
+    """
+
+class Test(unittest.TestCase):
+
+    def test1(self):
+        pass
+
+    def test2(self):
+        pass
+
+    def test3(self):
+        f()
+
+    def test4(self):
+        pass
+
+    def test5(self):
+        pass
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(doctest.DocTestSuite())
+    suite.addTest(unittest.makeSuite(Test))
+    suite.addTest(doctest.DocFileSuite('e.txt'))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/do-not-enter/sampletests.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/donotenter/sampletests.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/donotenter/sampletests.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/donotenter/sampletests.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,56 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+def f():
+    g()
+
+def g():
+    x = 1
+    x = x + 1
+    x = y + 1
+    x = x + 1
+
+
+def eek(self):
+    """
+    >>> f()
+    1
+    """
+
+class Test(unittest.TestCase):
+
+    def test1(self):
+        pass
+
+    def test2(self):
+        pass
+
+    def test3(self):
+        f()
+
+    def test4(self):
+        pass
+
+    def test5(self):
+        pass
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(doctest.DocTestSuite())
+    suite.addTest(unittest.makeSuite(Test))
+    suite.addTest(doctest.DocFileSuite('e.txt'))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/donotenter/sampletests.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/e.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/e.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/e.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,4 @@
+    >>> def f():
+    ...     return x
+   
+    >>> f()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/e.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/sampletests.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/sampletests.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/sampletests.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,88 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB(unittest.TestCase):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+
+class TestNotMuch(unittest.TestCase):
+    def test_1(self):
+        pass
+    def test_2(self):
+        pass
+    def test_3(self):
+        pass
+
+def setUp(test):
+    test.globs['z'] = 1
+
+def test_y0(self):
+    """
+    >>> y
+    0
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    suite.addTest(doctest.DocTestSuite(setUp=setUp))
+    suite.addTest(doctest.DocFileSuite('../../sampletests.txt',
+                                       setUp=setUp))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/sampletests.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/sampletests_i.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/sampletests_i.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/sampletests_i.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,25 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import zope.testing.huh
+
+from zope.testing import doctest
+
+class Test(unittest.TestCase):
+
+    def test(self):
+        self.assertEqual(1,0)
+        
+def test_suite():
+    return unittest.makeSuite(Test)


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample21/sampletests_i.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample22/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample22/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample22/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample22/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample22/sampletests_i.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample22/sampletests_i.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample22/sampletests_i.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,24 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+class Test(unittest.TestCase):
+
+    def test(self):
+        self.assertEqual(1,0)
+        
+def test_suitex():
+    return unittest.makeSuite(Test)


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample22/sampletests_i.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample23/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample23/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample23/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample23/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample23/sampletests_i.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample23/sampletests_i.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample23/sampletests_i.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+class Test(unittest.TestCase):
+
+    def test(self):
+        self.assertEqual(1,0)
+
+    raise TypeError('eek')
+
+def test_suite():
+    return unittest.makeSuite(Test)


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sample23/sampletests_i.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/test_1.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/test_1.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/test_1.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,88 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB(unittest.TestCase):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+
+class TestNotMuch(unittest.TestCase):
+    def test_1(self):
+        pass
+    def test_2(self):
+        pass
+    def test_3(self):
+        pass
+
+def setUp(test):
+    test.globs['z'] = 1
+
+def test_y0(self):
+    """
+    >>> y
+    0
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    suite.addTest(doctest.DocTestSuite(setUp=setUp))
+    suite.addTest(doctest.DocFileSuite('../../sampletests.txt',
+                                       setUp=setUp))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/test_1.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/testone.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/testone.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/testone.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,88 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB(unittest.TestCase):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+
+class TestNotMuch(unittest.TestCase):
+    def test_1(self):
+        pass
+    def test_2(self):
+        pass
+    def test_3(self):
+        pass
+
+def setUp(test):
+    test.globs['z'] = 1
+
+def test_y0(self):
+    """
+    >>> y
+    0
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    suite.addTest(doctest.DocTestSuite(setUp=setUp))
+    suite.addTest(doctest.DocFileSuite('../../sampletests.txt',
+                                       setUp=setUp))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests/testone.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_1.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_1.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_1.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,29 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+from zope.testing import doctest
+
+def eek(self):
+    """
+    >>> x = y
+
+    >>> x
+
+
+    >>> z = x + 1
+
+    """
+        
+def test_suite():
+    return doctest.DocTestSuite()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_1.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_e.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_e.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_e.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,56 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+def f():
+    g()
+
+def g():
+    x = 1
+    x = x + 1
+    x = y + 1
+    x = x + 1
+
+
+def eek(self):
+    """
+    >>> f()
+    1
+    """
+
+class Test(unittest.TestCase):
+
+    def test1(self):
+        pass
+
+    def test2(self):
+        pass
+
+    def test3(self):
+        f()
+
+    def test4(self):
+        pass
+
+    def test5(self):
+        pass
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(doctest.DocTestSuite())
+    suite.addTest(unittest.makeSuite(Test))
+    suite.addTest(doctest.DocFileSuite('e.txt'))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_e.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_f.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_f.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_f.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,24 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+class Test(unittest.TestCase):
+
+    def test(self):
+        self.assertEqual(1,0)
+
+def test_suite():
+    return unittest.makeSuite(Test)


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_f.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_ntd.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_ntd.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_ntd.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Sample tests with a layer that can't be torn down
+
+$Id: sampletests_ntd.py 30971 2005-07-01 17:23:12Z jim $
+"""
+
+import unittest
+
+class Layer:
+
+    def setUp(self):
+        pass
+    setUp = classmethod(setUp)
+
+    def tearDown(self):
+        raise NotImplementedError
+    tearDown = classmethod(tearDown)
+
+class TestSomething(unittest.TestCase):
+
+    layer = Layer
+
+    def test_something(self):
+        pass
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestSomething))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_ntd.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_ntds.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_ntds.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_ntds.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,77 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Sample tests with a layer that can't be torn down
+
+$Id: sampletests_ntds.py 33295 2005-07-13 12:02:58Z jim $
+"""
+
+import unittest
+from zope.testing import doctest
+
+class Layer:
+
+    def setUp(self):
+        pass
+    setUp = classmethod(setUp)
+
+    def tearDown(self):
+        raise NotImplementedError
+    tearDown = classmethod(tearDown)
+
+class TestSomething(unittest.TestCase):
+
+    layer = Layer
+
+    def test_something(self):
+        import pdb; pdb.set_trace()
+
+    def test_something2(self):
+        import pdb; pdb.set_trace()
+
+    def test_something3(self):
+        import pdb; pdb.set_trace()
+
+    def test_something4(self):
+        import pdb; pdb.set_trace()
+
+    def test_something5(self):
+        f()
+
+def f():
+    import pdb; pdb.set_trace()
+
+def test_set_trace():
+    """
+    >>> if 1:
+    ...     x = 1
+    ...     import pdb; pdb.set_trace()
+    """
+    
+def test_set_trace2():
+    """
+    >>> f()
+    """
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestSomething))
+    d = doctest.DocTestSuite()
+    d.layer = Layer
+    suite.addTest(d)
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample2/sampletests_ntds.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem5.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem5.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem5.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,2 @@
+    >>> x = 1
+    >>> raise ValueError


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem5.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem6.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem6.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem6.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,2 @@
+    >>> from sample3.sampletests_d import g
+    >>> g()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem6.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem_failure.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem_failure.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem_failure.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,3 @@
+    >>> x = 1
+    >>> x
+    2


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/post_mortem_failure.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample31/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample31/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample31/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample31/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample32/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample32/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample32/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample32/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample33/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample33/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample33/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sample33/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,88 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB(unittest.TestCase):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+
+class TestNotMuch(unittest.TestCase):
+    def test_1(self):
+        pass
+    def test_2(self):
+        pass
+    def test_3(self):
+        pass
+
+def setUp(test):
+    test.globs['z'] = 1
+
+def test_y0(self):
+    """
+    >>> y
+    0
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    suite.addTest(doctest.DocTestSuite(setUp=setUp))
+    suite.addTest(doctest.DocFileSuite('../sampletests.txt',
+                                       setUp=setUp))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests_d.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests_d.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests_d.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,99 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""XXX short summary goes here.
+
+$Id: sampletests_d.py 30942 2005-06-28 13:59:49Z jim $
+"""
+
+import unittest
+from zope.testing import doctest
+
+class TestSomething(unittest.TestCase):
+
+    def test_set_trace1(self):
+        x = 1
+        import pdb; pdb.set_trace()
+        y = x
+
+    def test_set_trace2(self):
+        f()
+
+    def test_post_mortem1(self):
+        x = 1
+        raise ValueError
+
+    def test_post_mortem2(self):
+        g()
+
+    def test_post_mortem_failure1(self):
+        x = 1
+        y = 2
+        self.assertEqual(x, y)
+
+def f():
+    x = 1
+    import pdb; pdb.set_trace()
+    y = x
+
+def g():
+    x = 1
+    raise ValueError
+
+def set_trace3(self):
+    """
+    >>> x = 1
+    >>> if 1:
+    ...     import pdb; pdb.set_trace()
+    ...     y = x
+    """
+
+def set_trace4(self):
+    """
+    >>> f()
+    """
+
+def post_mortem3(self):
+    """
+    >>> x = 1
+    >>> raise ValueError
+    """
+
+def post_mortem4(self):
+    """
+    >>> g()
+    """
+
+
+def post_mortem_failure2():
+    """
+    >>> x = 1
+    >>> x
+    2
+    """
+
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocTestSuite(),
+        unittest.makeSuite(TestSomething),
+        doctest.DocFileSuite('set_trace5.txt'),
+        doctest.DocFileSuite('set_trace6.txt'),
+        doctest.DocFileSuite('post_mortem5.txt'),
+        doctest.DocFileSuite('post_mortem6.txt'),
+        doctest.DocFileSuite('post_mortem_failure.txt'),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')
+


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests_d.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests_ntd.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests_ntd.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests_ntd.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,61 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Sample tests with a layer that can't be torn down
+
+$Id: sampletests_ntd.py 33278 2005-07-12 11:45:54Z jim $
+"""
+
+import unittest
+
+class Layer:
+
+    def setUp(self):
+        pass
+    setUp = classmethod(setUp)
+
+    def tearDown(self):
+        raise NotImplementedError
+    tearDown = classmethod(tearDown)
+
+class TestSomething(unittest.TestCase):
+
+    layer = Layer
+
+    def test_something(self):
+        pass
+
+    def test_something_else(self):
+        pass
+
+    def test_error1(self):
+        raise TypeError("Can we see errors")
+
+    def test_error2(self):
+        raise TypeError("I hope so")
+
+    def test_fail1(self):
+        self.assertEqual(1, 2)
+
+    def test_fail2(self):
+        self.assertEqual(1, 3)
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestSomething))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/sampletests_ntd.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/set_trace5.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/set_trace5.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/set_trace5.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,4 @@
+    >>> x = 1
+    >>> if 1:
+    ...     import pdb; pdb.set_trace()
+    ...     y = x


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/set_trace5.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/set_trace6.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/set_trace6.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/set_trace6.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,2 @@
+    >>> from sample3.sampletests_d import f
+    >>> f()


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sample3/set_trace6.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/samplelayers.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/samplelayers.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/samplelayers.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,130 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Sample test layers
+
+$Id: samplelayers.py 30501 2005-05-25 17:40:56Z tim_one $
+"""
+
+layer = '0' # Internal to samples. Not part of layer API
+layerx = '0'
+
+class Layer1:
+    # Internal to samples. Not part of layer API:
+    layer = '1'
+    base = '0'
+    layerx = '0'
+
+    def setUp(self):
+        global layer
+        if layer != self.base:
+            raise ValueError("Bad layer, %s, for %s." % (layer, self))
+        layer = self.layer
+    setUp = classmethod(setUp)
+
+    def tearDown(self):
+        global layer
+        if layer != self.layer:
+            raise ValueError("Bad layer, %s, for %s." % (layer, self))
+        layer = self.base
+    tearDown = classmethod(tearDown)
+
+class Layerx:
+    layerx = '1' # Internal to samples. Not part of layer API
+    basex = '0'
+
+    def setUp(self):
+        global layerx
+        if layerx != self.basex:
+            raise ValueError("Bad layerx, %s, for %s." % (layerx, self))
+        layerx = self.layerx
+    setUp = classmethod(setUp)
+
+    def tearDown(self):
+        global layerx
+        if layerx != self.layerx:
+            raise ValueError("Bad layerx, %s, for %s." % (layerx, self))
+        layerx = self.basex
+    tearDown = classmethod(tearDown)
+
+class Layer11(Layer1):
+    layer = '11' # Internal to samples. Not part of layer API
+    base  = '1'  # Internal to samples. Not part of layer API
+
+class Layer12(Layer1):
+    layer = '12' # Internal to samples. Not part of layer API
+    base  = '1'  # Internal to samples. Not part of layer API
+
+class Layer111(Layerx, Layer11):
+    layer = '111' # Internal to samples. Not part of layer API
+    base  = '11'  # Internal to samples. Not part of layer API
+    layerx = '2' # Internal to samples. Not part of layer API
+    basex = '1'
+
+    def setUp(self):
+        global layer
+        if layer != self.base:
+            raise ValueError("Bad layer, %s, for %s." % (layer, self))
+        layer = self.layer
+        global layerx
+        if layerx != self.basex:
+            raise ValueError("Bad layerx, %s, for %s." % (layerx, self))
+        layerx = self.layerx
+    setUp = classmethod(setUp)
+
+    def tearDown(self):
+        global layer
+        if layer != self.layer:
+            raise ValueError("Bad layer, %s, for %s." % (layer, self))
+        layer = self.base
+        global layerx
+        if layerx != self.layerx:
+            raise ValueError("Bad layerx, %s, for %s." % (layerx, self))
+        layerx = self.basex
+    tearDown = classmethod(tearDown)
+
+class Layer121(Layer12):
+    layer = '121' # Internal to samples. Not part of layer API
+    base  = '12'  # Internal to samples. Not part of layer API
+
+class Layer112(Layerx, Layer11):
+    layer = '112' # Internal to samples. Not part of layer API
+    base  = '11'  # Internal to samples. Not part of layer API
+    layerx = '2' # Internal to samples. Not part of layer API
+    basex = '1'
+
+    def setUp(self):
+        global layer
+        if layer != self.base:
+            raise ValueError("Bad layer, %s, for %s." % (layer, self))
+        layer = self.layer
+        global layerx
+        if layerx != self.basex:
+            raise ValueError("Bad layerx, %s, for %s." % (layerx, self))
+        layerx = self.layerx
+    setUp = classmethod(setUp)
+
+    def tearDown(self):
+        global layer
+        if layer != self.layer:
+            raise ValueError("Bad layer, %s, for %s." % (layer, self))
+        layer = self.base
+        global layerx
+        if layerx != self.layerx:
+            raise ValueError("Bad layerx, %s, for %s." % (layerx, self))
+        layerx = self.basex
+    tearDown = classmethod(tearDown)
+
+class Layer122(Layer12):
+    layer = '122' # Internal to samples. Not part of layer API
+    base  = '12'  # Internal to samples. Not part of layer API


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/samplelayers.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test1.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test1.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test1.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,88 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB(unittest.TestCase):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+
+class TestNotMuch(unittest.TestCase):
+    def test_1(self):
+        pass
+    def test_2(self):
+        pass
+    def test_3(self):
+        pass
+
+def setUp(test):
+    test.globs['z'] = 1
+
+def test_y0(self):
+    """
+    >>> y
+    0
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    suite.addTest(doctest.DocTestSuite(setUp=setUp))
+    suite.addTest(doctest.DocFileSuite('../sampletests.txt',
+                                       setUp=setUp))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test1.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test11.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test11.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test11.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+import samplelayers
+
+layername = 'samplelayers.Layer11'
+layer = samplelayers.Layer11
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+class TestB(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+
+class TestNotMuch(unittest.TestCase):
+    layer = layername
+
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+def setUp(test):
+    test.globs['z'] = 1
+    test.globs['layer'] = layer.layer
+    test.globs['layerx'] = layer.layerx
+
+def test_y0(self):
+    """
+    >>> y
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    s = doctest.DocTestSuite(setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    s = doctest.DocFileSuite('../sampletestsl.txt', setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test11.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test111.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test111.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test111.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+import samplelayers
+
+layername = 'samplelayers.Layer111'
+layer = samplelayers.Layer111
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+class TestB(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+
+class TestNotMuch(unittest.TestCase):
+    layer = layername
+
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+def setUp(test):
+    test.globs['z'] = 1
+    test.globs['layer'] = layer.layer
+    test.globs['layerx'] = layer.layerx
+
+def test_y0(self):
+    """
+    >>> y
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    s = doctest.DocTestSuite(setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    s = doctest.DocFileSuite('../sampletestsl.txt', setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test111.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test112.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test112.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test112.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,134 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+import samplelayers
+
+layername = 'samplelayers.Layer112'
+layer = samplelayers.Layer112
+
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global x
+        x = 1
+        self.clean = getattr(self, 'clean', 0) + 1
+        
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+        # This is a test that the test runner clears attributes
+        # that are set in setUp but not cleared in tearDown.
+        self.assertEqual(self.clean, 1)
+
+class TestB(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+
+class TestNotMuch(unittest.TestCase):
+    layer = layername
+
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+def setUp(test):
+    test.globs['z'] = 1
+    test.globs['layer'] = layer.layer
+    test.globs['layerx'] = layer.layerx
+
+def test_y0(self):
+    """
+    >>> y
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    s = doctest.DocTestSuite(setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    s = doctest.DocFileSuite('../sampletestsl.txt', setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test112.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test12.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test12.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test12.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+import samplelayers
+
+layername = 'samplelayers.Layer12'
+layer = samplelayers.Layer12
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+class TestB(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+
+class TestNotMuch(unittest.TestCase):
+    layer = layername
+
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+def setUp(test):
+    test.globs['z'] = 1
+    test.globs['layer'] = layer.layer
+    test.globs['layerx'] = layer.layerx
+
+def test_y0(self):
+    """
+    >>> y
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    s = doctest.DocTestSuite(setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    s = doctest.DocFileSuite('../sampletestsl.txt', setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test12.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test121.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test121.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test121.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+import samplelayers
+
+layername = 'samplelayers.Layer121'
+layer = samplelayers.Layer121
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+class TestB(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+
+class TestNotMuch(unittest.TestCase):
+    layer = layername
+
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+def setUp(test):
+    test.globs['z'] = 1
+    test.globs['layer'] = layer.layer
+    test.globs['layerx'] = layer.layerx
+
+def test_y0(self):
+    """
+    >>> y
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    s = doctest.DocTestSuite(setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    s = doctest.DocFileSuite('../sampletestsl.txt', setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test121.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test122.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test122.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test122.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+import samplelayers
+
+layername = 'samplelayers.Layer122'
+layer = samplelayers.Layer122
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+class TestB(unittest.TestCase):
+    layer = layername
+
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+
+class TestNotMuch(unittest.TestCase):
+    layer = layername
+
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, layer.layer)
+        self.assertEqual(samplelayers.layerx, layer.layerx)
+
+def setUp(test):
+    test.globs['z'] = 1
+    test.globs['layer'] = layer.layer
+    test.globs['layerx'] = layer.layerx
+
+def test_y0(self):
+    """
+    >>> y
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+
+    >>> (layer == samplelayers.layer), (layerx == samplelayers.layerx)
+    (True, True)
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    s = doctest.DocTestSuite(setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    s = doctest.DocFileSuite('../sampletestsl.txt', setUp=setUp)
+    s.layer = layer
+    suite.addTest(s)
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test122.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test_one.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test_one.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test_one.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,88 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB(unittest.TestCase):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+
+class TestNotMuch(unittest.TestCase):
+    def test_1(self):
+        pass
+    def test_2(self):
+        pass
+    def test_3(self):
+        pass
+
+def setUp(test):
+    test.globs['z'] = 1
+
+def test_y0(self):
+    """
+    >>> y
+    0
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+    """
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    suite.addTest(doctest.DocTestSuite(setUp=setUp))
+    suite.addTest(doctest.DocFileSuite('../sampletests.txt',
+                                       setUp=setUp))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests/test_one.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,20 @@
+This is a sample doctest
+
+    >>> x=1
+    >>> x
+    1
+
+Blah blah blah
+
+    >>> x
+    1
+
+Blah blah blah
+
+    >>> x
+    1
+
+Blah blah blah
+
+    >>> x
+    1


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletests.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletestsf.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletestsf.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletestsf.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,172 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+x=0
+y=0
+z=0
+
+class TestA(unittest.TestCase):
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestA2(unittest.TestCase):
+    level = 2
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+class TestB(unittest.TestCase):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+
+
+class TestNotMuch(unittest.TestCase):
+    def test_1(self):
+        pass
+    def test_2(self):
+        pass
+    def test_3(self):
+        pass
+
+
+def setUp(test):
+    test.globs['z'] = 1
+
+
+def test_y0(self):
+    """
+    >>> y
+    0
+    """
+
+def test_x0(self):
+    """
+    >>> x
+    0
+    """
+
+def test_z1(self):
+    """
+    >>> z
+    1
+    """
+
+import samplelayers
+
+class Layered:
+
+    layer = 'samplelayers.Layer1'
+    layerv = '1'
+    layerx = '0'
+
+class TestA1(unittest.TestCase, Layered):
+
+    def setUp(self):
+        global x
+        x = 1
+    def tearDown(self):
+        global x
+        x = 0
+    def test_x1(self):
+        self.assertEqual(x, 1)
+        self.assertEqual(samplelayers.layer, self.layerv)
+        self.assertEqual(samplelayers.layerx, self.layerx)
+    def test_y0(self):
+        self.assertEqual(y, 0)
+        self.assertEqual(samplelayers.layer, self.layerv)
+        self.assertEqual(samplelayers.layerx, self.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, self.layerv)
+        self.assertEqual(samplelayers.layerx, self.layerx)
+
+class TestB1(unittest.TestCase, Layered):
+    def setUp(self):
+        global y
+        y = 1
+    def tearDown(self):
+        global y
+        y = 0
+    def test_y1(self):
+        self.assertEqual(y, 1)
+        self.assertEqual(samplelayers.layer, self.layerv)
+        self.assertEqual(samplelayers.layerx, self.layerx)
+    def test_x0(self):
+        self.assertEqual(x, 0)
+        self.assertEqual(samplelayers.layer, self.layerv)
+        self.assertEqual(samplelayers.layerx, self.layerx)
+    def test_z0(self):
+        self.assertEqual(z, 0)
+        self.assertEqual(samplelayers.layer, self.layerv)
+        self.assertEqual(samplelayers.layerx, self.layerx)
+
+
+class TestNotMuch1(unittest.TestCase, Layered):
+    def test_1(self):
+        self.assertEqual(samplelayers.layer, self.layerv)
+        self.assertEqual(samplelayers.layerx, self.layerx)
+    def test_2(self):
+        self.assertEqual(samplelayers.layer, self.layerv)
+        self.assertEqual(samplelayers.layerx, self.layerx)
+    def test_3(self):
+        self.assertEqual(samplelayers.layer, self.layerv)
+        self.assertEqual(samplelayers.layerx, self.layerx)
+
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestA))
+    suite.addTest(unittest.makeSuite(TestA2))
+    suite.addTest(unittest.makeSuite(TestB))
+    suite.addTest(unittest.makeSuite(TestNotMuch))
+    suite.addTest(doctest.DocTestSuite(setUp=setUp))
+    suite.addTest(doctest.DocFileSuite('sampletests.txt', setUp=setUp))
+    suite.addTest(unittest.makeSuite(TestA1))
+    suite.addTest(unittest.makeSuite(TestB1))
+    suite.addTest(unittest.makeSuite(TestNotMuch1))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletestsf.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletestsl.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletestsl.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletestsl.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,28 @@
+This is a sample doctest
+
+    >>> x=1
+    >>> x
+    1
+
+Blah blah blah
+
+    >>> x
+    1
+
+Blah blah blah
+
+    >>> x
+    1
+
+Blah blah blah
+
+    >>> x
+    1
+
+are we in the right laters?
+
+    >>> import samplelayers
+    >>> layer == samplelayers.layer
+    True
+    >>> layerx == samplelayers.layerx
+    True


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/sampletestsl.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/README.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/README.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/README.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,2 @@
+The tests in this subtree are trivial, and used only to test
+testrunner's --usecompiled option.


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+# Makes this a package.


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/compiletest.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/compiletest.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/compiletest.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,27 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+
+class Test(unittest.TestCase):
+
+    def test1(self):
+        self.assertEqual(1, 1)
+    def test2(self):
+        self.assertEqual(1, 1)
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(Test))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/compiletest.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/package/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/package/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/package/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+# Makes this a package.


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/package/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/package/compiletest.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/package/compiletest.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/package/compiletest.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,27 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+
+class Test(unittest.TestCase):
+
+    def test1(self):
+        self.assertEqual(1, 1)
+    def test2(self):
+        self.assertEqual(1, 1)
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(Test))
+    return suite


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex/usecompiled/package/compiletest.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/products/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/products/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/products/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,33 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Sample package that knits in extra directories.
+
+$Id: __init__.py 39695 2005-10-28 20:01:54Z jim $
+"""
+
+import os
+
+__path__.append(
+    os.path.join(
+        os.path.dirname( # testing
+            os.path.dirname( # testrunner-ex-knit-lib
+                os.path.dirname( # sample4
+                    os.path.dirname(__file__) # products
+                    )
+                )
+            )
+        , "testrunner-ex-pp-products"
+        )
+    )
+


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-lib/sample4/products/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/more/__init__.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/more/__init__.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/more/__init__.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+#


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/more/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/more/sampletests.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/more/sampletests.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/more/sampletests.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+class Test(unittest.TestCase):
+
+    layer = 'samplelayers.Layer111'
+
+    def test_another_test_in_products(self):
+        pass
+        
+def test_suite():
+    return unittest.makeSuite(Test)


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/more/sampletests.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/sampletests.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/sampletests.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/sampletests.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+from zope.testing import doctest
+
+class Test(unittest.TestCase):
+
+    layer = 'samplelayers.Layer111'
+
+    def test_extra_test_in_products(self):
+        pass
+        
+def test_suite():
+    return unittest.makeSuite(Test)


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-ex-pp-products/sampletests.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-gc.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-gc.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-gc.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,85 @@
+Test Runner
+===========
+
+Garbage Collection Control
+--------------------------
+
+When having problems that seem to be caused my memory-management
+errors, it can be helpful to adjust Python's cyclic garbage collector
+or to get garbage colection statistics.  The --gc option can be used
+for this purpose.
+
+If you think you are getting a test failure due to a garbage
+collection problem, you can try disabling garbage collection by
+using the --gc option with a value of zero.
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> defaults = ['--path', directory_with_tests]
+
+    >>> from zope.testing import testrunner
+    
+    >>> sys.argv = 'test --tests-pattern ^gc0$ --gc 0 -vv'.split()
+    >>> _ = testrunner.run(defaults)
+    Running tests at level 1
+    Cyclic garbage collection is disabled.
+    Running unit tests:
+      Running:
+        make_sure_gc_is_disabled (gc0)
+      Ran 1 tests with 0 failures and 0 errors in 0.001 seconds.
+
+Alternatively, if you think you are having a garbage collection
+related problem, you can cause garbage collection to happen more often
+by providing a low threshold:
+    
+    >>> sys.argv = 'test --tests-pattern ^gc1$ --gc 1 -vv'.split()
+    >>> _ = testrunner.run(defaults)
+    Running tests at level 1
+    Cyclic garbage collection threshold set to: (1,)
+    Running unit tests:
+      Running:
+        make_sure_gc_threshold_is_one (gc1)
+      Ran 1 tests with 0 failures and 0 errors in 0.001 seconds.
+
+You can specify up to 3 --gc options to set each of the 3 gc threshold
+values:
+
+    
+    >>> sys.argv = ('test --tests-pattern ^gcset$ --gc 701 --gc 11 --gc 9 -vv'
+    ...             .split())
+    >>> _ = testrunner.run(defaults)
+    Running tests at level 1
+    Cyclic garbage collection threshold set to: (701, 11, 9)
+    Running unit tests:
+      Running:
+        make_sure_gc_threshold_is_701_11_9 (gcset)
+      Ran 1 tests with 0 failures and 0 errors in 0.001 seconds.
+
+Garbage Collection Statistics
+-----------------------------
+
+You can enable gc debugging statistics using the --gc-options (-G)
+option.  You should provide names of one or more of the flags
+described in the library documentation for the gc module.
+
+The output statistics are written to standard error.  
+
+    >>> from StringIO import StringIO
+    >>> err = StringIO()
+    >>> stderr = sys.stderr
+    >>> sys.stderr = err
+    >>> sys.argv = ('test --tests-pattern ^gcstats$ -G DEBUG_STATS'
+    ...             ' -G DEBUG_COLLECTABLE -vv'
+    ...             .split())
+    >>> _ = testrunner.run(defaults)
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        generate_some_gc_statistics (gcstats)
+      Ran 1 tests with 0 failures and 0 errors in 0.006 seconds.
+
+    >>> sys.stderr = stderr
+
+    >>> print err.getvalue()        # doctest: +ELLIPSIS
+    gc: collecting generation ...
+        


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-gc.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-knit.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-knit.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-knit.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,108 @@
+Test Runner
+===========
+
+Knitting in extra package directories
+-------------------------------------
+
+Python packages have __path__ variables that can be manipulated to add
+extra directories cntaining software used in the packages.  The
+testrunner needs to be given extra information about this sort of
+situation.
+
+Let's look at an example.  The testrunner-ex-knit-lib directory
+is a directory that we want to add to the Python path, but that we
+don't want to search for tests.  It has a sample4 package and a
+products subpackage.  The products subpackage adds the
+testrunner-ex-knit-products to it's __path__.  We want to run tests
+from the testrunner-ex-knit-products directory.  When we import these
+tests, we need to import them from the sample4.products package.  We
+can't use the --path option to name testrunner-ex-knit-products.
+It isn't enough to add the containing directory to the test path
+because then we wouldn't be able to determine the package name
+properly.  We might be able to use the --package option to run the
+tests from the sample4/products package, but we want to run tests in
+testrunner-ex that aren't in this package.  
+
+We can use the --package-path option in this case.  The --package-path
+option is like the --test-path option in that it defines a path to be
+searched for tests without affecting the python path.  It differs in
+that it supplied a package name that is added a profex when importing
+any modules found.  The --package-path option takes *two* arguments, a
+package name and file path.
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> sys.path.append(os.path.join(this_directory, 'testrunner-ex-pp-lib'))
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     '--package-path',
+    ...     os.path.join(this_directory, 'testrunner-ex-pp-products'),
+    ...     'sample4.products',
+    ...     ]
+
+    >>> from zope.testing import testrunner
+    
+    >>> sys.argv = 'test --layer Layer111 -vv'.split()
+    >>> _ = testrunner.run(defaults)
+    Running tests at level 1
+    Running samplelayers.Layer111 tests:
+      Set up samplelayers.Layerx in 0.000 seconds.
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer11 in 0.000 seconds.
+      Set up samplelayers.Layer111 in 0.000 seconds.
+      Running:
+        test_x1 (sample1.sampletests.test111.TestA)
+        test_y0 (sample1.sampletests.test111.TestA)
+        ...
+        test_y0 (sampletests.test111)
+        test_z1 (sampletests.test111)
+        testrunner-ex/sampletests/../sampletestsl.txt
+        test_extra_test_in_products (sample4.products.sampletests.Test)
+        test_another_test_in_products (sample4.products.more.sampletests.Test)
+      Ran 36 tests with 0 failures and 0 errors in 0.008 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer111 in 0.000 seconds.
+      Tear down samplelayers.Layerx in 0.000 seconds.
+      Tear down samplelayers.Layer11 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+
+In the example, the last test, test_extra_test_in_products, came from
+the products directory.  As usual, we can select the knit-in packages
+or individual packages within knit-in packages:
+
+    >>> sys.argv = 'test --package sample4.products -vv'.split()
+    >>> _ = testrunner.run(defaults)
+    Running tests at level 1
+    Running samplelayers.Layer111 tests:
+      Set up samplelayers.Layerx in 0.000 seconds.
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer11 in 0.000 seconds.
+      Set up samplelayers.Layer111 in 0.000 seconds.
+      Running:
+        test_extra_test_in_products (sample4.products.sampletests.Test)
+        test_another_test_in_products (sample4.products.more.sampletests.Test)
+      Ran 2 tests with 0 failures and 0 errors in 0.000 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer111 in 0.000 seconds.
+      Tear down samplelayers.Layerx in 0.000 seconds.
+      Tear down samplelayers.Layer11 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+
+    >>> sys.argv = 'test --package sample4.products.more -vv'.split()
+    >>> _ = testrunner.run(defaults)
+    Running tests at level 1
+    Running samplelayers.Layer111 tests:
+      Set up samplelayers.Layerx in 0.000 seconds.
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer11 in 0.000 seconds.
+      Set up samplelayers.Layer111 in 0.000 seconds.
+      Running:
+        test_another_test_in_products (sample4.products.more.sampletests.Test)
+      Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer111 in 0.000 seconds.
+      Tear down samplelayers.Layerx in 0.000 seconds.
+      Tear down samplelayers.Layer11 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-knit.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-layers-ntd.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-layers-ntd.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-layers-ntd.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,246 @@
+Test Runner
+===========
+
+Layers that can't be torn down
+------------------------------
+
+A layer can have a tearDown method that raises NotImplementedError.
+If this is the case and there are no remaining tests to run, the test
+runner will just note that the tear down couldn't be done:
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> from zope.testing import testrunner
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+
+    >>> sys.argv = 'test -ssample2 --tests-pattern sampletests_ntd$'.split()
+    >>> testrunner.run(defaults)
+    Running sample2.sampletests_ntd.Layer tests:
+      Set up sample2.sampletests_ntd.Layer in 0.000 seconds.
+      Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
+    Tearing down left over layers:
+      Tear down sample2.sampletests_ntd.Layer ... not supported
+    False
+
+If the tearDown method raises NotImplementedError and there are remaining
+layers to run, the test runner will restart itself as a new process,
+resuming tests where it left off:
+
+    >>> sys.argv = [testrunner_script, '--tests-pattern', 'sampletests_ntd$']
+    >>> testrunner.run(defaults)
+    Running sample1.sampletests_ntd.Layer tests:
+      Set up sample1.sampletests_ntd.Layer in N.NNN seconds.
+      Ran 1 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running sample2.sampletests_ntd.Layer tests:
+      Tear down sample1.sampletests_ntd.Layer ... not supported
+    Running sample2.sampletests_ntd.Layer tests:
+      Set up sample2.sampletests_ntd.Layer in N.NNN seconds.
+      Ran 1 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running sample3.sampletests_ntd.Layer tests:
+      Tear down sample2.sampletests_ntd.Layer ... not supported
+    Running sample3.sampletests_ntd.Layer tests:
+      Set up sample3.sampletests_ntd.Layer in N.NNN seconds.
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test test_error1 (sample3.sampletests_ntd.TestSomething)
+    Traceback (most recent call last):
+     testrunner-ex/sample3/sampletests_ntd.py", Line NNN, in test_error1
+        raise TypeError("Can we see errors")
+    TypeError: Can we see errors
+    <BLANKLINE>
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test test_error2 (sample3.sampletests_ntd.TestSomething)
+    Traceback (most recent call last):
+     testrunner-ex/sample3/sampletests_ntd.py", Line NNN, in test_error2
+        raise TypeError("I hope so")
+    TypeError: I hope so
+    <BLANKLINE>
+    <BLANKLINE>
+    <BLANKLINE>
+    Failure in test test_fail1 (sample3.sampletests_ntd.TestSomething)
+    Traceback (most recent call last):
+     testrunner-ex/sample3/sampletests_ntd.py", Line NNN, in test_fail1
+        self.assertEqual(1, 2)
+    AssertionError: 1 != 2
+    <BLANKLINE>
+    <BLANKLINE>
+    <BLANKLINE>
+    Failure in test test_fail2 (sample3.sampletests_ntd.TestSomething)
+    Traceback (most recent call last):
+     testrunner-ex/sample3/sampletests_ntd.py", Line NNN, in test_fail2
+        self.assertEqual(1, 3)
+    AssertionError: 1 != 3
+    <BLANKLINE>
+      Ran 6 tests with 2 failures and 2 errors in N.NNN seconds.
+    Tearing down left over layers:
+      Tear down sample3.sampletests_ntd.Layer ... not supported
+    Total: 8 tests, 2 failures, 2 errors
+    True
+
+in the example above, some of the tests run as a subprocess had errors
+and failures. They were displayed as usual and the failure and error
+statistice were updated as usual.
+
+Note that debugging doesn't work when running tests in a subprocess:
+
+    >>> sys.argv = [testrunner_script, '--tests-pattern', 'sampletests_ntd$',
+    ...             '-D', ]
+    >>> testrunner.run(defaults)
+    Running sample1.sampletests_ntd.Layer tests:
+      Set up sample1.sampletests_ntd.Layer in N.NNN seconds.
+      Ran 1 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running sample2.sampletests_ntd.Layer tests:
+      Tear down sample1.sampletests_ntd.Layer ... not supported
+    Running sample2.sampletests_ntd.Layer tests:
+      Set up sample2.sampletests_ntd.Layer in N.NNN seconds.
+      Ran 1 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running sample3.sampletests_ntd.Layer tests:
+      Tear down sample2.sampletests_ntd.Layer ... not supported
+    Running sample3.sampletests_ntd.Layer tests:
+      Set up sample3.sampletests_ntd.Layer in N.NNN seconds.
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test test_error1 (sample3.sampletests_ntd.TestSomething)
+    Traceback (most recent call last):
+     testrunner-ex/sample3/sampletests_ntd.py", Line NNN, in test_error1
+        raise TypeError("Can we see errors")
+    TypeError: Can we see errors
+    <BLANKLINE>
+    <BLANKLINE>
+    **********************************************************************
+    Can't post-mortem debug when running a layer as a subprocess!
+    **********************************************************************
+    <BLANKLINE>
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test test_error2 (sample3.sampletests_ntd.TestSomething)
+    Traceback (most recent call last):
+     testrunner-ex/sample3/sampletests_ntd.py", Line NNN, in test_error2
+        raise TypeError("I hope so")
+    TypeError: I hope so
+    <BLANKLINE>
+    <BLANKLINE>
+    **********************************************************************
+    Can't post-mortem debug when running a layer as a subprocess!
+    **********************************************************************
+    <BLANKLINE>
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test test_fail1 (sample3.sampletests_ntd.TestSomething)
+    Traceback (most recent call last):
+     testrunner-ex/sample3/sampletests_ntd.py", Line NNN, in test_fail1
+        self.assertEqual(1, 2)
+    AssertionError: 1 != 2
+    <BLANKLINE>
+    <BLANKLINE>
+    **********************************************************************
+    Can't post-mortem debug when running a layer as a subprocess!
+    **********************************************************************
+    <BLANKLINE>
+    <BLANKLINE>
+    <BLANKLINE>
+    Error in test test_fail2 (sample3.sampletests_ntd.TestSomething)
+    Traceback (most recent call last):
+     testrunner-ex/sample3/sampletests_ntd.py", Line NNN, in test_fail2
+        self.assertEqual(1, 3)
+    AssertionError: 1 != 3
+    <BLANKLINE>
+    <BLANKLINE>
+    **********************************************************************
+    Can't post-mortem debug when running a layer as a subprocess!
+    **********************************************************************
+    <BLANKLINE>
+      Ran 6 tests with 0 failures and 4 errors in N.NNN seconds.
+    Tearing down left over layers:
+      Tear down sample3.sampletests_ntd.Layer ... not supported
+    Total: 8 tests, 0 failures, 4 errors
+    True
+
+Similarly, pdb.set_trace doesn't work when running tests in a layer
+that is run as a subprocess:
+
+    >>> sys.argv = [testrunner_script, '--tests-pattern', 'sampletests_ntds']
+    >>> testrunner.run(defaults)
+    Running sample1.sampletests_ntds.Layer tests:
+      Set up sample1.sampletests_ntds.Layer in 0.000 seconds.
+      Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
+    Running sample2.sampletests_ntds.Layer tests:
+      Tear down sample1.sampletests_ntds.Layer ... not supported
+    Running sample2.sampletests_ntds.Layer tests:
+      Set up sample2.sampletests_ntds.Layer in 0.000 seconds.
+    --Return--
+    > testrunner-ex/sample2/sampletests_ntds.py(37)test_something()->None
+    -> import pdb; pdb.set_trace()
+    (Pdb) c
+    <BLANKLINE>
+    **********************************************************************
+    Can't use pdb.set_trace when running a layer as a subprocess!
+    **********************************************************************
+    <BLANKLINE>
+    --Return--
+    > testrunner-ex/sample2/sampletests_ntds.py(40)test_something2()->None
+    -> import pdb; pdb.set_trace()
+    (Pdb) c
+    <BLANKLINE>
+    **********************************************************************
+    Can't use pdb.set_trace when running a layer as a subprocess!
+    **********************************************************************
+    <BLANKLINE>
+    --Return--
+    > testrunner-ex/sample2/sampletests_ntds.py(43)test_something3()->None
+    -> import pdb; pdb.set_trace()
+    (Pdb) c
+    <BLANKLINE>
+    **********************************************************************
+    Can't use pdb.set_trace when running a layer as a subprocess!
+    **********************************************************************
+    <BLANKLINE>
+    --Return--
+    > testrunner-ex/sample2/sampletests_ntds.py(46)test_something4()->None
+    -> import pdb; pdb.set_trace()
+    (Pdb) c
+    <BLANKLINE>
+    **********************************************************************
+    Can't use pdb.set_trace when running a layer as a subprocess!
+    **********************************************************************
+    <BLANKLINE>
+    --Return--
+    > testrunner-ex/sample2/sampletests_ntds.py(52)f()->None
+    -> import pdb; pdb.set_trace()
+    (Pdb) c
+    <BLANKLINE>
+    **********************************************************************
+    Can't use pdb.set_trace when running a layer as a subprocess!
+    **********************************************************************
+    <BLANKLINE>
+    --Return--
+    > doctest.py(351)set_trace()->None
+    -> pdb.Pdb.set_trace(self)
+    (Pdb) c
+    <BLANKLINE>
+    **********************************************************************
+    Can't use pdb.set_trace when running a layer as a subprocess!
+    **********************************************************************
+    <BLANKLINE>
+    --Return--
+    > doctest.py(351)set_trace()->None
+    -> pdb.Pdb.set_trace(self)
+    (Pdb) c
+    <BLANKLINE>
+    **********************************************************************
+    Can't use pdb.set_trace when running a layer as a subprocess!
+    **********************************************************************
+    <BLANKLINE>
+      Ran 7 tests with 0 failures and 0 errors in 0.008 seconds.
+    Tearing down left over layers:
+      Tear down sample2.sampletests_ntds.Layer ... not supported
+    Total: 8 tests, 0 failures, 0 errors
+    False
+
+If you want to use pdb from a test in a layer that is run as a
+subprocess, then rerun the test runner selecting *just* that layer so
+that it's not run as a subprocess.


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-layers-ntd.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-layers.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-layers.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-layers.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,79 @@
+Test Runner
+===========
+
+Layer Selection
+---------------
+
+We can select which layers to run using the --layer option:
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+
+    >>> sys.argv = 'test --layer 112 --layer unit'.split()
+    >>> from zope.testing import testrunner
+    >>> testrunner.run(defaults)
+    Running unit tests:
+      Ran 192 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer112 tests:
+      Set up samplelayers.Layerx in N.NNN seconds.
+      Set up samplelayers.Layer1 in N.NNN seconds.
+      Set up samplelayers.Layer11 in N.NNN seconds.
+      Set up samplelayers.Layer112 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer112 in N.NNN seconds.
+      Tear down samplelayers.Layerx in N.NNN seconds.
+      Tear down samplelayers.Layer11 in N.NNN seconds.
+      Tear down samplelayers.Layer1 in N.NNN seconds.
+    Total: 226 tests, 0 failures, 0 errors
+    False
+
+We can also specify that we want to run only the unit tests:
+
+    >>> sys.argv = 'test -u'.split()
+    >>> testrunner.run(defaults)
+    Running unit tests:
+      Ran 192 tests with 0 failures and 0 errors in 0.033 seconds.
+    False
+
+Or that we want to run all of the tests except for the unit tests:
+
+    >>> sys.argv = 'test -f'.split()
+    >>> testrunner.run(defaults)
+    Running samplelayers.Layer1 tests:
+      Set up samplelayers.Layer1 in N.NNN seconds.
+      Ran 9 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer11 tests:
+      Set up samplelayers.Layer11 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer111 tests:
+      Set up samplelayers.Layerx in N.NNN seconds.
+      Set up samplelayers.Layer111 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer112 tests:
+      Tear down samplelayers.Layer111 in N.NNN seconds.
+      Set up samplelayers.Layer112 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer12 tests:
+      Tear down samplelayers.Layer112 in N.NNN seconds.
+      Tear down samplelayers.Layerx in N.NNN seconds.
+      Tear down samplelayers.Layer11 in N.NNN seconds.
+      Set up samplelayers.Layer12 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer121 tests:
+      Set up samplelayers.Layer121 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer122 tests:
+      Tear down samplelayers.Layer121 in N.NNN seconds.
+      Set up samplelayers.Layer122 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in N.NNN seconds.
+      Tear down samplelayers.Layer12 in N.NNN seconds.
+      Tear down samplelayers.Layer1 in N.NNN seconds.
+    Total: 213 tests, 0 failures, 0 errors
+    False


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-layers.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-leaks-err.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-leaks-err.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-leaks-err.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,25 @@
+Test Runner
+===========
+
+Debugging Memory Leaks without a debug build of Python 
+------------------------------------------------------
+
+To use the --report-refcounts (-r) to detect or debug memory leaks,
+you must have a debug build of Python. Without a debug build, you will
+get an error message:
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+
+    >>> from zope.testing import testrunner
+    
+    >>> sys.argv = 'test -r -N6'.split()
+    >>> _ = testrunner.run(defaults)
+            The Python you are running was not configured
+            with --with-pydebug. This is required to use
+            the --report-refcounts option.
+    <BLANKLINE>


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-leaks-err.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-leaks.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-leaks.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-leaks.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,221 @@
+Test Runner
+===========
+
+Debugging Memory Leaks
+----------------------
+
+The --report-refcounts (-r) option can be used with the --repeat (-N)
+option to detect and diagnose memory leaks.  To use this option, you
+must configure Python with the --with-pydebug option. (On Unix, pass
+this option to configure and then build Python.)
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+
+    >>> from zope.testing import testrunner
+    
+    >>> sys.argv = 'test --layer Layer11$ --layer Layer12$ -N4 -r'.split()
+    >>> _ = testrunner.run(defaults)
+    Running samplelayers.Layer11 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer11 in 0.000 seconds.
+    Iteration 1
+      Ran 34 tests with 0 failures and 0 errors in 0.013 seconds.
+    Iteration 2
+      Ran 34 tests with 0 failures and 0 errors in 0.012 seconds.
+      sys refcount=100401   change=0     
+    Iteration 3
+      Ran 34 tests with 0 failures and 0 errors in 0.012 seconds.
+      sys refcount=100401   change=0     
+    Iteration 4
+      Ran 34 tests with 0 failures and 0 errors in 0.013 seconds.
+      sys refcount=100401   change=0     
+    Running samplelayers.Layer12 tests:
+      Tear down samplelayers.Layer11 in 0.000 seconds.
+      Set up samplelayers.Layer12 in 0.000 seconds.
+    Iteration 1
+      Ran 34 tests with 0 failures and 0 errors in 0.013 seconds.
+    Iteration 2
+      Ran 34 tests with 0 failures and 0 errors in 0.012 seconds.
+      sys refcount=100411   change=0     
+    Iteration 3
+      Ran 34 tests with 0 failures and 0 errors in 0.012 seconds.
+      sys refcount=100411   change=0     
+    Iteration 4
+      Ran 34 tests with 0 failures and 0 errors in 0.012 seconds.
+      sys refcount=100411   change=0     
+    Tearing down left over layers:
+      Tear down samplelayers.Layer12 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    Total: 68 tests, 0 failures, 0 errors
+
+Each layer is repeated the requested number of times.  For each
+iteration after the first, the system refcount and change in system
+refcount is shown. The system refcount is the total of all refcount in
+the system.  When a refcount on any object is changed, the system
+refcount is changed by the same amount.  Tests that don't leak show
+zero changes in systen refcount.
+
+Let's look at an example test that leaks:
+
+    >>> sys.argv = 'test --tests-pattern leak -N4 -r'.split()
+    >>> _ = testrunner.run(defaults)
+    Running unit tests:
+    Iteration 1
+      Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
+    Iteration 2
+      Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
+      sys refcount=92506    change=12
+    Iteration 3
+      Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
+      sys refcount=92513    change=12
+    Iteration 4
+      Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
+      sys refcount=92520    change=12
+
+Here we see that the system refcount is increating.  If we specify a
+verbosity greater than one, we can get details broken out by object
+type (or class):
+
+    >>> sys.argv = 'test --tests-pattern leak -N5 -r -v'.split()
+    >>> _ = testrunner.run(defaults)
+    Running tests at level 1
+    Running unit tests:
+    Iteration 1
+      Running:
+        .
+      Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
+    Iteration 2
+      Running:
+        .
+      Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
+      sum detail refcount=95832    sys refcount=105668   change=16    
+        Leak details, changes in instances and refcounts by type/class:
+        type/class                                               insts   refs
+        -------------------------------------------------------  -----   ----
+        classobj                                                     0      1
+        dict                                                         2      2
+        float                                                        1      1
+        int                                                          2      2
+        leak.ClassicLeakable                                         1      1
+        leak.Leakable                                                1      1
+        str                                                          0      4
+        tuple                                                        1      1
+        type                                                         0      3
+        -------------------------------------------------------  -----   ----
+        total                                                        8     16
+    Iteration 3
+      Running:
+        .
+      Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
+      sum detail refcount=95844    sys refcount=105680   change=12    
+        Leak details, changes in instances and refcounts by type/class:
+        type/class                                               insts   refs
+        -------------------------------------------------------  -----   ----
+        classobj                                                     0      1
+        dict                                                         2      2
+        float                                                        1      1
+        int                                                         -1      0
+        leak.ClassicLeakable                                         1      1
+        leak.Leakable                                                1      1
+        str                                                          0      4
+        tuple                                                        1      1
+        type                                                         0      1
+        -------------------------------------------------------  -----   ----
+        total                                                        5     12
+    Iteration 4
+      Running:
+        .
+      Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
+      sum detail refcount=95856    sys refcount=105692   change=12    
+        Leak details, changes in instances and refcounts by type/class:
+        type/class                                               insts   refs
+        -------------------------------------------------------  -----   ----
+        classobj                                                     0      1
+        dict                                                         2      2
+        float                                                        1      1
+        leak.ClassicLeakable                                         1      1
+        leak.Leakable                                                1      1
+        str                                                          0      4
+        tuple                                                        1      1
+        type                                                         0      1
+        -------------------------------------------------------  -----   ----
+        total                                                        6     12
+    Iteration 5
+      Running:
+        .
+      Ran 1 tests with 0 failures and 0 errors in 0.000 seconds.
+      sum detail refcount=95868    sys refcount=105704   change=12    
+        Leak details, changes in instances and refcounts by type/class:
+        type/class                                               insts   refs
+        -------------------------------------------------------  -----   ----
+        classobj                                                     0      1
+        dict                                                         2      2
+        float                                                        1      1
+        leak.ClassicLeakable                                         1      1
+        leak.Leakable                                                1      1
+        str                                                          0      4
+        tuple                                                        1      1
+        type                                                         0      1
+        -------------------------------------------------------  -----   ----
+        total                                                        6     12
+
+It is instructive to analyze the results in some detail.  The test
+being run was designed to intentionally leak:
+
+    class ClassicLeakable:
+        def __init__(self):
+            self.x = 'x'
+
+    class Leakable(object):
+        def __init__(self):
+            self.x = 'x'
+
+    leaked = []
+
+    class TestSomething(unittest.TestCase):
+
+        def testleak(self):
+            leaked.append((ClassicLeakable(), Leakable(), time.time()))
+
+Let's go through this by type.
+
+float, leak.ClassicLeakable, leak.Leakable, and tuple
+    We leak one of these every time.  This is to be expected because
+    we are adding one of these to the list every time.
+
+str
+    We don't leak any instances, but we leak 4 references. These are
+    due to the instance attributes avd values.
+
+dict
+    We leak 2 of these, one for each ClassicLeakable and Leakable
+    instance. 
+
+classobj
+    We increase the number of classobj instance references by one each
+    time because each ClassicLeakable instance has a reference to its
+    class.  This instances increases the references in it's class,
+    which increases the total number of references to classic classes
+    (clasobj instances).
+
+type
+    For most interations, we increase the number of type references by
+    one for the same reason we increase the number of clasobj
+    references by one.  The increase of the number of type references
+    by 3 in the second iteration is puzzling, but illustrates that
+    this sort of data is often puzzling.
+
+int
+    The change in the number of int instances and references in this
+    example is a side effect of the statistics being gathered.  Lots
+    of integers are created to keep the memory statistics used here.
+
+The summary statistics include the sum of the detail refcounts.  (Note
+that this sum is less than the system refcount.  This is because the
+detailed analysis doesn't inspect every object. Not all objects in the
+system are returned by sys.getobjects.)


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-leaks.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-profiling.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-profiling.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-profiling.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,54 @@
+Profiling
+=========
+
+The testrunner includes the ability to profile the test execution with hotshot
+via the --profile option.
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> sys.path.append(directory_with_tests)
+
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+
+    >>> sys.argv = [testrunner_script, '--profile']
+
+When the tests are run, we get profiling output.
+
+    >>> from zope.testing import testrunner
+    >>> testrunner.run(defaults)
+    Running unit tests:
+    ...
+    Running samplelayers.Layer1 tests:
+    ...
+    Running samplelayers.Layer11 tests:
+    ...
+    Total: ... tests, 0 failures, 0 errors
+    ...
+       ncalls  tottime  percall  cumtime  percall filename:lineno(function)...
+
+Profiling also works across layers.
+
+    >>> sys.argv = [testrunner_script, '-ssample2', '--profile', 
+    ...             '--tests-pattern', 'sampletests_ntd']
+    >>> testrunner.run(defaults)
+    Running...
+      Tear down ... not supported...
+       ncalls  tottime  percall  cumtime  percall filename:lineno(function)...
+
+The testrunner creates temnporary files containing hotshot profiler
+data:
+
+    >>> import glob
+    >>> files = list(glob.glob('tests_profile.*.prof'))
+    >>> files.sort()
+    >>> files
+    ['tests_profile.cZj2jt.prof', 'tests_profile.yHD-so.prof']
+
+It deletes these when rerun.  We'll delete these ourselves:
+
+    >>> import os
+    >>> for f in files:
+    ...     os.unlink(f)


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-profiling.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-progress.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-progress.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-progress.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,367 @@
+Test Runner
+===========
+
+Test Progress
+-------------
+
+If the --progress (-p) option is used, progress information is printed and
+a carriage return (rather than a new-line) is printed between
+detail lines.  Let's look at the effect of --progress (-p) at different
+levels of verbosity.
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+
+    >>> sys.argv = 'test --layer 122 -p'.split()
+    >>> from zope.testing import testrunner
+    >>> testrunner.run(defaults)
+    Running samplelayers.Layer122 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer12 in 0.000 seconds.
+      Set up samplelayers.Layer122 in 0.000 seconds.
+      Running:
+        1/34 (2.9%)\r
+                   \r
+        2/34 (5.9%)\r
+                   \r
+        3/34 (8.8%)\r
+                   \r
+        4/34 (11.8%)\r
+                    \r
+        5/34 (14.7%)\r
+                    \r
+        6/34 (17.6%)\r
+                    \r
+        7/34 (20.6%)\r
+                    \r
+        8/34 (23.5%)\r
+                    \r
+        9/34 (26.5%)\r
+                    \r
+        10/34 (29.4%)\r
+                     \r
+        11/34 (32.4%)\r
+                     \r
+        12/34 (35.3%)\r
+                     \r
+        17/34 (50.0%)\r
+                     \r
+        18/34 (52.9%)\r
+                     \r
+        19/34 (55.9%)\r
+                     \r
+        20/34 (58.8%)\r
+                     \r
+        21/34 (61.8%)\r
+                     \r
+        22/34 (64.7%)\r
+                     \r
+        23/34 (67.6%)\r
+                     \r
+        24/34 (70.6%)\r
+                     \r
+        25/34 (73.5%)\r
+                     \r
+        26/34 (76.5%)\r
+                     \r
+        27/34 (79.4%)\r
+                     \r
+        28/34 (82.4%)\r
+                     \r
+        29/34 (85.3%)\r
+                     \r
+        34/34 (100.0%)\r
+                      \r
+    <BLANKLINE>
+      Ran 34 tests with 0 failures and 0 errors in 0.008 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in 0.000 seconds.
+      Tear down samplelayers.Layer12 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    False
+
+(Note that, in the examples above and below, we show "\r" followed by
+new lines where carriage returns would appear in actual output.)
+
+Using a single level of verbosity causes test descriptions to be
+output, but only if they fit in the terminal width.  The default
+width, when the terminal width can't be determined, is 80:
+
+>>> sys.argv = 'test --layer 122 -pv'.split()
+>>> testrunner.run(defaults)
+Running tests at level 1
+Running samplelayers.Layer122 tests:
+  Set up samplelayers.Layer1 in 0.000 seconds.
+  Set up samplelayers.Layer12 in 0.000 seconds.
+  Set up samplelayers.Layer122 in 0.000 seconds.
+  Running:
+    1/34 (2.9%) test_x1 (sample1.sampletests.test122.TestA)\r
+                                                           \r
+    2/34 (5.9%) test_y0 (sample1.sampletests.test122.TestA)\r
+                                                           \r
+    3/34 (8.8%) test_z0 (sample1.sampletests.test122.TestA)\r
+                                                           \r
+    4/34 (11.8%) test_x0 (sample1.sampletests.test122.TestB)\r
+                                                            \r
+    5/34 (14.7%) test_y1 (sample1.sampletests.test122.TestB)\r
+                                                            \r
+    6/34 (17.6%) test_z0 (sample1.sampletests.test122.TestB)\r
+                                                            \r
+    7/34 (20.6%) test_1 (sample1.sampletests.test122.TestNotMuch)\r
+                                                                 \r
+    8/34 (23.5%) test_2 (sample1.sampletests.test122.TestNotMuch)\r
+                                                                 \r
+    9/34 (26.5%) test_3 (sample1.sampletests.test122.TestNotMuch)\r
+                                                                 \r
+    10/34 (29.4%) test_x0 (sample1.sampletests.test122)\r
+                                                       \r
+    11/34 (32.4%) test_y0 (sample1.sampletests.test122)\r
+                                                       \r
+    12/34 (35.3%) test_z1 (sample1.sampletests.test122)\r
+                                                       \r
+    17/34 (50.0%) ... /testrunner-ex/sample1/sampletests/../../sampletestsl.txt\r
+                                                                               \r
+    18/34 (52.9%) test_x1 (sampletests.test122.TestA)\r
+                                                     \r
+    19/34 (55.9%) test_y0 (sampletests.test122.TestA)\r
+                                                     \r
+    20/34 (58.8%) test_z0 (sampletests.test122.TestA)\r
+                                                     \r
+    21/34 (61.8%) test_x0 (sampletests.test122.TestB)\r
+                                                     \r
+    22/34 (64.7%) test_y1 (sampletests.test122.TestB)\r
+                                                     \r
+    23/34 (67.6%) test_z0 (sampletests.test122.TestB)\r
+                                                     \r
+    24/34 (70.6%) test_1 (sampletests.test122.TestNotMuch)\r
+                                                          \r
+    25/34 (73.5%) test_2 (sampletests.test122.TestNotMuch)\r
+                                                          \r
+    26/34 (76.5%) test_3 (sampletests.test122.TestNotMuch)\r
+                                                          \r
+    27/34 (79.4%) test_x0 (sampletests.test122)\r
+                                               \r
+    28/34 (82.4%) test_y0 (sampletests.test122)\r
+                                               \r
+    29/34 (85.3%) test_z1 (sampletests.test122)\r
+                                               \r
+    34/34 (100.0%) ... pe/testing/testrunner-ex/sampletests/../sampletestsl.txt\r
+                                                                               \r
+<BLANKLINE>
+  Ran 34 tests with 0 failures and 0 errors in 0.008 seconds.
+Tearing down left over layers:
+  Tear down samplelayers.Layer122 in 0.000 seconds.
+  Tear down samplelayers.Layer12 in 0.000 seconds.
+  Tear down samplelayers.Layer1 in 0.000 seconds.
+False
+
+The terminal width is determined using the curses module.  To see
+that, we'll provide a fake curses module:
+
+    >>> class FakeCurses:
+    ...     def setupterm(self):
+    ...         pass
+    ...     def tigetnum(self, ignored):
+    ...         return 60
+    >>> old_curses = sys.modules.get('curses')
+    >>> sys.modules['curses'] = FakeCurses()
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running samplelayers.Layer122 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer12 in 0.000 seconds.
+      Set up samplelayers.Layer122 in 0.000 seconds.
+      Running:
+        1/34 (2.9%) test_x1 (sample1.sampletests.test122.TestA)\r
+                                                               \r
+        2/34 (5.9%) test_y0 (sample1.sampletests.test122.TestA)\r
+                                                               \r
+        3/34 (8.8%) test_z0 (sample1.sampletests.test122.TestA)\r
+                                                               \r
+        4/34 (11.8%) test_x0 (...le1.sampletests.test122.TestB)\r
+                                                               \r
+        5/34 (14.7%) test_y1 (...le1.sampletests.test122.TestB)\r
+                                                               \r
+        6/34 (17.6%) test_z0 (...le1.sampletests.test122.TestB)\r
+                                                               \r
+        7/34 (20.6%) test_1 (...ampletests.test122.TestNotMuch)\r
+                                                               \r
+        8/34 (23.5%) test_2 (...ampletests.test122.TestNotMuch)\r
+                                                               \r
+        9/34 (26.5%) test_3 (...ampletests.test122.TestNotMuch)\r
+                                                               \r
+        10/34 (29.4%) test_x0 (sample1.sampletests.test122)\r
+                                                           \r
+        11/34 (32.4%) test_y0 (sample1.sampletests.test122)\r
+                                                           \r
+        12/34 (35.3%) test_z1 (sample1.sampletests.test122)\r
+                                                           \r
+        17/34 (50.0%) ... e1/sampletests/../../sampletestsl.txt\r
+                                                               \r
+        18/34 (52.9%) test_x1 (sampletests.test122.TestA)\r
+                                                         \r
+        19/34 (55.9%) test_y0 (sampletests.test122.TestA)\r
+                                                         \r
+        20/34 (58.8%) test_z0 (sampletests.test122.TestA)\r
+                                                         \r
+        21/34 (61.8%) test_x0 (sampletests.test122.TestB)\r
+                                                         \r
+        22/34 (64.7%) test_y1 (sampletests.test122.TestB)\r
+                                                         \r
+        23/34 (67.6%) test_z0 (sampletests.test122.TestB)\r
+                                                         \r
+        24/34 (70.6%) test_1 (sampletests.test122.TestNotMuch)\r
+                                                              \r
+        25/34 (73.5%) test_2 (sampletests.test122.TestNotMuch)\r
+                                                              \r
+        26/34 (76.5%) test_3 (sampletests.test122.TestNotMuch)\r
+                                                              \r
+        27/34 (79.4%) test_x0 (sampletests.test122)\r
+                                                   \r
+        28/34 (82.4%) test_y0 (sampletests.test122)\r
+                                                   \r
+        29/34 (85.3%) test_z1 (sampletests.test122)\r
+                                                   \r
+        34/34 (100.0%) ... r-ex/sampletests/../sampletestsl.txt\r
+                                                               \r
+    <BLANKLINE>
+      Ran 34 tests with 0 failures and 0 errors in 0.008 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in 0.000 seconds.
+      Tear down samplelayers.Layer12 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    False
+
+    >>> sys.modules['curses'] = old_curses
+
+If a second or third level of verbosity are added, we get additional
+information.
+
+    >>> sys.argv = 'test --layer 122 -pvv -t !txt'.split()
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running samplelayers.Layer122 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer12 in 0.000 seconds.
+      Set up samplelayers.Layer122 in 0.000 seconds.
+      Running:
+        1/24 (4.2%) test_x1 (sample1.sampletests.test122.TestA)\r
+                                                              \r
+        2/24 (8.3%) test_y0 (sample1.sampletests.test122.TestA)\r
+                                                              \r
+        3/24 (12.5%) test_z0 (sample1.sampletests.test122.TestA)\r
+                                                               \r
+        4/24 (16.7%) test_x0 (sample1.sampletests.test122.TestB)\r
+                                                               \r
+        5/24 (20.8%) test_y1 (sample1.sampletests.test122.TestB)\r
+                                                               \r
+        6/24 (25.0%) test_z0 (sample1.sampletests.test122.TestB)\r
+                                                               \r
+        7/24 (29.2%) test_1 (sample1.sampletests.test122.TestNotMuch)\r
+                                                                    \r
+        8/24 (33.3%) test_2 (sample1.sampletests.test122.TestNotMuch)\r
+                                                                    \r
+        9/24 (37.5%) test_3 (sample1.sampletests.test122.TestNotMuch)\r
+                                                                    \r
+        10/24 (41.7%) test_x0 (sample1.sampletests.test122)\r
+                                                          \r
+        11/24 (45.8%) test_y0 (sample1.sampletests.test122)\r
+                                                          \r
+        12/24 (50.0%) test_z1 (sample1.sampletests.test122)\r
+                                                          \r
+        13/24 (54.2%) test_x1 (sampletests.test122.TestA)\r
+                                                        \r
+        14/24 (58.3%) test_y0 (sampletests.test122.TestA)\r
+                                                        \r
+        15/24 (62.5%) test_z0 (sampletests.test122.TestA)\r
+                                                        \r
+        16/24 (66.7%) test_x0 (sampletests.test122.TestB)\r
+                                                        \r
+        17/24 (70.8%) test_y1 (sampletests.test122.TestB)\r
+                                                        \r
+        18/24 (75.0%) test_z0 (sampletests.test122.TestB)\r
+                                                        \r
+        19/24 (79.2%) test_1 (sampletests.test122.TestNotMuch)\r
+                                                             \r
+        20/24 (83.3%) test_2 (sampletests.test122.TestNotMuch)\r
+                                                             \r
+        21/24 (87.5%) test_3 (sampletests.test122.TestNotMuch)\r
+                                                             \r
+        22/24 (91.7%) test_x0 (sampletests.test122)\r
+                                                  \r
+        23/24 (95.8%) test_y0 (sampletests.test122)\r
+                                                  \r
+        24/24 (100.0%) test_z1 (sampletests.test122)\r
+                                                   \r
+    <BLANKLINE>
+      Ran 24 tests with 0 failures and 0 errors in 0.006 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in 0.000 seconds.
+      Tear down samplelayers.Layer12 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    False
+
+Note that, in this example, we used a test-selection pattern starting
+with '!' to exclude tests containing the string "txt".
+
+    >>> sys.argv = 'test --layer 122 -pvvv -t!(txt|NotMuch)'.split()
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running samplelayers.Layer122 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer12 in 0.000 seconds.
+      Set up samplelayers.Layer122 in 0.000 seconds.
+      Running:
+        1/18 (5.6%) test_x1 (sample1.sampletests.test122.TestA) (0.000 ms)\r
+                                                                          \r
+        2/18 (11.1%) test_y0 (sample1.sampletests.test122.TestA) (0.000 ms)\r
+                                                                           \r
+        3/18 (16.7%) test_z0 (sample1.sampletests.test122.TestA) (0.000 ms)\r
+                                                                           \r
+        4/18 (22.2%) test_x0 (sample1.sampletests.test122.TestB) (0.000 ms)\r
+                                                                           \r
+        5/18 (27.8%) test_y1 (sample1.sampletests.test122.TestB) (0.000 ms)\r
+                                                                           \r
+        6/18 (33.3%) test_z0 (sample1.sampletests.test122.TestB) (0.000 ms)\r
+                                                                           \r
+        7/18 (38.9%) test_x0 (sample1.sampletests.test122) (0.001 ms)\r
+                                                                     \r
+        8/18 (44.4%) test_y0 (sample1.sampletests.test122) (0.001 ms)\r
+                                                                     \r
+        9/18 (50.0%) test_z1 (sample1.sampletests.test122) (0.001 ms)\r
+                                                                     \r
+        10/18 (55.6%) test_x1 (sampletests.test122.TestA) (0.000 ms)\r
+                                                                    \r
+        11/18 (61.1%) test_y0 (sampletests.test122.TestA) (0.000 ms)\r
+                                                                    \r
+        12/18 (66.7%) test_z0 (sampletests.test122.TestA) (0.000 ms)\r
+                                                                    \r
+        13/18 (72.2%) test_x0 (sampletests.test122.TestB) (0.000 ms)\r
+                                                                    \r
+        14/18 (77.8%) test_y1 (sampletests.test122.TestB) (0.000 ms)\r
+                                                                    \r
+        15/18 (83.3%) test_z0 (sampletests.test122.TestB) (0.000 ms)\r
+                                                                    \r
+        16/18 (88.9%) test_x0 (sampletests.test122) (0.001 ms)\r
+                                                              \r
+        17/18 (94.4%) test_y0 (sampletests.test122) (0.001 ms)\r
+                                                              \r
+        18/18 (100.0%) test_z1 (sampletests.test122) (0.001 ms)\r
+                                                               \r
+    <BLANKLINE>
+      Ran 18 tests with 0 failures and 0 errors in 0.006 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in 0.000 seconds.
+      Tear down samplelayers.Layer12 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    False
+
+In this example, we also excluded tests with "NotMuch" in their names.
+
+Unfortunately, the time data above doesn't buy us much because, in
+practice, the line is cleared before there is time to see the
+times. :/


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-progress.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-repeat.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-repeat.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-repeat.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,49 @@
+Test Runner
+===========
+
+Repeating Tests
+---------------
+
+The --repeat option can be used to repeat tests some number of times.
+Repeating tests is useful to help make sure that tests clean up after
+themselves.
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+
+    >>> sys.argv = 'test --layer 112 --layer unit --repeat 3'.split()
+    >>> from zope.testing import testrunner
+    >>> testrunner.run(defaults)
+    Running unit tests:
+    Iteration 1
+      Ran 192 tests with 0 failures and 0 errors in 0.054 seconds.
+    Iteration 2
+      Ran 192 tests with 0 failures and 0 errors in 0.054 seconds.
+    Iteration 3
+      Ran 192 tests with 0 failures and 0 errors in 0.052 seconds.
+    Running samplelayers.Layer112 tests:
+      Set up samplelayers.Layerx in 0.000 seconds.
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer11 in 0.000 seconds.
+      Set up samplelayers.Layer112 in 0.000 seconds.
+    Iteration 1
+      Ran 34 tests with 0 failures and 0 errors in 0.010 seconds.
+    Iteration 2
+      Ran 34 tests with 0 failures and 0 errors in 0.010 seconds.
+    Iteration 3
+      Ran 34 tests with 0 failures and 0 errors in 0.010 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer112 in 0.000 seconds.
+      Tear down samplelayers.Layerx in 0.000 seconds.
+      Tear down samplelayers.Layer11 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    Total: 226 tests, 0 failures, 0 errors
+    False
+
+The tests are repeated by layer.  Layers are set up and torn down only
+once.
+ 


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-repeat.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-simple.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-simple.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-simple.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,98 @@
+Test Runner
+===========
+
+Simple Usage
+------------
+
+The test runner consists of an importable module.  The test runner is
+used by providing scripts that import and invoke the `run` method from
+the module.  The `testrunner` module is controlled via command-line
+options.  Test scripts supply base and default options by supplying a
+list of default command-line options that are processed before the
+user-supplied command-line options are provided.
+
+Typically, a test script does 2 things:
+
+- Adds the directory containing the zope package to the Python
+  path.
+
+- Calls the test runner with default arguments and arguments supplied
+  to the script.
+
+  Normally, it just passes default/setup arguments.  The test runner
+  uses `sys.argv` to get the user's input.
+
+This testrunner_ex subdirectory contains a number of sample packages
+with tests.  Let's run the tests found here. First though, we'll set
+up our default options:
+
+    >>> import os.path
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+
+The default options are used by a script to customize the test runner
+for a particular application.  In this case, we use two options:
+
+path
+  Set the path where the test runner should look for tests.  This path
+  is also added to the Python path.
+
+tests-pattern
+  Tell the test runner how to recognize modules or packages containing
+  tests.
+
+Now, if we run the tests, without any other options:
+
+    >>> from zope.testing import testrunner
+    >>> import sys
+    >>> sys.argv = ['test']
+    >>> testrunner.run(defaults)
+    Running unit tests:
+      Ran 192 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer1 tests:
+      Set up samplelayers.Layer1 in N.NNN seconds.
+      Ran 9 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer11 tests:
+      Set up samplelayers.Layer11 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer111 tests:
+      Set up samplelayers.Layerx in N.NNN seconds.
+      Set up samplelayers.Layer111 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer112 tests:
+      Tear down samplelayers.Layer111 in N.NNN seconds.
+      Set up samplelayers.Layer112 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer12 tests:
+      Tear down samplelayers.Layer112 in N.NNN seconds.
+      Tear down samplelayers.Layerx in N.NNN seconds.
+      Tear down samplelayers.Layer11 in N.NNN seconds.
+      Set up samplelayers.Layer12 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer121 tests:
+      Set up samplelayers.Layer121 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Running samplelayers.Layer122 tests:
+      Tear down samplelayers.Layer121 in N.NNN seconds.
+      Set up samplelayers.Layer122 in N.NNN seconds.
+      Ran 34 tests with 0 failures and 0 errors in N.NNN seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in N.NNN seconds.
+      Tear down samplelayers.Layer12 in N.NNN seconds.
+      Tear down samplelayers.Layer1 in N.NNN seconds.
+    Total: 405 tests, 0 failures, 0 errors
+    False
+
+we see the normal testrunner output, which summarizes the tests run for
+each layer.  For each layer, we see what layers had to be torn down or
+set up to run the layer and we see the number of tests run, with
+results.
+
+The test runner returns a boolean indicating whether there were
+errors.  In this example, there were no errors, so it returned False.
+
+(Of course, the times shown in these examples are just examples.
+Times will vary depending on system speed.)


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-simple.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-test-selection.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-test-selection.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-test-selection.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,492 @@
+Test Runner
+===========
+
+
+Test Selection
+--------------
+
+We've already seen that we can select tests by layer.  There are three
+other ways we can select tests.  We can select tests by package:
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+
+    >>> sys.argv = 'test --layer 122 -ssample1 -vv'.split()
+    >>> from zope.testing import testrunner
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running samplelayers.Layer122 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer12 in 0.000 seconds.
+      Set up samplelayers.Layer122 in 0.000 seconds.
+      Running:
+        test_x1 (sample1.sampletests.test122.TestA)
+        test_y0 (sample1.sampletests.test122.TestA)
+        test_z0 (sample1.sampletests.test122.TestA)
+        test_x0 (sample1.sampletests.test122.TestB)
+        test_y1 (sample1.sampletests.test122.TestB)
+        test_z0 (sample1.sampletests.test122.TestB)
+        test_1 (sample1.sampletests.test122.TestNotMuch)
+        test_2 (sample1.sampletests.test122.TestNotMuch)
+        test_3 (sample1.sampletests.test122.TestNotMuch)
+        test_x0 (sample1.sampletests.test122)
+        test_y0 (sample1.sampletests.test122)
+        test_z1 (sample1.sampletests.test122)
+        testrunner-ex/sample1/sampletests/../../sampletestsl.txt
+      Ran 17 tests with 0 failures and 0 errors in 0.005 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in 0.000 seconds.
+      Tear down samplelayers.Layer12 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    False
+
+You can specify multiple packages:
+
+    >>> sys.argv = 'test -u  -vv -ssample1 -ssample2'.split()
+    >>> testrunner.run(defaults) 
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        test_x1 (sample1.sampletestsf.TestA)
+        test_y0 (sample1.sampletestsf.TestA)
+        test_z0 (sample1.sampletestsf.TestA)
+        test_x0 (sample1.sampletestsf.TestB)
+        test_y1 (sample1.sampletestsf.TestB)
+        test_z0 (sample1.sampletestsf.TestB)
+        test_1 (sample1.sampletestsf.TestNotMuch)
+        test_2 (sample1.sampletestsf.TestNotMuch)
+        test_3 (sample1.sampletestsf.TestNotMuch)
+        test_x0 (sample1.sampletestsf)
+        test_y0 (sample1.sampletestsf)
+        test_z1 (sample1.sampletestsf)
+        testrunner-ex/sample1/../sampletests.txt
+        test_x1 (sample1.sample11.sampletests.TestA)
+        test_y0 (sample1.sample11.sampletests.TestA)
+        test_z0 (sample1.sample11.sampletests.TestA)
+        test_x0 (sample1.sample11.sampletests.TestB)
+        test_y1 (sample1.sample11.sampletests.TestB)
+        test_z0 (sample1.sample11.sampletests.TestB)
+        test_1 (sample1.sample11.sampletests.TestNotMuch)
+        test_2 (sample1.sample11.sampletests.TestNotMuch)
+        test_3 (sample1.sample11.sampletests.TestNotMuch)
+        test_x0 (sample1.sample11.sampletests)
+        test_y0 (sample1.sample11.sampletests)
+        test_z1 (sample1.sample11.sampletests)
+        testrunner-ex/sample1/sample11/../../sampletests.txt
+        test_x1 (sample1.sample13.sampletests.TestA)
+        test_y0 (sample1.sample13.sampletests.TestA)
+        test_z0 (sample1.sample13.sampletests.TestA)
+        test_x0 (sample1.sample13.sampletests.TestB)
+        test_y1 (sample1.sample13.sampletests.TestB)
+        test_z0 (sample1.sample13.sampletests.TestB)
+        test_1 (sample1.sample13.sampletests.TestNotMuch)
+        test_2 (sample1.sample13.sampletests.TestNotMuch)
+        test_3 (sample1.sample13.sampletests.TestNotMuch)
+        test_x0 (sample1.sample13.sampletests)
+        test_y0 (sample1.sample13.sampletests)
+        test_z1 (sample1.sample13.sampletests)
+        testrunner-ex/sample1/sample13/../../sampletests.txt
+        test_x1 (sample1.sampletests.test1.TestA)
+        test_y0 (sample1.sampletests.test1.TestA)
+        test_z0 (sample1.sampletests.test1.TestA)
+        test_x0 (sample1.sampletests.test1.TestB)
+        test_y1 (sample1.sampletests.test1.TestB)
+        test_z0 (sample1.sampletests.test1.TestB)
+        test_1 (sample1.sampletests.test1.TestNotMuch)
+        test_2 (sample1.sampletests.test1.TestNotMuch)
+        test_3 (sample1.sampletests.test1.TestNotMuch)
+        test_x0 (sample1.sampletests.test1)
+        test_y0 (sample1.sampletests.test1)
+        test_z1 (sample1.sampletests.test1)
+        testrunner-ex/sample1/sampletests/../../sampletests.txt
+        test_x1 (sample1.sampletests.test_one.TestA)
+        test_y0 (sample1.sampletests.test_one.TestA)
+        test_z0 (sample1.sampletests.test_one.TestA)
+        test_x0 (sample1.sampletests.test_one.TestB)
+        test_y1 (sample1.sampletests.test_one.TestB)
+        test_z0 (sample1.sampletests.test_one.TestB)
+        test_1 (sample1.sampletests.test_one.TestNotMuch)
+        test_2 (sample1.sampletests.test_one.TestNotMuch)
+        test_3 (sample1.sampletests.test_one.TestNotMuch)
+        test_x0 (sample1.sampletests.test_one)
+        test_y0 (sample1.sampletests.test_one)
+        test_z1 (sample1.sampletests.test_one)
+        testrunner-ex/sample1/sampletests/../../sampletests.txt
+        test_x1 (sample2.sample21.sampletests.TestA)
+        test_y0 (sample2.sample21.sampletests.TestA)
+        test_z0 (sample2.sample21.sampletests.TestA)
+        test_x0 (sample2.sample21.sampletests.TestB)
+        test_y1 (sample2.sample21.sampletests.TestB)
+        test_z0 (sample2.sample21.sampletests.TestB)
+        test_1 (sample2.sample21.sampletests.TestNotMuch)
+        test_2 (sample2.sample21.sampletests.TestNotMuch)
+        test_3 (sample2.sample21.sampletests.TestNotMuch)
+        test_x0 (sample2.sample21.sampletests)
+        test_y0 (sample2.sample21.sampletests)
+        test_z1 (sample2.sample21.sampletests)
+        testrunner-ex/sample2/sample21/../../sampletests.txt
+        test_x1 (sample2.sampletests.test_1.TestA)
+        test_y0 (sample2.sampletests.test_1.TestA)
+        test_z0 (sample2.sampletests.test_1.TestA)
+        test_x0 (sample2.sampletests.test_1.TestB)
+        test_y1 (sample2.sampletests.test_1.TestB)
+        test_z0 (sample2.sampletests.test_1.TestB)
+        test_1 (sample2.sampletests.test_1.TestNotMuch)
+        test_2 (sample2.sampletests.test_1.TestNotMuch)
+        test_3 (sample2.sampletests.test_1.TestNotMuch)
+        test_x0 (sample2.sampletests.test_1)
+        test_y0 (sample2.sampletests.test_1)
+        test_z1 (sample2.sampletests.test_1)
+        testrunner-ex/sample2/sampletests/../../sampletests.txt
+        test_x1 (sample2.sampletests.testone.TestA)
+        test_y0 (sample2.sampletests.testone.TestA)
+        test_z0 (sample2.sampletests.testone.TestA)
+        test_x0 (sample2.sampletests.testone.TestB)
+        test_y1 (sample2.sampletests.testone.TestB)
+        test_z0 (sample2.sampletests.testone.TestB)
+        test_1 (sample2.sampletests.testone.TestNotMuch)
+        test_2 (sample2.sampletests.testone.TestNotMuch)
+        test_3 (sample2.sampletests.testone.TestNotMuch)
+        test_x0 (sample2.sampletests.testone)
+        test_y0 (sample2.sampletests.testone)
+        test_z1 (sample2.sampletests.testone)
+        testrunner-ex/sample2/sampletests/../../sampletests.txt
+      Ran 128 tests with 0 failures and 0 errors in 0.025 seconds.
+    False
+
+We can select by test module name using the --moduke (-m) option:
+
+    >>> sys.argv = 'test -u  -vv -ssample1 -m_one -mtest1'.split()
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        test_x1 (sample1.sampletests.test1.TestA)
+        test_y0 (sample1.sampletests.test1.TestA)
+        test_z0 (sample1.sampletests.test1.TestA)
+        test_x0 (sample1.sampletests.test1.TestB)
+        test_y1 (sample1.sampletests.test1.TestB)
+        test_z0 (sample1.sampletests.test1.TestB)
+        test_1 (sample1.sampletests.test1.TestNotMuch)
+        test_2 (sample1.sampletests.test1.TestNotMuch)
+        test_3 (sample1.sampletests.test1.TestNotMuch)
+        test_x0 (sample1.sampletests.test1)
+        test_y0 (sample1.sampletests.test1)
+        test_z1 (sample1.sampletests.test1)
+        testrunner-ex/sample1/sampletests/../../sampletests.txt
+        test_x1 (sample1.sampletests.test_one.TestA)
+        test_y0 (sample1.sampletests.test_one.TestA)
+        test_z0 (sample1.sampletests.test_one.TestA)
+        test_x0 (sample1.sampletests.test_one.TestB)
+        test_y1 (sample1.sampletests.test_one.TestB)
+        test_z0 (sample1.sampletests.test_one.TestB)
+        test_1 (sample1.sampletests.test_one.TestNotMuch)
+        test_2 (sample1.sampletests.test_one.TestNotMuch)
+        test_3 (sample1.sampletests.test_one.TestNotMuch)
+        test_x0 (sample1.sampletests.test_one)
+        test_y0 (sample1.sampletests.test_one)
+        test_z1 (sample1.sampletests.test_one)
+        testrunner-ex/sample1/sampletests/../../sampletests.txt
+      Ran 32 tests with 0 failures and 0 errors in 0.008 seconds.
+    False
+
+and by test within the module using the --test (-t) option:
+
+    >>> sys.argv = 'test -u  -vv -ssample1 -m_one -mtest1 -tx0 -ty0'.split()
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        test_y0 (sample1.sampletests.test1.TestA)
+        test_x0 (sample1.sampletests.test1.TestB)
+        test_x0 (sample1.sampletests.test1)
+        test_y0 (sample1.sampletests.test1)
+        test_y0 (sample1.sampletests.test_one.TestA)
+        test_x0 (sample1.sampletests.test_one.TestB)
+        test_x0 (sample1.sampletests.test_one)
+        test_y0 (sample1.sampletests.test_one)
+      Ran 8 tests with 0 failures and 0 errors in 0.003 seconds.
+    False
+
+
+    >>> sys.argv = 'test -u  -vv -ssample1 -ttxt'.split()
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        testrunner-ex/sample1/../sampletests.txt
+        testrunner-ex/sample1/sample11/../../sampletests.txt
+        testrunner-ex/sample1/sample13/../../sampletests.txt
+        testrunner-ex/sample1/sampletests/../../sampletests.txt
+        testrunner-ex/sample1/sampletests/../../sampletests.txt
+      Ran 20 tests with 0 failures and 0 errors in 0.004 seconds.
+    False
+
+The --moduke and --test options take regular expressions.  If the
+regular expressions specified begin with '!', then tests that don't
+match the regular expression are selected:
+
+    >>> sys.argv = 'test -u  -vv -ssample1 -m!sample1[.]sample1'.split()
+    >>> testrunner.run(defaults) 
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        test_x1 (sample1.sampletestsf.TestA)
+        test_y0 (sample1.sampletestsf.TestA)
+        test_z0 (sample1.sampletestsf.TestA)
+        test_x0 (sample1.sampletestsf.TestB)
+        test_y1 (sample1.sampletestsf.TestB)
+        test_z0 (sample1.sampletestsf.TestB)
+        test_1 (sample1.sampletestsf.TestNotMuch)
+        test_2 (sample1.sampletestsf.TestNotMuch)
+        test_3 (sample1.sampletestsf.TestNotMuch)
+        test_x0 (sample1.sampletestsf)
+        test_y0 (sample1.sampletestsf)
+        test_z1 (sample1.sampletestsf)
+        testrunner-ex/sample1/../sampletests.txt
+        test_x1 (sample1.sampletests.test1.TestA)
+        test_y0 (sample1.sampletests.test1.TestA)
+        test_z0 (sample1.sampletests.test1.TestA)
+        test_x0 (sample1.sampletests.test1.TestB)
+        test_y1 (sample1.sampletests.test1.TestB)
+        test_z0 (sample1.sampletests.test1.TestB)
+        test_1 (sample1.sampletests.test1.TestNotMuch)
+        test_2 (sample1.sampletests.test1.TestNotMuch)
+        test_3 (sample1.sampletests.test1.TestNotMuch)
+        test_x0 (sample1.sampletests.test1)
+        test_y0 (sample1.sampletests.test1)
+        test_z1 (sample1.sampletests.test1)
+        testrunner-ex/sample1/sampletests/../../sampletests.txt
+        test_x1 (sample1.sampletests.test_one.TestA)
+        test_y0 (sample1.sampletests.test_one.TestA)
+        test_z0 (sample1.sampletests.test_one.TestA)
+        test_x0 (sample1.sampletests.test_one.TestB)
+        test_y1 (sample1.sampletests.test_one.TestB)
+        test_z0 (sample1.sampletests.test_one.TestB)
+        test_1 (sample1.sampletests.test_one.TestNotMuch)
+        test_2 (sample1.sampletests.test_one.TestNotMuch)
+        test_3 (sample1.sampletests.test_one.TestNotMuch)
+        test_x0 (sample1.sampletests.test_one)
+        test_y0 (sample1.sampletests.test_one)
+        test_z1 (sample1.sampletests.test_one)
+        testrunner-ex/sample1/sampletests/../../sampletests.txt
+      Ran 48 tests with 0 failures and 0 errors in 0.017 seconds.
+    False
+
+Module and test filters can also be given as positional arguments:
+
+
+    >>> sys.argv = 'test -u  -vv -ssample1 !sample1[.]sample1'.split()
+    >>> testrunner.run(defaults) 
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        test_x1 (sample1.sampletestsf.TestA)
+        test_y0 (sample1.sampletestsf.TestA)
+        test_z0 (sample1.sampletestsf.TestA)
+        test_x0 (sample1.sampletestsf.TestB)
+        test_y1 (sample1.sampletestsf.TestB)
+        test_z0 (sample1.sampletestsf.TestB)
+        test_1 (sample1.sampletestsf.TestNotMuch)
+        test_2 (sample1.sampletestsf.TestNotMuch)
+        test_3 (sample1.sampletestsf.TestNotMuch)
+        test_x0 (sample1.sampletestsf)
+        test_y0 (sample1.sampletestsf)
+        test_z1 (sample1.sampletestsf)
+        testrunner-ex/sample1/../sampletests.txt
+        test_x1 (sample1.sampletests.test1.TestA)
+        test_y0 (sample1.sampletests.test1.TestA)
+        test_z0 (sample1.sampletests.test1.TestA)
+        test_x0 (sample1.sampletests.test1.TestB)
+        test_y1 (sample1.sampletests.test1.TestB)
+        test_z0 (sample1.sampletests.test1.TestB)
+        test_1 (sample1.sampletests.test1.TestNotMuch)
+        test_2 (sample1.sampletests.test1.TestNotMuch)
+        test_3 (sample1.sampletests.test1.TestNotMuch)
+        test_x0 (sample1.sampletests.test1)
+        test_y0 (sample1.sampletests.test1)
+        test_z1 (sample1.sampletests.test1)
+        testrunner-ex/sample1/sampletests/../../sampletests.txt
+        test_x1 (sample1.sampletests.test_one.TestA)
+        test_y0 (sample1.sampletests.test_one.TestA)
+        test_z0 (sample1.sampletests.test_one.TestA)
+        test_x0 (sample1.sampletests.test_one.TestB)
+        test_y1 (sample1.sampletests.test_one.TestB)
+        test_z0 (sample1.sampletests.test_one.TestB)
+        test_1 (sample1.sampletests.test_one.TestNotMuch)
+        test_2 (sample1.sampletests.test_one.TestNotMuch)
+        test_3 (sample1.sampletests.test_one.TestNotMuch)
+        test_x0 (sample1.sampletests.test_one)
+        test_y0 (sample1.sampletests.test_one)
+        test_z1 (sample1.sampletests.test_one)
+        testrunner-ex/sample1/sampletests/../../sampletests.txt
+      Ran 48 tests with 0 failures and 0 errors in 0.017 seconds.
+    False
+
+    >>> sys.argv = 'test -u  -vv -ssample1 . txt'.split()
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        testrunner-ex/sample1/../sampletests.txt
+        testrunner-ex/sample1/sample11/../../sampletests.txt
+        testrunner-ex/sample1/sample13/../../sampletests.txt
+        testrunner-ex/sample1/sampletests/../../sampletests.txt
+        testrunner-ex/sample1/sampletests/../../sampletests.txt
+      Ran 20 tests with 0 failures and 0 errors in 0.004 seconds.
+    False
+
+Sometimes, ere are tests that you don't want to run by default.
+For example, you might have tests that take a long time.  Tests can
+have a level attribute.  If no level is specified, a level of 1 is
+assumed and, by default, only tests at level one are run.  to run
+tests at a higher level, use the --at-level (-a) option to specify a higher
+level.  For example, with the following options:
+
+
+    >>> sys.argv = 'test -u  -vv -t test_y1 -t test_y0'.split()
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        test_y0 (sampletestsf.TestA)
+        test_y1 (sampletestsf.TestB)
+        test_y0 (sampletestsf)
+        test_y0 (sample1.sampletestsf.TestA)
+        test_y1 (sample1.sampletestsf.TestB)
+        test_y0 (sample1.sampletestsf)
+        test_y0 (sample1.sample11.sampletests.TestA)
+        test_y1 (sample1.sample11.sampletests.TestB)
+        test_y0 (sample1.sample11.sampletests)
+        test_y0 (sample1.sample13.sampletests.TestA)
+        test_y1 (sample1.sample13.sampletests.TestB)
+        test_y0 (sample1.sample13.sampletests)
+        test_y0 (sample1.sampletests.test1.TestA)
+        test_y1 (sample1.sampletests.test1.TestB)
+        test_y0 (sample1.sampletests.test1)
+        test_y0 (sample1.sampletests.test_one.TestA)
+        test_y1 (sample1.sampletests.test_one.TestB)
+        test_y0 (sample1.sampletests.test_one)
+        test_y0 (sample2.sample21.sampletests.TestA)
+        test_y1 (sample2.sample21.sampletests.TestB)
+        test_y0 (sample2.sample21.sampletests)
+        test_y0 (sample2.sampletests.test_1.TestA)
+        test_y1 (sample2.sampletests.test_1.TestB)
+        test_y0 (sample2.sampletests.test_1)
+        test_y0 (sample2.sampletests.testone.TestA)
+        test_y1 (sample2.sampletests.testone.TestB)
+        test_y0 (sample2.sampletests.testone)
+        test_y0 (sample3.sampletests.TestA)
+        test_y1 (sample3.sampletests.TestB)
+        test_y0 (sample3.sampletests)
+        test_y0 (sampletests.test1.TestA)
+        test_y1 (sampletests.test1.TestB)
+        test_y0 (sampletests.test1)
+        test_y0 (sampletests.test_one.TestA)
+        test_y1 (sampletests.test_one.TestB)
+        test_y0 (sampletests.test_one)
+      Ran 36 tests with 0 failures and 0 errors in 0.009 seconds.
+    False
+
+
+We get run 36 tests.  If we specify a level of 2, we get some
+additional tests:
+
+    >>> sys.argv = 'test -u  -vv -a 2 -t test_y1 -t test_y0'.split()
+    >>> testrunner.run(defaults)
+    Running tests at level 2
+    Running unit tests:
+      Running:
+        test_y0 (sampletestsf.TestA)
+        test_y0 (sampletestsf.TestA2)
+        test_y1 (sampletestsf.TestB)
+        test_y0 (sampletestsf)
+        test_y0 (sample1.sampletestsf.TestA)
+        test_y1 (sample1.sampletestsf.TestB)
+        test_y0 (sample1.sampletestsf)
+        test_y0 (sample1.sample11.sampletests.TestA)
+        test_y1 (sample1.sample11.sampletests.TestB)
+        test_y1 (sample1.sample11.sampletests.TestB2)
+        test_y0 (sample1.sample11.sampletests)
+        test_y0 (sample1.sample13.sampletests.TestA)
+        test_y1 (sample1.sample13.sampletests.TestB)
+        test_y0 (sample1.sample13.sampletests)
+        test_y0 (sample1.sampletests.test1.TestA)
+        test_y1 (sample1.sampletests.test1.TestB)
+        test_y0 (sample1.sampletests.test1)
+        test_y0 (sample1.sampletests.test_one.TestA)
+        test_y1 (sample1.sampletests.test_one.TestB)
+        test_y0 (sample1.sampletests.test_one)
+        test_y0 (sample2.sample21.sampletests.TestA)
+        test_y1 (sample2.sample21.sampletests.TestB)
+        test_y0 (sample2.sample21.sampletests)
+        test_y0 (sample2.sampletests.test_1.TestA)
+        test_y1 (sample2.sampletests.test_1.TestB)
+        test_y0 (sample2.sampletests.test_1)
+        test_y0 (sample2.sampletests.testone.TestA)
+        test_y1 (sample2.sampletests.testone.TestB)
+        test_y0 (sample2.sampletests.testone)
+        test_y0 (sample3.sampletests.TestA)
+        test_y1 (sample3.sampletests.TestB)
+        test_y0 (sample3.sampletests)
+        test_y0 (sampletests.test1.TestA)
+        test_y1 (sampletests.test1.TestB)
+        test_y0 (sampletests.test1)
+        test_y0 (sampletests.test_one.TestA)
+        test_y1 (sampletests.test_one.TestB)
+        test_y0 (sampletests.test_one)
+      Ran 38 tests with 0 failures and 0 errors in 0.009 seconds.
+    False
+
+We can use the --all option to run tests at all levels:
+
+    >>> sys.argv = 'test -u  -vv --all -t test_y1 -t test_y0'.split()
+    >>> testrunner.run(defaults)
+    Running tests at all levels
+    Running unit tests:
+      Running:
+        test_y0 (sampletestsf.TestA)
+        test_y0 (sampletestsf.TestA2)
+        test_y1 (sampletestsf.TestB)
+        test_y0 (sampletestsf)
+        test_y0 (sample1.sampletestsf.TestA)
+        test_y1 (sample1.sampletestsf.TestB)
+        test_y0 (sample1.sampletestsf)
+        test_y0 (sample1.sample11.sampletests.TestA)
+        test_y0 (sample1.sample11.sampletests.TestA3)
+        test_y1 (sample1.sample11.sampletests.TestB)
+        test_y1 (sample1.sample11.sampletests.TestB2)
+        test_y0 (sample1.sample11.sampletests)
+        test_y0 (sample1.sample13.sampletests.TestA)
+        test_y1 (sample1.sample13.sampletests.TestB)
+        test_y0 (sample1.sample13.sampletests)
+        test_y0 (sample1.sampletests.test1.TestA)
+        test_y1 (sample1.sampletests.test1.TestB)
+        test_y0 (sample1.sampletests.test1)
+        test_y0 (sample1.sampletests.test_one.TestA)
+        test_y1 (sample1.sampletests.test_one.TestB)
+        test_y0 (sample1.sampletests.test_one)
+        test_y0 (sample2.sample21.sampletests.TestA)
+        test_y1 (sample2.sample21.sampletests.TestB)
+        test_y0 (sample2.sample21.sampletests)
+        test_y0 (sample2.sampletests.test_1.TestA)
+        test_y1 (sample2.sampletests.test_1.TestB)
+        test_y0 (sample2.sampletests.test_1)
+        test_y0 (sample2.sampletests.testone.TestA)
+        test_y1 (sample2.sampletests.testone.TestB)
+        test_y0 (sample2.sampletests.testone)
+        test_y0 (sample3.sampletests.TestA)
+        test_y1 (sample3.sampletests.TestB)
+        test_y0 (sample3.sampletests)
+        test_y0 (sampletests.test1.TestA)
+        test_y1 (sampletests.test1.TestB)
+        test_y0 (sampletests.test1)
+        test_y0 (sampletests.test_one.TestA)
+        test_y1 (sampletests.test_one.TestB)
+        test_y0 (sampletests.test_one)
+      Ran 39 tests with 0 failures and 0 errors in 0.009 seconds.
+    False


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-test-selection.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-verbose.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-verbose.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-verbose.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,154 @@
+Test Runner
+===========
+
+Verbose Output
+--------------
+
+Normally, we just get a summary.  We can use the -v option to get
+increasingly more information.
+
+If we use a single --verbose (-v) option, we get a dot printed for each
+test:
+
+    >>> import os.path, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     ]
+    >>> sys.argv = 'test --layer 122 -v'.split()
+    >>> from zope.testing import testrunner
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running samplelayers.Layer122 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer12 in 0.000 seconds.
+      Set up samplelayers.Layer122 in 0.000 seconds.
+      Running:
+        ..................................
+      Ran 34 tests with 0 failures and 0 errors in 0.007 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in 0.000 seconds.
+      Tear down samplelayers.Layer12 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    False
+
+If there are more than 50 tests, the dots are printed in groups of
+50:
+
+    >>> sys.argv = 'test -uv'.split()
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        ..................................................
+        ..................................................
+        ..................................................
+        ..........................................
+      Ran 192 tests with 0 failures and 0 errors in 0.035 seconds.
+    False
+
+If the --verbose (-v) option is used twice, then the name and location of
+each test is printed as it is run:
+
+    >>> sys.argv = 'test --layer 122 -vv'.split()
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running samplelayers.Layer122 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer12 in 0.000 seconds.
+      Set up samplelayers.Layer122 in 0.000 seconds.
+      Running:
+        test_x1 (sample1.sampletests.test122.TestA)
+        test_y0 (sample1.sampletests.test122.TestA)
+        test_z0 (sample1.sampletests.test122.TestA)
+        test_x0 (sample1.sampletests.test122.TestB)
+        test_y1 (sample1.sampletests.test122.TestB)
+        test_z0 (sample1.sampletests.test122.TestB)
+        test_1 (sample1.sampletests.test122.TestNotMuch)
+        test_2 (sample1.sampletests.test122.TestNotMuch)
+        test_3 (sample1.sampletests.test122.TestNotMuch)
+        test_x0 (sample1.sampletests.test122)
+        test_y0 (sample1.sampletests.test122)
+        test_z1 (sample1.sampletests.test122)
+        testrunner-ex/sample1/sampletests/../../sampletestsl.txt
+        test_x1 (sampletests.test122.TestA)
+        test_y0 (sampletests.test122.TestA)
+        test_z0 (sampletests.test122.TestA)
+        test_x0 (sampletests.test122.TestB)
+        test_y1 (sampletests.test122.TestB)
+        test_z0 (sampletests.test122.TestB)
+        test_1 (sampletests.test122.TestNotMuch)
+        test_2 (sampletests.test122.TestNotMuch)
+        test_3 (sampletests.test122.TestNotMuch)
+        test_x0 (sampletests.test122)
+        test_y0 (sampletests.test122)
+        test_z1 (sampletests.test122)
+        testrunner-ex/sampletests/../sampletestsl.txt
+      Ran 34 tests with 0 failures and 0 errors in 0.009 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in 0.000 seconds.
+      Tear down samplelayers.Layer12 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    False
+
+if the --verbose (-v) option is used three times, then individual
+test-execution times are printed:
+
+    >>> sys.argv = 'test --layer 122 -vvv'.split()
+    >>> testrunner.run(defaults)
+    Running tests at level 1
+    Running samplelayers.Layer122 tests:
+      Set up samplelayers.Layer1 in 0.000 seconds.
+      Set up samplelayers.Layer12 in 0.000 seconds.
+      Set up samplelayers.Layer122 in 0.000 seconds.
+      Running:
+        test_x1 (sample1.sampletests.test122.TestA) (0.000 ms)
+        test_y0 (sample1.sampletests.test122.TestA) (0.000 ms)
+        test_z0 (sample1.sampletests.test122.TestA) (0.000 ms)
+        test_x0 (sample1.sampletests.test122.TestB) (0.000 ms)
+        test_y1 (sample1.sampletests.test122.TestB) (0.000 ms)
+        test_z0 (sample1.sampletests.test122.TestB) (0.000 ms)
+        test_1 (sample1.sampletests.test122.TestNotMuch) (0.000 ms)
+        test_2 (sample1.sampletests.test122.TestNotMuch) (0.000 ms)
+        test_3 (sample1.sampletests.test122.TestNotMuch) (0.000 ms)
+        test_x0 (sample1.sampletests.test122) (0.001 ms)
+        test_y0 (sample1.sampletests.test122) (0.001 ms)
+        test_z1 (sample1.sampletests.test122) (0.001 ms)
+        testrunner-ex/sample1/sampletests/../../sampletestsl.txt (0.001 ms)
+        test_x1 (sampletests.test122.TestA) (0.000 ms)
+        test_y0 (sampletests.test122.TestA) (0.000 ms)
+        test_z0 (sampletests.test122.TestA) (0.000 ms)
+        test_x0 (sampletests.test122.TestB) (0.000 ms)
+        test_y1 (sampletests.test122.TestB) (0.000 ms)
+        test_z0 (sampletests.test122.TestB) (0.000 ms)
+        test_1 (sampletests.test122.TestNotMuch) (0.000 ms)
+        test_2 (sampletests.test122.TestNotMuch) (0.000 ms)
+        test_3 (sampletests.test122.TestNotMuch) (0.000 ms)
+        test_x0 (sampletests.test122) (0.001 ms)
+        test_y0 (sampletests.test122) (0.001 ms)
+        test_z1 (sampletests.test122) (0.001 ms)
+        testrunner-ex/sampletests/../sampletestsl.txt (0.001 ms)
+      Ran 34 tests with 0 failures and 0 errors in 0.009 seconds.
+    Tearing down left over layers:
+      Tear down samplelayers.Layer122 in 0.000 seconds.
+      Tear down samplelayers.Layer12 in 0.000 seconds.
+      Tear down samplelayers.Layer1 in 0.000 seconds.
+    False
+
+Quiet output
+------------
+
+The --quiet (-q) option cancels all verbose options.  It's useful when
+the default verbosity is non-zero:
+
+    >>> defaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^sampletestsf?$',
+    ...     '-v'
+    ...     ]
+    >>> sys.argv = 'test -q -u'.split()
+    >>> testrunner.run(defaults)
+    Running unit tests:
+      Ran 192 tests with 0 failures and 0 errors in 0.034 seconds.
+    False


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-verbose.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-wo-source.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-wo-source.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-wo-source.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,93 @@
+Test Runner
+===========
+
+Running Without Source Code
+---------------------------
+
+The ``--usecompiled`` option allows running tests in a tree without .py
+source code, provided compiled .pyc or .pyo files exist (without
+``--usecompiled``, .py files are necessary).
+
+We have a very simple directory tree, under ``usecompiled/``, to test
+this.  Because we're going to delete its .py files, we want to work
+in a copy of that:
+
+    >>> import os.path, shutil, sys
+    >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+
+    >>> NEWNAME = "unlikely_package_name"
+    >>> src = os.path.join(directory_with_tests, 'usecompiled')
+    >>> os.path.isdir(src)
+    True
+    >>> dst = os.path.join(directory_with_tests, NEWNAME)
+    >>> os.path.isdir(dst)
+    False
+
+Have to use our own copying code, to avoid copying read-only SVN files that
+can't be deleted later.
+
+    >>> n = len(src) + 1
+    >>> for root, dirs, files in os.walk(src):
+    ...     dirs[:] = [d for d in dirs if d == "package"] # prune cruft
+    ...     os.mkdir(os.path.join(dst, root[n:]))
+    ...     for f in files:
+    ...         shutil.copy(os.path.join(root, f),
+    ...                     os.path.join(dst, root[n:], f))
+
+Now run the tests in the copy:
+
+
+    >>> from zope.testing import testrunner
+
+    >>> mydefaults = [
+    ...     '--path', directory_with_tests,
+    ...     '--tests-pattern', '^compiletest$',
+    ...     '--package', NEWNAME,
+    ...     '-vv',
+    ...     ]
+    >>> sys.argv = ['test']
+    >>> testrunner.run(mydefaults)
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        test1 (unlikely_package_name.compiletest.Test)
+        test2 (unlikely_package_name.compiletest.Test)
+        test1 (unlikely_package_name.package.compiletest.Test)
+        test2 (unlikely_package_name.package.compiletest.Test)
+      Ran 4 tests with 0 failures and 0 errors in N.NNN seconds.
+    False
+
+If we delete the source files, it's normally a disaster:  the test runner
+doesn't believe any test files, or even packages, exist.  Note that we pass
+``--keepbytecode`` this time, because otherwise the test runner would
+delete the compiled Python files too:
+
+    >>> for root, dirs, files in os.walk(dst):
+    ...    for f in files:
+    ...        if f.endswith(".py"):
+    ...            os.remove(os.path.join(root, f))
+    >>> testrunner.run(mydefaults, ["test", "--keepbytecode"])
+    Running tests at level 1
+    Total: 0 tests, 0 failures, 0 errors
+    False
+
+Finally, passing ``--usecompiled`` asks the test runner to treat .pyc
+and .pyo files as adequate replacements for .py files.  Note that the
+output is the same as when running with .py source above.  The absence
+of "removing stale bytecode ..." messages shows that ``--usecompiled``
+also implies ``--keepbytecode``:
+
+    >>> testrunner.run(mydefaults, ["test", "--usecompiled"])
+    Running tests at level 1
+    Running unit tests:
+      Running:
+        test1 (unlikely_package_name.compiletest.Test)
+        test2 (unlikely_package_name.compiletest.Test)
+        test1 (unlikely_package_name.package.compiletest.Test)
+        test2 (unlikely_package_name.package.compiletest.Test)
+      Ran 4 tests with 0 failures and 0 errors in N.NNN seconds.
+    False
+
+Remove the copy:
+
+    >>> shutil.rmtree(dst)


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner-wo-source.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,1898 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Test runner
+
+$Id: testrunner.py 41060 2006-01-01 18:41:00Z jim $
+"""
+
+# Too bad: For now, we depend on zope.testing.  This is because
+# we want to use the latest, greatest doctest, which zope.testing
+# provides.  Then again, zope.testing is generally useful.
+import gc
+import glob
+import logging
+import optparse
+import os
+import pdb
+import re
+import sys
+import tempfile
+import threading
+import time
+import trace
+import traceback
+import types
+import unittest
+
+# some Linux distributions don't include the profiler, which hotshot uses
+try:
+    import hotshot
+    import hotshot.stats
+except ImportError:
+    hotshot = None
+
+
+real_pdb_set_trace = pdb.set_trace
+
+class TestIgnore:
+
+    def __init__(self, options):
+        self._test_dirs = [d[0] + os.path.sep for d in test_dirs(options, {})]
+        self._ignore = {'<string>': 1}
+        self._ignored = self._ignore.get
+        
+    def names(self, filename, modulename):
+        ignore = self._ignored(modulename)
+        if ignore is None:
+            ignore = True
+            if filename is not None:
+                for d in self._test_dirs:
+                    if filename.startswith(d):
+                        ignore = False
+                        break
+            self._ignore[modulename] = ignore
+        return ignore
+
+class TestTrace(trace.Trace):
+    """Simple tracer.
+
+    >>> tracer = TestTrace(None, count=False, trace=False)
+
+    Simple rules for use: you can't stop the tracer if it not started
+    and you can't start the tracer if it already started:
+
+    >>> tracer.stop()
+    Traceback (most recent call last):
+        File 'testrunner.py'
+    AssertionError: can't stop if not started
+
+    >>> tracer.start()
+    >>> tracer.start()
+    Traceback (most recent call last):
+        File 'testrunner.py'
+    AssertionError: can't start if already started
+
+    >>> tracer.stop()
+    >>> tracer.stop()
+    Traceback (most recent call last):
+        File 'testrunner.py'
+    AssertionError: can't stop if not started
+    """
+
+    def __init__(self, options, **kw):
+        trace.Trace.__init__(self, **kw)
+        if options is not None:
+            self.ignore = TestIgnore(options)
+        self.started = False
+
+    def start(self):
+        assert not self.started, "can't start if already started"
+        if not self.donothing:
+            sys.settrace(self.globaltrace)
+            threading.settrace(self.globaltrace)
+        self.started = True
+
+    def stop(self):
+        assert self.started, "can't stop if not started"
+        if not self.donothing:
+            sys.settrace(None)
+            threading.settrace(None)
+        self.started = False
+
+class EndRun(Exception):
+    """Indicate that the existing run call should stop
+
+    Used to prevent additional test output after post-mortem debugging.
+    """
+
+def strip_py_ext(options, path):
+    """Return path without its .py (or .pyc or .pyo) extension, or None.
+
+    If options.usecompiled is false:
+        If path ends with ".py", the path without the extension is returned.
+        Else None is returned.
+
+    If options.usecompiled is true:
+        If Python is running with -O, a .pyo extension is also accepted.
+        If Python is running without -O, a .pyc extension is also accepted.
+    """
+    if path.endswith(".py"):
+        return path[:-3]
+    if options.usecompiled:
+        if __debug__:
+            # Python is running without -O.
+            ext = ".pyc"
+        else:
+            # Python is running with -O.
+            ext = ".pyo"
+        if path.endswith(ext):
+            return path[:-len(ext)]
+    return None
+
+def contains_init_py(options, fnamelist):
+    """Return true iff fnamelist contains a suitable spelling of __init__.py.
+
+    If options.usecompiled is false, this is so iff "__init__.py" is in
+    the list.
+
+    If options.usecompiled is true, then "__init__.pyo" is also acceptable
+    if Python is running with -O, and "__init__.pyc" is also acceptable if
+    Python is running without -O.
+    """
+    if "__init__.py" in fnamelist:
+        return True
+    if options.usecompiled:
+        if __debug__:
+            # Python is running without -O.
+            return "__init__.pyc" in fnamelist
+        else:
+            # Python is running with -O.
+            return "__init__.pyo" in fnamelist
+    return False
+
+def run(defaults=None, args=None):
+    if args is None:
+        args = sys.argv
+
+    # Set the default logging policy.
+    # XXX There are no tests for this logging behavior.
+    # It's not at all clear that the test runner should be doing this.
+    configure_logging()
+
+    # Control reporting flags during run
+    old_reporting_flags = doctest.set_unittest_reportflags(0)
+
+    # Check to see if we are being run as a subprocess. If we are,
+    # then use the resume-layer and defaults passed in.
+    if len(args) > 1 and args[1] == '--resume-layer':
+        args.pop(1)
+        resume_layer = args.pop(1)
+        defaults = []
+        while len(args) > 1 and args[1] == '--default':
+            args.pop(1)
+            defaults.append(args.pop(1))
+
+        sys.stdin = FakeInputContinueGenerator()
+    else:
+        resume_layer = None
+
+    options = get_options(args, defaults)
+    if options.fail:
+        return True
+
+    options.testrunner_defaults = defaults
+    options.resume_layer = resume_layer
+
+    # Make sure we start with real pdb.set_trace.  This is needed
+    # to make tests of the test runner work properly. :)
+    pdb.set_trace = real_pdb_set_trace
+
+    if hotshot is None and options.profile:
+        print ('The Python you\'re using doesn\'t seem to have the profiler '
+               'so you can\'t use the --profile switch.')
+        sys.exit()
+
+    if (options.profile
+        and sys.version_info[:3] <= (2,4,1)
+        and __debug__):
+        print ('Because of a bug in Python < 2.4.1, profiling '
+               'during tests requires the -O option be passed to '
+               'Python (not the test runner).')
+        sys.exit()
+
+    if options.coverage:
+        tracer = TestTrace(options, trace=False, count=True)
+        tracer.start()
+    else:
+        tracer = None
+
+    if options.profile:
+        prof_prefix = 'tests_profile.'
+        prof_suffix = '.prof'
+        prof_glob = prof_prefix + '*' + prof_suffix
+
+        # if we are going to be profiling, and this isn't a subprocess,
+        # clean up any stale results files
+        if not options.resume_layer:
+            for file_name in glob.glob(prof_glob):
+                os.unlink(file_name)
+
+        # set up the output file
+        oshandle, file_path = tempfile.mkstemp(prof_suffix, prof_prefix, '.')
+        prof = hotshot.Profile(file_path)
+        prof.start()
+
+    try:
+        try:
+            failed = run_with_options(options)
+        except EndRun:
+            failed = True
+    finally:
+        if tracer:
+            tracer.stop()
+        if options.profile:
+            prof.stop()
+            prof.close()
+            # We must explicitly close the handle mkstemp returned, else on
+            # Windows this dies the next time around just above due to an
+            # attempt to unlink a still-open file.
+            os.close(oshandle)
+
+    if options.profile and not options.resume_layer:
+        stats = None
+        for file_name in glob.glob(prof_glob):
+            loaded = hotshot.stats.load(file_name)
+            if stats is None:
+                stats = loaded
+            else:
+                stats.add(loaded)
+
+        stats.sort_stats('cumulative', 'calls')
+        stats.print_stats(50)
+
+    if tracer:
+        coverdir = os.path.join(os.getcwd(), options.coverage)
+        r = tracer.results()
+        r.write_results(summary=True, coverdir=coverdir)
+
+    doctest.set_unittest_reportflags(old_reporting_flags)
+
+    return failed
+
+def run_with_options(options):
+
+    if options.resume_layer:
+        original_stderr = sys.stderr
+        sys.stderr = sys.stdout
+    elif options.verbose:
+        if options.all:
+            print "Running tests at all levels"
+        else:
+            print "Running tests at level %d" % options.at_level
+
+
+    old_threshold = gc.get_threshold()
+    if options.gc:
+        if len(options.gc) > 3:
+            print "Too many --gc options"
+            sys.exit(1)
+        if options.gc[0]:
+            print ("Cyclic garbage collection threshold set to: %s" %
+                   `tuple(options.gc)`)
+        else:
+            print "Cyclic garbage collection is disabled."
+
+        gc.set_threshold(*options.gc)
+
+    old_flags = gc.get_debug()
+    if options.gc_option:
+        new_flags = 0
+        for op in options.gc_option:
+            new_flags |= getattr(gc, op)
+        gc.set_debug(new_flags)
+
+    old_reporting_flags = doctest.set_unittest_reportflags(0)
+    reporting_flags = 0
+    if options.ndiff:
+        reporting_flags = doctest.REPORT_NDIFF
+    if options.udiff:
+        if reporting_flags:
+            print "Can only give one of --ndiff, --udiff, or --cdiff"
+            sys.exit(1)
+        reporting_flags = doctest.REPORT_UDIFF
+    if options.cdiff:
+        if reporting_flags:
+            print "Can only give one of --ndiff, --udiff, or --cdiff"
+            sys.exit(1)
+        reporting_flags = doctest.REPORT_CDIFF
+    if options.report_only_first_failure:
+        reporting_flags |= doctest.REPORT_ONLY_FIRST_FAILURE
+
+    if reporting_flags:
+        doctest.set_unittest_reportflags(reporting_flags)
+    else:
+        doctest.set_unittest_reportflags(old_reporting_flags)
+
+
+    # Add directories to the path
+    for path in options.path:
+        if path not in sys.path:
+            sys.path.append(path)
+
+    remove_stale_bytecode(options)
+
+    tests_by_layer_name = find_tests(options)
+
+    ran = 0
+    failures = []
+    errors = []
+    nlayers = 0
+    import_errors = tests_by_layer_name.pop(None, None)
+
+    if import_errors:
+        print "Test-module import failures:"
+        for error in import_errors:
+            print_traceback("Module: %s\n" % error.module, error.exc_info),
+        print
+
+
+    if 'unit' in tests_by_layer_name:
+        tests = tests_by_layer_name.pop('unit')
+        if (not options.non_unit) and not options.resume_layer:
+            if options.layer:
+                should_run = False
+                for pat in options.layer:
+                    if pat('unit'):
+                        should_run = True
+                        break
+            else:
+                should_run = True
+
+            if should_run:
+                print "Running unit tests:"
+                nlayers += 1
+                ran += run_tests(options, tests, 'unit', failures, errors)
+
+    if options.resume_layer:
+        resume = False
+    else:
+        resume = True
+
+    setup_layers = {}
+    for layer_name, layer, tests in ordered_layers(tests_by_layer_name):
+        if options.layer:
+            should_run = False
+            for pat in options.layer:
+                if pat(layer_name):
+                    should_run = True
+                    break
+        else:
+            should_run = True
+
+        if should_run:
+            if (not resume) and (layer_name == options.resume_layer):
+                resume = True
+            if not resume:
+                continue
+            nlayers += 1
+            try:
+                ran += run_layer(options, layer_name, layer, tests,
+                                 setup_layers, failures, errors)
+            except CanNotTearDown:
+                setup_layers = None
+                ran += resume_tests(options, layer_name, failures, errors)
+                break
+
+    if setup_layers:
+        print "Tearing down left over layers:"
+        tear_down_unneeded((), setup_layers, True)
+
+    if options.resume_layer:
+        sys.stdout.close()
+        print >> original_stderr, ran, len(failures), len(errors)
+        for test, exc_info in failures:
+            print >> original_stderr, ' '.join(str(test).strip().split('\n'))
+        for test, exc_info in errors:
+            print >> original_stderr, ' '.join(str(test).strip().split('\n'))
+
+    else:
+        if options.verbose > 1:
+            if errors:
+                print
+                print "Tests with errors:"
+                for test, exc_info in errors:
+                    print "  ", test
+
+            if failures:
+                print
+                print "Tests with failures:"
+                for test, exc_info in failures:
+                    print "  ", test
+
+        if nlayers != 1:
+            print "Total: %s tests, %s failures, %s errors" % (
+                ran, len(failures), len(errors))
+
+        if import_errors:
+            print
+            print "Test-modules with import problems:"
+            for test in import_errors:
+                print "  " + test.module
+
+    doctest.set_unittest_reportflags(old_reporting_flags)
+
+    if options.gc_option:
+        gc.set_debug(old_flags)
+
+    if options.gc:
+        gc.set_threshold(*old_threshold)
+
+    return bool(import_errors or failures or errors)
+
+def run_tests(options, tests, name, failures, errors):
+    repeat = options.repeat or 1
+    repeat_range = iter(range(repeat))
+    ran = 0
+
+    gc.collect()
+    lgarbage = len(gc.garbage)
+
+    sumrc = 0
+    if options.report_refcounts:
+        if options.verbose:
+            track = TrackRefs()
+        rc = sys.gettotalrefcount()
+
+    for i in repeat_range:
+        if repeat > 1:
+            print "Iteration", i+1
+
+        if options.verbose > 0 or options.progress:
+            print '  Running:'
+        if options.verbose == 1 and not options.progress:
+            print '    ',
+        result = TestResult(options, tests)
+
+        t = time.time()
+
+        if options.post_mortem:
+            # post-mortem debugging
+            for test in tests:
+                if result.shouldStop:
+                    break
+                result.startTest(test)
+                state = test.__dict__.copy()
+                try:
+                    try:
+                        test.debug()
+                    except:
+                        result.addError(
+                            test,
+                            sys.exc_info()[:2] + (sys.exc_info()[2].tb_next, ),
+                            )
+                    else:
+                        result.addSuccess(test)
+                finally:
+                    result.stopTest(test)
+                test.__dict__.clear()
+                test.__dict__.update(state)
+
+        else:
+            # normal
+            for test in tests:
+                if result.shouldStop:
+                    break
+                state = test.__dict__.copy()
+                test(result)
+                test.__dict__.clear()
+                test.__dict__.update(state)
+ 
+        t = time.time() - t
+        if options.verbose == 1 or options.progress:
+            result.stopTests()
+            print
+        failures.extend(result.failures)
+        errors.extend(result.errors)
+        print (
+            "  Ran %s tests with %s failures and %s errors in %.3f seconds." %
+            (result.testsRun, len(result.failures), len(result.errors), t)
+            )
+        ran = result.testsRun
+
+        gc.collect()
+        if len(gc.garbage) > lgarbage:
+            print ("Tests generated new (%d) garbage:"
+                   % (len(gc.garbage)-lgarbage))
+            print gc.garbage[lgarbage:]
+            lgarbage = len(gc.garbage)
+
+        if options.report_refcounts:
+
+            # If we are being tested, we don't want stdout itself to
+            # foul up the numbers. :)
+            try:
+                sys.stdout.getvalue()
+            except AttributeError:
+                pass
+
+            prev = rc
+            rc = sys.gettotalrefcount()
+            if options.verbose:
+                track.update()
+                if i:
+                    print (" "
+                           " sum detail refcount=%-8d"
+                           " sys refcount=%-8d"
+                           " change=%-6d"
+                           % (track.n, rc, rc - prev))
+                    if options.verbose:
+                        track.output()
+                else:
+                    track.delta = None
+            elif i:
+                print "  sys refcount=%-8d change=%-6d" % (rc, rc - prev)
+
+    return ran
+
+def run_layer(options, layer_name, layer, tests, setup_layers,
+              failures, errors):
+    print "Running %s tests:" % layer_name
+
+    gathered = []
+    gather_layers(layer, gathered)
+    needed = dict([(l, 1) for l in gathered])
+    tear_down_unneeded(needed, setup_layers)
+
+    setup_layer(layer, setup_layers)
+    return run_tests(options, tests, layer_name, failures, errors)
+
+def resume_tests(options, layer_name, failures, errors):
+    args = [sys.executable,
+            options.original_testrunner_args[0],
+            '--resume-layer', layer_name,
+            ]
+    for d in options.testrunner_defaults:
+        args.extend(['--default', d])
+
+    args.extend(options.original_testrunner_args[1:])
+
+    # this is because of a bug in Python (http://www.python.org/sf/900092)
+    if (hotshot is not None and options.profile
+    and sys.version_info[:3] <= (2,4,1)):
+        args.insert(1, '-O')
+
+    if sys.platform.startswith('win'):
+        args = args[0] + ' ' + ' '.join([
+            ('"' + a.replace('\\', '\\\\').replace('"', '\\"') + '"')
+            for a in args[1:]
+            ])
+
+    subin, subout, suberr = os.popen3(args)
+    for l in subout:
+        sys.stdout.write(l)
+
+    line = suberr.readline()
+    try:
+        ran, nfail, nerr = map(int, line.strip().split())
+    except:
+        raise SubprocessError(line+suberr.read())
+
+    while nfail > 0:
+        nfail -= 1
+        failures.append((suberr.readline().strip(), None))
+    while nerr > 0:
+        nerr -= 1
+        errors.append((suberr.readline().strip(), None))
+    return ran
+
+
+class SubprocessError(Exception):
+    """An error occurred when running a subprocess
+    """
+
+class CanNotTearDown(Exception):
+    "Couldn't tear down a test"
+
+def tear_down_unneeded(needed, setup_layers, optional=False):
+    # Tear down any layers not needed for these tests. The unneeded
+    # layers might interfere.
+    unneeded = [l for l in setup_layers if l not in needed]
+    unneeded = order_by_bases(unneeded)
+    unneeded.reverse()
+    for l in unneeded:
+        print "  Tear down %s" % name_from_layer(l),
+        t = time.time()
+        try:
+            l.tearDown()
+        except NotImplementedError:
+            print "... not supported"
+            if not optional:
+                raise CanNotTearDown(l)
+        else:
+            print "in %.3f seconds." % (time.time() - t)
+        del setup_layers[l]
+
+def setup_layer(layer, setup_layers):
+    if layer not in setup_layers:
+        for base in layer.__bases__:
+            setup_layer(base, setup_layers)
+        print "  Set up %s.%s" % (layer.__module__, layer.__name__),
+        t = time.time()
+        layer.setUp()
+        print "in %.3f seconds." % (time.time() - t)
+        setup_layers[layer] = 1
+
+def dependencies(bases, result):
+    for base in bases:
+        result[base] = 1
+        dependencies(base.__bases__, result)
+
+class TestResult(unittest.TestResult):
+
+    max_width = 80
+
+    def __init__(self, options, tests):
+        unittest.TestResult.__init__(self)
+        self.options = options
+        if options.progress:
+            count = 0
+            for test in tests:
+                count += test.countTestCases()
+            self.count = count
+        self.last_width = 0
+
+        if options.progress:
+            try:
+                # Note that doing this every time is more test friendly.
+                import curses
+            except ImportError:
+                # avoid repimporting a broken module in python 2.3
+                sys.modules['curses'] = None
+            else:
+                try:
+                    curses.setupterm()
+                except TypeError:
+                    pass
+                else:
+                    self.max_width = curses.tigetnum('cols')
+
+    def getShortDescription(self, test, room):
+        room -= 1
+        s = str(test)
+        if len(s) > room:
+            pos = s.find(" (")
+            if pos >= 0:
+                w = room - (pos + 5)
+                if w < 1:
+                    # first portion (test method name) is too long
+                    s = s[:room-3] + "..."
+                else:
+                    pre = s[:pos+2]
+                    post = s[-w:]
+                    s = "%s...%s" % (pre, post)
+            else:
+                w = room - 4
+                s = '... ' + s[-w:]
+
+        return ' ' + s[:room]
+
+    def startTest(self, test):
+        unittest.TestResult.startTest(self, test)
+        testsRun = self.testsRun - 1
+        count = test.countTestCases()
+        self.testsRun = testsRun + count
+        options = self.options
+        self.test_width = 0
+
+        if options.progress:
+            if self.last_width:
+                sys.stdout.write('\r' + (' ' * self.last_width) + '\r')
+
+            s = "    %d/%d (%.1f%%)" % (
+                self.testsRun, self.count,
+                (self.testsRun) * 100.0 / self.count
+                )
+            sys.stdout.write(s)
+            self.test_width += len(s)
+            if options.verbose == 1:
+                room = self.max_width - self.test_width - 1
+                s = self.getShortDescription(test, room)
+                sys.stdout.write(s)
+                self.test_width += len(s)
+
+        elif options.verbose == 1:
+            for i in range(count):
+                sys.stdout.write('.')
+                testsRun += 1
+                if (testsRun % 50) == 0:
+                    print
+                    print '    ',
+        elif options.verbose > 1:
+            print '   ',
+
+        if options.verbose > 1:
+            s = str(test)
+            sys.stdout.write(' ')
+            sys.stdout.write(s)
+            self.test_width += len(s) + 1
+
+        sys.stdout.flush()
+
+        self._threads = threading.enumerate()
+        self._start_time = time.time()
+
+    def addSuccess(self, test):
+        if self.options.verbose > 2:
+            t = max(time.time() - self._start_time, 0.0)
+            s = " (%.3f ms)" % t
+            sys.stdout.write(s)
+            self.test_width += len(s) + 1
+
+    def addError(self, test, exc_info):
+        if self.options.verbose > 2:
+            print " (%.3f ms)" % (time.time() - self._start_time)
+
+        unittest.TestResult.addError(self, test, exc_info)
+        print
+        self._print_traceback("Error in test %s" % test, exc_info)
+
+        if self.options.post_mortem:
+            if self.options.resume_layer:
+                print
+                print '*'*70
+                print ("Can't post-mortem debug when running a layer"
+                       " as a subprocess!")
+                print '*'*70
+                print
+            else:
+                post_mortem(exc_info)
+
+        self.test_width = self.last_width = 0
+
+    def addFailure(self, test, exc_info):
+
+
+        if self.options.verbose > 2:
+            print " (%.3f ms)" % (time.time() - self._start_time)
+
+        unittest.TestResult.addFailure(self, test, exc_info)
+        print
+        self._print_traceback("Failure in test %s" % test, exc_info)
+
+        if self.options.post_mortem:
+            post_mortem(exc_info)
+
+        self.test_width = self.last_width = 0
+
+
+    def stopTests(self):
+        if self.options.progress and self.last_width:
+            sys.stdout.write('\r' + (' ' * self.last_width) + '\r')
+
+    def stopTest(self, test):
+        if self.options.progress:
+            self.last_width = self.test_width
+        elif self.options.verbose > 1:
+            print
+
+        if gc.garbage:
+            print "The following test left garbage:"
+            print test
+            print gc.garbage
+            # TODO: Perhaps eat the garbage here, so that the garbage isn't
+            #       printed for every subsequent test.
+
+        # Did the test leave any new threads behind?
+        new_threads = [t for t in threading.enumerate()
+                         if (t.isAlive()
+                             and
+                             t not in self._threads)]
+        if new_threads:
+            print "The following test left new threads behind:"
+            print test
+            print "New thread(s):", new_threads
+
+        sys.stdout.flush()
+
+
+    def _print_traceback(self, msg, exc_info):
+        print_traceback(msg, exc_info)
+
+doctest_template = """
+File "%s", line %s, in %s
+
+%s
+Want:
+%s
+Got:
+%s
+"""
+
+class FakeInputContinueGenerator:
+
+    def readline(self):
+        print  'c\n'
+        print '*'*70
+        print ("Can't use pdb.set_trace when running a layer"
+               " as a subprocess!")
+        print '*'*70
+        print
+        return 'c\n'
+
+
+def print_traceback(msg, exc_info):
+    print
+    print msg
+
+    v = exc_info[1]
+    if isinstance(v, doctest.DocTestFailureException):
+        tb = v.args[0]
+    elif isinstance(v, doctest.DocTestFailure):
+        tb = doctest_template % (
+            v.test.filename,
+            v.test.lineno + v.example.lineno + 1,
+            v.test.name,
+            v.example.source,
+            v.example.want,
+            v.got,
+            )
+    else:
+        tb = "".join(traceback.format_exception(*exc_info))
+
+    print tb
+
+def post_mortem(exc_info):
+    err = exc_info[1]
+    if isinstance(err, (doctest.UnexpectedException, doctest.DocTestFailure)):
+
+        if isinstance(err, doctest.UnexpectedException):
+            exc_info = err.exc_info
+
+            # Print out location info if the error was in a doctest
+            if exc_info[2].tb_frame.f_code.co_filename == '<string>':
+                print_doctest_location(err)
+
+        else:
+            print_doctest_location(err)
+            # Hm, we have a DocTestFailure exception.  We need to
+            # generate our own traceback
+            try:
+                exec ('raise ValueError'
+                      '("Expected and actual output are different")'
+                      ) in err.test.globs
+            except:
+                exc_info = sys.exc_info()
+
+    print "%s:" % (exc_info[0], )
+    print exc_info[1]
+    pdb.post_mortem(exc_info[2])
+    raise EndRun
+
+def print_doctest_location(err):
+    # This mimicks pdb's output, which gives way cool results in emacs :)
+    filename = err.test.filename
+    if filename.endswith('.pyc'):
+        filename = filename[:-1]
+    print "> %s(%s)_()" % (filename, err.test.lineno+err.example.lineno+1)
+
+def ordered_layers(tests_by_layer_name):
+    layer_names = dict([(layer_from_name(layer_name), layer_name)
+                        for layer_name in tests_by_layer_name])
+    for layer in order_by_bases(layer_names):
+        layer_name = layer_names[layer]
+        yield layer_name, layer, tests_by_layer_name[layer_name]
+
+def gather_layers(layer, result):
+    result.append(layer)
+    for b in layer.__bases__:
+        gather_layers(b, result)
+
+def layer_from_name(layer_name):
+    layer_names = layer_name.split('.')
+    layer_module, module_layer_name = layer_names[:-1], layer_names[-1]
+    return getattr(import_name('.'.join(layer_module)), module_layer_name)
+
+def order_by_bases(layers):
+    """Order the layers from least to most specific (bottom to top)
+    """
+    named_layers = [(name_from_layer(layer), layer) for layer in layers]
+    named_layers.sort()
+    named_layers.reverse()
+    gathered = []
+    for name, layer in named_layers:
+        gather_layers(layer, gathered)
+    gathered.reverse()
+    seen = {}
+    result = []
+    for layer in gathered:
+        if layer not in seen:
+            seen[layer] = 1
+            if layer in layers:
+                result.append(layer)
+    return result
+
+def name_from_layer(layer):
+    return layer.__module__ + '.' + layer.__name__
+
+def find_tests(options):
+    suites = {}
+    for suite in find_suites(options):
+        for test, layer_name in tests_from_suite(suite, options):
+            suite = suites.get(layer_name)
+            if not suite:
+                suite = suites[layer_name] = unittest.TestSuite()
+            suite.addTest(test)
+    return suites
+
+def tests_from_suite(suite, options, dlevel=1, dlayer='unit'):
+    level = getattr(suite, 'level', dlevel)
+    layer = getattr(suite, 'layer', dlayer)
+    if not isinstance(layer, basestring):
+        layer = layer.__module__ + '.' + layer.__name__
+
+    if isinstance(suite, unittest.TestSuite):
+        for possible_suite in suite:
+            for r in tests_from_suite(possible_suite, options, level, layer):
+                yield r
+    elif isinstance(suite, StartUpFailure):
+        yield (suite, None)
+    else:
+        if level <= options.at_level:
+            for pat in options.test:
+                if pat(str(suite)):
+                    yield (suite, layer)
+                    break
+
+
+def find_suites(options):
+    for fpath, package in find_test_files(options):
+        for (prefix, prefix_package) in options.prefix:
+            if fpath.startswith(prefix) and package == prefix_package:
+                # strip prefix, strip .py suffix and convert separator to dots
+                noprefix = fpath[len(prefix):]
+                noext = strip_py_ext(options, noprefix)
+                assert noext is not None
+                module_name = noext.replace(os.path.sep, '.')
+                if package:
+                    module_name = package + '.' + module_name
+
+                for filter in options.module:
+                    if filter(module_name):
+                        break
+                else:
+                    continue
+
+                try:
+                    module = import_name(module_name)
+                except:
+                    suite = StartUpFailure(
+                        options, module_name,
+                        sys.exc_info()[:2]
+                        + (sys.exc_info()[2].tb_next.tb_next,),
+                        )
+                else:
+                    try:
+                        suite = getattr(module, options.suite_name)()
+                        if isinstance(suite, unittest.TestSuite):
+                            check_suite(suite, module_name)
+                        else:
+                            raise TypeError(
+                                "Invalid test_suite, %r, in %s"
+                                % (suite, module_name)
+                                )
+                    except:
+                        suite = StartUpFailure(
+                            options, module_name, sys.exc_info()[:2]+(None,))
+
+
+                yield suite
+                break
+
+def check_suite(suite, module_name):
+    for x in suite:
+        if isinstance(x, unittest.TestSuite):
+            check_suite(x, module_name)
+        elif not isinstance(x, unittest.TestCase):
+            raise TypeError(
+                "Invalid test, %r,\nin test_suite from %s"
+                % (x, module_name)
+                )
+
+
+
+
+class StartUpFailure:
+
+    def __init__(self, options, module, exc_info):
+        if options.post_mortem:
+            post_mortem(exc_info)
+        self.module = module
+        self.exc_info = exc_info
+
+def find_test_files(options):
+    found = {}
+    for f, package in find_test_files_(options):
+        if f not in found:
+            found[f] = 1
+            yield f, package
+
+identifier = re.compile(r'[_a-zA-Z]\w*$').match
+def find_test_files_(options):
+    tests_pattern = options.tests_pattern
+    test_file_pattern = options.test_file_pattern
+
+    # If options.usecompiled, we can accept .pyc or .pyo files instead
+    # of .py files.  We'd rather use a .py file if one exists.  `root2ext`
+    # maps a test file path, sans extension, to the path with the best
+    # extension found (.py if it exists, else .pyc or .pyo).
+    # Note that "py" < "pyc" < "pyo", so if more than one extension is
+    # found, the lexicographically smaller one is best.
+
+    # Found a new test file, in directory `dirname`.  `noext` is the
+    # file name without an extension, and `withext` is the file name
+    # with its extension.
+    def update_root2ext(dirname, noext, withext):
+        key = os.path.join(dirname, noext)
+        new = os.path.join(dirname, withext)
+        if key in root2ext:
+            root2ext[key] = min(root2ext[key], new)
+        else:
+            root2ext[key] = new
+
+    for (p, package) in test_dirs(options, {}):
+        for dirname, dirs, files in walk_with_symlinks(options, p):
+            if dirname != p and not contains_init_py(options, files):
+                continue    # not a plausible test directory
+            root2ext = {}
+            dirs[:] = filter(identifier, dirs)
+            d = os.path.split(dirname)[1]
+            if tests_pattern(d) and contains_init_py(options, files):
+                # tests directory
+                for file in files:
+                    noext = strip_py_ext(options, file)
+                    if noext and test_file_pattern(noext):
+                        update_root2ext(dirname, noext, file)
+
+            for file in files:
+                noext = strip_py_ext(options, file)
+                if noext and tests_pattern(noext):
+                    update_root2ext(dirname, noext, file)
+
+            winners = root2ext.values()
+            winners.sort()
+            for file in winners:
+                yield file, package
+
+def walk_with_symlinks(options, dir):
+    # TODO -- really should have test of this that uses symlinks
+    #         this is hard on a number of levels ...
+    for dirpath, dirs, files in os.walk(dir):
+        dirs.sort()
+        files.sort()
+        dirs[:] = [d for d in dirs if d not in options.ignore_dir]
+        yield (dirpath, dirs, files)
+        for d in dirs:
+            p = os.path.join(dirpath, d)
+            if os.path.islink(p):
+                for sdirpath, sdirs, sfiles in walk_with_symlinks(options, p):
+                    yield (sdirpath, sdirs, sfiles)
+
+compiled_sufixes = '.pyc', '.pyo'
+def remove_stale_bytecode(options):
+    if options.keepbytecode:
+        return
+    for (p, _) in options.test_path:
+        for dirname, dirs, files in walk_with_symlinks(options, p):
+            for file in files:
+                if file[-4:] in compiled_sufixes and file[:-1] not in files:
+                    fullname = os.path.join(dirname, file)
+                    print "Removing stale bytecode file", fullname
+                    os.unlink(fullname)
+
+
+def test_dirs(options, seen):
+    if options.package:
+        for p in options.package:
+            p = import_name(p)
+            for p in p.__path__:
+                p = os.path.abspath(p)
+                if p in seen:
+                    continue
+                for (prefix, package) in options.prefix:
+                    if p.startswith(prefix) or p == prefix[:-1]:
+                        seen[p] = 1
+                        yield p, package
+                        break
+    else:
+        for dpath in options.test_path:
+            yield dpath
+
+
+def import_name(name):
+    __import__(name)
+    return sys.modules[name]
+
+def configure_logging():
+    """Initialize the logging module."""
+    import logging.config
+
+    # Get the log.ini file from the current directory instead of
+    # possibly buried in the build directory.  TODO: This isn't
+    # perfect because if log.ini specifies a log file, it'll be
+    # relative to the build directory.  Hmm...  logini =
+    # os.path.abspath("log.ini")
+
+    logini = os.path.abspath("log.ini")
+    if os.path.exists(logini):
+        logging.config.fileConfig(logini)
+    else:
+        # If there's no log.ini, cause the logging package to be
+        # silent during testing.
+        root = logging.getLogger()
+        root.addHandler(NullHandler())
+        logging.basicConfig()
+
+    if os.environ.has_key("LOGGING"):
+        level = int(os.environ["LOGGING"])
+        logging.getLogger().setLevel(level)
+
+class NullHandler(logging.Handler):
+    """Logging handler that drops everything on the floor.
+
+    We require silence in the test environment.  Hush.
+    """
+
+    def emit(self, record):
+        pass
+
+
+class TrackRefs(object):
+    """Object to track reference counts across test runs."""
+
+    def __init__(self):
+        self.type2count = {}
+        self.type2all = {}
+        self.delta = None
+        self.n = 0
+        self.update()
+        self.delta = None
+
+    def update(self):
+        gc.collect()
+        obs = sys.getobjects(0)
+        type2count = {}
+        type2all = {}
+        n = 0
+        for o in obs:
+            if type(o) is str and o == '<dummy key>':
+                # avoid dictionary madness
+                continue
+
+            all = sys.getrefcount(o) - 3
+            n += all
+
+            t = type(o)
+            if t is types.InstanceType:
+                t = o.__class__
+
+            if t in type2count:
+                type2count[t] += 1
+                type2all[t] += all
+            else:
+                type2count[t] = 1
+                type2all[t] = all
+
+
+        ct = [(
+               type_or_class_title(t),
+               type2count[t] - self.type2count.get(t, 0),
+               type2all[t] - self.type2all.get(t, 0),
+               )
+              for t in type2count.iterkeys()]
+        ct += [(
+                type_or_class_title(t),
+                - self.type2count[t],
+                - self.type2all[t],
+                )
+               for t in self.type2count.iterkeys()
+               if t not in type2count]
+        ct.sort()
+        self.delta = ct
+        self.type2count = type2count
+        self.type2all = type2all
+        self.n = n
+
+
+    def output(self):
+        printed = False
+        s1 = s2 = 0
+        for t, delta1, delta2 in self.delta:
+            if delta1 or delta2:
+                if not printed:
+                    print (
+                        '    Leak details, changes in instances and refcounts'
+                        ' by type/class:')
+                    print "    %-55s %6s %6s" % ('type/class', 'insts', 'refs')
+                    print "    %-55s %6s %6s" % ('-' * 55, '-----', '----')
+                    printed = True
+                print "    %-55s %6d %6d" % (t, delta1, delta2)
+                s1 += delta1
+                s2 += delta2
+
+        if printed:
+            print "    %-55s %6s %6s" % ('-' * 55, '-----', '----')
+            print "    %-55s %6s %6s" % ('total', s1, s2)
+
+
+        self.delta = None
+
+def type_or_class_title(t):
+    module = getattr(t, '__module__', '__builtin__')
+    if module == '__builtin__':
+        return t.__name__
+    return "%s.%s" % (module, t.__name__)
+
+
+###############################################################################
+# Command-line UI
+
+parser = optparse.OptionParser("Usage: %prog [options] [MODULE] [TEST]")
+
+######################################################################
+# Searching and filtering
+
+searching = optparse.OptionGroup(parser, "Searching and filtering", """\
+Options in this group are used to define which tests to run.
+""")
+
+searching.add_option(
+    '--package', '--dir', '-s', action="append", dest='package',
+    help="""\
+Search the given package's directories for tests.  This can be
+specified more than once to run tests in multiple parts of the source
+tree.  For example, if refactoring interfaces, you don't want to see
+the way you have broken setups for tests in other packages. You *just*
+want to run the interface tests.
+
+Packages are supplied as dotted names.  For compatibility with the old
+test runner, forward and backward slashed in package names are
+converted to dots.
+
+(In the special case of packages spread over multiple directories,
+only directories within the test search path are searched. See the
+--path option.)
+
+""")
+
+searching.add_option(
+    '--module', '-m', action="append", dest='module',
+    help="""\
+Specify a test-module filter as a regular expression.  This is a
+case-sensitive regular expression, used in search (not match) mode, to
+limit which test modules are searched for tests.  The regular
+expressions are checked against dotted module names.  In an extension
+of Python regexp notation, a leading "!" is stripped and causes the
+sense of the remaining regexp to be negated (so "!bc" matches any
+string that does not match "bc", and vice versa).  The option can be
+specified multiple test-module filters.  Test modules matching any of
+the test filters are searched.  If no test-module filter is specified,
+then all test moduless are used.
+""")
+
+searching.add_option(
+    '--test', '-t', action="append", dest='test',
+    help="""\
+Specify a test filter as a regular expression.  This is a
+case-sensitive regular expression, used in search (not match) mode, to
+limit which tests are run.  In an extension of Python regexp notation,
+a leading "!" is stripped and causes the sense of the remaining regexp
+to be negated (so "!bc" matches any string that does not match "bc",
+and vice versa).  The option can be specified multiple test filters.
+Tests matching any of the test filters are included.  If no test
+filter is specified, then all tests are run.
+""")
+
+searching.add_option(
+    '--unit', '-u', action="store_true", dest='unit',
+    help="""\
+Run only unit tests, ignoring any layer options.
+""")
+
+searching.add_option(
+    '--non-unit', '-f', action="store_true", dest='non_unit',
+    help="""\
+Run tests other than unit tests.
+""")
+
+searching.add_option(
+    '--layer', action="append", dest='layer',
+    help="""\
+Specify a test layer to run.  The option can be given multiple times
+to specify more than one layer.  If not specified, all layers are run.
+It is common for the running script to provide default values for this
+option.  Layers are specified regular expressions, used in search
+mode, for dotted names of objects that define a layer.  In an
+extension of Python regexp notation, a leading "!" is stripped and
+causes the sense of the remaining regexp to be negated (so "!bc"
+matches any string that does not match "bc", and vice versa).  The
+layer named 'unit' is reserved for unit tests, however, take note of
+the --unit and non-unit options.
+""")
+
+searching.add_option(
+    '-a', '--at-level', type='int', dest='at_level',
+    help="""\
+Run the tests at the given level.  Any test at a level at or below
+this is run, any test at a level above this is not run.  Level 0
+runs all tests.
+""")
+
+searching.add_option(
+    '--all', action="store_true", dest='all',
+    help="Run tests at all levels.")
+
+parser.add_option_group(searching)
+
+######################################################################
+# Reporting
+
+reporting = optparse.OptionGroup(parser, "Reporting", """\
+Reporting options control basic aspects of test-runner output
+""")
+
+reporting.add_option(
+    '--verbose', '-v', action="count", dest='verbose',
+    help="""\
+Make output more verbose.
+Increment the verbosity level.
+""")
+
+reporting.add_option(
+    '--quiet', '-q', action="store_true", dest='quiet',
+    help="""\
+Make the output minimal, overriding any verbosity options.
+""")
+
+reporting.add_option(
+    '--progress', '-p', action="store_true", dest='progress',
+    help="""\
+Output progress status
+""")
+
+reporting.add_option(
+    '-1', action="store_true", dest='report_only_first_failure',
+    help="""\
+Report only the first failure in a doctest. (Examples after the
+failure are still executed, in case they do any cleanup.)
+""")
+
+reporting.add_option(
+    '--ndiff', action="store_true", dest="ndiff",
+    help="""\
+When there is a doctest failure, show it as a diff using the ndiff.py utility.
+""")
+
+reporting.add_option(
+    '--udiff', action="store_true", dest="udiff",
+    help="""\
+When there is a doctest failure, show it as a unified diff.
+""")
+
+reporting.add_option(
+    '--cdiff', action="store_true", dest="cdiff",
+    help="""\
+When there is a doctest failure, show it as a context diff.
+""")
+
+parser.add_option_group(reporting)
+
+######################################################################
+# Analysis
+
+analysis = optparse.OptionGroup(parser, "Analysis", """\
+Analysis options provide tools for analysing test output.
+""")
+
+
+analysis.add_option(
+    '--post-mortem', '-D', action="store_true", dest='post_mortem',
+    help="Enable post-mortem debugging of test failures"
+    )
+
+
+analysis.add_option(
+    '--gc', '-g', action="append", dest='gc', type="int",
+    help="""\
+Set the garbage collector generation threshold.  This can be used
+to stress memory and gc correctness.  Some crashes are only
+reproducible when the threshold is set to 1 (agressive garbage
+collection).  Do "--gc 0" to disable garbage collection altogether.
+
+The --gc option can be used up to 3 times to specify up to 3 of the 3
+Python gc_threshold settings.
+
+""")
+
+analysis.add_option(
+    '--gc-option', '-G', action="append", dest='gc_option', type="choice",
+    choices=['DEBUG_STATS', 'DEBUG_COLLECTABLE', 'DEBUG_UNCOLLECTABLE',
+             'DEBUG_INSTANCES', 'DEBUG_OBJECTS', 'DEBUG_SAVEALL',
+             'DEBUG_LEAK'],
+    help="""\
+Set a Python gc-module debug flag.  This option can be used more than
+once to set multiple flags.
+""")
+
+analysis.add_option(
+    '--repeat', '-N', action="store", type="int", dest='repeat',
+    help="""\
+Repeat the testst the given number of times.  This option is used to
+make sure that tests leave thier environment in the state they found
+it and, with the --report-refcounts option to look for memory leaks.
+""")
+
+analysis.add_option(
+    '--report-refcounts', '-r', action="store_true", dest='report_refcounts',
+    help="""\
+After each run of the tests, output a report summarizing changes in
+refcounts by object type.  This option that requires that Python was
+built with the --with-pydebug option to configure.
+""")
+
+analysis.add_option(
+    '--coverage', action="store", type='string', dest='coverage',
+    help="""\
+Perform code-coverage analysis, saving trace data to the directory
+with the given name.  A code coverage summary is printed to standard
+out.
+""")
+
+analysis.add_option(
+    '--profile', action="store_true", dest='profile',
+    help="""\
+Run the tests under hotshot and display the top 50 stats, sorted by
+cumulative time and number of calls.
+""")
+
+def do_pychecker(*args):
+    if not os.environ.get("PYCHECKER"):
+        os.environ["PYCHECKER"] = "-q"
+    import pychecker.checker
+
+analysis.add_option(
+    '--pychecker', action="callback", callback=do_pychecker,
+    help="""\
+Run the tests under pychecker
+""")
+
+parser.add_option_group(analysis)
+
+######################################################################
+# Setup
+
+setup = optparse.OptionGroup(parser, "Setup", """\
+Setup options are normally supplied by the testrunner script, although
+they can be overridden by users.
+""")
+
+setup.add_option(
+    '--path', action="append", dest='path',
+    help="""\
+Specify a path to be added to Python's search path.  This option can
+be used multiple times to specify multiple search paths.  The path is
+usually specified by the test-runner script itself, rather than by
+users of the script, although it can be overridden by users.  Only
+tests found in the path will be run.
+
+This option also specifies directories to be searched for tests.
+See the search_directory.
+""")
+
+setup.add_option(
+    '--test-path', action="append", dest='test_path',
+    help="""\
+Specify a path to be searched for tests, but not added to the Python
+search path.  This option can be used multiple times to specify
+multiple search paths.  The path is usually specified by the
+test-runner script itself, rather than by users of the script,
+although it can be overridden by users.  Only tests found in the path
+will be run.
+""")
+
+setup.add_option(
+    '--package-path', action="append", dest='package_path', nargs=2,
+    help="""\
+Specify a path to be searched for tests, but not added to the Python
+search path.  Also specify a package for files found in this path.
+This is used to deal with directories that are stiched into packages
+that are not otherwise searched for tests.
+
+This option takes 2 arguments.  The first is a path name. The second is
+the package name.
+
+This option can be used multiple times to specify
+multiple search paths.  The path is usually specified by the
+test-runner script itself, rather than by users of the script,
+although it can be overridden by users.  Only tests found in the path
+will be run.
+""")
+
+setup.add_option(
+    '--tests-pattern', action="store", dest='tests_pattern',
+    help="""\
+The test runner looks for modules containing tests.  It uses this
+pattern to identify these modules.  The modules may be either packages
+or python files.
+
+If a test module is a package, it uses the value given by the
+test-file-pattern to identify python files within the package
+containing tests.
+""")
+
+setup.add_option(
+    '--suite-name', action="store", dest='suite_name',
+    help="""\
+Specify the name of the object in each test_module that contains the
+module's test suite.
+""")
+
+setup.add_option(
+    '--test-file-pattern', action="store", dest='test_file_pattern',
+    help="""\
+Specify a pattern for identifying python files within a tests package.
+See the documentation for the --tests-pattern option.
+""")
+
+setup.add_option(
+    '--ignore_dir', action="append", dest='ignore_dir',
+    help="""\
+Specifies the name of a directory to ignore when looking for tests.
+""")
+
+parser.add_option_group(setup)
+
+######################################################################
+# Other
+
+other = optparse.OptionGroup(parser, "Other", "Other options")
+
+other.add_option(
+    '--keepbytecode', '-k', action="store_true", dest='keepbytecode',
+    help="""\
+Normally, the test runner scans the test paths and the test
+directories looking for and deleting pyc or pyo files without
+corresponding py files.  This is to prevent spurious test failures due
+to finding compiled modules where source modules have been deleted.
+This scan can be time consuming.  Using this option disables this
+scan.  If you know you haven't removed any modules since last running
+the tests, can make the test run go much faster.
+""")
+
+other.add_option(
+    '--usecompiled', action="store_true", dest='usecompiled',
+    help="""\
+Normally, a package must contain an __init__.py file, and only .py files
+can contain test code.  When this option is specified, compiled Python
+files (.pyc and .pyo) can be used instead:  a directory containing
+__init__.pyc or __init__.pyo is also considered to be a package, and if
+file XYZ.py contains tests but is absent while XYZ.pyc or XYZ.pyo exists
+then the compiled files will be used.  This is necessary when running
+tests against a tree where the .py files have been removed after
+compilation to .pyc/.pyo.  Use of this option implies --keepbytecode.
+""")
+
+parser.add_option_group(other)
+
+######################################################################
+# Command-line processing
+
+def compile_filter(pattern):
+    if pattern.startswith('!'):
+        pattern = re.compile(pattern[1:]).search
+        return (lambda s: not pattern(s))
+    return re.compile(pattern).search
+
+def merge_options(options, defaults):
+    odict = options.__dict__
+    for name, value in defaults.__dict__.items():
+        if (value is not None) and (odict[name] is None):
+            odict[name] = value
+
+default_setup_args = [
+    '--tests-pattern', '^tests$',
+    '--at-level', 1,
+    '--ignore', '.svn',
+    '--ignore', 'CVS',
+    '--ignore', '{arch}',
+    '--ignore', '.arch-ids',
+    '--ignore', '_darcs',
+    '--test-file-pattern', '^test',
+    '--suite-name', 'test_suite',
+    ]
+
+def get_options(args=None, defaults=None):
+
+    default_setup, _ = parser.parse_args(default_setup_args)
+    assert not _
+    if defaults:
+        defaults, _ = parser.parse_args(defaults)
+        assert not _
+        merge_options(defaults, default_setup)
+    else:
+        defaults = default_setup
+
+    if args is None:
+        args = sys.argv
+    original_testrunner_args = args
+    args = args[1:]
+    options, positional = parser.parse_args(args)
+    merge_options(options, defaults)
+    options.original_testrunner_args = original_testrunner_args
+
+    options.fail = False
+
+    if positional:
+        module_filter = positional.pop(0)
+        if module_filter != '.':
+            if options.module:
+                options.module.append(module_filter)
+            else:
+                options.module = [module_filter]
+
+        if positional:
+            test_filter = positional.pop(0)
+            if options.test:
+                options.test.append(test_filter)
+            else:
+                options.test = [test_filter]
+
+            if positional:
+                parser.error("Too mant positional arguments")
+
+    options.ignore_dir = dict([(d,1) for d in options.ignore_dir])
+    options.test_file_pattern = re.compile(options.test_file_pattern).search
+    options.tests_pattern = re.compile(options.tests_pattern).search
+    options.test = map(compile_filter, options.test or ('.'))
+    options.module = map(compile_filter, options.module or ('.'))
+
+    if options.package:
+        options.package = [p.replace('/', '.').replace('\\', '.')
+                           for p in options.package]
+    options.path = map(os.path.abspath, options.path or ())
+    options.test_path = map(os.path.abspath, options.test_path or ())
+    options.test_path += options.path
+
+    options.test_path = ([(path, '') for path in options.test_path]
+                         +
+                         [(os.path.abspath(path), package)
+                          for (path, package) in options.package_path or ()
+                          ])
+
+
+    options.prefix = [(path + os.path.sep, package)
+                      for (path, package) in options.test_path]
+    if options.all:
+        options.at_level = sys.maxint
+
+    if options.unit:
+        options.layer = ['unit']
+    if options.layer:
+        options.layer = map(compile_filter, options.layer)
+
+    options.layer = options.layer and dict([(l, 1) for l in options.layer])
+
+    if options.usecompiled:
+        options.keepbytecode = options.usecompiled
+
+    if options.quiet:
+        options.verbose = 0
+
+    if options.report_refcounts and options.repeat < 2:
+        print """\
+        You must use the --repeat (-N) option to specify a repeat
+        count greater than 1 when using the --report_refcounts (-r)
+        option.
+        """
+        options.fail = True
+        return options
+
+
+    if options.report_refcounts and not hasattr(sys, "gettotalrefcount"):
+        print """\
+        The Python you are running was not configured
+        with --with-pydebug. This is required to use
+        the --report-refcounts option.
+        """
+        options.fail = True
+        return options
+
+    return options
+
+# Command-line UI
+###############################################################################
+
+###############################################################################
+# Install 2.4 TestSuite __iter__ into earlier versions
+
+if sys.version_info < (2, 4):
+    def __iter__(suite):
+        return iter(suite._tests)
+    unittest.TestSuite.__iter__ = __iter__
+    del __iter__
+
+# Install 2.4 TestSuite __iter__ into earlier versions
+###############################################################################
+
+###############################################################################
+# Test the testrunner
+
+def test_suite():
+
+    import renormalizing
+    checker = renormalizing.RENormalizing([
+        (re.compile('^> [^\n]+->None$', re.M), '> ...->None'),
+        (re.compile('\\\\'), '/'),   # hopefully, we'll make windows happy
+        (re.compile('/r'), '\\\\r'), # undo damage from previous
+        (re.compile(r'\r'), '\\\\r\n'),
+        (re.compile(r'\d+[.]\d\d\d seconds'), 'N.NNN seconds'),
+        (re.compile(r'\d+[.]\d\d\d ms'), 'N.NNN ms'),
+        (re.compile('( |")[^\n]+testrunner-ex'), r'\1testrunner-ex'),
+        (re.compile('( |")[^\n]+testrunner.py'), r'\1testrunner.py'),
+        (re.compile(r'> [^\n]*(doc|unit)test[.]py\(\d+\)'),
+                       r'\1doctest.py(NNN)'),
+        (re.compile(r'[.]py\(\d+\)'), r'.py(NNN)'),
+        (re.compile(r'[.]py:\d+'), r'.py:NNN'),
+        (re.compile(r' line \d+,', re.IGNORECASE), r' Line NNN,'),
+
+        # omit traceback entries for unittest.py or doctest.py from
+        # output:
+        (re.compile(r'^ +File "[^\n]+(doc|unit)test.py", [^\n]+\n[^\n]+\n',
+                    re.MULTILINE),
+         r''),
+        (re.compile('^> [^\n]+->None$', re.M), '> ...->None'),
+        (re.compile('import pdb; pdb'), 'Pdb()'), # Py 2.3
+
+        ])
+
+    def setUp(test):
+        test.globs['saved-sys-info'] = (
+            sys.path[:],
+            sys.argv[:],
+            sys.modules.copy(),
+            gc.get_threshold(),
+            )
+        test.globs['this_directory'] = os.path.split(__file__)[0]
+        test.globs['testrunner_script'] = __file__
+
+    def tearDown(test):
+        sys.path[:], sys.argv[:] = test.globs['saved-sys-info'][:2]
+        gc.set_threshold(*test.globs['saved-sys-info'][3])
+        sys.modules.clear()
+        sys.modules.update(test.globs['saved-sys-info'][2])
+
+    suites = [
+        doctest.DocFileSuite(
+        'testrunner-arguments.txt',
+        'testrunner-coverage.txt',
+        'testrunner-debugging.txt',
+        'testrunner-edge-cases.txt',
+        'testrunner-errors.txt',
+        'testrunner-layers-ntd.txt',
+        'testrunner-layers.txt',
+        'testrunner-progress.txt',
+        'testrunner-simple.txt',
+        'testrunner-test-selection.txt',
+        'testrunner-verbose.txt',
+        'testrunner-wo-source.txt',
+        'testrunner-repeat.txt',
+        'testrunner-gc.txt',
+        'testrunner-knit.txt',
+        setUp=setUp, tearDown=tearDown,
+        optionflags=doctest.ELLIPSIS+doctest.NORMALIZE_WHITESPACE,
+        checker=checker),
+        doctest.DocTestSuite()
+        ]
+
+    # Python <= 2.4.1 had a bug that prevented hotshot from runnint in
+    # non-optimize mode
+    if sys.version_info[:3] > (2,4,1) or not __debug__:
+        # some Linux distributions don't include the profiling module (which
+        # hotshot.stats depends on)
+        try:
+            import hotshot.stats
+        except ImportError:
+            pass
+        else:
+            suites.append(
+                doctest.DocFileSuite(
+                    'testrunner-profiling.txt',
+                    setUp=setUp, tearDown=tearDown,
+                    optionflags=doctest.ELLIPSIS+doctest.NORMALIZE_WHITESPACE,
+                    checker = renormalizing.RENormalizing([
+                        (re.compile('tests_profile[.]\S*[.]prof'),
+                         'tests_profile.*.prof'),
+                        ]),
+                    )
+                )
+
+    if hasattr(sys, 'gettotalrefcount'):
+        suites.append(
+            doctest.DocFileSuite(
+            'testrunner-leaks.txt',
+            setUp=setUp, tearDown=tearDown,
+            optionflags=doctest.ELLIPSIS+doctest.NORMALIZE_WHITESPACE,
+            checker = renormalizing.RENormalizing([
+              (re.compile(r'\d+[.]\d\d\d seconds'), 'N.NNN seconds'),
+              (re.compile(r'sys refcount=\d+ +change=\d+'),
+               'sys refcount=NNNNNN change=NN'),
+              (re.compile(r'sum detail refcount=\d+ +'),
+               'sum detail refcount=NNNNNN '),
+              (re.compile(r'total +\d+ +\d+'),
+               'total               NNNN    NNNN'),
+              (re.compile(r"^ +(int|type) +-?\d+ +-?\d+ *\n", re.M),
+               ''),
+              ]),
+
+            )
+        )
+    else:
+        suites.append(
+            doctest.DocFileSuite(
+            'testrunner-leaks-err.txt',
+            setUp=setUp, tearDown=tearDown,
+            optionflags=doctest.ELLIPSIS+doctest.NORMALIZE_WHITESPACE,
+            checker=checker,
+            )
+        )
+
+
+    return unittest.TestSuite(suites)
+
+def main():
+    default = [
+        '--path', os.path.split(sys.argv[0])[0],
+        '--tests-pattern', '^testrunner$',
+        ]
+    run(default)
+
+if __name__ == '__main__':
+
+    # if --resume_layer is in the arguments, we are being run from the
+    # test runner's own tests.  We need to adjust the path in hopes of
+    # not getting a different version installed in the system python.
+    if len(sys.argv) > 1 and sys.argv[1] == '--resume-layer':
+        sys.path.insert(0,
+            os.path.split(
+                os.path.split(
+                    os.path.split(
+                        os.path.abspath(sys.argv[0])
+                        )[0]
+                    )[0]
+                )[0]
+            )
+
+    # Hm, when run as a script, we need to import the testrunner under
+    # its own name, so that there's the imported flavor has the right
+    # real_pdb_set_trace.
+    import zope.testing.testrunner
+    from zope.testing import doctest
+
+    main()
+
+# Test the testrunner
+###############################################################################
+
+# Delay import to give main an opportunity to fix up the path if
+# necessary
+from zope.testing import doctest


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/testrunner.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/testrunner.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,89 @@
+Test Runner
+===========
+
+The testrunner module is used to run automated tests defined using the
+unittest framework.  Its primary feature is that it *finds* tests by
+searching directory trees.  It doesn't require the manual
+concatenation of specific test suites.  It is highly customizable and
+should be usable with any project.  In addition to finding and running
+tests, it provides the following additional features:
+
+- Test filtering using specifications of:
+
+  o test packages within a larger tree
+
+  o regular expression patterns for test modules
+
+  o regular expression patterns for individual tests
+
+- Organization of tests into levels and layers
+
+  Sometimes, tests take so long to run that you don't want to run them
+  on every run of the test runner.  Tests can be defined at different
+  levels.  The test runner can be configured to only run tests at a
+  specific level or below by default.  Command-line options can be
+  used to specify a minimum level to use for a specific run, or to run
+  all tests.  Individual tests or test suites can specify their level
+  via a 'level' attribute. where levels are integers increasing from 1.
+
+  Most tests are unit tests.  They don't depend on other facilities, or
+  set up whatever dependencies they have.  For larger applications,
+  it's useful to specify common facilities that a large number of
+  tests share.  Making each test set up and and tear down these
+  facilities is both ineffecient and inconvenient.  For this reason,
+  we've introduced the concept of layers, based on the idea of layered
+  application architectures.  Software build for a layer should be
+  able to depend on the facilities of lower layers already being set
+  up.  For example, Zope defines a component architecture.  Much Zope
+  software depends on that architecture.  We should be able to treat
+  the component architecture as a layer that we set up once and reuse.
+  Similarly, Zope application software should be able to depend on the
+  Zope application server without having to set it up in each test.
+
+  The test runner introduces test layers, which are objects that can
+  set up environments for tests within the layers to use.  A layer is
+  set up before running the tests in it.  Individual tests or test
+  suites can define a layer by defining a `layer` attribute, which is
+  a test layer.
+
+- Reporting
+
+  - progress meter
+
+  - summaries of tests run
+
+- Analysis of test execution
+
+  - post-mortem debugging of test failures
+
+  - memory leaks
+
+  - code coverage
+
+  - source analysis using pychecker
+
+  - memory errors
+
+  - execution times
+
+  - profiling
+
+Chapters:
+
+- `Simple Usage <testrunner-simple.txt>`_
+- `Layer Selection <testrunner-layers.txt>`_
+- `Passing arguments explicitly <testrunner-arguments.txt>`_
+- `Verbose Output <testrunner-verbose.txt>`_
+- `Test Selection <testrunner-test-selection.txt>`_
+- `Test Progress <testrunner-progress.txt>`_
+- `Errors and Failures <testrunner-errors.txt>`_
+- `Debugging <testrunner-debugging.txt>`_
+- `Layers that can't be torn down <testrunner-layers-ntd.txt>`_
+- `Code Coverage <testrunner-coverage.txt>`_
+- `Profiling <testrunner-profiling.txt>`_
+- `Running Without Source Code <testrunner-wo-source.txt>`_
+- `Repeating Tests <testrunner-repeat.txt>`_
+- `Garbage Collection Control and Statistics <testrunner-gc.txt>`_
+- `Debugging Memory Leaks <testrunner-leaks.txt>`_
+- `Knitting in extra package directories <testrunner-knit.txt>`_
+- `Edge Cases <testrunner-edge-cases.txt>`_


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/testrunner.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope/testing/tests.py
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope/testing/tests.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope/testing/tests.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,32 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Tests for the testing framework.
+
+$Id: tests.py 30492 2005-05-24 20:28:53Z jim $
+"""
+import os
+import sys
+import unittest
+from zope.testing import doctest, testrunner
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocTestSuite('zope.testing.renormalizing'),
+        doctest.DocFileSuite('formparser.txt'),
+        doctest.DocTestSuite('zope.testing.loggingsupport'),
+        testrunner.test_suite(),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: python-zope.testing/branches/upstream/current/src/zope/testing/tests.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/PKG-INFO
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/PKG-INFO	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/PKG-INFO	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,10 @@
+Metadata-Version: 1.0
+Name: zope.testing
+Version: 2.0.2
+Summary: Zope3 Testrunner
+Home-page: http://svn.zope.org/zope.testing
+Author: Zope Corporation and Contributors
+Author-email: zope3-dev at zope.org
+License: ZPL 2.1
+Description: UNKNOWN
+Platform: UNKNOWN

Added: python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/SOURCES.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/SOURCES.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/SOURCES.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,131 @@
+CHANGES.txt
+INSTALL.txt
+MANIFEST.in
+README.txt
+develop.py
+setup.cfg.in
+setup.py
+test.py
+src/zope/__init__.py
+src/zope.testing.egg-info/PKG-INFO
+src/zope.testing.egg-info/SOURCES.txt
+src/zope.testing.egg-info/namespace_packages.txt
+src/zope.testing.egg-info/not-zip-safe
+src/zope.testing.egg-info/requires.txt
+src/zope.testing.egg-info/top_level.txt
+src/zope/testing/DEPENDENCIES.cfg
+src/zope/testing/__init__.py
+src/zope/testing/cleanup.py
+src/zope/testing/doctest.py
+src/zope/testing/doctestunit.py
+src/zope/testing/formparser.py
+src/zope/testing/formparser.txt
+src/zope/testing/loggingsupport.py
+src/zope/testing/loghandler.py
+src/zope/testing/module.py
+src/zope/testing/renormalizing.py
+src/zope/testing/testrunner-arguments.txt
+src/zope/testing/testrunner-coverage.txt
+src/zope/testing/testrunner-debugging.txt
+src/zope/testing/testrunner-edge-cases.txt
+src/zope/testing/testrunner-errors.txt
+src/zope/testing/testrunner-gc.txt
+src/zope/testing/testrunner-knit.txt
+src/zope/testing/testrunner-layers-ntd.txt
+src/zope/testing/testrunner-layers.txt
+src/zope/testing/testrunner-leaks-err.txt
+src/zope/testing/testrunner-leaks.txt
+src/zope/testing/testrunner-profiling.txt
+src/zope/testing/testrunner-progress.txt
+src/zope/testing/testrunner-repeat.txt
+src/zope/testing/testrunner-simple.txt
+src/zope/testing/testrunner-test-selection.txt
+src/zope/testing/testrunner-verbose.txt
+src/zope/testing/testrunner-wo-source.txt
+src/zope/testing/testrunner.py
+src/zope/testing/testrunner.txt
+src/zope/testing/tests.py
+src/zope/testing/testrunner-ex/README.txt
+src/zope/testing/testrunner-ex/gc0.py
+src/zope/testing/testrunner-ex/gc1.py
+src/zope/testing/testrunner-ex/gcset.py
+src/zope/testing/testrunner-ex/gcstats.py
+src/zope/testing/testrunner-ex/leak.py
+src/zope/testing/testrunner-ex/pledge.py
+src/zope/testing/testrunner-ex/samplelayers.py
+src/zope/testing/testrunner-ex/sampletests.txt
+src/zope/testing/testrunner-ex/sampletestsf.py
+src/zope/testing/testrunner-ex/sampletestsl.txt
+src/zope/testing/testrunner-ex-pp-lib/sample4/__init__.py
+src/zope/testing/testrunner-ex-pp-lib/sample4/products/__init__.py
+src/zope/testing/testrunner-ex-pp-products/__init__.py
+src/zope/testing/testrunner-ex-pp-products/sampletests.py
+src/zope/testing/testrunner-ex-pp-products/more/__init__.py
+src/zope/testing/testrunner-ex-pp-products/more/sampletests.py
+src/zope/testing/testrunner-ex/sample1/__init__.py
+src/zope/testing/testrunner-ex/sample1/sampletests_none_suite.py
+src/zope/testing/testrunner-ex/sample1/sampletests_none_test.py
+src/zope/testing/testrunner-ex/sample1/sampletests_ntd.py
+src/zope/testing/testrunner-ex/sample1/sampletests_ntds.py
+src/zope/testing/testrunner-ex/sample1/sampletestsf.py
+src/zope/testing/testrunner-ex/sample1/sample11/__init__.py
+src/zope/testing/testrunner-ex/sample1/sample11/sampletests.py
+src/zope/testing/testrunner-ex/sample1/sample12/__init__.py
+src/zope/testing/testrunner-ex/sample1/sample13/__init__.py
+src/zope/testing/testrunner-ex/sample1/sample13/sampletests.py
+src/zope/testing/testrunner-ex/sample1/sampletests/__init__.py
+src/zope/testing/testrunner-ex/sample1/sampletests/test1.py
+src/zope/testing/testrunner-ex/sample1/sampletests/test11.py
+src/zope/testing/testrunner-ex/sample1/sampletests/test111.py
+src/zope/testing/testrunner-ex/sample1/sampletests/test112.py
+src/zope/testing/testrunner-ex/sample1/sampletests/test12.py
+src/zope/testing/testrunner-ex/sample1/sampletests/test121.py
+src/zope/testing/testrunner-ex/sample1/sampletests/test122.py
+src/zope/testing/testrunner-ex/sample1/sampletests/test_one.py
+src/zope/testing/testrunner-ex/sample2/__init__.py
+src/zope/testing/testrunner-ex/sample2/e.txt
+src/zope/testing/testrunner-ex/sample2/sampletests_1.py
+src/zope/testing/testrunner-ex/sample2/sampletests_e.py
+src/zope/testing/testrunner-ex/sample2/sampletests_f.py
+src/zope/testing/testrunner-ex/sample2/sampletests_ntd.py
+src/zope/testing/testrunner-ex/sample2/sampletests_ntds.py
+src/zope/testing/testrunner-ex/sample2/do-not-enter/sampletests.py
+src/zope/testing/testrunner-ex/sample2/donotenter/sampletests.py
+src/zope/testing/testrunner-ex/sample2/sample21/__init__.py
+src/zope/testing/testrunner-ex/sample2/sample21/sampletests.py
+src/zope/testing/testrunner-ex/sample2/sample21/sampletests_i.py
+src/zope/testing/testrunner-ex/sample2/sample22/__init__.py
+src/zope/testing/testrunner-ex/sample2/sample22/sampletests_i.py
+src/zope/testing/testrunner-ex/sample2/sample23/__init__.py
+src/zope/testing/testrunner-ex/sample2/sample23/sampletests_i.py
+src/zope/testing/testrunner-ex/sample2/sampletests/__init__.py
+src/zope/testing/testrunner-ex/sample2/sampletests/test_1.py
+src/zope/testing/testrunner-ex/sample2/sampletests/testone.py
+src/zope/testing/testrunner-ex/sample3/__init__.py
+src/zope/testing/testrunner-ex/sample3/post_mortem5.txt
+src/zope/testing/testrunner-ex/sample3/post_mortem6.txt
+src/zope/testing/testrunner-ex/sample3/post_mortem_failure.txt
+src/zope/testing/testrunner-ex/sample3/sampletests.py
+src/zope/testing/testrunner-ex/sample3/sampletests_d.py
+src/zope/testing/testrunner-ex/sample3/sampletests_ntd.py
+src/zope/testing/testrunner-ex/sample3/set_trace5.txt
+src/zope/testing/testrunner-ex/sample3/set_trace6.txt
+src/zope/testing/testrunner-ex/sample3/sample31/__init__.py
+src/zope/testing/testrunner-ex/sample3/sample32/__init__.py
+src/zope/testing/testrunner-ex/sample3/sample33/__init__.py
+src/zope/testing/testrunner-ex/sampletests/__init__.py
+src/zope/testing/testrunner-ex/sampletests/test1.py
+src/zope/testing/testrunner-ex/sampletests/test11.py
+src/zope/testing/testrunner-ex/sampletests/test111.py
+src/zope/testing/testrunner-ex/sampletests/test112.py
+src/zope/testing/testrunner-ex/sampletests/test12.py
+src/zope/testing/testrunner-ex/sampletests/test121.py
+src/zope/testing/testrunner-ex/sampletests/test122.py
+src/zope/testing/testrunner-ex/sampletests/test_one.py
+src/zope/testing/testrunner-ex/usecompiled/README.txt
+src/zope/testing/testrunner-ex/usecompiled/__init__.py
+src/zope/testing/testrunner-ex/usecompiled/compiletest.py
+src/zope/testing/testrunner-ex/usecompiled/package/__init__.py
+src/zope/testing/testrunner-ex/usecompiled/package/compiletest.py
+workspace/__init__.py
+workspace/develop.py


Property changes on: python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/SOURCES.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/namespace_packages.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/namespace_packages.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/namespace_packages.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+zope


Property changes on: python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/namespace_packages.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/not-zip-safe
===================================================================

Added: python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/requires.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/requires.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/requires.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+zope.exceptions
\ No newline at end of file


Property changes on: python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/requires.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/top_level.txt
===================================================================
--- python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/top_level.txt	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/top_level.txt	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1 @@
+zope


Property changes on: python-zope.testing/branches/upstream/current/src/zope.testing.egg-info/top_level.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/test.py
===================================================================
--- python-zope.testing/branches/upstream/current/test.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/test.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Sample test script using zope.testing.testrunner
+
+see zope.testing testrunner.txt
+
+$Id: test.py 66450 2006-04-04 21:09:30Z tseaver $
+"""
+
+import os, sys
+
+src = os.path.join(os.path.split(sys.argv[0])[0], 'src')
+sys.path.insert(0, src) # put at beginning to avoid one in site_packages
+
+from zope.testing import testrunner
+
+defaults = [
+    '--path', src,
+    '--package', 'zope.testing',
+    '--tests-pattern', '^tests$',
+    ]
+
+sys.exit(testrunner.run(defaults))
+


Property changes on: python-zope.testing/branches/upstream/current/test.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/workspace/__init__.py
===================================================================


Property changes on: python-zope.testing/branches/upstream/current/workspace/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: python-zope.testing/branches/upstream/current/workspace/develop.py
===================================================================
--- python-zope.testing/branches/upstream/current/workspace/develop.py	2006-10-29 19:23:08 UTC (rev 369)
+++ python-zope.testing/branches/upstream/current/workspace/develop.py	2006-10-29 19:24:26 UTC (rev 370)
@@ -0,0 +1,177 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Project checkout setup script
+
+$Id$
+"""
+
+import os
+import sys
+import shutil
+import optparse
+import ConfigParser
+import urllib2
+
+DEV_SECTION = 'development'
+DEV_DEPENDS = 'depends'
+
+def bootstrap(libdir, bindir):
+    """Bootstrap our setuptools installation in the target directory."""
+
+    # make sure ez_setup is available
+    try:
+        # check if we have ez_setup available
+        import ez_setup
+        
+    except ImportError, e:
+        # retrieve ez_setup.py from the interweb
+        EZ_URL = "http://peak.telecommunity.com/dist/ez_setup.py"
+        
+        ez_filename = os.path.join(os.path.dirname(__file__), 'ez_setup.py')
+        file(ez_filename, 'w').write(
+            urllib2.urlopen(EZ_URL).read()
+            )
+
+        import ez_setup
+        
+    os.environ['PYTHONPATH'] = (os.environ.setdefault('PYTHONPATH', '')
+                               + ":" + libdir)
+    ez_setup.main(['--install-dir', libdir,
+                   '--script-dir', bindir,
+                   '-U', 'setuptools'])
+
+def initSetupCfg(setup_file, template_file='setup.cfg.in'):
+    """Check if the setup_file (setup.cfg) exists; if it doesn't, and
+    setup.cfg.in does, copy setup.cfg.in to setup.cfg to serve as a
+    template."""
+
+    if not(os.path.exists(setup_file)) and os.path.exists(template_file):
+        shutil.copyfile(template_file, setup_file)
+        
+def updateSetupCfg(setup_file, opts):
+    """Update or create a setup.cfg (setup_file) for working on this
+    project."""
+
+    # initialize the setup file if necessary
+    initSetupCfg(setup_file)
+    
+    # load the existing version
+    setup_cfg = ConfigParser.ConfigParser()
+    setup_cfg.read(setup_file)
+
+    # make sure the sections we want exist
+    if not(setup_cfg.has_section('easy_install')):
+        setup_cfg.add_section('easy_install')
+
+    if not(setup_cfg.has_section('egg_info')):
+        setup_cfg.add_section('egg_info')
+        
+    # update lib dir
+    if opts.libdir is None:
+        # no libdir specified; check for one in setup.cfg
+        if setup_cfg.has_option('easy_install', 'install-dir'):
+            opts.libdir = setup_cfg.get('easy_install', 'install-dir')
+        else:
+            opts.libdir = os.path.abspath('./lib')
+
+    setup_cfg.set('easy_install', 'install-dir', opts.libdir)
+
+    # update bin dir
+    if opts.bindir is None:
+        # no bindir specified; check for one in setup.cfg
+        if setup_cfg.has_option('easy_install', 'script-dir'):
+            opts.bindir = setup_cfg.get('easy_install', 'script-dir')
+        else:
+            opts.bindir = os.path.abspath('./bin')
+
+    setup_cfg.set('easy_install', 'script-dir', opts.bindir)
+        
+    # update site-dirs
+    setup_cfg.set('easy_install', 'site-dirs', opts.libdir)
+    
+    # update find-links
+    setup_cfg.set('easy_install', 'find-links', opts.finddirs)
+
+    # update egg_info for development version
+    if not setup_cfg.has_option('egg_info', 'tag_build'):
+        setup_cfg.set('egg_info', 'tag_build', '.dev')
+
+    if not setup_cfg.has_option('egg_info', 'tag_svn_revision'):
+        setup_cfg.set('egg_info', 'tag_svn_revision', '1')
+
+    # store the updated version
+    setup_cfg.write(file(setup_file, 'w'))
+
+def load_dev_deps(setup_file):
+    global DEV_SECTION
+    global DEV_DEPENDS
+    
+    # load the existing version
+    setup_cfg = ConfigParser.ConfigParser()
+    setup_cfg.read(setup_file)
+
+    if not(setup_cfg.has_option(DEV_SECTION, DEV_DEPENDS)):
+        return []
+    else:
+        return [n.strip() for n in
+                setup_cfg.get(DEV_SECTION, DEV_DEPENDS).strip().split()]
+
+def check_dirs(*dirs):
+    """Check that our target directories all exist."""
+
+    for d in dirs:
+        if not(os.path.exists(os.path.abspath(d))):
+            os.makedirs(os.path.abspath(d))
+
+def cmdline_parser():
+    """Create an option parser and populate our available options."""
+
+    parser = optparse.OptionParser()
+    parser.add_option("-s", "--file", dest="setup_cfg",
+                      help="File to read setup configuration from." )
+    parser.add_option("-l", "--libdir", dest="libdir",
+                      help="Location of Python libraries.")
+    parser.add_option("-b", "--bindir", dest="bindir",
+                      help="Location of Python scripts.")
+    parser.add_option("-f", "--find-dirs", dest="finddirs",
+                      help="Location to examine for package links.")
+
+    parser.set_defaults(setup_cfg="setup.cfg",
+                        libdir=None,
+                        bindir=None,
+                        finddirs="http://download.zope.org/distribution/")
+
+    return parser
+
+def main():
+    (options, args) = cmdline_parser().parse_args()
+
+    # update setup.cfg with the lib dir, bin dir, etc
+    updateSetupCfg(options.setup_cfg, options)
+    
+    # make sure that the lib directory structure of our prefix exists
+    check_dirs(options.bindir, options.libdir)
+    sys.path.insert(0, options.libdir)
+
+    # bootstrap setuptools into our libdir
+    bootstrap(options.libdir, options.bindir)
+
+    # install the development dependencies
+    from setuptools.command.easy_install import main as einstall
+    deps = load_dev_deps(options.setup_cfg)
+    if deps and len(deps) > 0:
+        einstall(deps)
+    
+if __name__ == '__main__':
+    main()


Property changes on: python-zope.testing/branches/upstream/current/workspace/develop.py
___________________________________________________________________
Name: svn:eol-style
   + native




More information about the pkg-zope-commits mailing list