Integration and coverage tests. (Fixes issue #2)
[python-bulletml.git] / tests / __init__.py
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644 (file)
index 0000000..8640d5a
--- /dev/null
@@ -0,0 +1,72 @@
+"""Generic test runner.
+
+This module scans for filenames begining with test_ and runs the tests
+in them. It is less noisy than the default Python test runners.
+"""
+
+from __future__ import division
+from __future__ import print_function
+
+import glob
+import os
+import sys
+import unittest
+
+from unittest import TestCase
+
+suites = []
+add = suites.append
+
+for name in glob.glob(os.path.join(os.path.dirname(__file__), "test_*.py")):
+    module = "tests." + os.path.basename(name)
+    __import__(module[:-3], {}, {}, [])
+
+class Result(unittest.TestResult):
+
+    separator1 = '=' * 70
+    separator2 = '-' * 70
+
+    def addSuccess(self, test):
+        unittest.TestResult.addSuccess(self, test)
+        sys.stdout.write('.')
+
+    def addError(self, test, err):
+        unittest.TestResult.addError(self, test, err)
+        sys.stdout.write('E')
+
+    def addFailure(self, test, err):
+        unittest.TestResult.addFailure(self, test, err)
+        sys.stdout.write('F')
+
+    def printErrors(self):
+        succ = self.testsRun - (len(self.errors) + len(self.failures))
+        v = "%3d" % succ
+        count = 50 - self.testsRun
+        sys.stdout.write((" " * count) + v + "\n")
+        self.printErrorList('ERROR', self.errors)
+        self.printErrorList('FAIL', self.failures)
+
+    def printErrorList(self, flavour, errors):
+        for test, err in errors:
+            sys.stdout.write(self.separator1 + "\n")
+            sys.stdout.write("%s: %s\n" % (flavour, str(test)))
+            sys.stdout.write(self.separator2 + "\n")
+            sys.stdout.write("%s\n" % err)
+
+class Runner(object):
+    def run(self, test):
+        suite = unittest.makeSuite(test)
+        pref = '%s (%d): ' % (test.__name__, len(suite._tests))
+        print(pref + " " * (25 - len(pref)), end=" ")
+        result = Result()
+        suite(result)
+        result.printErrors()
+        return bool(result.failures + result.errors)
+
+def unit(run=[]):
+    runner = Runner()
+    failures = False
+    for test in suites:
+        if not run or test.__name__ in run or test.__name__.lstrip("T") in run:
+            failures |= runner.run(test)
+    return failures