Coverage for tests / test_completion / test_completion_install.py: 100%

80 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-03-26 21:46 +0000

1import os 1abcfgde

2import subprocess 1abcfgde

3import sys 1abcfgde

4from pathlib import Path 1abcfgde

5from unittest import mock 1abcfgde

6 

7import shellingham 1abcfgde

8from typer.testing import CliRunner 1abcfgde

9 

10from docs_src.typer_app import tutorial001_py310 as mod 1abcfgde

11 

12from ..utils import requires_completion_permission 1abcfgde

13 

14runner = CliRunner() 1abcfgde

15app = mod.app 1abcfgde

16 

17 

18@requires_completion_permission 1abcfgde

19def test_completion_install_no_shell(): 1abcfgde

20 result = subprocess.run( 1abcfgde

21 [sys.executable, "-m", "coverage", "run", mod.__file__, "--install-completion"], 

22 capture_output=True, 

23 encoding="utf-8", 

24 env={ 

25 **os.environ, 

26 "_TYPER_COMPLETE_TEST_DISABLE_SHELL_DETECTION": "True", 

27 }, 

28 ) 

29 assert "Option '--install-completion' requires an argument" in result.stderr 1abcfgde

30 

31 

32@requires_completion_permission 1abcfgde

33def test_completion_install_bash(): 1abcfgde

34 bash_completion_path: Path = Path.home() / ".bashrc" 1abcfgde

35 text = "" 1abcfgde

36 if bash_completion_path.is_file(): 1abcfgde

37 text = bash_completion_path.read_text() 1abcde

38 result = subprocess.run( 1abcfgde

39 [ 

40 sys.executable, 

41 "-m", 

42 "coverage", 

43 "run", 

44 mod.__file__, 

45 "--install-completion", 

46 "bash", 

47 ], 

48 capture_output=True, 

49 encoding="utf-8", 

50 env={ 

51 **os.environ, 

52 "_TYPER_COMPLETE_TEST_DISABLE_SHELL_DETECTION": "True", 

53 }, 

54 ) 

55 new_text = bash_completion_path.read_text() 1abcfgde

56 bash_completion_path.write_text(text) 1abcfgde

57 install_source = Path(".bash_completions/tutorial001_py310.py.sh") 1abcfgde

58 assert str(install_source) not in text 1abcfgde

59 assert str(install_source) in new_text 1abcfgde

60 assert "completion installed in" in result.stdout 1abcfgde

61 assert "Completion will take effect once you restart the terminal" in result.stdout 1abcfgde

62 install_source_path = Path.home() / install_source 1abcfgde

63 assert install_source_path.is_file() 1abcfgde

64 install_content = install_source_path.read_text() 1abcfgde

65 install_source_path.unlink() 1abcfgde

66 assert ( 1abcfgde

67 "complete -o default -F _tutorial001_py310py_completion tutorial001_py310.py" 

68 in install_content 

69 ) 

70 

71 

72@requires_completion_permission 1abcfgde

73def test_completion_install_zsh(): 1abcfgde

74 completion_path: Path = Path.home() / ".zshrc" 1abcfgde

75 text = "" 1abcfgde

76 if not completion_path.is_file(): # pragma: no cover 1abcfgde

77 completion_path.write_text('echo "custom .zshrc"') 1abcfgde

78 if completion_path.is_file(): 1abcfgde

79 text = completion_path.read_text() 1abcfgde

80 result = subprocess.run( 1abcfgde

81 [ 

82 sys.executable, 

83 "-m", 

84 "coverage", 

85 "run", 

86 mod.__file__, 

87 "--install-completion", 

88 "zsh", 

89 ], 

90 capture_output=True, 

91 encoding="utf-8", 

92 env={ 

93 **os.environ, 

94 "_TYPER_COMPLETE_TEST_DISABLE_SHELL_DETECTION": "True", 

95 }, 

96 ) 

97 new_text = completion_path.read_text() 1abcfgde

98 completion_path.write_text(text) 1abcfgde

99 zfunc_fragment = "fpath+=~/.zfunc" 1abcfgde

100 assert zfunc_fragment in new_text 1abcfgde

101 assert "completion installed in" in result.stdout 1abcfgde

102 assert "Completion will take effect once you restart the terminal" in result.stdout 1abcfgde

103 install_source_path = Path.home() / ".zfunc/_tutorial001_py310.py" 1abcfgde

104 assert install_source_path.is_file() 1abcfgde

105 install_content = install_source_path.read_text() 1abcfgde

106 install_source_path.unlink() 1abcfgde

107 assert ( 1abcfgde

108 "compdef _tutorial001_py310py_completion tutorial001_py310.py" 

109 in install_content 

110 ) 

111 

112 

113@requires_completion_permission 1abcfgde

114def test_completion_install_fish(): 1abcfgde

115 script_path = Path(mod.__file__) 1abcfgde

116 completion_path: Path = ( 1abcfgde

117 Path.home() / f".config/fish/completions/{script_path.name}.fish" 

118 ) 

119 result = subprocess.run( 1abcfgde

120 [ 

121 sys.executable, 

122 "-m", 

123 "coverage", 

124 "run", 

125 mod.__file__, 

126 "--install-completion", 

127 "fish", 

128 ], 

129 capture_output=True, 

130 encoding="utf-8", 

131 env={ 

132 **os.environ, 

133 "_TYPER_COMPLETE_TEST_DISABLE_SHELL_DETECTION": "True", 

134 }, 

135 ) 

136 new_text = completion_path.read_text() 1abcfgde

137 completion_path.unlink() 1abcfgde

138 assert "complete --command tutorial001_py310.py" in new_text 1abcfgde

139 assert "completion installed in" in result.stdout 1abcfgde

140 assert "Completion will take effect once you restart the terminal" in result.stdout 1abcfgde

141 

142 

143@requires_completion_permission 1abcfgde

144def test_completion_install_powershell(): 1abcfgde

145 completion_path: Path = ( 1abcfgde

146 Path.home() / ".config/powershell/Microsoft.PowerShell_profile.ps1" 

147 ) 

148 completion_path_bytes = f"{completion_path}\n".encode("windows-1252") 1abcfgde

149 text = "" 1abcfgde

150 if completion_path.is_file(): # pragma: no cover 1abcfgde

151 text = completion_path.read_text() 

152 

153 with mock.patch.object( 1abcfgde

154 shellingham, "detect_shell", return_value=("pwsh", "/usr/bin/pwsh") 

155 ): 

156 with mock.patch.object( 1abcfgde

157 subprocess, 

158 "run", 

159 return_value=subprocess.CompletedProcess( 

160 ["pwsh"], returncode=0, stdout=completion_path_bytes 

161 ), 

162 ): 

163 result = runner.invoke(app, ["--install-completion"]) 1abcfgde

164 install_script = "Register-ArgumentCompleter -Native -CommandName mocked-typer-testing-app -ScriptBlock $scriptblock" 1abcfgde

165 parent: Path = completion_path.parent 1abcfgde

166 parent.mkdir(parents=True, exist_ok=True) 1abcfgde

167 completion_path.write_text(install_script) 1abcfgde

168 new_text = completion_path.read_text() 1abcfgde

169 completion_path.write_text(text) 1abcfgde

170 assert install_script not in text 1abcfgde

171 assert install_script in new_text 1abcfgde

172 assert "completion installed in" in result.stdout 1abcfgde

173 assert "Completion will take effect once you restart the terminal" in result.stdout 1abcfgde