Skip to content
This repository has been archived by the owner on Jan 5, 2019. It is now read-only.

Commit

Permalink
run doctests in unittest
Browse files Browse the repository at this point in the history
  • Loading branch information
jedie committed May 12, 2015
1 parent 3b86446 commit de42dd9
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 100 deletions.
32 changes: 16 additions & 16 deletions secure_js_login/utils/crypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ class PBKDF2SHA1Hasher(PBKDF2SHA1PasswordHasher):
...
AssertionError: wrong iterations
>>> PBKDF2SHA1Hasher(iterations=1000, length=16).verify(password="not secret", encoded=hash)
Traceback (most recent call last):
...
crypt.CryptError: wrong hash length
>>> try:
... PBKDF2SHA1Hasher(iterations=1000, length=16).verify(password="not secret", encoded=hash)
... except CryptError as err:print(err)
wrong hash length
>>> PBKDF2SHA1Hasher(iterations=1000, length=32).must_update(encoded=hash)
False
Expand Down Expand Up @@ -246,20 +246,20 @@ class XorCryptor(object):
>>> xor.decrypt(encrypted, "ABCD")
'1234'
>>> xor.decrypt(encrypted, "AXXD")
Traceback (most recent call last):
...
crypt.CryptError: XOR decrypted data: PBKDF2 hash test failed
>>> try:
... xor.decrypt(encrypted, "AXXD")
... except CryptError as err: print(err)
XOR decrypted data: PBKDF2 hash test failed
>>> xor.decrypt('pbkdf2_sha1$10$DEBUG$bb6212418fade7c4101179b0$70XxxX70', "ABCD")
Traceback (most recent call last):
...
crypt.CryptError: unhexlify error: Non-hexadecimal digit found with data: '70XxxX70'
>>> try:
... xor.decrypt('pbkdf2_sha1$10$DEBUG$bb6212418fade7c4101179b0$70XxxX70', "ABCD")
... except CryptError as err: print(err)
unhexlify error: Non-hexadecimal digit found with data: '70XxxX70'
>>> xor.decrypt(encrypted, "wrong pass")
Traceback (most recent call last):
...
crypt.CryptError: encrypt error: b'pppp' and 'wrong pass' must have the same length!
>>> try:
... xor.decrypt(encrypted, "wrong pass")
... except CryptError as err: print(err)
encrypt error: b'pppp' and 'wrong pass' must have the same length!
"""
def xor(self, txt, key):
"""
Expand Down
86 changes: 2 additions & 84 deletions tests/runtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,85 +23,14 @@
from __future__ import absolute_import, print_function

import os
os.environ['DJANGO_SETTINGS_MODULE'] = os.environ.get('DJANGO_SETTINGS_MODULE', 'tests.test_utils.test_settings')

import doctest
import sys
import time

os.environ['DJANGO_SETTINGS_MODULE'] = os.environ.get('DJANGO_SETTINGS_MODULE', 'tests.test_utils.test_settings')

import django
from django.conf import settings
from django.test.utils import get_runner

import secure_js_login


SKIP_DIRS = (".settings", ".git", "dist", "python_creole.egg-info")
SKIP_FILES = ("setup.py", "test.py")


def run_all_doctests(verbosity, base_path):
"""
run all existing DocTests
"""
start_time = time.time()

if verbosity >= 2:
print("")
print("_" * 79)
print("Running %r DocTests:\n" % base_path)

total_files = 0
total_doctests = 0
total_attempted = 0
total_failed = 0
for root, dirs, filelist in os.walk(base_path, followlinks=True):
for skip_dir in SKIP_DIRS:
if skip_dir in dirs:
dirs.remove(skip_dir) # don't visit this directories

for filename in filelist:
if not filename.endswith(".py"):
continue
if filename in SKIP_FILES:
continue

total_files += 1

sys.path.insert(0, root)
try:
m = __import__(filename[:-3])
except ImportError as err:
if verbosity >= 2:
print("***DocTest import %s error*** %s" % (filename, err))
except Exception as err:
if verbosity >= 2:
print("***DocTest %s error*** %s" % (filename, err))
else:
failed, attempted = doctest.testmod(m)
total_attempted += attempted
total_failed += failed
if attempted or failed:
total_doctests += 1

if attempted and not failed:
filepath = os.path.join(root, filename)
if verbosity <= 1:
sys.stdout.write(".")
elif verbosity >= 2:
print("DocTest in %s OK (failed=%i, attempted=%i)" % (
filepath, failed, attempted
))
finally:
del sys.path[0]

duration = time.time() - start_time
print("")
print("-" * 70)
print(" *** Ran %i DocTests from %i files in %.3fs: failed=%i, attempted=%i\n\n" % (
total_doctests, total_files, duration, total_failed, total_attempted
))


def run_unittests(test_labels=None):
django.setup()
Expand All @@ -121,19 +50,8 @@ def run_unittests(test_labels=None):

def cli_run():
if "-v" in sys.argv or "--verbosity" in sys.argv:
verbosity = 2
elif "-q" in sys.argv or "--quite" in sys.argv:
verbosity = 0
else:
verbosity = 1

if verbosity:
print("DJANGO_SETTINGS_MODULE=%r" % os.environ['DJANGO_SETTINGS_MODULE'])

base_path = os.path.abspath(os.path.dirname(secure_js_login.__file__))

# verbosity=3
run_all_doctests(verbosity, base_path)
run_unittests(test_labels=sys.argv[1:])


Expand Down
103 changes: 103 additions & 0 deletions tests/test_doctests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import os
import unittest
import doctest
import sys

from django.utils import six

import secure_js_login


SKIP_DIRS = (".settings", ".git", "dist", ".egg-info")
SKIP_FILES = ("setup.py", "test.py")


def get_all_doctests(base_path, verbose=False):
suites = []
for root, dirs, filelist in os.walk(base_path, followlinks=True):
for skip_dir in SKIP_DIRS:
if skip_dir in dirs:
dirs.remove(skip_dir) # don't visit this directories

for filename in filelist:
if not filename.endswith(".py"):
continue
if filename in SKIP_FILES:
continue

sys.path.insert(0, root)
try:
module = __import__(filename[:-3])
except ImportError as err:
if verbose:
print(
"\tDocTest import %s error %s" % (filename, err),
file=sys.stderr
)
except Exception as err:
if verbose:
print(
"\tDocTest %s error %s" % (filename, err),
file=sys.stderr
)
else:
try:
suite = doctest.DocTestSuite(module)
except ValueError: # has no docstrings
continue

test_count = suite.countTestCases()
if test_count<1:
if verbose:
print(
"\tNo DocTests in %r" % module.__name__,
file=sys.stderr
)
continue

if verbose:
file_info = module.__file__
else:
file_info = module.__name__
print(
"\t%i DocTests in %r" % (test_count,file_info),
file=sys.stderr
)
suites.append((module,suite))
finally:
del sys.path[0]

return suites


class TestDoctests(unittest.TestCase):
def run_doctest(self, module, suite):
module_name = module.__name__
print("Run DocTests in %r..." % module_name, file=sys.stderr)

result = self.defaultTestResult()

old_stdout = sys.stdout
sys.stdout = sys.stderr
try:
suite.run(result)
finally:
sys.stdout = old_stdout

msg = "Doctest %r results: run=%i errors=%i failures=%i" % (
module_name, result.testsRun, len(result.errors), len(result.failures)
)
self.assertEqual(len(result.errors), 0, msg)
self.assertEqual(len(result.failures), 0, msg)
print(msg, file=sys.stderr)

@unittest.skipIf(six.PY2, "DocTests are for Python 3")
def test_doctests(self):
print("\ncollect DocTests:", file=sys.stderr)
path = os.path.abspath(os.path.dirname(secure_js_login.__file__))
suites = get_all_doctests(
base_path=path,
# verbose=True
)
for module, suite in suites:
self.run_doctest(module, suite)

0 comments on commit de42dd9

Please sign in to comment.