@@ -76,13 +76,15 @@ def tearDown(self):
7676 self .remove ()
7777 super ().tearDown ()
7878
79- def verify_install (self , script = manage_script ):
79+ def verify_install (self , script = None ):
8080 pass
8181
82- def verify_remove (self , script = manage_script ):
82+ def verify_remove (self , script = None ):
8383 pass
8484
85- def install (self , script = manage_script ):
85+ def install (self , script = None ):
86+ if not script :
87+ script = self .manage_script
8688 kwargs = {}
8789 if self .shell :
8890 kwargs ["shell" ] = self .shell
@@ -91,7 +93,9 @@ def install(self, script=manage_script):
9193 self .command .install (** kwargs )
9294 self .verify_install (script = script )
9395
94- def remove (self , script = manage_script ):
96+ def remove (self , script = None ):
97+ if not script :
98+ script = self .manage_script
9599 kwargs = {}
96100 if self .shell :
97101 kwargs ["shell" ] = self .shell
@@ -185,20 +189,49 @@ def test_shell_complete(self):
185189 self .install ()
186190
187191
192+ class _InstalledScriptTestCase (_DefaultCompleteTestCase ):
193+ """
194+ These shell completes use an installed script available on the path
195+ instead of a script directly invoked by path. The difference may
196+ seem trivial - but it is not given how most shells determine if completion
197+ logic should be invoked for a given command.
198+ """
199+
200+ MANAGE_SCRIPT_TMPL = Path (__file__ ).parent / "django_manage.py"
201+ manage_script = "django_manage"
202+ launch_script = "django_manage"
203+
204+ def setUp (self ):
205+ lines = []
206+ with open (self .MANAGE_SCRIPT_TMPL , "r" ) as f :
207+ for line in f .readlines ():
208+ if line .startswith ("#!{{shebang}}" ):
209+ line = f"#!{ sys .executable } \n "
210+ lines .append (line )
211+ exe = Path (sys .executable ).parent / self .manage_script
212+ with open (exe , "w" ) as f :
213+ for line in lines :
214+ f .write (line )
215+
216+ # make the script executable
217+ os .chmod (exe , os .stat (exe ).st_mode | 0o111 )
218+ super ().setUp ()
219+
220+
188221@pytest .mark .skipif (shutil .which ("zsh" ) is None , reason = "Z-Shell not available" )
189222class ZshShellTests (_DefaultCompleteTestCase , TestCase ):
190223
191224 shell = "zsh"
192225 directory = Path ("~/.zfunc" ).expanduser ()
193226
194- def verify_install (self , script = _DefaultCompleteTestCase . manage_script ):
227+ def verify_install (self , script = None ):
195228 if not script :
196- script = self .command . manage_script_name
229+ script = self .manage_script
197230 self .assertTrue ((self .directory / f"_{ script } " ).exists ())
198231
199- def verify_remove (self , script = _DefaultCompleteTestCase . manage_script ):
232+ def verify_remove (self , script = None ):
200233 if not script :
201- script = self .command . manage_script_name
234+ script = self .manage_script
202235 self .assertFalse ((self .directory / f"_{ script } " ).exists ())
203236
204237
@@ -218,17 +251,22 @@ def set_environment(self, fd):
218251 os .write (fd , f"source ~/.bashrc\n " .encode ())
219252 os .write (fd , f"source .venv/bin/activate\n " .encode ())
220253
221- def verify_install (self , script = _DefaultCompleteTestCase . manage_script ):
254+ def verify_install (self , script = None ):
222255 if not script :
223- script = self .command . manage_script_name
256+ script = self .manage_script
224257 self .assertTrue ((self .directory / f"{ script } .sh" ).exists ())
225258
226- def verify_remove (self , script = _DefaultCompleteTestCase . manage_script ):
259+ def verify_remove (self , script = None ):
227260 if not script :
228- script = self .command . manage_script_name
261+ script = self .manage_script
229262 self .assertFalse ((self .directory / f"{ script } .sh" ).exists ())
230263
231264
265+ @pytest .mark .skipif (shutil .which ("bash" ) is None , reason = "Bash not available" )
266+ class BashExeShellTests (_InstalledScriptTestCase , TestCase ):
267+ pass
268+
269+
232270@pytest .mark .skipif (shutil .which ("pwsh" ) is None , reason = "Powershell not available" )
233271class PowerShellTests (_DefaultCompleteTestCase , TestCase ):
234272
@@ -257,18 +295,18 @@ def test_shell_complete(self):
257295 self .install ()
258296 self .remove ()
259297
260- def verify_install (self , script = _DefaultCompleteTestCase . manage_script ):
298+ def verify_install (self , script = None ):
261299 if not script :
262- script = self .command . manage_script_name
300+ script = self .manage_script
263301 self .assertTrue ((self .directory / f"Microsoft.PowerShell_profile.ps1" ).exists ())
264302 self .assertTrue (
265303 f"Register-ArgumentCompleter -Native -CommandName { script } -ScriptBlock $scriptblock"
266304 in (self .directory / f"Microsoft.PowerShell_profile.ps1" ).read_text ()
267305 )
268306
269- def verify_remove (self , script = _DefaultCompleteTestCase . manage_script ):
307+ def verify_remove (self , script = None ):
270308 if not script :
271- script = self .command . manage_script_name
309+ script = self .manage_script
272310 if (self .directory / f"Microsoft.PowerShell_profile.ps1" ).exists ():
273311 contents = (
274312 self .directory / f"Microsoft.PowerShell_profile.ps1"
0 commit comments