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