test_testing.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. import os
  2. import sys
  3. from io import BytesIO
  4. import pytest
  5. import click
  6. from click._compat import WIN
  7. from click.testing import CliRunner
  8. def test_runner():
  9. @click.command()
  10. def test():
  11. i = click.get_binary_stream("stdin")
  12. o = click.get_binary_stream("stdout")
  13. while True:
  14. chunk = i.read(4096)
  15. if not chunk:
  16. break
  17. o.write(chunk)
  18. o.flush()
  19. runner = CliRunner()
  20. result = runner.invoke(test, input="Hello World!\n")
  21. assert not result.exception
  22. assert result.output == "Hello World!\n"
  23. def test_echo_stdin_stream():
  24. @click.command()
  25. def test():
  26. i = click.get_binary_stream("stdin")
  27. o = click.get_binary_stream("stdout")
  28. while True:
  29. chunk = i.read(4096)
  30. if not chunk:
  31. break
  32. o.write(chunk)
  33. o.flush()
  34. runner = CliRunner(echo_stdin=True)
  35. result = runner.invoke(test, input="Hello World!\n")
  36. assert not result.exception
  37. assert result.output == "Hello World!\nHello World!\n"
  38. def test_echo_stdin_prompts():
  39. @click.command()
  40. def test_python_input():
  41. foo = input("Foo: ")
  42. click.echo(f"foo={foo}")
  43. runner = CliRunner(echo_stdin=True)
  44. result = runner.invoke(test_python_input, input="bar bar\n")
  45. assert not result.exception
  46. assert result.output == "Foo: bar bar\nfoo=bar bar\n"
  47. @click.command()
  48. @click.option("--foo", prompt=True)
  49. def test_prompt(foo):
  50. click.echo(f"foo={foo}")
  51. result = runner.invoke(test_prompt, input="bar bar\n")
  52. assert not result.exception
  53. assert result.output == "Foo: bar bar\nfoo=bar bar\n"
  54. @click.command()
  55. @click.option("--foo", prompt=True, hide_input=True)
  56. def test_hidden_prompt(foo):
  57. click.echo(f"foo={foo}")
  58. result = runner.invoke(test_hidden_prompt, input="bar bar\n")
  59. assert not result.exception
  60. assert result.output == "Foo: \nfoo=bar bar\n"
  61. @click.command()
  62. @click.option("--foo", prompt=True)
  63. @click.option("--bar", prompt=True)
  64. def test_multiple_prompts(foo, bar):
  65. click.echo(f"foo={foo}, bar={bar}")
  66. result = runner.invoke(test_multiple_prompts, input="one\ntwo\n")
  67. assert not result.exception
  68. assert result.output == "Foo: one\nBar: two\nfoo=one, bar=two\n"
  69. def test_runner_with_stream():
  70. @click.command()
  71. def test():
  72. i = click.get_binary_stream("stdin")
  73. o = click.get_binary_stream("stdout")
  74. while True:
  75. chunk = i.read(4096)
  76. if not chunk:
  77. break
  78. o.write(chunk)
  79. o.flush()
  80. runner = CliRunner()
  81. result = runner.invoke(test, input=BytesIO(b"Hello World!\n"))
  82. assert not result.exception
  83. assert result.output == "Hello World!\n"
  84. runner = CliRunner(echo_stdin=True)
  85. result = runner.invoke(test, input=BytesIO(b"Hello World!\n"))
  86. assert not result.exception
  87. assert result.output == "Hello World!\nHello World!\n"
  88. def test_prompts():
  89. @click.command()
  90. @click.option("--foo", prompt=True)
  91. def test(foo):
  92. click.echo(f"foo={foo}")
  93. runner = CliRunner()
  94. result = runner.invoke(test, input="wau wau\n")
  95. assert not result.exception
  96. assert result.output == "Foo: wau wau\nfoo=wau wau\n"
  97. @click.command()
  98. @click.option("--foo", prompt=True, hide_input=True)
  99. def test(foo):
  100. click.echo(f"foo={foo}")
  101. runner = CliRunner()
  102. result = runner.invoke(test, input="wau wau\n")
  103. assert not result.exception
  104. assert result.output == "Foo: \nfoo=wau wau\n"
  105. def test_getchar():
  106. @click.command()
  107. def continue_it():
  108. click.echo(click.getchar())
  109. runner = CliRunner()
  110. result = runner.invoke(continue_it, input="y")
  111. assert not result.exception
  112. assert result.output == "y\n"
  113. runner = CliRunner(echo_stdin=True)
  114. result = runner.invoke(continue_it, input="y")
  115. assert not result.exception
  116. assert result.output == "y\n"
  117. @click.command()
  118. def getchar_echo():
  119. click.echo(click.getchar(echo=True))
  120. runner = CliRunner()
  121. result = runner.invoke(getchar_echo, input="y")
  122. assert not result.exception
  123. assert result.output == "yy\n"
  124. runner = CliRunner(echo_stdin=True)
  125. result = runner.invoke(getchar_echo, input="y")
  126. assert not result.exception
  127. assert result.output == "yy\n"
  128. def test_catch_exceptions():
  129. class CustomError(Exception):
  130. pass
  131. @click.command()
  132. def cli():
  133. raise CustomError(1)
  134. runner = CliRunner()
  135. result = runner.invoke(cli)
  136. assert isinstance(result.exception, CustomError)
  137. assert type(result.exc_info) is tuple
  138. assert len(result.exc_info) == 3
  139. with pytest.raises(CustomError):
  140. runner.invoke(cli, catch_exceptions=False)
  141. CustomError = SystemExit
  142. result = runner.invoke(cli)
  143. assert result.exit_code == 1
  144. @pytest.mark.skipif(WIN, reason="Test does not make sense on Windows.")
  145. def test_with_color():
  146. @click.command()
  147. def cli():
  148. click.secho("hello world", fg="blue")
  149. runner = CliRunner()
  150. result = runner.invoke(cli)
  151. assert result.output == "hello world\n"
  152. assert not result.exception
  153. result = runner.invoke(cli, color=True)
  154. assert result.output == f"{click.style('hello world', fg='blue')}\n"
  155. assert not result.exception
  156. def test_with_color_but_pause_not_blocking():
  157. @click.command()
  158. def cli():
  159. click.pause()
  160. runner = CliRunner()
  161. result = runner.invoke(cli, color=True)
  162. assert not result.exception
  163. assert result.output == ""
  164. def test_exit_code_and_output_from_sys_exit():
  165. # See issue #362
  166. @click.command()
  167. def cli_string():
  168. click.echo("hello world")
  169. sys.exit("error")
  170. @click.command()
  171. @click.pass_context
  172. def cli_string_ctx_exit(ctx):
  173. click.echo("hello world")
  174. ctx.exit("error")
  175. @click.command()
  176. def cli_int():
  177. click.echo("hello world")
  178. sys.exit(1)
  179. @click.command()
  180. @click.pass_context
  181. def cli_int_ctx_exit(ctx):
  182. click.echo("hello world")
  183. ctx.exit(1)
  184. @click.command()
  185. def cli_float():
  186. click.echo("hello world")
  187. sys.exit(1.0)
  188. @click.command()
  189. @click.pass_context
  190. def cli_float_ctx_exit(ctx):
  191. click.echo("hello world")
  192. ctx.exit(1.0)
  193. @click.command()
  194. def cli_no_error():
  195. click.echo("hello world")
  196. runner = CliRunner()
  197. result = runner.invoke(cli_string)
  198. assert result.exit_code == 1
  199. assert result.output == "hello world\nerror\n"
  200. result = runner.invoke(cli_string_ctx_exit)
  201. assert result.exit_code == 1
  202. assert result.output == "hello world\nerror\n"
  203. result = runner.invoke(cli_int)
  204. assert result.exit_code == 1
  205. assert result.output == "hello world\n"
  206. result = runner.invoke(cli_int_ctx_exit)
  207. assert result.exit_code == 1
  208. assert result.output == "hello world\n"
  209. result = runner.invoke(cli_float)
  210. assert result.exit_code == 1
  211. assert result.output == "hello world\n1.0\n"
  212. result = runner.invoke(cli_float_ctx_exit)
  213. assert result.exit_code == 1
  214. assert result.output == "hello world\n1.0\n"
  215. result = runner.invoke(cli_no_error)
  216. assert result.exit_code == 0
  217. assert result.output == "hello world\n"
  218. def test_env():
  219. @click.command()
  220. def cli_env():
  221. click.echo(f"ENV={os.environ['TEST_CLICK_ENV']}")
  222. runner = CliRunner()
  223. env_orig = dict(os.environ)
  224. env = dict(env_orig)
  225. assert "TEST_CLICK_ENV" not in env
  226. env["TEST_CLICK_ENV"] = "some_value"
  227. result = runner.invoke(cli_env, env=env)
  228. assert result.exit_code == 0
  229. assert result.output == "ENV=some_value\n"
  230. assert os.environ == env_orig
  231. def test_stderr():
  232. @click.command()
  233. def cli_stderr():
  234. click.echo("stdout")
  235. click.echo("stderr", err=True)
  236. runner = CliRunner(mix_stderr=False)
  237. result = runner.invoke(cli_stderr)
  238. assert result.output == "stdout\n"
  239. assert result.stdout == "stdout\n"
  240. assert result.stderr == "stderr\n"
  241. runner_mix = CliRunner(mix_stderr=True)
  242. result_mix = runner_mix.invoke(cli_stderr)
  243. assert result_mix.output == "stdout\nstderr\n"
  244. assert result_mix.stdout == "stdout\nstderr\n"
  245. with pytest.raises(ValueError):
  246. result_mix.stderr
  247. @click.command()
  248. def cli_empty_stderr():
  249. click.echo("stdout")
  250. runner = CliRunner(mix_stderr=False)
  251. result = runner.invoke(cli_empty_stderr)
  252. assert result.output == "stdout\n"
  253. assert result.stdout == "stdout\n"
  254. assert result.stderr == ""
  255. @pytest.mark.parametrize(
  256. "args, expected_output",
  257. [
  258. (None, "bar\n"),
  259. ([], "bar\n"),
  260. ("", "bar\n"),
  261. (["--foo", "one two"], "one two\n"),
  262. ('--foo "one two"', "one two\n"),
  263. ],
  264. )
  265. def test_args(args, expected_output):
  266. @click.command()
  267. @click.option("--foo", default="bar")
  268. def cli_args(foo):
  269. click.echo(foo)
  270. runner = CliRunner()
  271. result = runner.invoke(cli_args, args=args)
  272. assert result.exit_code == 0
  273. assert result.output == expected_output
  274. def test_setting_prog_name_in_extra():
  275. @click.command()
  276. def cli():
  277. click.echo("ok")
  278. runner = CliRunner()
  279. result = runner.invoke(cli, prog_name="foobar")
  280. assert not result.exception
  281. assert result.output == "ok\n"
  282. def test_command_standalone_mode_returns_value():
  283. @click.command()
  284. def cli():
  285. click.echo("ok")
  286. return "Hello, World!"
  287. runner = CliRunner()
  288. result = runner.invoke(cli, standalone_mode=False)
  289. assert result.output == "ok\n"
  290. assert result.return_value == "Hello, World!"
  291. assert result.exit_code == 0
  292. def test_file_stdin_attrs(runner):
  293. @click.command()
  294. @click.argument("f", type=click.File())
  295. def cli(f):
  296. click.echo(f.name)
  297. click.echo(f.mode, nl=False)
  298. result = runner.invoke(cli, ["-"])
  299. assert result.output == "<stdin>\nr"
  300. def test_isolated_runner(runner):
  301. with runner.isolated_filesystem() as d:
  302. assert os.path.exists(d)
  303. assert not os.path.exists(d)
  304. def test_isolated_runner_custom_tempdir(runner, tmp_path):
  305. with runner.isolated_filesystem(temp_dir=tmp_path) as d:
  306. assert os.path.exists(d)
  307. assert os.path.exists(d)
  308. os.rmdir(d)
  309. def test_isolation_stderr_errors():
  310. """Writing to stderr should escape invalid characters instead of
  311. raising a UnicodeEncodeError.
  312. """
  313. runner = CliRunner(mix_stderr=False)
  314. with runner.isolation() as (_, err):
  315. click.echo("\udce2", err=True, nl=False)
  316. assert err.getvalue() == b"\\udce2"