busser-behave 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (418) hide show
  1. checksums.yaml +7 -0
  2. data/.cane +0 -0
  3. data/.gitignore +17 -0
  4. data/.tailor +4 -0
  5. data/.travis.yml +11 -0
  6. data/CHANGELOG.md +3 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +15 -0
  9. data/README.md +41 -0
  10. data/Rakefile +68 -0
  11. data/busser-behave.gemspec +30 -0
  12. data/features/plugin_install_command.feature +11 -0
  13. data/features/plugin_list_command.feature +8 -0
  14. data/features/support/env.rb +13 -0
  15. data/features/test_command.feature +31 -0
  16. data/lib/busser/behave/version.rb +26 -0
  17. data/lib/busser/runner_plugin/behave.rb +37 -0
  18. data/vendor/behave/CHANGES.rst +483 -0
  19. data/vendor/behave/LICENSE +23 -0
  20. data/vendor/behave/MANIFEST.in +37 -0
  21. data/vendor/behave/PROJECT_INFO.rst +21 -0
  22. data/vendor/behave/README.rst +112 -0
  23. data/vendor/behave/VERSION.txt +1 -0
  24. data/vendor/behave/behave.ini +22 -0
  25. data/vendor/behave/behave/__init__.py +30 -0
  26. data/vendor/behave/behave/__main__.py +187 -0
  27. data/vendor/behave/behave/_stepimport.py +185 -0
  28. data/vendor/behave/behave/_types.py +134 -0
  29. data/vendor/behave/behave/api/__init__.py +7 -0
  30. data/vendor/behave/behave/api/async_step.py +283 -0
  31. data/vendor/behave/behave/capture.py +227 -0
  32. data/vendor/behave/behave/compat/__init__.py +5 -0
  33. data/vendor/behave/behave/compat/collections.py +20 -0
  34. data/vendor/behave/behave/configuration.py +788 -0
  35. data/vendor/behave/behave/contrib/__init__.py +0 -0
  36. data/vendor/behave/behave/contrib/scenario_autoretry.py +73 -0
  37. data/vendor/behave/behave/formatter/__init__.py +12 -0
  38. data/vendor/behave/behave/formatter/_builtins.py +39 -0
  39. data/vendor/behave/behave/formatter/_registry.py +135 -0
  40. data/vendor/behave/behave/formatter/ansi_escapes.py +91 -0
  41. data/vendor/behave/behave/formatter/base.py +200 -0
  42. data/vendor/behave/behave/formatter/formatters.py +57 -0
  43. data/vendor/behave/behave/formatter/json.py +253 -0
  44. data/vendor/behave/behave/formatter/null.py +12 -0
  45. data/vendor/behave/behave/formatter/plain.py +158 -0
  46. data/vendor/behave/behave/formatter/pretty.py +351 -0
  47. data/vendor/behave/behave/formatter/progress.py +287 -0
  48. data/vendor/behave/behave/formatter/rerun.py +114 -0
  49. data/vendor/behave/behave/formatter/sphinx_steps.py +372 -0
  50. data/vendor/behave/behave/formatter/sphinx_util.py +118 -0
  51. data/vendor/behave/behave/formatter/steps.py +497 -0
  52. data/vendor/behave/behave/formatter/tags.py +178 -0
  53. data/vendor/behave/behave/i18n.py +614 -0
  54. data/vendor/behave/behave/importer.py +102 -0
  55. data/vendor/behave/behave/json_parser.py +264 -0
  56. data/vendor/behave/behave/log_capture.py +233 -0
  57. data/vendor/behave/behave/matchers.py +402 -0
  58. data/vendor/behave/behave/model.py +1737 -0
  59. data/vendor/behave/behave/model_core.py +416 -0
  60. data/vendor/behave/behave/model_describe.py +105 -0
  61. data/vendor/behave/behave/parser.py +615 -0
  62. data/vendor/behave/behave/reporter/__init__.py +0 -0
  63. data/vendor/behave/behave/reporter/base.py +45 -0
  64. data/vendor/behave/behave/reporter/junit.py +473 -0
  65. data/vendor/behave/behave/reporter/summary.py +94 -0
  66. data/vendor/behave/behave/runner.py +753 -0
  67. data/vendor/behave/behave/runner_util.py +417 -0
  68. data/vendor/behave/behave/step_registry.py +112 -0
  69. data/vendor/behave/behave/tag_expression.py +111 -0
  70. data/vendor/behave/behave/tag_matcher.py +465 -0
  71. data/vendor/behave/behave/textutil.py +137 -0
  72. data/vendor/behave/behave/userdata.py +130 -0
  73. data/vendor/behave/behave4cmd0/__all_steps__.py +12 -0
  74. data/vendor/behave/behave4cmd0/__init__.py +5 -0
  75. data/vendor/behave/behave4cmd0/__setup.py +11 -0
  76. data/vendor/behave/behave4cmd0/command_shell.py +216 -0
  77. data/vendor/behave/behave4cmd0/command_shell_proc.py +256 -0
  78. data/vendor/behave/behave4cmd0/command_steps.py +532 -0
  79. data/vendor/behave/behave4cmd0/command_util.py +147 -0
  80. data/vendor/behave/behave4cmd0/failing_steps.py +49 -0
  81. data/vendor/behave/behave4cmd0/log/__init__.py +1 -0
  82. data/vendor/behave/behave4cmd0/log/steps.py +395 -0
  83. data/vendor/behave/behave4cmd0/note_steps.py +29 -0
  84. data/vendor/behave/behave4cmd0/passing_steps.py +36 -0
  85. data/vendor/behave/behave4cmd0/pathutil.py +146 -0
  86. data/vendor/behave/behave4cmd0/setup_command_shell.py +24 -0
  87. data/vendor/behave/behave4cmd0/textutil.py +304 -0
  88. data/vendor/behave/bin/behave +44 -0
  89. data/vendor/behave/bin/behave.cmd +10 -0
  90. data/vendor/behave/bin/behave.junit_filter.py +85 -0
  91. data/vendor/behave/bin/behave.step_durations.py +163 -0
  92. data/vendor/behave/bin/behave2cucumber_json.py +63 -0
  93. data/vendor/behave/bin/behave_cmd.py +44 -0
  94. data/vendor/behave/bin/convert_i18n_yaml.py +77 -0
  95. data/vendor/behave/bin/explore_platform_encoding.py +24 -0
  96. data/vendor/behave/bin/i18n.yml +621 -0
  97. data/vendor/behave/bin/invoke +8 -0
  98. data/vendor/behave/bin/invoke.cmd +9 -0
  99. data/vendor/behave/bin/json.format.py +167 -0
  100. data/vendor/behave/bin/jsonschema_validate.py +122 -0
  101. data/vendor/behave/bin/make_localpi.py +279 -0
  102. data/vendor/behave/bin/project_bootstrap.sh +30 -0
  103. data/vendor/behave/bin/toxcmd.py +270 -0
  104. data/vendor/behave/bin/toxcmd3.py +270 -0
  105. data/vendor/behave/conftest.py +27 -0
  106. data/vendor/behave/docs/Makefile +154 -0
  107. data/vendor/behave/docs/_static/agogo.css +501 -0
  108. data/vendor/behave/docs/_static/behave_logo.png +0 -0
  109. data/vendor/behave/docs/_static/behave_logo1.png +0 -0
  110. data/vendor/behave/docs/_static/behave_logo2.png +0 -0
  111. data/vendor/behave/docs/_static/behave_logo3.png +0 -0
  112. data/vendor/behave/docs/_themes/LICENSE +45 -0
  113. data/vendor/behave/docs/_themes/kr/layout.html +17 -0
  114. data/vendor/behave/docs/_themes/kr/relations.html +19 -0
  115. data/vendor/behave/docs/_themes/kr/static/flasky.css_t +480 -0
  116. data/vendor/behave/docs/_themes/kr/static/small_flask.css +90 -0
  117. data/vendor/behave/docs/_themes/kr/theme.conf +7 -0
  118. data/vendor/behave/docs/_themes/kr_small/layout.html +22 -0
  119. data/vendor/behave/docs/_themes/kr_small/static/flasky.css_t +287 -0
  120. data/vendor/behave/docs/_themes/kr_small/theme.conf +10 -0
  121. data/vendor/behave/docs/api.rst +408 -0
  122. data/vendor/behave/docs/appendix.rst +19 -0
  123. data/vendor/behave/docs/behave.rst +640 -0
  124. data/vendor/behave/docs/behave.rst-template +86 -0
  125. data/vendor/behave/docs/behave_ecosystem.rst +81 -0
  126. data/vendor/behave/docs/comparison.rst +85 -0
  127. data/vendor/behave/docs/conf.py +293 -0
  128. data/vendor/behave/docs/context_attributes.rst +66 -0
  129. data/vendor/behave/docs/django.rst +192 -0
  130. data/vendor/behave/docs/formatters.rst +61 -0
  131. data/vendor/behave/docs/gherkin.rst +673 -0
  132. data/vendor/behave/docs/index.rst +57 -0
  133. data/vendor/behave/docs/install.rst +60 -0
  134. data/vendor/behave/docs/more_info.rst +184 -0
  135. data/vendor/behave/docs/new_and_noteworthy.rst +18 -0
  136. data/vendor/behave/docs/new_and_noteworthy_v1.2.4.rst +11 -0
  137. data/vendor/behave/docs/new_and_noteworthy_v1.2.5.rst +814 -0
  138. data/vendor/behave/docs/new_and_noteworthy_v1.2.6.rst +255 -0
  139. data/vendor/behave/docs/parse_builtin_types.rst +59 -0
  140. data/vendor/behave/docs/philosophy.rst +235 -0
  141. data/vendor/behave/docs/regular_expressions.rst +71 -0
  142. data/vendor/behave/docs/related.rst +14 -0
  143. data/vendor/behave/docs/test_domains.rst +62 -0
  144. data/vendor/behave/docs/tutorial.rst +636 -0
  145. data/vendor/behave/docs/update_behave_rst.py +100 -0
  146. data/vendor/behave/etc/json/behave.json-schema +172 -0
  147. data/vendor/behave/etc/junit.xml/behave_junit.xsd +103 -0
  148. data/vendor/behave/etc/junit.xml/junit-4.xsd +92 -0
  149. data/vendor/behave/examples/async_step/README.txt +8 -0
  150. data/vendor/behave/examples/async_step/behave.ini +14 -0
  151. data/vendor/behave/examples/async_step/features/async_dispatch.feature +8 -0
  152. data/vendor/behave/examples/async_step/features/async_run.feature +6 -0
  153. data/vendor/behave/examples/async_step/features/environment.py +28 -0
  154. data/vendor/behave/examples/async_step/features/steps/async_dispatch_steps.py +26 -0
  155. data/vendor/behave/examples/async_step/features/steps/async_steps34.py +10 -0
  156. data/vendor/behave/examples/async_step/features/steps/async_steps35.py +10 -0
  157. data/vendor/behave/examples/async_step/testrun_example.async_dispatch.txt +11 -0
  158. data/vendor/behave/examples/async_step/testrun_example.async_run.txt +9 -0
  159. data/vendor/behave/examples/env_vars/README.rst +26 -0
  160. data/vendor/behave/examples/env_vars/behave.ini +15 -0
  161. data/vendor/behave/examples/env_vars/behave_run.output_example.txt +12 -0
  162. data/vendor/behave/examples/env_vars/features/env_var.feature +6 -0
  163. data/vendor/behave/examples/env_vars/features/steps/env_var_steps.py +38 -0
  164. data/vendor/behave/features/README.txt +12 -0
  165. data/vendor/behave/features/background.feature +392 -0
  166. data/vendor/behave/features/capture_stderr.feature +172 -0
  167. data/vendor/behave/features/capture_stdout.feature +125 -0
  168. data/vendor/behave/features/cmdline.lang_list.feature +33 -0
  169. data/vendor/behave/features/configuration.default_paths.feature +116 -0
  170. data/vendor/behave/features/context.global_params.feature +35 -0
  171. data/vendor/behave/features/context.local_params.feature +17 -0
  172. data/vendor/behave/features/directory_layout.advanced.feature +147 -0
  173. data/vendor/behave/features/directory_layout.basic.feature +75 -0
  174. data/vendor/behave/features/directory_layout.basic2.feature +87 -0
  175. data/vendor/behave/features/environment.py +53 -0
  176. data/vendor/behave/features/exploratory_testing.with_table.feature +141 -0
  177. data/vendor/behave/features/feature.description.feature +0 -0
  178. data/vendor/behave/features/feature.exclude_from_run.feature +96 -0
  179. data/vendor/behave/features/formatter.help.feature +30 -0
  180. data/vendor/behave/features/formatter.json.feature +420 -0
  181. data/vendor/behave/features/formatter.progress3.feature +235 -0
  182. data/vendor/behave/features/formatter.rerun.feature +296 -0
  183. data/vendor/behave/features/formatter.steps.feature +181 -0
  184. data/vendor/behave/features/formatter.steps_catalog.feature +100 -0
  185. data/vendor/behave/features/formatter.steps_doc.feature +140 -0
  186. data/vendor/behave/features/formatter.steps_usage.feature +404 -0
  187. data/vendor/behave/features/formatter.tags.feature +134 -0
  188. data/vendor/behave/features/formatter.tags_location.feature +183 -0
  189. data/vendor/behave/features/formatter.user_defined.feature +196 -0
  190. data/vendor/behave/features/i18n.unicode_problems.feature +445 -0
  191. data/vendor/behave/features/logcapture.clear_handlers.feature +114 -0
  192. data/vendor/behave/features/logcapture.feature +188 -0
  193. data/vendor/behave/features/logcapture.filter.feature +130 -0
  194. data/vendor/behave/features/logging.no_capture.feature +99 -0
  195. data/vendor/behave/features/logging.setup_format.feature +157 -0
  196. data/vendor/behave/features/logging.setup_level.feature +168 -0
  197. data/vendor/behave/features/logging.setup_with_configfile.feature +137 -0
  198. data/vendor/behave/features/parser.background.sad_cases.feature +129 -0
  199. data/vendor/behave/features/parser.feature.sad_cases.feature +144 -0
  200. data/vendor/behave/features/runner.abort_by_user.feature +305 -0
  201. data/vendor/behave/features/runner.continue_after_failed_step.feature +136 -0
  202. data/vendor/behave/features/runner.default_format.feature +175 -0
  203. data/vendor/behave/features/runner.dry_run.feature +184 -0
  204. data/vendor/behave/features/runner.feature_listfile.feature +223 -0
  205. data/vendor/behave/features/runner.hook_errors.feature +382 -0
  206. data/vendor/behave/features/runner.multiple_formatters.feature +285 -0
  207. data/vendor/behave/features/runner.scenario_autoretry.feature +131 -0
  208. data/vendor/behave/features/runner.select_files_by_regexp.example.feature +71 -0
  209. data/vendor/behave/features/runner.select_files_by_regexp.feature +84 -0
  210. data/vendor/behave/features/runner.select_scenarios_by_file_location.feature +403 -0
  211. data/vendor/behave/features/runner.select_scenarios_by_name.feature +289 -0
  212. data/vendor/behave/features/runner.select_scenarios_by_tag.feature +225 -0
  213. data/vendor/behave/features/runner.stop_after_failure.feature +122 -0
  214. data/vendor/behave/features/runner.tag_logic.feature +67 -0
  215. data/vendor/behave/features/runner.unknown_formatter.feature +23 -0
  216. data/vendor/behave/features/runner.use_stage_implementations.feature +126 -0
  217. data/vendor/behave/features/scenario.description.feature +171 -0
  218. data/vendor/behave/features/scenario.exclude_from_run.feature +217 -0
  219. data/vendor/behave/features/scenario_outline.basics.feature +100 -0
  220. data/vendor/behave/features/scenario_outline.improved.feature +177 -0
  221. data/vendor/behave/features/scenario_outline.name_annotation.feature +157 -0
  222. data/vendor/behave/features/scenario_outline.parametrized.feature +401 -0
  223. data/vendor/behave/features/scenario_outline.tagged_examples.feature +118 -0
  224. data/vendor/behave/features/step.async_steps.feature +225 -0
  225. data/vendor/behave/features/step.duplicated_step.feature +106 -0
  226. data/vendor/behave/features/step.execute_steps.feature +59 -0
  227. data/vendor/behave/features/step.execute_steps.with_table.feature +65 -0
  228. data/vendor/behave/features/step.import_other_step_module.feature +103 -0
  229. data/vendor/behave/features/step.pending_steps.feature +128 -0
  230. data/vendor/behave/features/step.undefined_steps.feature +307 -0
  231. data/vendor/behave/features/step.use_step_library.feature +44 -0
  232. data/vendor/behave/features/step_dialect.generic_steps.feature +189 -0
  233. data/vendor/behave/features/step_dialect.given_when_then.feature +89 -0
  234. data/vendor/behave/features/step_param.builtin_types.with_float.feature +239 -0
  235. data/vendor/behave/features/step_param.builtin_types.with_integer.feature +305 -0
  236. data/vendor/behave/features/step_param.custom_types.feature +134 -0
  237. data/vendor/behave/features/steps/behave_active_tags_steps.py +86 -0
  238. data/vendor/behave/features/steps/behave_context_steps.py +67 -0
  239. data/vendor/behave/features/steps/behave_model_tag_logic_steps.py +105 -0
  240. data/vendor/behave/features/steps/behave_model_util.py +105 -0
  241. data/vendor/behave/features/steps/behave_select_files_steps.py +83 -0
  242. data/vendor/behave/features/steps/behave_tag_expression_steps.py +166 -0
  243. data/vendor/behave/features/steps/behave_undefined_steps.py +101 -0
  244. data/vendor/behave/features/steps/use_steplib_behave4cmd.py +12 -0
  245. data/vendor/behave/features/summary.undefined_steps.feature +114 -0
  246. data/vendor/behave/features/tags.active_tags.feature +385 -0
  247. data/vendor/behave/features/tags.default_tags.feature +104 -0
  248. data/vendor/behave/features/tags.tag_expression.feature +105 -0
  249. data/vendor/behave/features/userdata.feature +331 -0
  250. data/vendor/behave/invoke.yaml +21 -0
  251. data/vendor/behave/issue.features/README.txt +17 -0
  252. data/vendor/behave/issue.features/environment.py +97 -0
  253. data/vendor/behave/issue.features/issue0030.feature +21 -0
  254. data/vendor/behave/issue.features/issue0031.feature +16 -0
  255. data/vendor/behave/issue.features/issue0032.feature +28 -0
  256. data/vendor/behave/issue.features/issue0035.feature +74 -0
  257. data/vendor/behave/issue.features/issue0040.feature +154 -0
  258. data/vendor/behave/issue.features/issue0041.feature +135 -0
  259. data/vendor/behave/issue.features/issue0042.feature +230 -0
  260. data/vendor/behave/issue.features/issue0044.feature +51 -0
  261. data/vendor/behave/issue.features/issue0046.feature +77 -0
  262. data/vendor/behave/issue.features/issue0052.feature +66 -0
  263. data/vendor/behave/issue.features/issue0059.feature +29 -0
  264. data/vendor/behave/issue.features/issue0063.feature +102 -0
  265. data/vendor/behave/issue.features/issue0064.feature +97 -0
  266. data/vendor/behave/issue.features/issue0065.feature +18 -0
  267. data/vendor/behave/issue.features/issue0066.feature +80 -0
  268. data/vendor/behave/issue.features/issue0067.feature +90 -0
  269. data/vendor/behave/issue.features/issue0069.feature +64 -0
  270. data/vendor/behave/issue.features/issue0072.feature +32 -0
  271. data/vendor/behave/issue.features/issue0073.feature +228 -0
  272. data/vendor/behave/issue.features/issue0075.feature +18 -0
  273. data/vendor/behave/issue.features/issue0077.feature +89 -0
  274. data/vendor/behave/issue.features/issue0080.feature +49 -0
  275. data/vendor/behave/issue.features/issue0081.feature +138 -0
  276. data/vendor/behave/issue.features/issue0083.feature +69 -0
  277. data/vendor/behave/issue.features/issue0084.feature +69 -0
  278. data/vendor/behave/issue.features/issue0085.feature +119 -0
  279. data/vendor/behave/issue.features/issue0092.feature +66 -0
  280. data/vendor/behave/issue.features/issue0096.feature +173 -0
  281. data/vendor/behave/issue.features/issue0099.feature +130 -0
  282. data/vendor/behave/issue.features/issue0109.feature +60 -0
  283. data/vendor/behave/issue.features/issue0111.feature +53 -0
  284. data/vendor/behave/issue.features/issue0112.feature +64 -0
  285. data/vendor/behave/issue.features/issue0114.feature +118 -0
  286. data/vendor/behave/issue.features/issue0116.feature +71 -0
  287. data/vendor/behave/issue.features/issue0125.feature +49 -0
  288. data/vendor/behave/issue.features/issue0127.feature +64 -0
  289. data/vendor/behave/issue.features/issue0139.feature +67 -0
  290. data/vendor/behave/issue.features/issue0142.feature +37 -0
  291. data/vendor/behave/issue.features/issue0143.feature +54 -0
  292. data/vendor/behave/issue.features/issue0145.feature +63 -0
  293. data/vendor/behave/issue.features/issue0148.feature +105 -0
  294. data/vendor/behave/issue.features/issue0152.feature +52 -0
  295. data/vendor/behave/issue.features/issue0159.feature +74 -0
  296. data/vendor/behave/issue.features/issue0162.feature +86 -0
  297. data/vendor/behave/issue.features/issue0171.feature +16 -0
  298. data/vendor/behave/issue.features/issue0172.feature +51 -0
  299. data/vendor/behave/issue.features/issue0175.feature +91 -0
  300. data/vendor/behave/issue.features/issue0177.feature +40 -0
  301. data/vendor/behave/issue.features/issue0181.feature +36 -0
  302. data/vendor/behave/issue.features/issue0184.feature +144 -0
  303. data/vendor/behave/issue.features/issue0186.feature +12 -0
  304. data/vendor/behave/issue.features/issue0188.feature +60 -0
  305. data/vendor/behave/issue.features/issue0191.feature +178 -0
  306. data/vendor/behave/issue.features/issue0194.feature +215 -0
  307. data/vendor/behave/issue.features/issue0197.feature +11 -0
  308. data/vendor/behave/issue.features/issue0216.feature +129 -0
  309. data/vendor/behave/issue.features/issue0226.feature +51 -0
  310. data/vendor/behave/issue.features/issue0228.feature +41 -0
  311. data/vendor/behave/issue.features/issue0230.feature +46 -0
  312. data/vendor/behave/issue.features/issue0231.feature +77 -0
  313. data/vendor/behave/issue.features/issue0238.feature +52 -0
  314. data/vendor/behave/issue.features/issue0251.feature +15 -0
  315. data/vendor/behave/issue.features/issue0280.feature +118 -0
  316. data/vendor/behave/issue.features/issue0288.feature +95 -0
  317. data/vendor/behave/issue.features/issue0300.feature +49 -0
  318. data/vendor/behave/issue.features/issue0302.feature +91 -0
  319. data/vendor/behave/issue.features/issue0309.feature +52 -0
  320. data/vendor/behave/issue.features/issue0330.feature +124 -0
  321. data/vendor/behave/issue.features/issue0349.feature +9 -0
  322. data/vendor/behave/issue.features/issue0361.feature +79 -0
  323. data/vendor/behave/issue.features/issue0383.feature +76 -0
  324. data/vendor/behave/issue.features/issue0384.feature +103 -0
  325. data/vendor/behave/issue.features/issue0385.feature +109 -0
  326. data/vendor/behave/issue.features/issue0424.feature +66 -0
  327. data/vendor/behave/issue.features/issue0446.feature +116 -0
  328. data/vendor/behave/issue.features/issue0449.feature +42 -0
  329. data/vendor/behave/issue.features/issue0453.feature +42 -0
  330. data/vendor/behave/issue.features/issue0457.feature +65 -0
  331. data/vendor/behave/issue.features/issue0462.feature +38 -0
  332. data/vendor/behave/issue.features/issue0476.feature +39 -0
  333. data/vendor/behave/issue.features/issue0487.feature +92 -0
  334. data/vendor/behave/issue.features/issue0506.feature +77 -0
  335. data/vendor/behave/issue.features/issue0510.feature +51 -0
  336. data/vendor/behave/issue.features/requirements.txt +12 -0
  337. data/vendor/behave/issue.features/steps/ansi_steps.py +20 -0
  338. data/vendor/behave/issue.features/steps/behave_hooks_steps.py +10 -0
  339. data/vendor/behave/issue.features/steps/use_steplib_behave4cmd.py +13 -0
  340. data/vendor/behave/more.features/formatter.json.validate_output.feature +37 -0
  341. data/vendor/behave/more.features/steps/tutorial_steps.py +16 -0
  342. data/vendor/behave/more.features/steps/use_steplib_behave4cmd.py +7 -0
  343. data/vendor/behave/more.features/tutorial.feature +6 -0
  344. data/vendor/behave/py.requirements/README.txt +5 -0
  345. data/vendor/behave/py.requirements/all.txt +16 -0
  346. data/vendor/behave/py.requirements/basic.txt +21 -0
  347. data/vendor/behave/py.requirements/develop.txt +28 -0
  348. data/vendor/behave/py.requirements/docs.txt +6 -0
  349. data/vendor/behave/py.requirements/json.txt +7 -0
  350. data/vendor/behave/py.requirements/more_py26.txt +8 -0
  351. data/vendor/behave/py.requirements/testing.txt +10 -0
  352. data/vendor/behave/pytest.ini +24 -0
  353. data/vendor/behave/setup.cfg +29 -0
  354. data/vendor/behave/setup.py +118 -0
  355. data/vendor/behave/setuptools_behave.py +130 -0
  356. data/vendor/behave/tasks/__behave.py +45 -0
  357. data/vendor/behave/tasks/__init__.py +55 -0
  358. data/vendor/behave/tasks/__main__.py +70 -0
  359. data/vendor/behave/tasks/_setup.py +135 -0
  360. data/vendor/behave/tasks/_vendor/README.rst +35 -0
  361. data/vendor/behave/tasks/_vendor/invoke.zip +0 -0
  362. data/vendor/behave/tasks/_vendor/path.py +1725 -0
  363. data/vendor/behave/tasks/_vendor/pathlib.py +1280 -0
  364. data/vendor/behave/tasks/_vendor/six.py +868 -0
  365. data/vendor/behave/tasks/clean.py +246 -0
  366. data/vendor/behave/tasks/docs.py +97 -0
  367. data/vendor/behave/tasks/requirements.txt +17 -0
  368. data/vendor/behave/tasks/test.py +192 -0
  369. data/vendor/behave/test/__init__.py +0 -0
  370. data/vendor/behave/test/_importer_candidate.py +3 -0
  371. data/vendor/behave/test/reporters/__init__.py +0 -0
  372. data/vendor/behave/test/reporters/test_summary.py +240 -0
  373. data/vendor/behave/test/test_ansi_escapes.py +73 -0
  374. data/vendor/behave/test/test_configuration.py +172 -0
  375. data/vendor/behave/test/test_formatter.py +265 -0
  376. data/vendor/behave/test/test_formatter_progress.py +39 -0
  377. data/vendor/behave/test/test_formatter_rerun.py +97 -0
  378. data/vendor/behave/test/test_formatter_tags.py +57 -0
  379. data/vendor/behave/test/test_importer.py +151 -0
  380. data/vendor/behave/test/test_log_capture.py +29 -0
  381. data/vendor/behave/test/test_matchers.py +236 -0
  382. data/vendor/behave/test/test_model.py +871 -0
  383. data/vendor/behave/test/test_parser.py +1590 -0
  384. data/vendor/behave/test/test_runner.py +1074 -0
  385. data/vendor/behave/test/test_step_registry.py +96 -0
  386. data/vendor/behave/test/test_tag_expression.py +506 -0
  387. data/vendor/behave/test/test_tag_expression2.py +462 -0
  388. data/vendor/behave/test/test_tag_matcher.py +729 -0
  389. data/vendor/behave/test/test_userdata.py +184 -0
  390. data/vendor/behave/tests/README.txt +12 -0
  391. data/vendor/behave/tests/__init__.py +0 -0
  392. data/vendor/behave/tests/api/__ONLY_PY34_or_newer.txt +0 -0
  393. data/vendor/behave/tests/api/__init__.py +0 -0
  394. data/vendor/behave/tests/api/_test_async_step34.py +130 -0
  395. data/vendor/behave/tests/api/_test_async_step35.py +75 -0
  396. data/vendor/behave/tests/api/test_async_step.py +18 -0
  397. data/vendor/behave/tests/api/testing_support.py +94 -0
  398. data/vendor/behave/tests/api/testing_support_async.py +21 -0
  399. data/vendor/behave/tests/issues/test_issue0336.py +66 -0
  400. data/vendor/behave/tests/issues/test_issue0449.py +55 -0
  401. data/vendor/behave/tests/issues/test_issue0453.py +62 -0
  402. data/vendor/behave/tests/issues/test_issue0458.py +54 -0
  403. data/vendor/behave/tests/issues/test_issue0495.py +65 -0
  404. data/vendor/behave/tests/unit/__init__.py +0 -0
  405. data/vendor/behave/tests/unit/test_behave4cmd_command_shell_proc.py +135 -0
  406. data/vendor/behave/tests/unit/test_capture.py +280 -0
  407. data/vendor/behave/tests/unit/test_model_core.py +56 -0
  408. data/vendor/behave/tests/unit/test_textutil.py +267 -0
  409. data/vendor/behave/tools/test-features/background.feature +9 -0
  410. data/vendor/behave/tools/test-features/environment.py +8 -0
  411. data/vendor/behave/tools/test-features/french.feature +11 -0
  412. data/vendor/behave/tools/test-features/outline.feature +39 -0
  413. data/vendor/behave/tools/test-features/parse.feature +10 -0
  414. data/vendor/behave/tools/test-features/step-data.feature +60 -0
  415. data/vendor/behave/tools/test-features/steps/steps.py +120 -0
  416. data/vendor/behave/tools/test-features/tags.feature +18 -0
  417. data/vendor/behave/tox.ini +159 -0
  418. metadata +562 -0
@@ -0,0 +1,102 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Importer module for lazy-loading/importing modules and objects.
4
+
5
+ REQUIRES: importlib (provided in Python2.7, Python3.2...)
6
+ """
7
+
8
+ from __future__ import absolute_import
9
+ import importlib
10
+ from behave._types import Unknown
11
+
12
+ def parse_scoped_name(scoped_name):
13
+ """
14
+ SCHEMA: my.module_name:MyClassName
15
+ EXAMPLE:
16
+ behave.formatter.plain:PlainFormatter
17
+ """
18
+ scoped_name = scoped_name.strip()
19
+ if "::" in scoped_name:
20
+ # -- ALTERNATIVE: my.module_name::MyClassName
21
+ scoped_name = scoped_name.replace("::", ":")
22
+ module_name, object_name = scoped_name.rsplit(":", 1)
23
+ return module_name, object_name
24
+
25
+ def load_module(module_name):
26
+ return importlib.import_module(module_name)
27
+
28
+
29
+ class LazyObject(object):
30
+ """
31
+ Provides a placeholder for an object that should be loaded lazily.
32
+ """
33
+
34
+ def __init__(self, module_name, object_name=None):
35
+ if ":" in module_name and not object_name:
36
+ module_name, object_name = parse_scoped_name(module_name)
37
+ assert ":" not in module_name
38
+ self.module_name = module_name
39
+ self.object_name = object_name
40
+ self.resolved_object = None
41
+
42
+ def __get__(self, obj=None, type=None): # pylint: disable=redefined-builtin
43
+ """
44
+ Implement descriptor protocol,
45
+ useful if this class is used as attribute.
46
+ :return: Real object (lazy-loaded if necessary).
47
+ :raise ImportError: If module or object cannot be imported.
48
+ """
49
+ __pychecker__ = "unusednames=obj,type"
50
+ resolved_object = None
51
+ if not self.resolved_object:
52
+ # -- SETUP-ONCE: Lazy load the real object.
53
+ module = load_module(self.module_name)
54
+ resolved_object = getattr(module, self.object_name, Unknown)
55
+ if resolved_object is Unknown:
56
+ msg = "%s: %s is Unknown" % (self.module_name, self.object_name)
57
+ raise ImportError(msg)
58
+ self.resolved_object = resolved_object
59
+ return resolved_object
60
+
61
+ def __set__(self, obj, value):
62
+ """Implement descriptor protocol."""
63
+ __pychecker__ = "unusednames=obj"
64
+ self.resolved_object = value
65
+
66
+ def get(self):
67
+ return self.__get__()
68
+
69
+
70
+ class LazyDict(dict):
71
+ """
72
+ Provides a dict that supports lazy loading of objects.
73
+ A LazyObject is provided as placeholder for a value that should be
74
+ loaded lazily.
75
+ """
76
+
77
+ def __getitem__(self, key):
78
+ """
79
+ Provides access to stored dict values.
80
+ Implements lazy loading of item value (if necessary).
81
+ When lazy object is loaded, its value with the dict is replaced
82
+ with the real value.
83
+
84
+ :param key: Key to access the value of an item in the dict.
85
+ :return: value
86
+ :raises: KeyError if item is not found
87
+ :raises: ImportError for a LazyObject that cannot be imported.
88
+ """
89
+ value = dict.__getitem__(self, key)
90
+ if isinstance(value, LazyObject):
91
+ # -- LAZY-LOADING MECHANISM: Load object and replace with lazy one.
92
+ value = value.__get__()
93
+ self[key] = value
94
+ return value
95
+
96
+ def load_all(self, strict=False):
97
+ for key in self.keys():
98
+ try:
99
+ self.__getitem__(key)
100
+ except ImportError:
101
+ if strict:
102
+ raise
@@ -0,0 +1,264 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Read behave's JSON output files and store retrieved information in
4
+ :mod:`behave.model` elements.
5
+
6
+ Utility to retrieve runtime information from behave's JSON output.
7
+
8
+ REQUIRES: Python >= 2.6 (json module is part of Python standard library)
9
+ """
10
+
11
+ from __future__ import absolute_import
12
+ import codecs
13
+ from behave import model
14
+ from behave.model_core import Status
15
+ try:
16
+ import json
17
+ except ImportError:
18
+ # -- PYTHON 2.5 backward compatible: Use simplejson module.
19
+ import simplejson as json
20
+
21
+
22
+ __author__ = "Jens Engel"
23
+
24
+
25
+ # ----------------------------------------------------------------------------
26
+ # FUNCTIONS:
27
+ # ----------------------------------------------------------------------------
28
+ def parse(json_filename, encoding="UTF-8"):
29
+ """
30
+ Reads behave JSON output file back in and stores information in
31
+ behave model elements.
32
+
33
+ :param json_filename: JSON filename to process.
34
+ :return: List of feature objects.
35
+ """
36
+ with codecs.open(json_filename, "rU", encoding=encoding) as input_file:
37
+ json_data = json.load(input_file, encoding=encoding)
38
+ json_processor = JsonParser()
39
+ features = json_processor.parse_features(json_data)
40
+ return features
41
+
42
+
43
+ # ----------------------------------------------------------------------------
44
+ # CLASSES:
45
+ # ----------------------------------------------------------------------------
46
+ class JsonParser(object):
47
+
48
+ def __init__(self):
49
+ self.current_scenario_outline = None
50
+
51
+ def parse_features(self, json_data):
52
+ assert isinstance(json_data, list)
53
+ features = []
54
+ json_features = json_data
55
+ for json_feature in json_features:
56
+ feature = self.parse_feature(json_feature)
57
+ features.append(feature)
58
+ return features
59
+
60
+ def parse_feature(self, json_feature):
61
+ name = json_feature.get("name", u"")
62
+ keyword = json_feature.get("keyword", None)
63
+ tags = json_feature.get("tags", [])
64
+ description = json_feature.get("description", [])
65
+ location = json_feature.get("location", u"")
66
+ filename, line = location.split(":")
67
+ feature = model.Feature(filename, line, keyword, name, tags, description)
68
+
69
+ json_elements = json_feature.get("elements", [])
70
+ for json_element in json_elements:
71
+ self.add_feature_element(feature, json_element)
72
+ return feature
73
+
74
+
75
+ def add_feature_element(self, feature, json_element):
76
+ datatype = json_element.get("type", u"")
77
+ category = datatype.lower()
78
+ if category == "background":
79
+ background = self.parse_background(json_element)
80
+ feature.background = background
81
+ elif category == "scenario":
82
+ scenario = self.parse_scenario(json_element)
83
+ feature.add_scenario(scenario)
84
+ elif category == "scenario_outline":
85
+ scenario_outline = self.parse_scenario_outline(json_element)
86
+ feature.add_scenario(scenario_outline)
87
+ self.current_scenario_outline = scenario_outline
88
+ # elif category == "examples":
89
+ # examples = self.parse_examples(json_element)
90
+ # self.current_scenario_outline.examples = examples
91
+ else:
92
+ raise KeyError("Invalid feature-element keyword: %s" % category)
93
+
94
+
95
+ def parse_background(self, json_element):
96
+ """
97
+ self.add_feature_element({
98
+ 'keyword': background.keyword,
99
+ 'location': background.location,
100
+ 'steps': [],
101
+ })
102
+ """
103
+ keyword = json_element.get("keyword", u"")
104
+ name = json_element.get("name", u"")
105
+ location = json_element.get("location", u"")
106
+ json_steps = json_element.get("steps", [])
107
+ steps = self.parse_steps(json_steps)
108
+ filename, line = location.split(":")
109
+ background = model.Background(filename, line, keyword, name, steps)
110
+ return background
111
+
112
+ def parse_scenario(self, json_element):
113
+ """
114
+ self.add_feature_element({
115
+ 'keyword': scenario.keyword,
116
+ 'name': scenario.name,
117
+ 'tags': scenario.tags,
118
+ 'location': scenario.location,
119
+ 'steps': [],
120
+ })
121
+ """
122
+ keyword = json_element.get("keyword", u"")
123
+ name = json_element.get("name", u"")
124
+ description = json_element.get("description", [])
125
+ tags = json_element.get("tags", [])
126
+ location = json_element.get("location", u"")
127
+ json_steps = json_element.get("steps", [])
128
+ steps = self.parse_steps(json_steps)
129
+ filename, line = location.split(":")
130
+ scenario = model.Scenario(filename, line, keyword, name, tags, steps)
131
+ scenario.description = description
132
+ return scenario
133
+
134
+ def parse_scenario_outline(self, json_element):
135
+ """
136
+ self.add_feature_element({
137
+ 'keyword': scenario_outline.keyword,
138
+ 'name': scenario_outline.name,
139
+ 'tags': scenario_outline.tags,
140
+ 'location': scenario_outline.location,
141
+ 'steps': [],
142
+ 'examples': [],
143
+ })
144
+ """
145
+ keyword = json_element.get("keyword", u"")
146
+ name = json_element.get("name", u"")
147
+ description = json_element.get("description", [])
148
+ tags = json_element.get("tags", [])
149
+ location = json_element.get("location", u"")
150
+ json_steps = json_element.get("steps", [])
151
+ json_examples = json_element.get("examples", [])
152
+ steps = self.parse_steps(json_steps)
153
+ examples = []
154
+ if json_examples:
155
+ # pylint: disable=redefined-variable-type
156
+ examples = self.parse_examples(json_examples)
157
+ filename, line = location.split(":")
158
+ scenario_outline = model.ScenarioOutline(filename, line, keyword, name,
159
+ tags=tags, steps=steps,
160
+ examples=examples)
161
+ scenario_outline.description = description
162
+ return scenario_outline
163
+
164
+ def parse_steps(self, json_steps):
165
+ steps = []
166
+ for json_step in json_steps:
167
+ step = self.parse_step(json_step)
168
+ steps.append(step)
169
+ return steps
170
+
171
+ def parse_step(self, json_element):
172
+ """
173
+ s = {
174
+ 'keyword': step.keyword,
175
+ 'step_type': step.step_type,
176
+ 'name': step.name,
177
+ 'location': step.location,
178
+ }
179
+
180
+ if step.text:
181
+ s['text'] = step.text
182
+ if step.table:
183
+ s['table'] = self.make_table(step.table)
184
+ element = self.current_feature_element
185
+ element['steps'].append(s)
186
+ """
187
+ keyword = json_element.get("keyword", u"")
188
+ name = json_element.get("name", u"")
189
+ step_type = json_element.get("step_type", u"")
190
+ location = json_element.get("location", u"")
191
+ text = json_element.get("text", None)
192
+ if isinstance(text, list):
193
+ text = "\n".join(text)
194
+ table = None
195
+ json_table = json_element.get("table", None)
196
+ if json_table:
197
+ table = self.parse_table(json_table)
198
+ filename, line = location.split(":")
199
+ step = model.Step(filename, line, keyword, step_type, name)
200
+ step.text = text
201
+ step.table = table
202
+ json_result = json_element.get("result", None)
203
+ if json_result:
204
+ self.add_step_result(step, json_result)
205
+ return step
206
+
207
+ @staticmethod
208
+ def add_step_result(step, json_result):
209
+ """
210
+ steps = self.current_feature_element['steps']
211
+ steps[self._step_index]['result'] = {
212
+ 'status': result.status.name,
213
+ 'duration': result.duration,
214
+ }
215
+ """
216
+ status_name = json_result.get("status", u"")
217
+ duration = json_result.get("duration", 0)
218
+ error_message = json_result.get("error_message", None)
219
+ if isinstance(error_message, list):
220
+ error_message = "\n".join(error_message)
221
+ step.status = Status.from_name(status_name)
222
+ step.duration = duration
223
+ step.error_message = error_message
224
+
225
+ @staticmethod
226
+ def parse_table(json_table):
227
+ """
228
+ table_data = {
229
+ 'headings': table.headings,
230
+ 'rows': [ list(row) for row in table.rows ]
231
+ }
232
+ return table_data
233
+ """
234
+ headings = json_table.get("headings", [])
235
+ rows = json_table.get("rows", [])
236
+ table = model.Table(headings, rows=rows)
237
+ return table
238
+
239
+
240
+ def parse_examples(self, json_element):
241
+ """
242
+ e = {
243
+ 'keyword': examples.keyword,
244
+ 'name': examples.name,
245
+ 'location': examples.location,
246
+ }
247
+
248
+ if examples.table:
249
+ e['table'] = self.make_table(examples.table)
250
+
251
+ element = self.current_feature_element
252
+ element['examples'].append(e)
253
+ """
254
+ keyword = json_element.get("keyword", u"")
255
+ name = json_element.get("name", u"")
256
+ location = json_element.get("location", u"")
257
+
258
+ table = None
259
+ json_table = json_element.get("table", None)
260
+ if json_table:
261
+ table = self.parse_table(json_table)
262
+ filename, line = location.split(":")
263
+ examples = model.Examples(filename, line, keyword, name, table)
264
+ return examples
@@ -0,0 +1,233 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from __future__ import absolute_import, print_function
4
+ from logging.handlers import BufferingHandler
5
+ import logging
6
+ import functools
7
+ import re
8
+
9
+
10
+ class RecordFilter(object):
11
+ """Implement logging record filtering as per the configuration
12
+ --logging-filter option.
13
+ """
14
+ def __init__(self, names):
15
+ self.include = set()
16
+ self.exclude = set()
17
+ for name in names.split(','):
18
+ if name[0] == '-':
19
+ self.exclude.add(name[1:])
20
+ else:
21
+ self.include.add(name)
22
+
23
+ def filter(self, record):
24
+ if self.exclude:
25
+ return record.name not in self.exclude
26
+ return record.name in self.include
27
+
28
+
29
+ # originally from nostetsts logcapture plugin
30
+ class LoggingCapture(BufferingHandler):
31
+ """Capture logging events in a memory buffer for later display or query.
32
+
33
+ Captured logging events are stored on the attribute
34
+ :attr:`~LoggingCapture.buffer`:
35
+
36
+ .. attribute:: buffer
37
+
38
+ This is a list of captured logging events as `logging.LogRecords`_.
39
+
40
+ .. _`logging.LogRecords`:
41
+ http://docs.python.org/library/logging.html#logrecord-objects
42
+
43
+ By default the format of the messages will be::
44
+
45
+ '%(levelname)s:%(name)s:%(message)s'
46
+
47
+ This may be overridden using standard logging formatter names in the
48
+ configuration variable ``logging_format``.
49
+
50
+ The level of logging captured is set to ``logging.NOTSET`` by default. You
51
+ may override this using the configuration setting ``logging_level`` (which
52
+ is set to a level name.)
53
+
54
+ Finally there may be `filtering of logging events`__ specified by the
55
+ configuration variable ``logging_filter``.
56
+
57
+ .. __: behave.html#command-line-arguments
58
+ """
59
+
60
+ def __init__(self, config, level=None):
61
+ BufferingHandler.__init__(self, 1000)
62
+ self.config = config
63
+ self.old_handlers = []
64
+ self.old_level = None
65
+
66
+ # set my formatter
67
+ log_format = datefmt = None
68
+ if config.logging_format:
69
+ log_format = config.logging_format
70
+ else:
71
+ log_format = '%(levelname)s:%(name)s:%(message)s'
72
+ if config.logging_datefmt:
73
+ datefmt = config.logging_datefmt
74
+ formatter = logging.Formatter(log_format, datefmt)
75
+ self.setFormatter(formatter)
76
+
77
+ # figure the level we're logging at
78
+ if level is not None:
79
+ self.level = level
80
+ elif config.logging_level:
81
+ self.level = config.logging_level
82
+ else:
83
+ self.level = logging.NOTSET
84
+
85
+ # construct my filter
86
+ if config.logging_filter:
87
+ self.addFilter(RecordFilter(config.logging_filter))
88
+
89
+ def __bool__(self):
90
+ return bool(self.buffer)
91
+
92
+ def flush(self):
93
+ pass # do nothing
94
+
95
+ def truncate(self):
96
+ self.buffer = []
97
+
98
+ def getvalue(self):
99
+ return '\n'.join(self.formatter.format(r) for r in self.buffer)
100
+
101
+ def find_event(self, pattern):
102
+ """Search through the buffer for a message that matches the given
103
+ regular expression.
104
+
105
+ Returns boolean indicating whether a match was found.
106
+ """
107
+ pattern = re.compile(pattern)
108
+ for record in self.buffer:
109
+ if pattern.search(record.getMessage()) is not None:
110
+ return True
111
+ return False
112
+
113
+ def any_errors(self):
114
+ """Search through the buffer for any ERROR or CRITICAL events.
115
+
116
+ Returns boolean indicating whether a match was found.
117
+ """
118
+ return any(record for record in self.buffer
119
+ if record.levelname in ('ERROR', 'CRITICAL'))
120
+
121
+ def inveigle(self):
122
+ """Turn on logging capture by replacing all existing handlers
123
+ configured in the logging module.
124
+
125
+ If the config var logging_clear_handlers is set then we also remove
126
+ all existing handlers.
127
+
128
+ We also set the level of the root logger.
129
+
130
+ The opposite of this is :meth:`~LoggingCapture.abandon`.
131
+ """
132
+ root_logger = logging.getLogger()
133
+ if self.config.logging_clear_handlers:
134
+ # kill off all the other log handlers
135
+ for logger in logging.Logger.manager.loggerDict.values():
136
+ if hasattr(logger, "handlers"):
137
+ for handler in logger.handlers:
138
+ self.old_handlers.append((logger, handler))
139
+ logger.removeHandler(handler)
140
+
141
+ # sanity check: remove any existing LoggingCapture
142
+ for handler in root_logger.handlers[:]:
143
+ if isinstance(handler, LoggingCapture):
144
+ root_logger.handlers.remove(handler)
145
+ elif self.config.logging_clear_handlers:
146
+ self.old_handlers.append((root_logger, handler))
147
+ root_logger.removeHandler(handler)
148
+
149
+ # right, we're it now
150
+ root_logger.addHandler(self)
151
+
152
+ # capture the level we're interested in
153
+ self.old_level = root_logger.level
154
+ root_logger.setLevel(self.level)
155
+
156
+ def abandon(self):
157
+ """Turn off logging capture.
158
+
159
+ If other handlers were removed by :meth:`~LoggingCapture.inveigle` then
160
+ they are reinstated.
161
+ """
162
+ root_logger = logging.getLogger()
163
+ for handler in root_logger.handlers[:]:
164
+ if handler is self:
165
+ root_logger.handlers.remove(handler)
166
+
167
+ if self.config.logging_clear_handlers:
168
+ for logger, handler in self.old_handlers:
169
+ logger.addHandler(handler)
170
+
171
+ if self.old_level is not None:
172
+ # -- RESTORE: Old log.level before inveigle() was used.
173
+ root_logger.setLevel(self.old_level)
174
+ self.old_level = None
175
+
176
+ # pre-1.2 backwards compatibility
177
+ MemoryHandler = LoggingCapture
178
+
179
+
180
+ def capture(*args, **kw):
181
+ """Decorator to wrap an *environment file function* in log file capture.
182
+
183
+ It configures the logging capture using the *behave* context - the first
184
+ argument to the function being decorated (so don't use this to decorate
185
+ something that doesn't have *context* as the first argument.)
186
+
187
+ The basic usage is:
188
+
189
+ .. code-block: python
190
+
191
+ @capture
192
+ def after_scenario(context, scenario):
193
+ ...
194
+
195
+ The function prints any captured logging (at the level determined by the
196
+ ``log_level`` configuration setting) directly to stdout, regardless of
197
+ error conditions.
198
+
199
+ It is mostly useful for debugging in situations where you are seeing a
200
+ message like::
201
+
202
+ No handlers could be found for logger "name"
203
+
204
+ The decorator takes an optional "level" keyword argument which limits the
205
+ level of logging captured, overriding the level in the run's configuration:
206
+
207
+ .. code-block: python
208
+
209
+ @capture(level=logging.ERROR)
210
+ def after_scenario(context, scenario):
211
+ ...
212
+
213
+ This would limit the logging captured to just ERROR and above, and thus
214
+ only display logged events if they are interesting.
215
+ """
216
+ def create_decorator(func, level=None):
217
+ def f(context, *args):
218
+ h = LoggingCapture(context.config, level=level)
219
+ h.inveigle()
220
+ try:
221
+ func(context, *args)
222
+ finally:
223
+ h.abandon()
224
+ v = h.getvalue()
225
+ if v:
226
+ print("Captured Logging:")
227
+ print(v)
228
+ return f
229
+
230
+ if not args:
231
+ return functools.partial(create_decorator, level=kw.get("level"))
232
+ else:
233
+ return create_decorator(args[0])