PageRenderTime 99ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/nltk/test/doctest_nose_plugin.py

https://github.com/BrucePHill/nltk
Python | 94 lines | 71 code | 7 blank | 16 comment | 4 complexity | cf14db2c2435763a92ed6da80cfb00eb MD5 | raw file
Possible License(s): Apache-2.0
  1. # -*- coding: utf-8 -*-
  2. from __future__ import print_function
  3. from nose.suite import ContextList
  4. import re
  5. import doctest
  6. from nose.plugins.base import Plugin
  7. from nose.util import tolist
  8. from nose.plugins.doctests import Doctest
  9. ALLOW_UNICODE = doctest.register_optionflag('ALLOW_UNICODE')
  10. class _UnicodeOutputChecker(doctest.OutputChecker):
  11. _literal_re = re.compile(r"(\W|^)[uU]([rR]?[\'\"])", re.UNICODE)
  12. def _remove_u_prefixes(self, txt):
  13. return re.sub(self._literal_re, r'\1\2', txt)
  14. def check_output(self, want, got, optionflags):
  15. res = doctest.OutputChecker.check_output(self, want, got, optionflags)
  16. if res:
  17. return True
  18. if not (optionflags & ALLOW_UNICODE):
  19. return False
  20. # ALLOW_UNICODE is active and want != got
  21. cleaned_want = self._remove_u_prefixes(want)
  22. cleaned_got = self._remove_u_prefixes(got)
  23. res = doctest.OutputChecker.check_output(self, cleaned_want, cleaned_got, optionflags)
  24. return res
  25. _checker = _UnicodeOutputChecker()
  26. class DoctestPluginHelper(object):
  27. """
  28. This mixin adds print_function future import to all test cases.
  29. It also adds support for '#doctest +ALLOW_UNICODE' option that
  30. makes DocTestCase think u'foo' == 'foo'.
  31. """
  32. def loadTestsFromFile(self, filename):
  33. cases = super(DoctestPluginHelper, self).loadTestsFromFile(filename)
  34. for case in cases:
  35. if isinstance(case, ContextList):
  36. yield ContextList([self._patchTestCase(c) for c in case], case.context)
  37. else:
  38. yield self._patchTestCase(case)
  39. def loadTestsFromModule(self, module):
  40. """Load doctests from the module.
  41. """
  42. for suite in super(DoctestPluginHelper, self).loadTestsFromModule(module):
  43. cases = [self._patchTestCase(case) for case in suite._get_tests()]
  44. yield self.suiteClass(cases, context=module, can_split=False)
  45. def _patchTestCase(self, case):
  46. if case:
  47. case._dt_test.globs['print_function'] = print_function
  48. case._dt_checker = _checker
  49. return case
  50. def configure(self, options, config):
  51. # it is overriden in order to fix doctest options discovery
  52. Plugin.configure(self, options, config)
  53. self.doctest_result_var = options.doctest_result_var
  54. self.doctest_tests = options.doctest_tests
  55. self.extension = tolist(options.doctestExtension)
  56. self.fixtures = options.doctestFixtures
  57. self.finder = doctest.DocTestFinder()
  58. #super(DoctestPluginHelper, self).configure(options, config)
  59. self.optionflags = 0
  60. if options.doctestOptions:
  61. flags = ",".join(options.doctestOptions).split(',')
  62. for flag in flags:
  63. try:
  64. if flag.startswith('+'):
  65. self.optionflags |= doctest.OPTIONFLAGS_BY_NAME[flag[1:]]
  66. elif flag.startswith('-'):
  67. self.optionflags &= ~doctest.OPTIONFLAGS_BY_NAME[flag[1:]]
  68. else:
  69. raise ValueError(
  70. "Must specify doctest options with starting " +
  71. "'+' or '-'. Got %s" % (flag,))
  72. except (AttributeError, KeyError):
  73. raise ValueError("Unknown doctest option %s" %
  74. (flag[1:],))
  75. class DoctestFix(DoctestPluginHelper, Doctest):
  76. pass