1from unittest2.test.support import EqualityMixin, LoggingResult
2
3import sys
4import unittest2
5
6class Test(object):
7    class Foo(unittest2.TestCase):
8        def test_1(self): pass
9        def test_2(self): pass
10        def test_3(self): pass
11        def runTest(self): pass
12
13def _mk_TestSuite(*names):
14    return unittest2.TestSuite(Test.Foo(n) for n in names)
15
16
17class Test_TestSuite(unittest2.TestCase, EqualityMixin):
18
19    ### Set up attributes needed by inherited tests
20    ################################################################
21
22    # Used by EqualityMixin.test_eq
23    eq_pairs = [(unittest2.TestSuite(), unittest2.TestSuite()),
24                (unittest2.TestSuite(), unittest2.TestSuite([])),
25                (_mk_TestSuite('test_1'), _mk_TestSuite('test_1'))]
26
27    # Used by EqualityMixin.test_ne
28    ne_pairs = [(unittest2.TestSuite(), _mk_TestSuite('test_1')),
29                (unittest2.TestSuite([]), _mk_TestSuite('test_1')),
30                (_mk_TestSuite('test_1', 'test_2'), _mk_TestSuite('test_1', 'test_3')),
31                (_mk_TestSuite('test_1'), _mk_TestSuite('test_2'))]
32
33    ################################################################
34    ### /Set up attributes needed by inherited tests
35
36    ### Tests for TestSuite.__init__
37    ################################################################
38
39    # "class TestSuite([tests])"
40    #
41    # The tests iterable should be optional
42    def test_init__tests_optional(self):
43        suite = unittest2.TestSuite()
44
45        self.assertEqual(suite.countTestCases(), 0)
46
47    # "class TestSuite([tests])"
48    # ...
49    # "If tests is given, it must be an iterable of individual test cases
50    # or other test suites that will be used to build the suite initially"
51    #
52    # TestSuite should deal with empty tests iterables by allowing the
53    # creation of an empty suite
54    def test_init__empty_tests(self):
55        suite = unittest2.TestSuite([])
56
57        self.assertEqual(suite.countTestCases(), 0)
58
59    # "class TestSuite([tests])"
60    # ...
61    # "If tests is given, it must be an iterable of individual test cases
62    # or other test suites that will be used to build the suite initially"
63    #
64    # TestSuite should allow any iterable to provide tests
65    def test_init__tests_from_any_iterable(self):
66        def tests():
67            yield unittest2.FunctionTestCase(lambda: None)
68            yield unittest2.FunctionTestCase(lambda: None)
69
70        suite_1 = unittest2.TestSuite(tests())
71        self.assertEqual(suite_1.countTestCases(), 2)
72
73        suite_2 = unittest2.TestSuite(suite_1)
74        self.assertEqual(suite_2.countTestCases(), 2)
75
76        suite_3 = unittest2.TestSuite(set(suite_1))
77        self.assertEqual(suite_3.countTestCases(), 2)
78
79    # "class TestSuite([tests])"
80    # ...
81    # "If tests is given, it must be an iterable of individual test cases
82    # or other test suites that will be used to build the suite initially"
83    #
84    # Does TestSuite() also allow other TestSuite() instances to be present
85    # in the tests iterable?
86    def test_init__TestSuite_instances_in_tests(self):
87        def tests():
88            ftc = unittest2.FunctionTestCase(lambda: None)
89            yield unittest2.TestSuite([ftc])
90            yield unittest2.FunctionTestCase(lambda: None)
91
92        suite = unittest2.TestSuite(tests())
93        self.assertEqual(suite.countTestCases(), 2)
94
95    ################################################################
96    ### /Tests for TestSuite.__init__
97
98    # Container types should support the iter protocol
99    def test_iter(self):
100        test1 = unittest2.FunctionTestCase(lambda: None)
101        test2 = unittest2.FunctionTestCase(lambda: None)
102        suite = unittest2.TestSuite((test1, test2))
103
104        self.assertEqual(list(suite), [test1, test2])
105
106    # "Return the number of tests represented by the this test object.
107    # ...this method is also implemented by the TestSuite class, which can
108    # return larger [greater than 1] values"
109    #
110    # Presumably an empty TestSuite returns 0?
111    def test_countTestCases_zero_simple(self):
112        suite = unittest2.TestSuite()
113
114        self.assertEqual(suite.countTestCases(), 0)
115
116    # "Return the number of tests represented by the this test object.
117    # ...this method is also implemented by the TestSuite class, which can
118    # return larger [greater than 1] values"
119    #
120    # Presumably an empty TestSuite (even if it contains other empty
121    # TestSuite instances) returns 0?
122    def test_countTestCases_zero_nested(self):
123        class Test1(unittest2.TestCase):
124            def test(self):
125                pass
126
127        suite = unittest2.TestSuite([unittest2.TestSuite()])
128
129        self.assertEqual(suite.countTestCases(), 0)
130
131    # "Return the number of tests represented by the this test object.
132    # ...this method is also implemented by the TestSuite class, which can
133    # return larger [greater than 1] values"
134    def test_countTestCases_simple(self):
135        test1 = unittest2.FunctionTestCase(lambda: None)
136        test2 = unittest2.FunctionTestCase(lambda: None)
137        suite = unittest2.TestSuite((test1, test2))
138
139        self.assertEqual(suite.countTestCases(), 2)
140
141    # "Return the number of tests represented by the this test object.
142    # ...this method is also implemented by the TestSuite class, which can
143    # return larger [greater than 1] values"
144    #
145    # Make sure this holds for nested TestSuite instances, too
146    def test_countTestCases_nested(self):
147        class Test1(unittest2.TestCase):
148            def test1(self): pass
149            def test2(self): pass
150
151        test2 = unittest2.FunctionTestCase(lambda: None)
152        test3 = unittest2.FunctionTestCase(lambda: None)
153        child = unittest2.TestSuite((Test1('test2'), test2))
154        parent = unittest2.TestSuite((test3, child, Test1('test1')))
155
156        self.assertEqual(parent.countTestCases(), 4)
157
158    # "Run the tests associated with this suite, collecting the result into
159    # the test result object passed as result."
160    #
161    # And if there are no tests? What then?
162    def test_run__empty_suite(self):
163        events = []
164        result = LoggingResult(events)
165
166        suite = unittest2.TestSuite()
167
168        suite.run(result)
169
170        self.assertEqual(events, [])
171
172    # "Note that unlike TestCase.run(), TestSuite.run() requires the
173    # "result object to be passed in."
174    def test_run__requires_result(self):
175        suite = unittest2.TestSuite()
176
177        try:
178            suite.run()
179        except TypeError:
180            pass
181        else:
182            self.fail("Failed to raise TypeError")
183
184    # "Run the tests associated with this suite, collecting the result into
185    # the test result object passed as result."
186    def test_run(self):
187        events = []
188        result = LoggingResult(events)
189
190        class LoggingCase(unittest2.TestCase):
191            def run(self, result):
192                events.append('run %s' % self._testMethodName)
193
194            def test1(self): pass
195            def test2(self): pass
196
197        tests = [LoggingCase('test1'), LoggingCase('test2')]
198
199        unittest2.TestSuite(tests).run(result)
200
201        self.assertEqual(events, ['run test1', 'run test2'])
202
203    # "Add a TestCase ... to the suite"
204    def test_addTest__TestCase(self):
205        class Foo(unittest2.TestCase):
206            def test(self): pass
207
208        test = Foo('test')
209        suite = unittest2.TestSuite()
210
211        suite.addTest(test)
212
213        self.assertEqual(suite.countTestCases(), 1)
214        self.assertEqual(list(suite), [test])
215
216    # "Add a ... TestSuite to the suite"
217    def test_addTest__TestSuite(self):
218        class Foo(unittest2.TestCase):
219            def test(self): pass
220
221        suite_2 = unittest2.TestSuite([Foo('test')])
222
223        suite = unittest2.TestSuite()
224        suite.addTest(suite_2)
225
226        self.assertEqual(suite.countTestCases(), 1)
227        self.assertEqual(list(suite), [suite_2])
228
229    # "Add all the tests from an iterable of TestCase and TestSuite
230    # instances to this test suite."
231    #
232    # "This is equivalent to iterating over tests, calling addTest() for
233    # each element"
234    def test_addTests(self):
235        class Foo(unittest2.TestCase):
236            def test_1(self): pass
237            def test_2(self): pass
238
239        test_1 = Foo('test_1')
240        test_2 = Foo('test_2')
241        inner_suite = unittest2.TestSuite([test_2])
242
243        def gen():
244            yield test_1
245            yield test_2
246            yield inner_suite
247
248        suite_1 = unittest2.TestSuite()
249        suite_1.addTests(gen())
250
251        self.assertEqual(list(suite_1), list(gen()))
252
253        # "This is equivalent to iterating over tests, calling addTest() for
254        # each element"
255        suite_2 = unittest2.TestSuite()
256        for t in gen():
257            suite_2.addTest(t)
258
259        self.assertEqual(suite_1, suite_2)
260
261    # "Add all the tests from an iterable of TestCase and TestSuite
262    # instances to this test suite."
263    #
264    # What happens if it doesn't get an iterable?
265    def test_addTest__noniterable(self):
266        suite = unittest2.TestSuite()
267
268        try:
269            suite.addTests(5)
270        except TypeError:
271            pass
272        else:
273            self.fail("Failed to raise TypeError")
274
275    def test_addTest__noncallable(self):
276        suite = unittest2.TestSuite()
277        self.assertRaises(TypeError, suite.addTest, 5)
278
279    def test_addTest__casesuiteclass(self):
280        suite = unittest2.TestSuite()
281        self.assertRaises(TypeError, suite.addTest, Test_TestSuite)
282        self.assertRaises(TypeError, suite.addTest, unittest2.TestSuite)
283
284    def test_addTests__string(self):
285        suite = unittest2.TestSuite()
286        self.assertRaises(TypeError, suite.addTests, "foo")
287
288    def test_function_in_suite(self):
289        def f(_):
290            pass
291        suite = unittest2.TestSuite()
292        suite.addTest(f)
293
294        # when the bug is fixed this line will not crash
295        suite.run(unittest2.TestResult())
296
297
298    def test_basetestsuite(self):
299        class Test(unittest2.TestCase):
300            wasSetUp = False
301            wasTornDown = False
302            @classmethod
303            def setUpClass(cls):
304                cls.wasSetUp = True
305            @classmethod
306            def tearDownClass(cls):
307                cls.wasTornDown = True
308            def testPass(self):
309                pass
310            def testFail(self):
311                fail
312        class Module(object):
313            wasSetUp = False
314            wasTornDown = False
315            @staticmethod
316            def setUpModule():
317                Module.wasSetUp = True
318            @staticmethod
319            def tearDownModule():
320                Module.wasTornDown = True
321
322        Test.__module__ = 'Module'
323        sys.modules['Module'] = Module
324        self.addCleanup(sys.modules.pop, 'Module')
325
326        suite = unittest2.BaseTestSuite()
327        suite.addTests([Test('testPass'), Test('testFail')])
328        self.assertEqual(suite.countTestCases(), 2)
329
330        result = unittest2.TestResult()
331        suite.run(result)
332        self.assertFalse(Module.wasSetUp)
333        self.assertFalse(Module.wasTornDown)
334        self.assertFalse(Test.wasSetUp)
335        self.assertFalse(Test.wasTornDown)
336        self.assertEqual(len(result.errors), 1)
337        self.assertEqual(len(result.failures), 0)
338        self.assertEqual(result.testsRun, 2)
339
340if __name__ == '__main__':
341    unittest2.main()
342