175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport os
275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport re
375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport sys
475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport unittest2
675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass TestDiscovery(unittest2.TestCase):
975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
1075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # Heavily mocked tests so I can avoid hitting the filesystem
1175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def test_get_name_from_path(self):
1275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader = unittest2.TestLoader()
1375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
1475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader._top_level_dir = '/foo'
1575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        name = loader._get_name_from_path('/foo/bar/baz.py')
1675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(name, 'bar.baz')
1775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
1875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not __debug__:
1975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            # asserts are off
2075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
2175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
2275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertRaises(AssertionError,
2375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                          loader._get_name_from_path,
2475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                          '/bar/baz.py')
2575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
2675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def test_find_tests(self):
2775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader = unittest2.TestLoader()
2875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
2975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        original_listdir = os.listdir
3075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def restore_listdir():
3175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.listdir = original_listdir
3275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        original_isfile = os.path.isfile
3375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def restore_isfile():
3475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.path.isfile = original_isfile
3575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        original_isdir = os.path.isdir
3675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def restore_isdir():
3775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.path.isdir = original_isdir
3875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
3975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        path_lists = [['test1.py', 'test2.py', 'not_a_test.py', 'test_dir',
4075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                       'test.foo', 'test-not-a-module.py', 'another_dir'],
4175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                      ['test3.py', 'test4.py', ]]
4275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.listdir = lambda path: path_lists.pop(0)
4375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addCleanup(restore_listdir)
4475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
4575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def isdir(path):
4675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return path.endswith('dir')
4775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.path.isdir = isdir
4875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addCleanup(restore_isdir)
4975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
5075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def isfile(path):
5175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            # another_dir is not a package and so shouldn't be recursed into
5275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return not path.endswith('dir') and not 'another_dir' in path
5375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.path.isfile = isfile
5475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addCleanup(restore_isfile)
5575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
5675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader._get_module_from_name = lambda path: path + ' module'
5775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader.loadTestsFromModule = lambda module: module + ' tests'
5875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
5975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        top_level = os.path.abspath('/foo')
6075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader._top_level_dir = top_level
6175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        suite = list(loader._find_tests(top_level, 'test*.py'))
6275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
6375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        expected = [name + ' module tests' for name in
6475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    ('test1', 'test2')]
6575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        expected.extend([('test_dir.%s' % name) + ' module tests' for name in
6675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    ('test3', 'test4')])
6775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(suite, expected)
6875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
6975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def test_find_tests_with_package(self):
7075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader = unittest2.TestLoader()
7175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
7275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        original_listdir = os.listdir
7375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def restore_listdir():
7475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.listdir = original_listdir
7575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        original_isfile = os.path.isfile
7675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def restore_isfile():
7775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.path.isfile = original_isfile
7875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        original_isdir = os.path.isdir
7975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def restore_isdir():
8075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.path.isdir = original_isdir
8175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
8275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        directories = ['a_directory', 'test_directory', 'test_directory2']
8375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        path_lists = [directories, [], [], []]
8475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.listdir = lambda path: path_lists.pop(0)
8575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addCleanup(restore_listdir)
8675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
8775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.path.isdir = lambda path: True
8875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addCleanup(restore_isdir)
8975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
9075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.path.isfile = lambda path: os.path.basename(path) not in directories
9175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addCleanup(restore_isfile)
9275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
9375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        class Module(object):
9475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            paths = []
9575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            load_tests_args = []
9675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
9775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            def __init__(self, path):
9875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self.path = path
9975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self.paths.append(path)
10075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                if os.path.basename(path) == 'test_directory':
10175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    def load_tests(loader, tests, pattern):
10275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                        self.load_tests_args.append((loader, tests, pattern))
10375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                        return 'load_tests'
10475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    self.load_tests = load_tests
10575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
10675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            def __eq__(self, other):
10775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                return self.path == other.path
10875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
10975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            # Silence py3k warning
11075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            __hash__ = None
11175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
11275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader._get_module_from_name = lambda name: Module(name)
11375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def loadTestsFromModule(module, use_load_tests):
11475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if use_load_tests:
11575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                raise self.failureException('use_load_tests should be False for packages')
11675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return module.path + ' module tests'
11775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader.loadTestsFromModule = loadTestsFromModule
11875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
11975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader._top_level_dir = '/foo'
12075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # this time no '.py' on the pattern so that it can match
12175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # a test package
12275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        suite = list(loader._find_tests('/foo', 'test*'))
12375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
12475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # We should have loaded tests from the test_directory package by calling load_tests
12575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # and directly from the test_directory2 package
12675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(suite,
12775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                         ['load_tests', 'test_directory2' + ' module tests'])
12875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(Module.paths, ['test_directory', 'test_directory2'])
12975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
13075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # load_tests should have been called once with loader, tests and pattern
13175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(Module.load_tests_args,
13275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                         [(loader, 'test_directory' + ' module tests', 'test*')])
13375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
13475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def test_discover(self):
13575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader = unittest2.TestLoader()
13675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
13775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        original_isfile = os.path.isfile
13875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        original_isdir = os.path.isdir
13975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def restore_isfile():
14075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.path.isfile = original_isfile
14175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
14275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.path.isfile = lambda path: False
14375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addCleanup(restore_isfile)
14475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
14575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        orig_sys_path = sys.path[:]
14675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def restore_path():
14775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            sys.path[:] = orig_sys_path
14875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addCleanup(restore_path)
14975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
15075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        full_path = os.path.abspath(os.path.normpath('/foo'))
15175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertRaises(ImportError,
15275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                          loader.discover,
15375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                          '/foo/bar', top_level_dir='/foo')
15475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
15575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(loader._top_level_dir, full_path)
15675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertIn(full_path, sys.path)
15775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
15875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.path.isfile = lambda path: True
15975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.path.isdir = lambda path: True
16075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
16175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def restore_isdir():
16275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.path.isdir = original_isdir
16375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addCleanup(restore_isdir)
16475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
16575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        _find_tests_args = []
16675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def _find_tests(start_dir, pattern):
16775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            _find_tests_args.append((start_dir, pattern))
16875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return ['tests']
16975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader._find_tests = _find_tests
17075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader.suiteClass = str
17175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
17275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        suite = loader.discover('/foo/bar/baz', 'pattern', '/foo/bar')
17375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
17475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        top_level_dir = os.path.abspath(os.path.normpath('/foo/bar'))
17575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        start_dir = os.path.abspath(os.path.normpath('/foo/bar/baz'))
17675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(suite, "['tests']")
17775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(loader._top_level_dir, top_level_dir)
17875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(_find_tests_args, [(start_dir, 'pattern')])
17975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertIn(top_level_dir, sys.path)
18075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
18175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def test_discover_with_modules_that_fail_to_import(self):
18275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader = unittest2.TestLoader()
18375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
18475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        listdir = os.listdir
18575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.listdir = lambda _: ['test_this_does_not_exist.py']
18675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        isfile = os.path.isfile
18775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.path.isfile = lambda _: True
18875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        orig_sys_path = sys.path[:]
18975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def restore():
19075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.path.isfile = isfile
19175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.listdir = listdir
19275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            sys.path[:] = orig_sys_path
19375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addCleanup(restore)
19475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
19575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        suite = loader.discover('.')
19675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertIn(os.getcwd(), sys.path)
19775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(suite.countTestCases(), 1)
19875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        test = list(list(suite)[0])[0] # extract test from suite
19975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
20075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertRaises(ImportError,
20175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            lambda: test.test_this_does_not_exist())
20275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
20375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def test_command_line_handling_parseArgs(self):
20475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # Haha - take that uninstantiable class
20575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program = object.__new__(unittest2.TestProgram)
20675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
20775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        args = []
20875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def do_discovery(argv):
20975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            args.extend(argv)
21075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program._do_discovery = do_discovery
21175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program.parseArgs(['something', 'discover'])
21275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(args, [])
21375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
21475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program.parseArgs(['something', 'discover', 'foo', 'bar'])
21575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(args, ['foo', 'bar'])
21675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
21775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def test_command_line_handling_do_discovery_too_many_arguments(self):
21875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        class Stop(Exception):
21975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            pass
22075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def usageExit():
22175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise Stop
22275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
22375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program = object.__new__(unittest2.TestProgram)
22475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program.usageExit = usageExit
22575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
22675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertRaises(Stop,
22775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            # too many args
22875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            lambda: program._do_discovery(['one', 'two', 'three', 'four']))
22975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
23075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
23175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def test_command_line_handling_do_discovery_calls_loader(self):
23275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program = object.__new__(unittest2.TestProgram)
23375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
23475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        class Loader(object):
23575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            args = []
23675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            def discover(self, start_dir, pattern, top_level_dir):
23775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self.args.append((start_dir, pattern, top_level_dir))
23875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                return 'tests'
23975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
24075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program._do_discovery(['-v'], Loader=Loader)
24175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(program.verbosity, 2)
24275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(program.test, 'tests')
24375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(Loader.args, [('.', 'test*.py', None)])
24475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
24575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Loader.args = []
24675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program = object.__new__(unittest2.TestProgram)
24775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program._do_discovery(['--verbose'], Loader=Loader)
24875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(program.test, 'tests')
24975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(Loader.args, [('.', 'test*.py', None)])
25075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
25175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Loader.args = []
25275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program = object.__new__(unittest2.TestProgram)
25375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program._do_discovery([], Loader=Loader)
25475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(program.test, 'tests')
25575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(Loader.args, [('.', 'test*.py', None)])
25675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
25775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Loader.args = []
25875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program = object.__new__(unittest2.TestProgram)
25975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program._do_discovery(['fish'], Loader=Loader)
26075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(program.test, 'tests')
26175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(Loader.args, [('fish', 'test*.py', None)])
26275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
26375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Loader.args = []
26475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program = object.__new__(unittest2.TestProgram)
26575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program._do_discovery(['fish', 'eggs'], Loader=Loader)
26675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(program.test, 'tests')
26775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(Loader.args, [('fish', 'eggs', None)])
26875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
26975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Loader.args = []
27075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program = object.__new__(unittest2.TestProgram)
27175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program._do_discovery(['fish', 'eggs', 'ham'], Loader=Loader)
27275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(program.test, 'tests')
27375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(Loader.args, [('fish', 'eggs', 'ham')])
27475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
27575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Loader.args = []
27675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program = object.__new__(unittest2.TestProgram)
27775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program._do_discovery(['-s', 'fish'], Loader=Loader)
27875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(program.test, 'tests')
27975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(Loader.args, [('fish', 'test*.py', None)])
28075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
28175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Loader.args = []
28275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program = object.__new__(unittest2.TestProgram)
28375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program._do_discovery(['-t', 'fish'], Loader=Loader)
28475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(program.test, 'tests')
28575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(Loader.args, [('.', 'test*.py', 'fish')])
28675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
28775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Loader.args = []
28875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program = object.__new__(unittest2.TestProgram)
28975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program._do_discovery(['-p', 'fish'], Loader=Loader)
29075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(program.test, 'tests')
29175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(Loader.args, [('.', 'fish', None)])
29275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertFalse(program.failfast)
29375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertFalse(program.catchbreak)
29475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
29575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        args = ['-p', 'eggs', '-s', 'fish', '-v', '-f']
29675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
29775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            import signal
29875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except ImportError:
29975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            signal = None
30075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        else:
30175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            args.append('-c')
30275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Loader.args = []
30375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program = object.__new__(unittest2.TestProgram)
30475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        program._do_discovery(args, Loader=Loader)
30575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(program.test, 'tests')
30675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(Loader.args, [('fish', 'eggs', None)])
30775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(program.verbosity, 2)
30875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertTrue(program.failfast)
30975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if signal is not None:
31075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.assertTrue(program.catchbreak)
31175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
31275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def test_detect_module_clash(self):
31375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        class Module(object):
31475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            __file__ = 'bar/foo.py'
31575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        sys.modules['foo'] = Module
31675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        full_path = os.path.abspath('foo')
31775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        original_listdir = os.listdir
31875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        original_isfile = os.path.isfile
31975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        original_isdir = os.path.isdir
32075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
32175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def cleanup():
32275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.listdir = original_listdir
32375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.path.isfile = original_isfile
32475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            os.path.isdir = original_isdir
32575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            del sys.modules['foo']
32675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if full_path in sys.path:
32775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                sys.path.remove(full_path)
32875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addCleanup(cleanup)
32975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
33075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def listdir(_):
33175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return ['foo.py']
33275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def isfile(_):
33375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return True
33475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def isdir(_):
33575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return True
33675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.listdir = listdir
33775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.path.isfile = isfile
33875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        os.path.isdir = isdir
33975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
34075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader = unittest2.TestLoader()
34175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
34275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        mod_dir = os.path.abspath('bar')
34375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        expected_dir = os.path.abspath('foo')
34475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        msg = re.escape(r"'foo' module incorrectly imported from %r. Expected %r. "
34575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                "Is this module globally installed?" % (mod_dir, expected_dir))
34675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertRaisesRegexp(
34775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            ImportError, '^%s$' % msg, loader.discover,
34875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            start_dir='foo', pattern='foo.py'
34975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        )
35075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(sys.path[0], full_path)
35175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
35275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
35375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def test_discovery_from_dotted_path(self):
35475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader = unittest2.TestLoader()
35575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
35675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        tests = [self]
35775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        expectedPath = os.path.abspath(os.path.dirname(unittest2.test.__file__))
35875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
35975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.wasRun = False
36075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def _find_tests(start_dir, pattern):
36175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.wasRun = True
36275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.assertEqual(start_dir, expectedPath)
36375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return tests
36475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        loader._find_tests = _find_tests
36575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        suite = loader.discover('unittest2.test')
36675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertTrue(self.wasRun)
36775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertEqual(suite._tests, tests)
36875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
36975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
37075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenif __name__ == '__main__':
37175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    unittest2.main()
372