1import os, sys, warnings
2def in_development_mode():
3    "True if we're in development mode, False if we're deployed"
4    return "TESTOOB_DEVEL_TEST" in os.environ
5
6def project_subpath(*components):
7    from os.path import dirname, join, normpath
8    return normpath(join(dirname(__file__), "..", *components))
9
10def module_path():
11    return project_subpath("src")
12
13def which(executable):
14    import procutils
15    results = procutils.which(executable)
16    if len(results) == 0:
17        raise RuntimeError("Executable %r not found in the path" % executable)
18    if len(results) > 1:
19        warnings.warn("Found more than one instance of %r in the path, using %r, options are %s" % (executable, results[0], results))
20    return results[0]
21
22def executable_path():
23    if in_development_mode():
24        return project_subpath("src", "testoob", "testoob")
25    else:
26        return which("testoob")
27
28def add_module_path(path):
29    if path not in sys.path:
30        sys.path.insert(0, path)
31
32if in_development_mode():
33    print "Development mode: adding %r to sys.path" % module_path()
34    add_module_path( module_path() )
35
36from testoob.reporting.base import BaseReporter
37class ReporterWithMemory(BaseReporter):
38    "A reporter that remembers info on the test fixtures run"
39    def __init__(self):
40        BaseReporter.__init__(self)
41        self.started = []
42        self.finished = []
43        self.stdout = ""
44        self.stderr = ""
45
46        self.has_started = False
47        self.is_done = False
48
49    def _append_test(self, l, test_info):
50        # TODO: use test_info.methodname()
51        l.append(str(test_info).split()[0])
52
53    def start(self):
54        self.has_started = True
55    def done(self):
56        self.is_done = True
57    def startTest(self, test_info):
58        self._append_test(self.started, test_info)
59    def stopTest(self, test_info):
60        self._append_test(self.finished, test_info)
61    def addError(self, test_info, err_info):
62        self._append_test(self.errors, test_info)
63    def addFailure(self, test_info, err_info):
64        self._append_test(self.failures, test_info)
65    def addSuccess(self, test_info):
66        self._append_test(self.successes, test_info)
67    def addAssert(self, test_info, assertName, varList, exception):
68        self.asserts[str(test_info).split()[0]] = (assertName, exception.__class__)
69
70    def __str__(self):
71        attrs = ("started","successes","errors","failures","finished","stdout","stderr")
72        return "\n".join(["%s = %s" % (attr, getattr(self,attr)) for attr in attrs])
73
74class TestoobRunnerWithMemory:
75    def __init__(self):
76        self.reporter = ReporterWithMemory()
77
78    def run(self, **kwargs):
79        testoob.running.run(reporters=[self.reporter], **kwargs)
80
81    def check_reporter(self, **kwargs):
82        for attr, expected in kwargs.items():
83            actual = getattr(self.reporter, attr)
84            if type(expected) == type([]):
85                expected.sort()
86                actual.sort()
87            from testoob.testing import assert_equals
88            assert_equals(expected, actual)
89
90import unittest
91import testoob.running
92class TestoobBaseTestCase(unittest.TestCase):
93    def setUp(self):
94        self.runner = TestoobRunnerWithMemory()
95    def tearDown(self):
96        del self.runner
97    def _check_reporter(self, **kwargs):
98        self.runner.check_reporter(**kwargs)
99    def _run(self, **kwargs):
100        self.runner.run(**kwargs)
101
102def ensure_coverage_support():
103    from testoob import coverage, testing
104    if not coverage.supported():
105        testing.skip(reason="No coverage support")
106