|
2 | 2 | # Copyright (C) 2011-2016 by Yann Kaiser and contributors. See AUTHORS and
|
3 | 3 | # COPYING for details.
|
4 | 4 |
|
5 |
| -import os |
| 5 | +import pathlib |
6 | 6 | import sys
|
7 |
| -import shutil |
8 | 7 | import unittest
|
9 | 8 | from io import StringIO
|
10 | 9 |
|
11 |
| -from clize.tests.util import Fixtures, Tests |
| 10 | +import repeated_test |
| 11 | +from repeated_test import options |
| 12 | + |
12 | 13 | from clize import runner, errors
|
| 14 | +from clize.tests.util import Fixtures, Tests |
13 | 15 |
|
14 | 16 |
|
15 | 17 | class MockModule(object):
|
@@ -43,107 +45,96 @@ def _test(self, filename, name, package, result):
|
43 | 45 |
|
44 | 46 | def test_pudb_script(self):
|
45 | 47 | module = BadModule(sp+'pack/cli.py', '__main__')
|
46 |
| - self.assertRaises(AttributeError, runner.main_module_name, module) |
| 48 | + self.assertEqual(None, runner.main_module_name(module)) |
47 | 49 |
|
48 | 50 |
|
49 |
| -class GetExcecutableTests(Fixtures): |
50 |
| - def _test(self, path, default, result, which='/usr/bin'): |
51 |
| - which_backup = getattr(shutil, 'which', None) |
52 |
| - def which_(name, *args, **kwargs): |
| 51 | +@repeated_test.with_options_matrix( |
| 52 | + to_path=[pathlib.PurePosixPath, pathlib.PureWindowsPath] |
| 53 | +) |
| 54 | +class GetExecutableTests(Fixtures): |
| 55 | + def _test(self, path, expected, *, which=None, to_path): |
| 56 | + def which_(name): |
53 | 57 | if which:
|
54 |
| - return os.path.join('/usr/bin', name) |
| 58 | + return str(to_path(which, name)) |
55 | 59 | else:
|
56 | 60 | return None
|
57 |
| - shutil.which = which_ |
58 |
| - if which is None: |
59 |
| - del shutil.which |
60 |
| - try: |
61 |
| - ret = runner.get_executable(path, default) |
62 |
| - self.assertEqual(ret, result) |
63 |
| - finally: |
64 |
| - if which_backup: |
65 |
| - shutil.which = which_backup |
66 |
| - elif which is not None: |
67 |
| - del shutil.which |
68 |
| - |
69 |
| - none = None, 'python', 'python' |
70 |
| - empty = '', 'myapp', 'myapp' |
71 |
| - dotpy = '/a/path/leading/to/myapp.py', None, '/a/path/leading/to/myapp.py' |
72 |
| - in_path = '/usr/bin/myapp', None, 'myapp' |
73 |
| - in_path_2 = '/usr/bin/myapp', None, 'myapp', None |
74 |
| - not_in_path = '/opt/myapp/bin/myapp', None, '/opt/myapp/bin/myapp' |
75 |
| - relpath = 'myapp/bin/myapp', None, 'myapp/bin/myapp', '' |
76 |
| - parentpath = '../myapp/bin/myapp', None, '../myapp/bin/myapp', '' |
77 |
| - parentpath_2 = '../myapp/bin/myapp', None, '../myapp/bin/myapp', None |
78 |
| - |
79 |
| - def test_run_with_no_which(self): |
80 |
| - try: |
81 |
| - which_backup = shutil.which |
82 |
| - except AttributeError: # pragma: no cover |
83 |
| - return |
84 |
| - del shutil.which |
85 |
| - try: |
86 |
| - self._test(*GetExcecutableTests.empty) |
87 |
| - self.assertFalse(hasattr(shutil, 'which')) |
88 |
| - self._test(*GetExcecutableTests.in_path_2) |
89 |
| - self.assertFalse(hasattr(shutil, 'which')) |
90 |
| - finally: |
91 |
| - shutil.which = which_backup |
| 61 | + ret = runner._get_executable(path, which=which_, to_path=to_path) |
| 62 | + self.assertEqual(ret, expected) |
| 63 | + |
| 64 | + none = None, None |
| 65 | + empty = '', None |
| 66 | + |
| 67 | + with options(to_path=pathlib.PurePosixPath): |
| 68 | + posix_dotpy = '/a/path/leading/to/myapp.py', '/a/path/leading/to/myapp.py' |
| 69 | + posix_in_path = '/usr/bin/myapp', 'myapp', options(which='/usr/bin') |
| 70 | + posix_not_in_path = '/opt/myapp/bin/myapp', '/opt/myapp/bin/myapp' |
| 71 | + posix_not_from_path = '/opt/myapp/bin/myapp', '/opt/myapp/bin/myapp', options(which='/usr/bin') |
| 72 | + posix_relpath = 'myapp/bin/myapp', 'myapp/bin/myapp', options(which='') |
| 73 | + posix_parentpath_also_in_path = '../myapp/bin/myapp', '../myapp/bin/myapp', options(which='') |
| 74 | + posix_parentpath = '../myapp/bin/myapp', '../myapp/bin/myapp', options(which=None) |
| 75 | + |
| 76 | + with options(to_path=pathlib.PureWindowsPath): |
| 77 | + win_dotpy = "C:/a/path/leading/to/myapp.py", r"C:\a\path\leading\to\myapp.py" |
| 78 | + win_in_path = 'C:/Program Files/myapp/bin/myapp.py', 'myapp.py', options(which='C:/Program Files/myapp/bin/') |
| 79 | + win_not_in_path = 'C:/Users/Myself/Documents/myapp', r'C:\Users\Myself\Documents\myapp' |
| 80 | + win_not_from_path = 'C:/Users/Myself/Documents/myapp', r'C:\Users\Myself\Documents\myapp', options(which='C:/system32') |
| 81 | + win_relpath = './my/folder/myapp.py', r'my\folder\myapp.py', options(which=None) |
| 82 | + win_parentpath_also_in_path = '../myapp/bin/myapp', r'..\myapp\bin\myapp', options(which='') |
| 83 | + win_parentpath = '../myapp/bin/myapp', r'..\myapp\bin\myapp', options(which=None) |
| 84 | + win_diff_drives = 'D:/myapp/bin/myapp', r"D:\myapp\bin\myapp", options(which="C:/myapp/bin/myapp") |
92 | 85 |
|
93 | 86 |
|
94 |
| -def get_executable(path, default): |
95 |
| - return default |
| 87 | +def get_executable_verbatim(path): |
| 88 | + return path |
96 | 89 |
|
97 | 90 |
|
| 91 | +@repeated_test.with_options_matrix(platform=["anythingreally", "win32"], executable=["interpreter"], get_executable=[get_executable_verbatim]) |
98 | 92 | class FixArgvTests(Fixtures):
|
99 |
| - def _test(self, argv, path, main, expect): |
100 |
| - def get_executable(path, default): |
101 |
| - return default |
102 |
| - _get_executable = runner.get_executable |
103 |
| - runner.get_executable = get_executable |
104 |
| - try: |
105 |
| - module = MockModule(*main) |
106 |
| - self.assertEqual(expect, runner.fix_argv(argv, path, module)) |
107 |
| - finally: |
108 |
| - runner.get_executable = _get_executable |
| 93 | + def _test(self, argv, path, main, expect, *, platform, executable, get_executable): |
| 94 | + module = MockModule(*main) |
| 95 | + self.assertEqual(expect, runner._fix_argv(argv, path, module, executable=executable, platform=platform, get_executable=get_executable)) |
109 | 96 |
|
110 | 97 | plainfile = (
|
111 | 98 | ['afile.py', '...'], ['/path/to/cwd', '/usr/lib/pythonX.Y'],
|
112 | 99 | ['afile.py', '__main__', None],
|
113 |
| - ['afile.py', '...'] |
114 |
| - ) |
| 100 | + ['afile.py', '...'], |
| 101 | + options(platform="anythingreally"), |
| 102 | + ) |
| 103 | + |
| 104 | + plainfile_win = ( |
| 105 | + ['afile.py', '...'], ['/path/to/cwd', '/usr/lib/pythonX.Y'], |
| 106 | + ['afile.py', '__main__', None], |
| 107 | + ['interpreter afile.py', '...'], |
| 108 | + options(platform="win32"), |
| 109 | + ) |
| 110 | + |
115 | 111 | asmodule = (
|
116 | 112 | ['/path/to/cwd/afile.py', '...'], ['', '/usr/lib/pythonX.Y'],
|
117 | 113 | ['/path/to/cwd/afile.py', '__main__', ''],
|
118 |
| - ['python -m afile', '...'] |
| 114 | + ['interpreter -m afile', '...'] |
119 | 115 | )
|
120 | 116 | packedmodule = (
|
121 | 117 | ['/path/to/cwd/apkg/afile.py', '...'], ['', '/usr/lib/pythonX.Y'],
|
122 | 118 | ['/path/to/cwd/apkg/afile.py', '__main__', 'apkg'],
|
123 |
| - ['python -m apkg.afile', '...'] |
| 119 | + ['interpreter -m apkg.afile', '...'] |
124 | 120 | )
|
125 | 121 | packedmain2 = (
|
126 | 122 | ['/path/to/cwd/apkg/__main__.py', '...'], ['', '/usr/lib/pythonX.Y'],
|
127 | 123 | ['/path/to/cwd/apkg/__main__.py', 'apkg.__main__', 'apkg'],
|
128 |
| - ['python -m apkg', '...'] |
| 124 | + ['interpreter -m apkg', '...'] |
129 | 125 | )
|
130 | 126 | packedmain3 = (
|
131 | 127 | ['/path/to/cwd/apkg/__main__.py', '...'], ['', '/usr/lib/pythonX.Y'],
|
132 | 128 | ['/path/to/cwd/apkg/__main__.py', '__main__', 'apkg'],
|
133 |
| - ['python -m apkg', '...'] |
| 129 | + ['interpreter -m apkg', '...'] |
134 | 130 | )
|
135 | 131 |
|
136 | 132 | def test_bad_fakemodule(self):
|
137 |
| - back = runner.get_executable |
138 |
| - runner.get_executable = get_executable |
139 |
| - try: |
140 |
| - module = BadModule('/path/to/cwd/afile.py', '__main__') |
141 |
| - argv = ['afile.py', '...'] |
142 |
| - path = ['', '/usr/lib/pythonX.Y'] |
143 |
| - self.assertEqual(['afile.py', '...'], |
144 |
| - runner.fix_argv(argv, path, module)) |
145 |
| - finally: |
146 |
| - runner.get_executable = back |
| 133 | + module = BadModule('/path/to/cwd/afile.py', '__main__') |
| 134 | + argv = ['afile.py', '...'] |
| 135 | + path = ['', '/usr/lib/pythonX.Y'] |
| 136 | + self.assertEqual(['afile.py', '...'], |
| 137 | + runner._fix_argv(argv, path, module, get_executable=lambda p: '')) |
147 | 138 |
|
148 | 139 |
|
149 | 140 | class GetCliTests(unittest.TestCase):
|
@@ -511,27 +502,24 @@ def test_run_sysargv(self):
|
511 | 502 | bmodules = sys.modules
|
512 | 503 | bargv = sys.argv
|
513 | 504 | bpath = sys.path
|
514 |
| - bget_executable = runner.get_executable |
515 | 505 | try:
|
516 | 506 | sys.modules['__main__'] \
|
517 | 507 | = MockModule('/path/to/cwd/afile.py', '__main__', '')
|
518 | 508 | sys.argv = ['afile.py', '...']
|
519 | 509 | sys.path = [''] + sys.path[1:]
|
520 |
| - runner.get_executable = get_executable |
521 | 510 | def func(arg=1):
|
522 | 511 | raise NotImplementedError
|
523 | 512 | out = StringIO()
|
524 | 513 | err = StringIO()
|
525 | 514 | runner.run(func, exit=False, out=out, err=err)
|
526 | 515 | self.assertFalse(out.getvalue())
|
527 |
| - self.assertEqual(err.getvalue(), |
528 |
| - "python -m afile: Bad value for arg: '...'\n" |
529 |
| - "Usage: python -m afile [arg]\n") |
| 516 | + self.assertRegex(err.getvalue(), |
| 517 | + ".* -m afile: Bad value for arg: '...'\n" |
| 518 | + r"Usage: .* -m afile \[arg\]" "\n") |
530 | 519 | finally:
|
531 | 520 | sys.modules = bmodules
|
532 | 521 | sys.argv = bargv
|
533 | 522 | sys.path = bpath
|
534 |
| - runner.get_executable = bget_executable |
535 | 523 |
|
536 | 524 | def test_run_out(self):
|
537 | 525 | bout = sys.stdout
|
|
0 commit comments