test_formatting.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. # -*- coding: utf-8 -*-
  2. import click
  3. def test_basic_functionality(runner):
  4. @click.command()
  5. def cli():
  6. """First paragraph.
  7. This is a very long second
  8. paragraph and not correctly
  9. wrapped but it will be rewrapped.
  10. \b
  11. This is
  12. a paragraph
  13. without rewrapping.
  14. \b
  15. 1
  16. 2
  17. 3
  18. And this is a paragraph
  19. that will be rewrapped again.
  20. """
  21. result = runner.invoke(cli, ["--help"], terminal_width=60)
  22. assert not result.exception
  23. assert result.output.splitlines() == [
  24. "Usage: cli [OPTIONS]",
  25. "",
  26. " First paragraph.",
  27. "",
  28. " This is a very long second paragraph and not correctly",
  29. " wrapped but it will be rewrapped.",
  30. "",
  31. " This is",
  32. " a paragraph",
  33. " without rewrapping.",
  34. "",
  35. " 1",
  36. " 2",
  37. " 3",
  38. "",
  39. " And this is a paragraph that will be rewrapped again.",
  40. "",
  41. "Options:",
  42. " --help Show this message and exit.",
  43. ]
  44. def test_wrapping_long_options_strings(runner):
  45. @click.group()
  46. def cli():
  47. """Top level command
  48. """
  49. @cli.group()
  50. def a_very_long():
  51. """Second level
  52. """
  53. @a_very_long.command()
  54. @click.argument("first")
  55. @click.argument("second")
  56. @click.argument("third")
  57. @click.argument("fourth")
  58. @click.argument("fifth")
  59. @click.argument("sixth")
  60. def command():
  61. """A command.
  62. """
  63. # 54 is chosen as a length where the second line is one character
  64. # longer than the maximum length.
  65. result = runner.invoke(cli, ["a-very-long", "command", "--help"], terminal_width=54)
  66. assert not result.exception
  67. assert result.output.splitlines() == [
  68. "Usage: cli a-very-long command [OPTIONS] FIRST SECOND",
  69. " THIRD FOURTH FIFTH",
  70. " SIXTH",
  71. "",
  72. " A command.",
  73. "",
  74. "Options:",
  75. " --help Show this message and exit.",
  76. ]
  77. def test_wrapping_long_command_name(runner):
  78. @click.group()
  79. def cli():
  80. """Top level command
  81. """
  82. @cli.group()
  83. def a_very_very_very_long():
  84. """Second level
  85. """
  86. @a_very_very_very_long.command()
  87. @click.argument("first")
  88. @click.argument("second")
  89. @click.argument("third")
  90. @click.argument("fourth")
  91. @click.argument("fifth")
  92. @click.argument("sixth")
  93. def command():
  94. """A command.
  95. """
  96. result = runner.invoke(
  97. cli, ["a-very-very-very-long", "command", "--help"], terminal_width=54
  98. )
  99. assert not result.exception
  100. assert result.output.splitlines() == [
  101. "Usage: cli a-very-very-very-long command ",
  102. " [OPTIONS] FIRST SECOND THIRD FOURTH FIFTH",
  103. " SIXTH",
  104. "",
  105. " A command.",
  106. "",
  107. "Options:",
  108. " --help Show this message and exit.",
  109. ]
  110. def test_formatting_empty_help_lines(runner):
  111. @click.command()
  112. def cli():
  113. """Top level command
  114. """
  115. result = runner.invoke(cli, ["--help"])
  116. assert not result.exception
  117. assert result.output.splitlines() == [
  118. "Usage: cli [OPTIONS]",
  119. "",
  120. " Top level command",
  121. "",
  122. "",
  123. "",
  124. "Options:",
  125. " --help Show this message and exit.",
  126. ]
  127. def test_formatting_usage_error(runner):
  128. @click.command()
  129. @click.argument("arg")
  130. def cmd(arg):
  131. click.echo("arg:{}".format(arg))
  132. result = runner.invoke(cmd, [])
  133. assert result.exit_code == 2
  134. assert result.output.splitlines() == [
  135. "Usage: cmd [OPTIONS] ARG",
  136. "Try 'cmd --help' for help.",
  137. "",
  138. "Error: Missing argument 'ARG'.",
  139. ]
  140. def test_formatting_usage_error_metavar_missing_arg(runner):
  141. """
  142. :author: @r-m-n
  143. Including attribution to #612
  144. """
  145. @click.command()
  146. @click.argument("arg", metavar="metavar")
  147. def cmd(arg):
  148. pass
  149. result = runner.invoke(cmd, [])
  150. assert result.exit_code == 2
  151. assert result.output.splitlines() == [
  152. "Usage: cmd [OPTIONS] metavar",
  153. "Try 'cmd --help' for help.",
  154. "",
  155. "Error: Missing argument 'metavar'.",
  156. ]
  157. def test_formatting_usage_error_metavar_bad_arg(runner):
  158. @click.command()
  159. @click.argument("arg", type=click.INT, metavar="metavar")
  160. def cmd(arg):
  161. pass
  162. result = runner.invoke(cmd, ["3.14"])
  163. assert result.exit_code == 2
  164. assert result.output.splitlines() == [
  165. "Usage: cmd [OPTIONS] metavar",
  166. "Try 'cmd --help' for help.",
  167. "",
  168. "Error: Invalid value for 'metavar': 3.14 is not a valid integer",
  169. ]
  170. def test_formatting_usage_error_nested(runner):
  171. @click.group()
  172. def cmd():
  173. pass
  174. @cmd.command()
  175. @click.argument("bar")
  176. def foo(bar):
  177. click.echo("foo:{}".format(bar))
  178. result = runner.invoke(cmd, ["foo"])
  179. assert result.exit_code == 2
  180. assert result.output.splitlines() == [
  181. "Usage: cmd foo [OPTIONS] BAR",
  182. "Try 'cmd foo --help' for help.",
  183. "",
  184. "Error: Missing argument 'BAR'.",
  185. ]
  186. def test_formatting_usage_error_no_help(runner):
  187. @click.command(add_help_option=False)
  188. @click.argument("arg")
  189. def cmd(arg):
  190. click.echo("arg:{}".format(arg))
  191. result = runner.invoke(cmd, [])
  192. assert result.exit_code == 2
  193. assert result.output.splitlines() == [
  194. "Usage: cmd [OPTIONS] ARG",
  195. "",
  196. "Error: Missing argument 'ARG'.",
  197. ]
  198. def test_formatting_usage_custom_help(runner):
  199. @click.command(context_settings=dict(help_option_names=["--man"]))
  200. @click.argument("arg")
  201. def cmd(arg):
  202. click.echo("arg:{}".format(arg))
  203. result = runner.invoke(cmd, [])
  204. assert result.exit_code == 2
  205. assert result.output.splitlines() == [
  206. "Usage: cmd [OPTIONS] ARG",
  207. "Try 'cmd --man' for help.",
  208. "",
  209. "Error: Missing argument 'ARG'.",
  210. ]
  211. def test_formatting_custom_type_metavar(runner):
  212. class MyType(click.ParamType):
  213. def get_metavar(self, param):
  214. return "MY_TYPE"
  215. @click.command("foo")
  216. @click.help_option()
  217. @click.argument("param", type=MyType())
  218. def cmd(param):
  219. pass
  220. result = runner.invoke(cmd, "--help")
  221. assert not result.exception
  222. assert result.output.splitlines() == [
  223. "Usage: foo [OPTIONS] MY_TYPE",
  224. "",
  225. "Options:",
  226. " --help Show this message and exit.",
  227. ]
  228. def test_truncating_docstring(runner):
  229. @click.command()
  230. @click.pass_context
  231. def cli(ctx):
  232. """First paragraph.
  233. This is a very long second
  234. paragraph and not correctly
  235. wrapped but it will be rewrapped.
  236. \f
  237. :param click.core.Context ctx: Click context.
  238. """
  239. result = runner.invoke(cli, ["--help"], terminal_width=60)
  240. assert not result.exception
  241. assert result.output.splitlines() == [
  242. "Usage: cli [OPTIONS]",
  243. "",
  244. " First paragraph.",
  245. "",
  246. " This is a very long second paragraph and not correctly",
  247. " wrapped but it will be rewrapped.",
  248. "",
  249. "Options:",
  250. " --help Show this message and exit.",
  251. ]
  252. def test_global_show_default(runner):
  253. @click.command(context_settings=dict(show_default=True))
  254. @click.option("-f", "in_file", default="out.txt", help="Output file name")
  255. def cli():
  256. pass
  257. result = runner.invoke(cli, ["--help"],)
  258. assert result.output.splitlines() == [
  259. "Usage: cli [OPTIONS]",
  260. "",
  261. "Options:",
  262. " -f TEXT Output file name [default: out.txt]",
  263. " --help Show this message and exit. [default: False]",
  264. ]
  265. def test_formatting_usage_multiline_option_padding(runner):
  266. @click.command("foo")
  267. @click.option("--bar", help="This help message will be padded if it wraps.")
  268. def cli():
  269. pass
  270. result = runner.invoke(cli, "--help", terminal_width=45)
  271. assert not result.exception
  272. assert result.output.splitlines() == [
  273. "Usage: foo [OPTIONS]",
  274. "",
  275. "Options:",
  276. " --bar TEXT This help message will be",
  277. " padded if it wraps.",
  278. "",
  279. " --help Show this message and exit.",
  280. ]
  281. def test_formatting_usage_no_option_padding(runner):
  282. @click.command("foo")
  283. @click.option("--bar", help="This help message will be padded if it wraps.")
  284. def cli():
  285. pass
  286. result = runner.invoke(cli, "--help", terminal_width=80)
  287. assert not result.exception
  288. assert result.output.splitlines() == [
  289. "Usage: foo [OPTIONS]",
  290. "",
  291. "Options:",
  292. " --bar TEXT This help message will be padded if it wraps.",
  293. " --help Show this message and exit.",
  294. ]