1from cStringIO import StringIO
2
3import os
4import sys
5import unittest
6import unittest.test
7
8
9class Test_TestProgram(unittest.TestCase):
10
11    def test_discovery_from_dotted_path(self):
12        loader = unittest.TestLoader()
13
14        tests = [self]
15        expectedPath = os.path.abspath(os.path.dirname(unittest.test.__file__))
16
17        self.wasRun = False
18        def _find_tests(start_dir, pattern):
19            self.wasRun = True
20            self.assertEqual(start_dir, expectedPath)
21            return tests
22        loader._find_tests = _find_tests
23        suite = loader.discover('unittest.test')
24        self.assertTrue(self.wasRun)
25        self.assertEqual(suite._tests, tests)
26
27    # Horrible white box test
28    def testNoExit(self):
29        result = object()
30        test = object()
31
32        class FakeRunner(object):
33            def run(self, test):
34                self.test = test
35                return result
36
37        runner = FakeRunner()
38
39        oldParseArgs = unittest.TestProgram.parseArgs
40        def restoreParseArgs():
41            unittest.TestProgram.parseArgs = oldParseArgs
42        unittest.TestProgram.parseArgs = lambda *args: None
43        self.addCleanup(restoreParseArgs)
44
45        def removeTest():
46            del unittest.TestProgram.test
47        unittest.TestProgram.test = test
48        self.addCleanup(removeTest)
49
50        program = unittest.TestProgram(testRunner=runner, exit=False, verbosity=2)
51
52        self.assertEqual(program.result, result)
53        self.assertEqual(runner.test, test)
54        self.assertEqual(program.verbosity, 2)
55
56    class FooBar(unittest.TestCase):
57        def testPass(self):
58            assert True
59        def testFail(self):
60            assert False
61
62    class FooBarLoader(unittest.TestLoader):
63        """Test loader that returns a suite containing FooBar."""
64        def loadTestsFromModule(self, module):
65            return self.suiteClass(
66                [self.loadTestsFromTestCase(Test_TestProgram.FooBar)])
67
68
69    def test_NonExit(self):
70        program = unittest.main(exit=False,
71                                argv=["foobar"],
72                                testRunner=unittest.TextTestRunner(stream=StringIO()),
73                                testLoader=self.FooBarLoader())
74        self.assertTrue(hasattr(program, 'result'))
75
76
77    def test_Exit(self):
78        self.assertRaises(
79            SystemExit,
80            unittest.main,
81            argv=["foobar"],
82            testRunner=unittest.TextTestRunner(stream=StringIO()),
83            exit=True,
84            testLoader=self.FooBarLoader())
85
86
87    def test_ExitAsDefault(self):
88        self.assertRaises(
89            SystemExit,
90            unittest.main,
91            argv=["foobar"],
92            testRunner=unittest.TextTestRunner(stream=StringIO()),
93            testLoader=self.FooBarLoader())
94
95
96class InitialisableProgram(unittest.TestProgram):
97    exit = False
98    result = None
99    verbosity = 1
100    defaultTest = None
101    testRunner = None
102    testLoader = unittest.defaultTestLoader
103    progName = 'test'
104    test = 'test'
105    def __init__(self, *args):
106        pass
107
108RESULT = object()
109
110class FakeRunner(object):
111    initArgs = None
112    test = None
113    raiseError = False
114
115    def __init__(self, **kwargs):
116        FakeRunner.initArgs = kwargs
117        if FakeRunner.raiseError:
118            FakeRunner.raiseError = False
119            raise TypeError
120
121    def run(self, test):
122        FakeRunner.test = test
123        return RESULT
124
125class TestCommandLineArgs(unittest.TestCase):
126
127    def setUp(self):
128        self.program = InitialisableProgram()
129        self.program.createTests = lambda: None
130        FakeRunner.initArgs = None
131        FakeRunner.test = None
132        FakeRunner.raiseError = False
133
134    def testHelpAndUnknown(self):
135        program = self.program
136        def usageExit(msg=None):
137            program.msg = msg
138            program.exit = True
139        program.usageExit = usageExit
140
141        for opt in '-h', '-H', '--help':
142            program.exit = False
143            program.parseArgs([None, opt])
144            self.assertTrue(program.exit)
145            self.assertIsNone(program.msg)
146
147        program.parseArgs([None, '-$'])
148        self.assertTrue(program.exit)
149        self.assertIsNotNone(program.msg)
150
151    def testVerbosity(self):
152        program = self.program
153
154        for opt in '-q', '--quiet':
155            program.verbosity = 1
156            program.parseArgs([None, opt])
157            self.assertEqual(program.verbosity, 0)
158
159        for opt in '-v', '--verbose':
160            program.verbosity = 1
161            program.parseArgs([None, opt])
162            self.assertEqual(program.verbosity, 2)
163
164    def testBufferCatchFailfast(self):
165        program = self.program
166        for arg, attr in (('buffer', 'buffer'), ('failfast', 'failfast'),
167                      ('catch', 'catchbreak')):
168            if attr == 'catch' and not hasInstallHandler:
169                continue
170
171            short_opt = '-%s' % arg[0]
172            long_opt = '--%s' % arg
173            for opt in short_opt, long_opt:
174                setattr(program, attr, None)
175
176                program.parseArgs([None, opt])
177                self.assertTrue(getattr(program, attr))
178
179            for opt in short_opt, long_opt:
180                not_none = object()
181                setattr(program, attr, not_none)
182
183                program.parseArgs([None, opt])
184                self.assertEqual(getattr(program, attr), not_none)
185
186    def testRunTestsRunnerClass(self):
187        program = self.program
188
189        program.testRunner = FakeRunner
190        program.verbosity = 'verbosity'
191        program.failfast = 'failfast'
192        program.buffer = 'buffer'
193
194        program.runTests()
195
196        self.assertEqual(FakeRunner.initArgs, {'verbosity': 'verbosity',
197                                                'failfast': 'failfast',
198                                                'buffer': 'buffer'})
199        self.assertEqual(FakeRunner.test, 'test')
200        self.assertIs(program.result, RESULT)
201
202    def testRunTestsRunnerInstance(self):
203        program = self.program
204
205        program.testRunner = FakeRunner()
206        FakeRunner.initArgs = None
207
208        program.runTests()
209
210        # A new FakeRunner should not have been instantiated
211        self.assertIsNone(FakeRunner.initArgs)
212
213        self.assertEqual(FakeRunner.test, 'test')
214        self.assertIs(program.result, RESULT)
215
216    def testRunTestsOldRunnerClass(self):
217        program = self.program
218
219        FakeRunner.raiseError = True
220        program.testRunner = FakeRunner
221        program.verbosity = 'verbosity'
222        program.failfast = 'failfast'
223        program.buffer = 'buffer'
224        program.test = 'test'
225
226        program.runTests()
227
228        # If initializing raises a type error it should be retried
229        # without the new keyword arguments
230        self.assertEqual(FakeRunner.initArgs, {})
231        self.assertEqual(FakeRunner.test, 'test')
232        self.assertIs(program.result, RESULT)
233
234    def testCatchBreakInstallsHandler(self):
235        module = sys.modules['unittest.main']
236        original = module.installHandler
237        def restore():
238            module.installHandler = original
239        self.addCleanup(restore)
240
241        self.installed = False
242        def fakeInstallHandler():
243            self.installed = True
244        module.installHandler = fakeInstallHandler
245
246        program = self.program
247        program.catchbreak = True
248
249        program.testRunner = FakeRunner
250
251        program.runTests()
252        self.assertTrue(self.installed)
253
254
255if __name__ == '__main__':
256    unittest.main()
257