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