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

82 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2025-04-14 00:18 +0000

1import os 1iabfghcde

2import subprocess 1iabfghcde

3import sys 1iabfghcde

4from pathlib import Path 1iabfghcde

5from unittest import mock 1iabfghcde

6 

7import shellingham 1iabfghcde

8import typer 1iabfghcde

9from typer.testing import CliRunner 1iabfghcde

10 

11from docs_src.commands.index import tutorial001 as mod 1iabfghcde

12 

13from ..utils import requires_completion_permission 1iabfghcde

14 

15runner = CliRunner() 1iabfghcde

16app = typer.Typer() 1iabfghcde

17app.command()(mod.main) 1iabfghcde

18 

19 

20@requires_completion_permission 1iabfghcde

21def test_completion_install_no_shell(): 1abfghcde

22 result = subprocess.run( 1iabfghcde

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

24 capture_output=True, 

25 encoding="utf-8", 

26 env={ 

27 **os.environ, 

28 "_TYPER_COMPLETE_TEST_DISABLE_SHELL_DETECTION": "True", 

29 }, 

30 ) 

31 assert "Option '--install-completion' requires an argument" in result.stderr 1iabfghcde

32 

33 

34@requires_completion_permission 1iabfghcde

35def test_completion_install_bash(): 1abfghcde

36 bash_completion_path: Path = Path.home() / ".bashrc" 1iabfghcde

37 text = "" 1iabfghcde

38 if bash_completion_path.is_file(): 1iabfghcde

39 text = bash_completion_path.read_text() 1iabcde

40 result = subprocess.run( 1iabfghcde

41 [ 

42 sys.executable, 

43 "-m", 

44 "coverage", 

45 "run", 

46 mod.__file__, 

47 "--install-completion", 

48 "bash", 

49 ], 

50 capture_output=True, 

51 encoding="utf-8", 

52 env={ 

53 **os.environ, 

54 "_TYPER_COMPLETE_TEST_DISABLE_SHELL_DETECTION": "True", 

55 }, 

56 ) 

57 new_text = bash_completion_path.read_text() 1iabfghcde

58 bash_completion_path.write_text(text) 1iabfghcde

59 install_source = Path(".bash_completions/tutorial001.py.sh") 1iabfghcde

60 assert str(install_source) not in text 1iabfghcde

61 assert str(install_source) in new_text 1iabfghcde

62 assert "completion installed in" in result.stdout 1iabfghcde

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

64 install_source_path = Path.home() / install_source 1iabfghcde

65 assert install_source_path.is_file() 1iabfghcde

66 install_content = install_source_path.read_text() 1iabfghcde

67 install_source_path.unlink() 1iabfghcde

68 assert ( 1iabfghcde

69 "complete -o default -F _tutorial001py_completion tutorial001.py" 

70 in install_content 

71 ) 

72 

73 

74@requires_completion_permission 1iabfghcde

75def test_completion_install_zsh(): 1abfghcde

76 completion_path: Path = Path.home() / ".zshrc" 1iabfghcde

77 text = "" 1iabfghcde

78 if not completion_path.is_file(): # pragma: no cover 1iabfghcde

79 completion_path.write_text('echo "custom .zshrc"') 1iabfghcde

80 if completion_path.is_file(): 1iabfghcde

81 text = completion_path.read_text() 1iabfghcde

82 result = subprocess.run( 1iabfghcde

83 [ 

84 sys.executable, 

85 "-m", 

86 "coverage", 

87 "run", 

88 mod.__file__, 

89 "--install-completion", 

90 "zsh", 

91 ], 

92 capture_output=True, 

93 encoding="utf-8", 

94 env={ 

95 **os.environ, 

96 "_TYPER_COMPLETE_TEST_DISABLE_SHELL_DETECTION": "True", 

97 }, 

98 ) 

99 new_text = completion_path.read_text() 1iabfghcde

100 completion_path.write_text(text) 1iabfghcde

101 zfunc_fragment = "fpath+=~/.zfunc" 1iabfghcde

102 assert zfunc_fragment in new_text 1iabfghcde

103 assert "completion installed in" in result.stdout 1iabfghcde

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

105 install_source_path = Path.home() / ".zfunc/_tutorial001.py" 1iabfghcde

106 assert install_source_path.is_file() 1iabfghcde

107 install_content = install_source_path.read_text() 1iabfghcde

108 install_source_path.unlink() 1iabfghcde

109 assert "compdef _tutorial001py_completion tutorial001.py" in install_content 1iabfghcde

110 

111 

112@requires_completion_permission 1iabfghcde

113def test_completion_install_fish(): 1abfghcde

114 script_path = Path(mod.__file__) 1iabfghcde

115 completion_path: Path = ( 1abfghcde

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

117 ) 

118 result = subprocess.run( 1iabfghcde

119 [ 

120 sys.executable, 

121 "-m", 

122 "coverage", 

123 "run", 

124 mod.__file__, 

125 "--install-completion", 

126 "fish", 

127 ], 

128 capture_output=True, 

129 encoding="utf-8", 

130 env={ 

131 **os.environ, 

132 "_TYPER_COMPLETE_TEST_DISABLE_SHELL_DETECTION": "True", 

133 }, 

134 ) 

135 new_text = completion_path.read_text() 1iabfghcde

136 completion_path.unlink() 1iabfghcde

137 assert "complete --command tutorial001.py" in new_text 1iabfghcde

138 assert "completion installed in" in result.stdout 1iabfghcde

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

140 

141 

142@requires_completion_permission 1iabfghcde

143def test_completion_install_powershell(): 1abfghcde

144 completion_path: Path = ( 1abfghcde

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

146 ) 

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

148 text = "" 1iabfghcde

149 if completion_path.is_file(): # pragma: no cover 1iabfghcde

150 text = completion_path.read_text() 

151 

152 with mock.patch.object( 1iabfghcde

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

154 ): 

155 with mock.patch.object( 1iabfghcde

156 subprocess, 

157 "run", 

158 return_value=subprocess.CompletedProcess( 

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

160 ), 

161 ): 

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

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

164 parent: Path = completion_path.parent 1iabfghcde

165 parent.mkdir(parents=True, exist_ok=True) 1iabfghcde

166 completion_path.write_text(install_script) 1iabfghcde

167 new_text = completion_path.read_text() 1iabfghcde

168 completion_path.write_text(text) 1iabfghcde

169 assert install_script not in text 1iabfghcde

170 assert install_script in new_text 1iabfghcde

171 assert "completion installed in" in result.stdout 1iabfghcde

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