2121
2222import os
2323
24- import click
25- from click .testing import CliRunner
24+ import attr
2625import pytest
2726
27+ from commoncode .command import execute2
2828from commoncode .fileutils import as_posixpath
2929from commoncode .fileutils import resource_iter
3030from commoncode .testcase import FileDrivenTesting
31- from commoncode .system import on_linux
3231from commoncode .system import on_windows
3332
34- from extractcode import cli
35-
3633test_env = FileDrivenTesting ()
3734test_env .test_data_dir = os .path .join (os .path .dirname (__file__ ), 'data' )
38- project_root = os .path .dirname (os .path .dirname (__file__ ))
39-
35+ project_root = os .path .abspath (os .path .dirname (os .path .dirname (__file__ )))
4036
4137"""
4238These CLI tests are dependent on py.test monkeypatch to ensure we are testing
4339the actual command outputs as if using a TTY or not.
4440"""
4541
4642
47- def test_extractcode_command_can_take_an_empty_directory (monkeypatch ):
43+ @attr .s
44+ class Result :
45+ exit_code = attr .ib ()
46+ output = attr .ib ()
47+
48+
49+ def run_extract (options , expected_rc = None , cwd = None ):
50+ """
51+ Run extractcode as a plain subprocess. Return rc, stdout, stderr.
52+ """
53+ cmd_loc = os .path .join (project_root , 'tmp' , 'bin' , 'extractcode' )
54+ rc , stdout , stderr = execute2 (cmd_loc = cmd_loc , args = options , cwd = cwd )
55+
56+ if expected_rc is not None and rc != expected_rc :
57+ opts = ' ' .join (options )
58+ error = '''
59+ Failure to run: extractcode %(opts)s
60+ stdout:
61+ %(stdout)s
62+
63+ stderr:
64+ %(stderr)s
65+ ''' % locals ()
66+ assert rc == expected_rc , error
67+
68+ return Result (exit_code = rc , output = stdout + stderr )
69+
70+
71+ def test_extractcode_command_can_take_an_empty_directory ():
4872 test_dir = test_env .get_temp_dir ()
49- monkeypatch .setattr (click ._termui_impl , 'isatty' , lambda _ : True )
50- runner = CliRunner ()
51- result = runner .invoke (cli .extractcode , [test_dir ])
52- assert result .exit_code == 0
73+ result = run_extract ([test_dir ], expected_rc = 0 )
74+
5375 assert 'Extracting archives...' in result .output
5476 assert 'Extracting done' in result .output
5577
5678
57- def test_extractcode_command_does_extract_verbose (monkeypatch ):
79+ def test_extractcode_command_does_extract_verbose ():
5880 test_dir = test_env .get_test_loc ('cli/extract' , copy = True )
59- monkeypatch .setattr (click ._termui_impl , 'isatty' , lambda _ : True )
60- runner = CliRunner ()
61- result = runner .invoke (cli .extractcode , ['--verbose' , test_dir ])
62- assert result .exit_code == 1
81+ result = run_extract (['--verbose' , test_dir ], expected_rc = 1 )
82+
6383 assert os .path .exists (os .path .join (test_dir , 'some.tar.gz-extract' ))
6484 expected = [
6585 'Extracting archives...' ,
@@ -74,71 +94,75 @@ def test_extractcode_command_does_extract_verbose(monkeypatch):
7494 assert e in result .output
7595
7696
77- def test_extractcode_command_always_shows_something_if_not_using_a_tty_verbose_or_not (monkeypatch ):
97+ def test_extractcode_command_always_shows_something_if_not_using_a_tty_verbose_or_not ():
7898 test_dir = test_env .get_test_loc ('cli/extract/some.tar.gz' , copy = True )
79- monkeypatch .setattr (click ._termui_impl , 'isatty' , lambda _ : False )
80- runner = CliRunner ()
81- result = runner .invoke (cli .extractcode , ['--verbose' , test_dir ])
99+
100+ result = run_extract (options = ['--verbose' , test_dir ], expected_rc = 0 )
82101 assert all (x in result .output for x in ('Extracting archives...' , 'Extracting: some.tar.gz' , 'Extracting done.' ))
83- result = runner .invoke (cli .extractcode , [test_dir ])
102+
103+ result = run_extract (options = [test_dir ], expected_rc = 0 )
84104 assert all (x in result .output for x in ('Extracting archives...' , 'Extracting done.' ))
85105
86106
87- def test_extractcode_command_works_with_relative_paths (monkeypatch ):
88- # The setup is a tad complex because we want to have a relative dir
89- # to the base dir where we run tests from, i.e. the git checkout dir
90- # To use relative paths, we use our tmp dir at the root of the code tree
91- from os .path import join , abspath
107+ def test_extractcode_command_works_with_relative_paths ():
108+ # The setup is complex because we want to have a relative dir to the base
109+ # dir where we run tests from, i.e. the git checkout dir To use relative
110+ # paths, we use our tmp dir at the root of the code tree
111+ from os .path import join
92112 from commoncode import fileutils
93113 import extractcode
94114 import tempfile
95115 import shutil
96116
97117 try :
118+ test_file = test_env .get_test_loc ('cli/extract_relative_path/basic.zip' )
119+
98120 project_tmp = join (project_root , 'tmp' )
99121 fileutils .create_dir (project_tmp )
100- project_root_abs = abspath (project_root )
101- test_src_dir = tempfile .mkdtemp (dir = project_tmp ).replace (project_root_abs , '' ).strip ('\\ /' )
102- test_file = test_env .get_test_loc ('cli/extract_relative_path/basic.zip' )
103- shutil .copy (test_file , test_src_dir )
104- test_src_file = join (test_src_dir , 'basic.zip' )
122+ temp_rel = tempfile .mkdtemp (dir = project_tmp )
123+ assert os .path .exists (temp_rel )
124+
125+ relative_dir = temp_rel .replace (project_root , '' ).strip ('\\ /' )
126+ shutil .copy (test_file , temp_rel )
127+
128+ test_src_file = join (relative_dir , 'basic.zip' )
105129 test_tgt_dir = join (project_root , test_src_file ) + extractcode .EXTRACT_SUFFIX
130+ result = run_extract ([test_src_file ], expected_rc = 0 , cwd = project_root )
106131
107- runner = CliRunner ()
108- monkeypatch .setattr (click ._termui_impl , 'isatty' , lambda _ : True )
109- result = runner .invoke (cli .extractcode , [test_src_file ])
110- assert result .exit_code == 0
111132 assert 'Extracting done' in result .output
112133 assert not 'WARNING' in result .output
113134 assert not 'ERROR' in result .output
135+
114136 expected = ['/c/a/a.txt' , '/c/b/a.txt' , '/c/c/a.txt' ]
115- file_result = [as_posixpath (f .replace (test_tgt_dir , '' )) for f in fileutils .resource_iter (test_tgt_dir , with_dirs = False )]
137+ file_result = [
138+ as_posixpath (f .replace (test_tgt_dir , '' ))
139+ for f in fileutils .resource_iter (test_tgt_dir , with_dirs = False )]
140+
116141 assert sorted (expected ) == sorted (file_result )
142+
117143 finally :
118- fileutils .delete (test_src_dir )
144+ fileutils .delete (relative_dir )
119145
120146
121- def test_extractcode_command_works_with_relative_paths_verbose (monkeypatch ):
147+ def test_extractcode_command_works_with_relative_paths_verbose ():
122148 # The setup is a tad complex because we want to have a relative dir
123149 # to the base dir where we run tests from, i.e. the git checkout dir
124150 # To use relative paths, we use our tmp dir at the root of the code tree
125- from os .path import join , abspath
151+ from os .path import join
126152 from commoncode import fileutils
127153 import tempfile
128154 import shutil
129155
130156 try :
131157 project_tmp = join (project_root , 'tmp' )
132158 fileutils .create_dir (project_tmp )
133- project_root_abs = abspath (project_root )
134- test_src_dir = tempfile .mkdtemp (dir = project_tmp ).replace (project_root_abs , '' ).strip ('\\ /' )
159+ test_src_dir = tempfile .mkdtemp (dir = project_tmp ).replace (project_root , '' ).strip ('\\ /' )
135160 test_file = test_env .get_test_loc ('cli/extract_relative_path/basic.zip' )
136161 shutil .copy (test_file , test_src_dir )
137162 test_src_file = join (test_src_dir , 'basic.zip' )
138- runner = CliRunner ()
139- monkeypatch .setattr (click ._termui_impl , 'isatty' , lambda _ : True )
140- result = runner .invoke (cli .extractcode , ['--verbose' , test_src_file ])
141- assert result .exit_code == 0
163+
164+ result = run_extract (['--verbose' , test_src_file ] , expected_rc = 2 )
165+
142166 # extract the path from the second line of the output
143167 # check that the path is relative and not absolute
144168 lines = result .output .splitlines (False )
@@ -153,31 +177,28 @@ def test_extractcode_command_works_with_relative_paths_verbose(monkeypatch):
153177 fileutils .delete (test_src_dir )
154178
155179
156- def test_usage_and_help_return_a_correct_script_name_on_all_platforms (monkeypatch ):
157- monkeypatch .setattr (click ._termui_impl , 'isatty' , lambda _ : True )
158- runner = CliRunner ()
159- result = runner .invoke (cli .extractcode , ['--help' ])
180+ def test_usage_and_help_return_a_correct_script_name_on_all_platforms ():
181+ options = ['--help' ]
182+
183+ result = run_extract (options , expected_rc = 0 )
184+
160185 assert 'Usage: extractcode [OPTIONS]' in result .output
161186 # this was showing up on Windows
162187 assert 'extractcode-script.py' not in result .output
163188
164- result = runner . invoke ( cli . extractcode , [])
189+ result = run_extract ( [])
165190 assert 'Usage: extractcode [OPTIONS]' in result .output
166191 # this was showing up on Windows
167192 assert 'extractcode-script.py' not in result .output
168193
169- result = runner . invoke ( cli . extractcode , ['-xyz' ])
194+ result = run_extract ( ['-xyz' ] , expected_rc = 2 )
170195 # this was showing up on Windows
171196 assert 'extractcode-script.py' not in result .output
172197
173198
174- def test_extractcode_command_can_extract_archive_with_unicode_names_verbose (monkeypatch ):
175- monkeypatch .setattr (click ._termui_impl , 'isatty' , lambda _ : True )
199+ def test_extractcode_command_can_extract_archive_with_unicode_names_verbose ():
176200 test_dir = test_env .get_test_loc ('cli/unicodearch' , copy = True )
177- runner = CliRunner ()
178- result = runner .invoke (cli .extractcode , ['--verbose' , test_dir ])
179- assert result .exit_code == 0
180-
201+ result = run_extract (['--verbose' , test_dir ] , expected_rc = 0 )
181202 assert 'Sanders' in result .output
182203
183204 file_result = [
@@ -193,12 +214,9 @@ def test_extractcode_command_can_extract_archive_with_unicode_names_verbose(monk
193214 assert sorted (expected ) == sorted (file_result )
194215
195216
196- def test_extractcode_command_can_extract_archive_with_unicode_names (monkeypatch ):
197- monkeypatch .setattr (click ._termui_impl , 'isatty' , lambda _ : True )
217+ def test_extractcode_command_can_extract_archive_with_unicode_names ():
198218 test_dir = test_env .get_test_loc ('cli/unicodearch' , copy = True )
199- runner = CliRunner ()
200- result = runner .invoke (cli .extractcode , [test_dir ])
201- assert result .exit_code == 0
219+ run_extract ([test_dir ] , expected_rc = 0 )
202220
203221 file_result = [
204222 f for f in map (as_posixpath , resource_iter (test_dir , with_dirs = False ))
@@ -213,12 +231,10 @@ def test_extractcode_command_can_extract_archive_with_unicode_names(monkeypatch)
213231 assert sorted (expected ) == sorted (file_result )
214232
215233
216- def test_extractcode_command_can_extract_shallow (monkeypatch ):
234+ def test_extractcode_command_can_extract_shallow ():
217235 test_dir = test_env .get_test_loc ('cli/extract_shallow' , copy = True )
218- monkeypatch .setattr (click ._termui_impl , 'isatty' , lambda _ : True )
219- runner = CliRunner ()
220- result = runner .invoke (cli .extractcode , ['--shallow' , test_dir ])
221- assert result .exit_code == 0
236+ run_extract (['--shallow' , test_dir ] , expected_rc = 0 )
237+
222238 file_result = [
223239 f for f in map (as_posixpath , resource_iter (test_dir , with_dirs = False ))
224240 if not f .endswith ('unicodepath.tgz' )]
@@ -233,12 +249,9 @@ def test_extractcode_command_can_extract_shallow(monkeypatch):
233249 assert sorted (expected ) == sorted (file_result )
234250
235251
236- def test_extractcode_command_can_ignore (monkeypatch ):
237- monkeypatch .setattr (click ._termui_impl , 'isatty' , lambda _ : True )
252+ def test_extractcode_command_can_ignore ():
238253 test_dir = test_env .get_test_loc ('cli/extract_ignore' , copy = True )
239- runner = CliRunner ()
240- result = runner .invoke (cli .extractcode , ['--ignore' , '*.tar' , test_dir ])
241- assert result .exit_code == 0
254+ run_extract (['--ignore' , '*.tar' , test_dir ] , expected_rc = 0 )
242255
243256 file_result = [
244257 f for f in map (as_posixpath , resource_iter (test_dir , with_dirs = False ))
@@ -255,11 +268,10 @@ def test_extractcode_command_can_ignore(monkeypatch):
255268
256269
257270@pytest .mark .skipif (on_windows , reason = 'FIXME: this test fails on Windows until we have support for long file names.' )
258- def test_extractcode_command_can_extract_nuget (monkeypatch ):
271+ def test_extractcode_command_can_extract_nuget ():
259272 test_dir = test_env .get_test_loc ('cli/extract_nuget' , copy = True )
260- monkeypatch .setattr (click ._termui_impl , 'isatty' , lambda _ : True )
261- runner = CliRunner ()
262- result = runner .invoke (cli .extractcode , ['--verbose' , test_dir ], catch_exceptions = False )
273+ result = run_extract (['--verbose' , test_dir ])
274+
263275 if result .exit_code != 0 :
264276 print (result .output )
265277 assert 'ERROR extracting' not in result .output
0 commit comments