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,134 @@
1
+ # -*- coding: UTF-8 -*-
2
+ """Basic types (helper classes)."""
3
+
4
+ import sys
5
+ import six
6
+ if six.PY2:
7
+ # -- USE PYTHON2 BACKPORT: With unicode support
8
+ import traceback2 as traceback
9
+ else:
10
+ import traceback
11
+
12
+
13
+ class Unknown(object):
14
+ """Placeholder for unknown/missing information, distinguishable from None.
15
+
16
+ .. code-block:: python
17
+
18
+ data = {}
19
+ value = data.get("name", Unknown)
20
+ if value is Unknown:
21
+ # -- DO SOMETHING
22
+ ...
23
+ """
24
+
25
+
26
+ class ExceptionUtil(object):
27
+ """Provides a utility class for accessing/modifying exception information.
28
+
29
+ .. seealso:: PEP-3134 Chained excpetions
30
+ """
31
+ # pylint: disable=no-init
32
+
33
+ @staticmethod
34
+ def get_traceback(exception):
35
+ # -- ASSUMPTION: assert isinstance(exception, Exception)
36
+ return getattr(exception, "__traceback__", None)
37
+
38
+ @staticmethod
39
+ def set_traceback(exception, exc_traceback=Unknown):
40
+ assert isinstance(exception, Exception)
41
+ if exc_traceback is Unknown:
42
+ exc_traceback = sys.exc_info()[2]
43
+ exception.__traceback__ = exc_traceback
44
+
45
+ @classmethod
46
+ def has_traceback(cls, exception):
47
+ """Indicates if traceback information related to this exception
48
+ is stored with the exception object.
49
+
50
+ :param exception: Exception object to check.
51
+ :return: True, if traceback info is stored. False, otherwise.
52
+ """
53
+ return cls.get_traceback(exception) is not None
54
+
55
+ @classmethod
56
+ def describe(cls, exception, use_traceback=False, prefix=""):
57
+ # -- NORMAL CASE:
58
+ text = u"{prefix}{0}: {1}\n".format(exception.__class__.__name__,
59
+ exception, prefix=prefix)
60
+ if use_traceback:
61
+ exc_traceback = cls.get_traceback(exception)
62
+ if exc_traceback:
63
+ # -- NOTE: Chained-exception cause (see: PEP-3134).
64
+ text += u"".join(traceback.format_tb(exc_traceback))
65
+ return text
66
+
67
+
68
+ class ChainedExceptionUtil(ExceptionUtil):
69
+ """Provides a utility class for accessing/modifying exception information
70
+ related to chained exceptions.
71
+
72
+ .. seealso:: PEP-3134 Chained excpetions
73
+ """
74
+ # pylint: disable=no-init
75
+
76
+ @staticmethod
77
+ def get_cause(exception):
78
+ # -- ASSUMPTION: assert isinstance(exception, Exception)
79
+ return getattr(exception, "__cause__", None)
80
+
81
+ @staticmethod
82
+ def set_cause(exception, exc_cause):
83
+ assert isinstance(exception, Exception)
84
+ assert isinstance(exc_cause, Exception) or exc_cause is None
85
+ exception.__cause__ = exc_cause
86
+ if exc_cause and not hasattr(exc_cause, "__traceback__"):
87
+ # -- NEEDED-FOR: Python2
88
+ # Otherwise, traceback formatting tries to access missing attribute.
89
+ exc_cause.__traceback__ = None
90
+
91
+ # pylint: disable=arguments-differ
92
+ @classmethod
93
+ def describe(cls, exception, use_traceback=False, prefix="", style="reversed"):
94
+ """Describes an exception, optionally together with its traceback info.
95
+ Also shows information about exception cause (chained exceptions),
96
+ if exists.
97
+
98
+ :param exception: Exception object to describe.
99
+ :param use_traceback: Indicates if traceback info should be shown.
100
+ :param prefix: Optional prefix for description text.
101
+ :param style: Optional style indicator ("reversed", "normal")
102
+ :return: Exception description as text.
103
+ """
104
+ text = ExceptionUtil.describe(exception, use_traceback, prefix)
105
+
106
+ # -- STEP: Collect chained exceptions.
107
+ causes = []
108
+ exc_cause = cls.get_cause(exception)
109
+ while exc_cause:
110
+ causes.append(exc_cause)
111
+ exc_cause = cls.get_cause(exc_cause)
112
+
113
+ # -- STEP: Describe causes for chained exceptions.
114
+ parts = []
115
+ if style == "normal":
116
+ prefix = "CAUSE: "
117
+ for exc_cause in reversed(causes):
118
+ cause_text = ExceptionUtil.describe(exc_cause, use_traceback,
119
+ prefix)
120
+ parts.append(cause_text)
121
+ if len(parts) == 1:
122
+ prefix = "CAUSES: "
123
+ parts.append(text)
124
+ else:
125
+ parts.append(text)
126
+ for exc_cause in causes:
127
+ cause_text = ExceptionUtil.describe(exc_cause, use_traceback,
128
+ prefix="CAUSED-BY: ")
129
+ parts.append(cause_text)
130
+ return u"\n".join(parts)
131
+ # if exc_cause:
132
+ # cause_text =
133
+ # text += u"\n" + cause_text
134
+ # return text
@@ -0,0 +1,7 @@
1
+ """
2
+ Provides/defines stable APIs for behave users:
3
+
4
+ * step writer(s): features/steps/*.py
5
+ * environment writers: features/environment.py
6
+ * ...
7
+ """
@@ -0,0 +1,283 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # pylint: disable=line-too-long
3
+ """
4
+ This module provides functionality to support "async steps" (coroutines)
5
+ in a step-module with behave. This functionality simplifies to test
6
+ frameworks and protocols that make use of `asyncio.coroutines`_ or
7
+ provide `asyncio.coroutines`_.
8
+
9
+ EXAMPLE:
10
+
11
+ .. code-block:: python
12
+
13
+ # -- FILE: features/steps/my_async_steps.py
14
+ # EXAMPLE REQUIRES: Python >= 3.5
15
+ from behave import step
16
+ from behave.api.async_step import async_run_until_complete
17
+
18
+ @step('an async coroutine step waits {duration:f} seconds')
19
+ @async_run_until_complete
20
+ async def step_async_step_waits_seconds(context, duration):
21
+ await asyncio.sleep(duration)
22
+
23
+ .. code-block:: python
24
+
25
+ # -- FILE: features/steps/my_async_steps2.py
26
+ # EXAMPLE REQUIRES: Python >= 3.4
27
+ from behave import step
28
+ from behave.api.async_step import async_run_until_complete
29
+ import asyncio
30
+
31
+ @step('a tagged-coroutine async step waits {duration:f} seconds')
32
+ @async_run_until_complete
33
+ @asyncio.coroutine
34
+ def step_async_step_waits_seconds2(context, duration):
35
+ yield from asyncio.sleep(duration)
36
+
37
+
38
+ .. requires:: Python 3.5 (or 3.4) or :mod:`asyncio` backport (like :pypi:`trollius`)
39
+ .. seealso::
40
+ https://docs.python.org/3/library/asyncio.html
41
+
42
+ .. _asyncio.coroutines: https://docs.python.org/3/library/asyncio-task.html#coroutines
43
+ """
44
+ # pylint: enable=line-too-long
45
+
46
+ from __future__ import print_function
47
+ # -- REQUIRES: Python >= 3.4
48
+ # MAYBE BACKPORT: trollius
49
+ import functools
50
+ from six import string_types
51
+ try:
52
+ import asyncio
53
+ has_asyncio = True
54
+ except ImportError:
55
+ has_asyncio = False
56
+
57
+ # -----------------------------------------------------------------------------
58
+ # ASYNC STEP DECORATORS:
59
+ # -----------------------------------------------------------------------------
60
+ def async_run_until_complete(astep_func=None, loop=None, timeout=None,
61
+ async_context=None, should_close=False):
62
+ """Provides a function decorator for async-steps (coroutines).
63
+ Provides an async event loop and runs the async-step until completion
64
+ (or timeout, if specified).
65
+
66
+ .. code-block:: python
67
+
68
+ from behave import step
69
+ from behave.api.async_step import async_run_until_complete
70
+ import asyncio
71
+
72
+ @step("an async step is executed")
73
+ @async_run_until_complete
74
+ async def astep_impl(context)
75
+ await asycio.sleep(0.1)
76
+
77
+ @step("an async step is executed")
78
+ @async_run_until_complete(timeout=1.2)
79
+ async def astep_impl2(context)
80
+ # -- NOTE: Wrapped event loop waits with timeout=1.2 seconds.
81
+ await asycio.sleep(0.3)
82
+
83
+ Parameters:
84
+ astep_func: Async step function (coroutine)
85
+ loop (asyncio.EventLoop): Event loop to use or None.
86
+ timeout (int, float): Timeout to wait for async-step completion.
87
+ async_context (name): Async_context name or object to use.
88
+ should_close (bool): Indicates if event lopp should be closed.
89
+
90
+ .. note::
91
+
92
+ * If :param:`loop` is None, the default event loop will be used
93
+ or a new event loop is created.
94
+ * If :param:`timeout` is provided, the event loop waits only the
95
+ specified time.
96
+ * :param:`async_context` is only used, if :param:`loop` is None.
97
+ * If :param:`async_context` is a name, it will be used to retrieve
98
+ the real async_context object from the context.
99
+
100
+ """
101
+ @functools.wraps(astep_func)
102
+ def step_decorator(astep_func, context, *args, **kwargs):
103
+ loop = kwargs.pop("_loop", None)
104
+ timeout = kwargs.pop("_timeout", None)
105
+ async_context = kwargs.pop("_async_context", None)
106
+ should_close = kwargs.pop("_should_close", None)
107
+
108
+ if isinstance(loop, string_types):
109
+ loop = getattr(context, loop, None)
110
+ elif async_context:
111
+ if isinstance(async_context, string_types):
112
+ name = async_context
113
+ async_context = use_or_create_async_context(context, name)
114
+ loop = async_context.loop
115
+ else:
116
+ assert isinstance(async_context, AsyncContext)
117
+ loop = async_context.loop
118
+ if loop is None:
119
+ loop = asyncio.get_event_loop() or asyncio.new_event_loop()
120
+
121
+ # -- WORKHORSE:
122
+ try:
123
+ if timeout is None:
124
+ loop.run_until_complete(astep_func(context, *args, **kwargs))
125
+ else:
126
+ # MAYBE: loop = asyncio.new_event_loop()
127
+ # MAYBE: should_close = True
128
+ task = loop.create_task(astep_func(context, *args, **kwargs))
129
+ done, pending = loop.run_until_complete(
130
+ asyncio.wait([task], timeout=timeout))
131
+ assert not pending, "TIMEOUT-OCCURED: timeout=%s" % timeout
132
+ finally:
133
+ if loop and should_close:
134
+ # -- MAYBE-AVOID:
135
+ loop.close()
136
+
137
+ if astep_func is None:
138
+ # -- CASE: @decorator(timeout=1.2, ...)
139
+ # MAYBE: return functools.partial(step_decorator,
140
+ def wrapped_decorator1(astep_func):
141
+ @functools.wraps(astep_func)
142
+ def wrapped_decorator2(context, *args, **kwargs):
143
+ return step_decorator(astep_func, context, *args,
144
+ _loop=loop,
145
+ _timeout=timeout,
146
+ _async_context=async_context,
147
+ _should_close=should_close, **kwargs)
148
+ assert callable(astep_func)
149
+ return wrapped_decorator2
150
+ return wrapped_decorator1
151
+ else:
152
+ # -- CASE: @decorator ... or astep = decorator(astep)
153
+ # MAYBE: return functools.partial(step_decorator, astep_func=astep_func)
154
+ assert callable(astep_func)
155
+ @functools.wraps(astep_func)
156
+ def wrapped_decorator(context, *args, **kwargs):
157
+ return step_decorator(astep_func, context, *args, **kwargs)
158
+ return wrapped_decorator
159
+
160
+ # -- ALIAS:
161
+ run_until_complete = async_run_until_complete
162
+
163
+ # -----------------------------------------------------------------------------
164
+ # ASYNC STEP UTILITY CLASSES:
165
+ # -----------------------------------------------------------------------------
166
+ class AsyncContext(object):
167
+ # pylint: disable=line-too-long
168
+ """Provides a context object for "async steps" to keep track:
169
+
170
+ * which event loop is used
171
+ * which (asyncio) tasks are used or of interest
172
+
173
+ .. attribute:: loop
174
+ Event loop object to use.
175
+ If none is provided, the current event-loop is used
176
+ (or a new one is created).
177
+
178
+ .. attribute:: tasks
179
+ List of started :mod:`asyncio` tasks (of interest).
180
+
181
+ .. attribute:: name
182
+
183
+ Optional name of this object (in the behave context).
184
+ If none is provided, :attr:`AsyncContext.default_name` is used.
185
+
186
+ .. attribute:: should_close
187
+ Indicates if the :attr:`loop` (event-loop) should be closed or not.
188
+
189
+ EXAMPLE:
190
+
191
+ .. code-block:: python
192
+
193
+ # -- FILE: features/steps/my_async_steps.py
194
+ # REQUIRES: Python 3.5
195
+ from behave import given, when, then, step
196
+ from behave.api.async_step import AsyncContext
197
+
198
+ @when('I dispatch an async-call with param "{param}"')
199
+ def step_impl(context, param):
200
+ async_context = getattr(context, "async_context", None)
201
+ if async_context is None:
202
+ async_context = context.async_context = AsyncContext()
203
+ task = async_context.loop.create_task(my_async_func(param))
204
+ async_context.tasks.append(task)
205
+
206
+ @then('I wait at most {duration:f} seconds until all async-calls are completed')
207
+ def step_impl(context, duration):
208
+ async_context = context.async_context
209
+ assert async_context.tasks
210
+ done, pending = async_context.loop.run_until_complete(asyncio.wait(
211
+ async_context.tasks, loop=async_context.loop, timeout=duration))
212
+ assert len(pending) == 0
213
+
214
+ # -- COROUTINE:
215
+ async def my_async_func(param):
216
+ await asyncio.sleep(0.5)
217
+ return param.upper()
218
+ """
219
+ # pylint: enable=line-too-long
220
+ default_name = "async_context"
221
+
222
+ def __init__(self, loop=None, name=None, should_close=False, tasks=None):
223
+ self.loop = loop or asyncio.get_event_loop() or asyncio.new_event_loop()
224
+ self.tasks = tasks or []
225
+ self.name = name or self.default_name
226
+ self.should_close = should_close
227
+
228
+ def __del__(self):
229
+ if self.loop and self.should_close:
230
+ self.close()
231
+
232
+ def close(self):
233
+ if self.loop and not self.loop.is_closed():
234
+ self.loop.close()
235
+ self.loop = None
236
+
237
+
238
+ # -----------------------------------------------------------------------------
239
+ # ASYNC STEP UTILITY FUNCTIONS:
240
+ # -----------------------------------------------------------------------------
241
+ def use_or_create_async_context(context, name=None, loop=None, **kwargs):
242
+ """Utility function to be used in step implementations to ensure that an
243
+ :class:`AsyncContext` object is stored in the :param:`context` object.
244
+
245
+ If no such attribute exists (under the given name),
246
+ a new :class:`AsyncContext` object is created with the provided args.
247
+ Otherwise, the existing context attribute is used.
248
+
249
+ EXAMPLE:
250
+
251
+ .. code-block:: python
252
+
253
+ # -- FILE: features/steps/my_async_steps.py
254
+ # EXAMPLE REQUIRES: Python 3.5
255
+ from behave import when
256
+ from behave.api.async_step import use_or_create_async_context
257
+
258
+ @when('I dispatch an async-call with param "{param}"')
259
+ def step_impl(context, param):
260
+ async_context = use_or_create_async_context(context, "async_context")
261
+ task = async_context.loop.create_task(my_async_func(param))
262
+ async_context.tasks.append(task)
263
+
264
+ # -- COROUTINE:
265
+ async def my_async_func(param):
266
+ await asyncio.sleep(0.5)
267
+ return param.upper()
268
+
269
+ :param context: Behave context object to use.
270
+ :param name: Optional name of async-context object (as string or None).
271
+ :param loop: Optional event_loop object to use for create call.
272
+ :param kwargs: Optional :class:`AsyncContext` params for create call.
273
+ :return: :class:`AsyncContext` object from the param:`context`.
274
+ """
275
+ if name is None:
276
+ name = AsyncContext.default_name
277
+ async_context = getattr(context, name, None)
278
+ if async_context is None:
279
+ async_context = AsyncContext(loop=loop, name=name, **kwargs)
280
+ setattr(context, async_context.name, async_context)
281
+ assert isinstance(async_context, AsyncContext)
282
+ assert getattr(context, async_context.name) is async_context
283
+ return async_context
@@ -0,0 +1,227 @@
1
+ # -*- coding: UTF-8 -*-
2
+ """
3
+ Capture output (stdout, stderr), logs, etc.
4
+ """
5
+
6
+ from __future__ import absolute_import
7
+ from contextlib import contextmanager
8
+ import sys
9
+ from six import StringIO, PY2
10
+ from behave.log_capture import LoggingCapture
11
+ from behave.textutil import text as _text
12
+
13
+ def add_text_to(value, more_text, separator="\n"):
14
+ if more_text:
15
+ if value:
16
+ if separator and not value.endswith(separator):
17
+ value += separator
18
+ value += more_text
19
+ else:
20
+ value = more_text
21
+ return value
22
+
23
+
24
+ class Captured(object):
25
+ """Stores and aggregates captured output data."""
26
+ empty = u""
27
+ linesep = u"\n"
28
+
29
+ def __init__(self, stdout=None, stderr=None, log_output=None):
30
+ self.stdout = stdout or self.empty
31
+ self.stderr = stderr or self.empty
32
+ self.log_output = log_output or self.empty
33
+
34
+ def reset(self):
35
+ self.stdout = self.empty
36
+ self.stderr = self.empty
37
+ self.log_output = self.empty
38
+
39
+ # -- PYTHON2:
40
+ if PY2:
41
+ def __nonzero__(self):
42
+ return bool(self.stdout or self.stderr or self.log_output)
43
+ else:
44
+ def __bool__(self):
45
+ return bool(self.stdout or self.stderr or self.log_output)
46
+
47
+ @property
48
+ def output(self):
49
+ """Makes a simple report of the captured data by concatenating
50
+ all parts.
51
+ """
52
+ output_text = self.stdout
53
+ output_text = add_text_to(output_text, self.stderr)
54
+ output_text = add_text_to(output_text, self.log_output)
55
+ return output_text
56
+
57
+ def add(self, captured):
58
+ """Adds/appends captured output data to this object.
59
+
60
+ :param captured: Captured object whose data should be added.
61
+ :return: self, to allow daisy-chaining (if needed).
62
+ """
63
+ assert isinstance(captured, Captured)
64
+ self.stdout = add_text_to(self.stdout, captured.stdout, self.linesep)
65
+ self.stderr = add_text_to(self.stderr, captured.stderr, self.linesep)
66
+ self.log_output = add_text_to(self.log_output, captured.log_output,
67
+ self.linesep)
68
+ return self
69
+
70
+ def make_report(self):
71
+ """Makes a detailled report of the captured output data.
72
+
73
+ :returns: Report as string.
74
+ """
75
+ report_parts = []
76
+ if self.stdout:
77
+ parts = ["Captured stdout:", _text(self.stdout).rstrip(), ""]
78
+ report_parts.extend(parts)
79
+ if self.stderr:
80
+ parts = ["Captured stderr:", _text(self.stderr).rstrip(), ""]
81
+ report_parts.extend(parts)
82
+ if self.log_output:
83
+ parts = ["Captured logging:", _text(self.log_output)]
84
+ report_parts.extend(parts)
85
+ return self.linesep.join(report_parts).strip()
86
+
87
+ def __add__(self, other):
88
+ """Supports incremental add::
89
+
90
+ captured1 = Captured("Hello")
91
+ captured2 = Captured("World")
92
+ captured3 = captured1 + captured2
93
+ assert captured3.stdout == "Hello\nWorld"
94
+ """
95
+ new_data = Captured(self.stdout, self.stderr, self.log_output)
96
+ return new_data.add(other)
97
+
98
+ def __iadd__(self, other):
99
+ """Supports incremental add::
100
+
101
+ captured1 = Captured("Hello")
102
+ captured2 = Captured("World")
103
+ captured1 += captured2
104
+ assert captured1.stdout == "Hello\nWorld"
105
+ """
106
+ return self.add(other)
107
+
108
+
109
+ class CaptureController(object):
110
+ """Simplifies the lifecycle to capture output from various sources."""
111
+ def __init__(self, config):
112
+ self.config = config
113
+ self.stdout_capture = None
114
+ self.stderr_capture = None
115
+ self.log_capture = None
116
+ self.old_stdout = None
117
+ self.old_stderr = None
118
+
119
+ @property
120
+ def captured(self):
121
+ """Provides access of the captured output data.
122
+
123
+ :return: Object that stores the captured output parts (as Captured).
124
+ """
125
+ stdout = None
126
+ stderr = None
127
+ log_out = None
128
+ if self.config.stdout_capture and self.stdout_capture:
129
+ stdout = _text(self.stdout_capture.getvalue())
130
+ if self.config.stderr_capture and self.stderr_capture:
131
+ stderr = _text(self.stderr_capture.getvalue())
132
+ if self.config.log_capture and self.log_capture:
133
+ log_out = _text(self.log_capture.getvalue())
134
+ return Captured(stdout, stderr, log_out)
135
+
136
+ def setup_capture(self, context):
137
+ assert context is not None
138
+ if self.config.stdout_capture:
139
+ self.stdout_capture = StringIO()
140
+ context.stdout_capture = self.stdout_capture
141
+
142
+ if self.config.stderr_capture:
143
+ self.stderr_capture = StringIO()
144
+ context.stderr_capture = self.stderr_capture
145
+
146
+ if self.config.log_capture:
147
+ self.log_capture = LoggingCapture(self.config)
148
+ self.log_capture.inveigle()
149
+ context.log_capture = self.log_capture
150
+
151
+ def start_capture(self):
152
+ if self.config.stdout_capture:
153
+ # -- REPLACE ONLY: In non-capturing mode.
154
+ if not self.old_stdout:
155
+ self.old_stdout = sys.stdout
156
+ sys.stdout = self.stdout_capture
157
+ assert sys.stdout is self.stdout_capture
158
+
159
+ if self.config.stderr_capture:
160
+ # -- REPLACE ONLY: In non-capturing mode.
161
+ if not self.old_stderr:
162
+ self.old_stderr = sys.stderr
163
+ sys.stderr = self.stderr_capture
164
+ assert sys.stderr is self.stderr_capture
165
+
166
+ def stop_capture(self):
167
+ if self.config.stdout_capture:
168
+ # -- RESTORE ONLY: In capturing mode.
169
+ if self.old_stdout:
170
+ sys.stdout = self.old_stdout
171
+ self.old_stdout = None
172
+ assert sys.stdout is not self.stdout_capture
173
+
174
+ if self.config.stderr_capture:
175
+ # -- RESTORE ONLY: In capturing mode.
176
+ if self.old_stderr:
177
+ sys.stderr = self.old_stderr
178
+ self.old_stderr = None
179
+ assert sys.stderr is not self.stderr_capture
180
+
181
+ def teardown_capture(self):
182
+ if self.config.log_capture:
183
+ self.log_capture.abandon()
184
+
185
+ def make_capture_report(self):
186
+ """Combine collected output and return as string."""
187
+ return self.captured.make_report()
188
+ # report = u""
189
+ # if self.config.stdout_capture and self.stdout_capture:
190
+ # output = self.stdout_capture.getvalue()
191
+ # if output:
192
+ # output = _text(output)
193
+ # report += u"\nCaptured stdout:\n" + output
194
+ # if self.config.stderr_capture and self.stderr_capture:
195
+ # output = self.stderr_capture.getvalue()
196
+ # if output:
197
+ # output = _text(output)
198
+ # report += u"\nCaptured stderr:\n" + output
199
+ # if self.config.log_capture and self.log_capture:
200
+ # output = self.log_capture.getvalue()
201
+ # if output:
202
+ # output = _text(output)
203
+ # report += u"\nCaptured logging:\n" + output
204
+ # return report
205
+
206
+ # -----------------------------------------------------------------------------
207
+ # UTILITY FUNCTIONS:
208
+ # -----------------------------------------------------------------------------
209
+ @contextmanager
210
+ def capture_output(controller, enabled=True):
211
+ """Provides a context manager that starts capturing output
212
+
213
+ .. code-block::
214
+
215
+ with capture_output(capture_controller):
216
+ ... # Do something
217
+ """
218
+ if enabled:
219
+ try:
220
+ controller.start_capture()
221
+ yield
222
+ finally:
223
+ controller.stop_capture()
224
+ else:
225
+ # -- CAPTURING OUTPUT is disabled.
226
+ # Needed to prevent recursive captures with context.execute_steps()
227
+ yield