test_completion.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. import os
  2. import sys
  3. import pytest
  4. def test_completion_for_bash(script):
  5. """
  6. Test getting completion for bash shell
  7. """
  8. bash_completion = """\
  9. _pip_completion()
  10. {
  11. COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \\
  12. COMP_CWORD=$COMP_CWORD \\
  13. PIP_AUTO_COMPLETE=1 $1 ) )
  14. }
  15. complete -o default -F _pip_completion pip"""
  16. result = script.pip('completion', '--bash')
  17. assert bash_completion in result.stdout, 'bash completion is wrong'
  18. def test_completion_for_zsh(script):
  19. """
  20. Test getting completion for zsh shell
  21. """
  22. zsh_completion = """\
  23. function _pip_completion {
  24. local words cword
  25. read -Ac words
  26. read -cn cword
  27. reply=( $( COMP_WORDS="$words[*]" \\
  28. COMP_CWORD=$(( cword-1 )) \\
  29. PIP_AUTO_COMPLETE=1 $words[1] ) )
  30. }
  31. compctl -K _pip_completion pip"""
  32. result = script.pip('completion', '--zsh')
  33. assert zsh_completion in result.stdout, 'zsh completion is wrong'
  34. def test_completion_for_fish(script):
  35. """
  36. Test getting completion for fish shell
  37. """
  38. fish_completion = """\
  39. function __fish_complete_pip
  40. set -lx COMP_WORDS (commandline -o) ""
  41. set -lx COMP_CWORD ( \\
  42. math (contains -i -- (commandline -t) $COMP_WORDS)-1 \\
  43. )
  44. set -lx PIP_AUTO_COMPLETE 1
  45. string split \\ -- (eval $COMP_WORDS[1])
  46. end
  47. complete -fa "(__fish_complete_pip)" -c pip"""
  48. result = script.pip('completion', '--fish')
  49. assert fish_completion in result.stdout, 'fish completion is wrong'
  50. def test_completion_for_unknown_shell(script):
  51. """
  52. Test getting completion for an unknown shell
  53. """
  54. error_msg = 'no such option: --myfooshell'
  55. result = script.pip('completion', '--myfooshell', expect_error=True)
  56. assert error_msg in result.stderr, 'tests for an unknown shell failed'
  57. def test_completion_alone(script):
  58. """
  59. Test getting completion for none shell, just pip completion
  60. """
  61. result = script.pip('completion', expect_error=True)
  62. assert 'ERROR: You must pass --bash or --fish or --zsh' in result.stderr, \
  63. 'completion alone failed -- ' + result.stderr
  64. def setup_completion(script, words, cword, cwd=None):
  65. script.environ = os.environ.copy()
  66. script.environ['PIP_AUTO_COMPLETE'] = '1'
  67. script.environ['COMP_WORDS'] = words
  68. script.environ['COMP_CWORD'] = cword
  69. # expect_error is True because autocomplete exists with 1 status code
  70. result = script.run(
  71. 'python', '-c', 'import pip._internal;pip._internal.autocomplete()',
  72. expect_error=True,
  73. cwd=cwd,
  74. )
  75. return result, script
  76. def test_completion_for_un_snippet(script):
  77. """
  78. Test getting completion for ``un`` should return uninstall
  79. """
  80. res, env = setup_completion(script, 'pip un', '1')
  81. assert res.stdout.strip().split() == ['uninstall'], res.stdout
  82. def test_completion_for_default_parameters(script):
  83. """
  84. Test getting completion for ``--`` should contain --help
  85. """
  86. res, env = setup_completion(script, 'pip --', '1')
  87. assert '--help' in res.stdout,\
  88. "autocomplete function could not complete ``--``"
  89. def test_completion_option_for_command(script):
  90. """
  91. Test getting completion for ``--`` in command (e.g. ``pip search --``)
  92. """
  93. res, env = setup_completion(script, 'pip search --', '2')
  94. assert '--help' in res.stdout,\
  95. "autocomplete function could not complete ``--``"
  96. def test_completion_short_option(script):
  97. """
  98. Test getting completion for short options after ``-`` (eg. pip -)
  99. """
  100. res, env = setup_completion(script, 'pip -', '1')
  101. assert '-h' in res.stdout.split(),\
  102. "autocomplete function could not complete short options after ``-``"
  103. def test_completion_short_option_for_command(script):
  104. """
  105. Test getting completion for short options after ``-`` in command
  106. (eg. pip search -)
  107. """
  108. res, env = setup_completion(script, 'pip search -', '2')
  109. assert '-h' in res.stdout.split(),\
  110. "autocomplete function could not complete short options after ``-``"
  111. def test_completion_files_after_option(script, data):
  112. """
  113. Test getting completion for <file> or <dir> after options in command
  114. (e.g. ``pip install -r``)
  115. """
  116. res, env = setup_completion(
  117. script=script,
  118. words=('pip install -r r'),
  119. cword='3',
  120. cwd=data.completion_paths,
  121. )
  122. assert 'requirements.txt' in res.stdout, (
  123. "autocomplete function could not complete <file> "
  124. "after options in command"
  125. )
  126. assert os.path.join('resources', '') in res.stdout, (
  127. "autocomplete function could not complete <dir> "
  128. "after options in command"
  129. )
  130. assert not any(out in res.stdout for out in
  131. (os.path.join('REPLAY', ''), 'README.txt')), (
  132. "autocomplete function completed <file> or <dir> that "
  133. "should not be completed"
  134. )
  135. if sys.platform != 'win32':
  136. return
  137. assert 'readme.txt' in res.stdout, (
  138. "autocomplete function could not complete <file> "
  139. "after options in command"
  140. )
  141. assert os.path.join('replay', '') in res.stdout, (
  142. "autocomplete function could not complete <dir> "
  143. "after options in command"
  144. )
  145. def test_completion_not_files_after_option(script, data):
  146. """
  147. Test not getting completion files after options which not applicable
  148. (e.g. ``pip install``)
  149. """
  150. res, env = setup_completion(
  151. script=script,
  152. words=('pip install r'),
  153. cword='2',
  154. cwd=data.completion_paths,
  155. )
  156. assert not any(out in res.stdout for out in
  157. ('requirements.txt', 'readme.txt',)), (
  158. "autocomplete function completed <file> when "
  159. "it should not complete"
  160. )
  161. assert not any(os.path.join(out, '') in res.stdout
  162. for out in ('replay', 'resources')), (
  163. "autocomplete function completed <dir> when "
  164. "it should not complete"
  165. )
  166. def test_completion_directories_after_option(script, data):
  167. """
  168. Test getting completion <dir> after options in command
  169. (e.g. ``pip --cache-dir``)
  170. """
  171. res, env = setup_completion(
  172. script=script,
  173. words=('pip --cache-dir r'),
  174. cword='2',
  175. cwd=data.completion_paths,
  176. )
  177. assert os.path.join('resources', '') in res.stdout, (
  178. "autocomplete function could not complete <dir> after options"
  179. )
  180. assert not any(out in res.stdout for out in (
  181. 'requirements.txt', 'README.txt', os.path.join('REPLAY', ''))), (
  182. "autocomplete function completed <dir> when "
  183. "it should not complete"
  184. )
  185. if sys.platform == 'win32':
  186. assert os.path.join('replay', '') in res.stdout, (
  187. "autocomplete function could not complete <dir> after options"
  188. )
  189. def test_completion_subdirectories_after_option(script, data):
  190. """
  191. Test getting completion <dir> after options in command
  192. given path of a directory
  193. """
  194. res, env = setup_completion(
  195. script=script,
  196. words=('pip --cache-dir ' + os.path.join('resources', '')),
  197. cword='2',
  198. cwd=data.completion_paths,
  199. )
  200. assert os.path.join('resources',
  201. os.path.join('images', '')) in res.stdout, (
  202. "autocomplete function could not complete <dir> "
  203. "given path of a directory after options"
  204. )
  205. def test_completion_path_after_option(script, data):
  206. """
  207. Test getting completion <path> after options in command
  208. given absolute path
  209. """
  210. res, env = setup_completion(
  211. script=script,
  212. words=('pip install -e ' + os.path.join(data.completion_paths, 'R')),
  213. cword='3',
  214. )
  215. assert all(os.path.normcase(os.path.join(data.completion_paths, out))
  216. in res.stdout for out in (
  217. 'README.txt', os.path.join('REPLAY', ''))), (
  218. "autocomplete function could not complete <path> "
  219. "after options in command given absolute path"
  220. )
  221. @pytest.mark.parametrize('flag', ['--bash', '--zsh', '--fish'])
  222. def test_completion_uses_same_executable_name(script, flag):
  223. expect_stderr = sys.version_info[:2] == (3, 3)
  224. executable_name = 'pip{}'.format(sys.version_info[0])
  225. result = script.run(
  226. executable_name, 'completion', flag, expect_stderr=expect_stderr
  227. )
  228. assert executable_name in result.stdout