diff options
| author | Carl Meyer <carl@oddbird.net> | 2013-05-27 14:41:39 -0600 |
|---|---|---|
| committer | Carl Meyer <carl@oddbird.net> | 2013-05-27 14:55:08 -0600 |
| commit | cd79f337233be3f2dfa22316314c9d4834093e31 (patch) | |
| tree | 6dc06e1069521cb84261cb56a7b32c7d42085a41 | |
| parent | 0027f1390443f199087d0784920450d93a359614 (diff) | |
Fixed #20503 - Moved doctest utilities in with the rest of the deprecated test code.
The ``DocTestRunner`` and ``OutputChecker`` were formerly in
``django.test.testcases``, now they are in ``django.test.simple``. This avoids
triggering the ``django.test._doctest`` deprecation message with any import
from ``django.test``. Since these utility classes are undocumented internal
API, they can be moved without a separate deprecation process.
Also removed the deprecation warnings specific to these classes, as they are
now covered by the module-level warning in ``django.test.simple``.
Thanks Anssi for the report.
Refs #17365.
| -rw-r--r-- | django/test/simple.py | 70 | ||||
| -rw-r--r-- | django/test/testcases.py | 79 | ||||
| -rw-r--r-- | docs/internals/deprecation.txt | 6 | ||||
| -rw-r--r-- | docs/releases/1.6.txt | 18 |
4 files changed, 78 insertions, 95 deletions
diff --git a/django/test/simple.py b/django/test/simple.py index 5117c6452f..f28b8a2830 100644 --- a/django/test/simple.py +++ b/django/test/simple.py @@ -3,14 +3,15 @@ This module is pending deprecation as of Django 1.6 and will be removed in version 1.8. """ - +import json +import re import unittest as real_unittest import warnings from django.db.models import get_app, get_apps from django.test import _doctest as doctest from django.test import runner -from django.test.testcases import OutputChecker, DocTestRunner +from django.test.utils import compare_xml, strip_quotes from django.utils import unittest from django.utils.importlib import import_module from django.utils.module_loading import module_has_submodule @@ -25,6 +26,71 @@ warnings.warn( # The module name for tests outside models.py TEST_MODULE = 'tests' + +normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s) +normalize_decimals = lambda s: re.sub(r"Decimal\('(\d+(\.\d*)?)'\)", + lambda m: "Decimal(\"%s\")" % m.groups()[0], s) + + +class OutputChecker(doctest.OutputChecker): + def check_output(self, want, got, optionflags): + """ + The entry method for doctest output checking. Defers to a sequence of + child checkers + """ + checks = (self.check_output_default, + self.check_output_numeric, + self.check_output_xml, + self.check_output_json) + for check in checks: + if check(want, got, optionflags): + return True + return False + + def check_output_default(self, want, got, optionflags): + """ + The default comparator provided by doctest - not perfect, but good for + most purposes + """ + return doctest.OutputChecker.check_output(self, want, got, optionflags) + + def check_output_numeric(self, want, got, optionflags): + """Doctest does an exact string comparison of output, which means that + some numerically equivalent values aren't equal. This check normalizes + * long integers (22L) so that they equal normal integers. (22) + * Decimals so that they are comparable, regardless of the change + made to __repr__ in Python 2.6. + """ + return doctest.OutputChecker.check_output(self, + normalize_decimals(normalize_long_ints(want)), + normalize_decimals(normalize_long_ints(got)), + optionflags) + + def check_output_xml(self, want, got, optionsflags): + try: + return compare_xml(want, got) + except Exception: + return False + + def check_output_json(self, want, got, optionsflags): + """ + Tries to compare want and got as if they were JSON-encoded data + """ + want, got = strip_quotes(want, got) + try: + want_json = json.loads(want) + got_json = json.loads(got) + except Exception: + return False + return want_json == got_json + + +class DocTestRunner(doctest.DocTestRunner): + def __init__(self, *args, **kwargs): + doctest.DocTestRunner.__init__(self, *args, **kwargs) + self.optionflags = doctest.ELLIPSIS + + doctestOutputChecker = OutputChecker() diff --git a/django/test/testcases.py b/django/test/testcases.py index 463914c1e1..08c03154b1 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -30,12 +30,11 @@ from django.core.urlresolvers import clear_url_caches, set_urlconf from django.db import connection, connections, DEFAULT_DB_ALIAS, transaction from django.forms.fields import CharField from django.http import QueryDict -from django.test import _doctest as doctest from django.test.client import Client from django.test.html import HTMLParseError, parse_html from django.test.signals import template_rendered from django.test.utils import (CaptureQueriesContext, ContextList, - override_settings, compare_xml, strip_quotes) + override_settings, compare_xml) from django.utils import six, unittest as ut2 from django.utils.encoding import force_text from django.utils.unittest import skipIf # Imported here for backward compatibility @@ -43,15 +42,10 @@ from django.utils.unittest.util import safe_repr from django.views.static import serve -__all__ = ('DocTestRunner', 'OutputChecker', 'TestCase', 'TransactionTestCase', +__all__ = ('TestCase', 'TransactionTestCase', 'SimpleTestCase', 'skipIfDBFeature', 'skipUnlessDBFeature') -normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s) -normalize_decimals = lambda s: re.sub(r"Decimal\('(\d+(\.\d*)?)'\)", - lambda m: "Decimal(\"%s\")" % m.groups()[0], s) - - def to_list(value): """ Puts value into a list if it's not already one. @@ -96,75 +90,6 @@ def assert_and_parse_html(self, html, user_msg, msg): return dom -class OutputChecker(doctest.OutputChecker): - def __init__(self): - warnings.warn( - "The django.test.testcases.OutputChecker class is deprecated; " - "use the doctest module from the Python standard library instead.", - PendingDeprecationWarning) - - def check_output(self, want, got, optionflags): - """ - The entry method for doctest output checking. Defers to a sequence of - child checkers - """ - checks = (self.check_output_default, - self.check_output_numeric, - self.check_output_xml, - self.check_output_json) - for check in checks: - if check(want, got, optionflags): - return True - return False - - def check_output_default(self, want, got, optionflags): - """ - The default comparator provided by doctest - not perfect, but good for - most purposes - """ - return doctest.OutputChecker.check_output(self, want, got, optionflags) - - def check_output_numeric(self, want, got, optionflags): - """Doctest does an exact string comparison of output, which means that - some numerically equivalent values aren't equal. This check normalizes - * long integers (22L) so that they equal normal integers. (22) - * Decimals so that they are comparable, regardless of the change - made to __repr__ in Python 2.6. - """ - return doctest.OutputChecker.check_output(self, - normalize_decimals(normalize_long_ints(want)), - normalize_decimals(normalize_long_ints(got)), - optionflags) - - def check_output_xml(self, want, got, optionsflags): - try: - return compare_xml(want, got) - except Exception: - return False - - def check_output_json(self, want, got, optionsflags): - """ - Tries to compare want and got as if they were JSON-encoded data - """ - want, got = strip_quotes(want, got) - try: - want_json = json.loads(want) - got_json = json.loads(got) - except Exception: - return False - return want_json == got_json - - -class DocTestRunner(doctest.DocTestRunner): - def __init__(self, *args, **kwargs): - warnings.warn( - "The django.test.testcases.DocTestRunner class is deprecated; " - "use the doctest module from the Python standard library instead.", - PendingDeprecationWarning) - doctest.DocTestRunner.__init__(self, *args, **kwargs) - self.optionflags = doctest.ELLIPSIS - - class _AssertNumQueriesContext(CaptureQueriesContext): def __init__(self, test_case, num, connection): self.test_case = test_case diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index c4bbc3b7a4..45f82b49e6 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -386,10 +386,8 @@ these changes. ``django.test.simple.DjangoTestSuiteRunner`` will be removed. Instead use ``django.test.runner.DiscoverRunner``. -* The module ``django.test._doctest`` and the classes - ``django.test.testcases.DocTestRunner`` and - ``django.test.testcases.OutputChecker`` will be removed. Instead use the - doctest module from the Python standard library. +* The module ``django.test._doctest`` will be removed. Instead use the doctest + module from the Python standard library. * The ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting will be removed. diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt index 4f4b615835..c01128c684 100644 --- a/docs/releases/1.6.txt +++ b/docs/releases/1.6.txt @@ -345,21 +345,15 @@ support some types of tests that were supported by the previous runner: your test suite, follow the `recommendations in the Python documentation`_. Django bundles a modified version of the :mod:`doctest` module from the Python -standard library (in ``django.test._doctest``) in order to allow passing in a -custom ``DocTestRunner`` when instantiating a ``DocTestSuite``, and includes -some additional doctest utilities (``django.test.testcases.DocTestRunner`` -turns on the ``ELLIPSIS`` option by default, and -``django.test.testcases.OutputChecker`` provides better matching of XML, JSON, -and numeric data types). - -These utilities are deprecated and will be removed in Django 1.8; doctest -suites should be updated to work with the standard library's doctest module (or -converted to unittest-compatible tests). +standard library (in ``django.test._doctest``) and includes some additional +doctest utilities. These utilities are deprecated and will be removed in Django +1.8; doctest suites should be updated to work with the standard library's +doctest module (or converted to unittest-compatible tests). If you wish to delay updates to your test suite, you can set your :setting:`TEST_RUNNER` setting to ``django.test.simple.DjangoTestSuiteRunner`` -to fully restore the old test behavior. ``DjangoTestSuiteRunner`` is -deprecated but will not be removed from Django until version 1.8. +to fully restore the old test behavior. ``DjangoTestSuiteRunner`` is deprecated +but will not be removed from Django until version 1.8. .. _recommendations in the Python documentation: http://docs.python.org/2/library/doctest.html#unittest-api |
