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,94 @@
1
+ # -*- coding: UTF-8 -*-
2
+ """
3
+ Provides a summary after each test run.
4
+ """
5
+
6
+ from __future__ import absolute_import, division
7
+ import sys
8
+ from behave.model import ScenarioOutline
9
+ from behave.model_core import Status
10
+ from behave.reporter.base import Reporter
11
+ from behave.formatter.base import StreamOpener
12
+
13
+
14
+ # -- DISABLED: optional_steps = ('untested', 'undefined')
15
+ optional_steps = (Status.untested,) # MAYBE: Status.undefined
16
+ status_order = (Status.passed, Status.failed, Status.skipped,
17
+ Status.undefined, Status.untested)
18
+
19
+ def format_summary(statement_type, summary):
20
+ parts = []
21
+ for status in status_order:
22
+ if status.name not in summary:
23
+ continue
24
+ counts = summary[status.name]
25
+ if status in optional_steps and counts == 0:
26
+ # -- SHOW-ONLY: For relevant counts, suppress: untested items, etc.
27
+ continue
28
+
29
+ if not parts:
30
+ # -- FIRST ITEM: Add statement_type to counter.
31
+ label = statement_type
32
+ if counts != 1:
33
+ label += 's'
34
+ part = u"%d %s %s" % (counts, label, status.name)
35
+ else:
36
+ part = u"%d %s" % (counts, status.name)
37
+ parts.append(part)
38
+ return ", ".join(parts) + "\n"
39
+
40
+
41
+ class SummaryReporter(Reporter):
42
+ show_failed_scenarios = True
43
+ output_stream_name = "stdout"
44
+
45
+ def __init__(self, config):
46
+ super(SummaryReporter, self).__init__(config)
47
+ stream = getattr(sys, self.output_stream_name, sys.stderr)
48
+ self.stream = StreamOpener.ensure_stream_with_encoder(stream)
49
+ self.feature_summary = {Status.passed.name: 0, Status.failed.name: 0,
50
+ Status.skipped.name: 0, Status.untested.name: 0}
51
+ self.scenario_summary = {Status.passed.name: 0, Status.failed.name: 0,
52
+ Status.skipped.name: 0, Status.untested.name: 0}
53
+ self.step_summary = {Status.passed.name: 0, Status.failed.name: 0,
54
+ Status.skipped.name: 0, Status.untested.name: 0,
55
+ Status.undefined.name: 0}
56
+ self.duration = 0.0
57
+ self.failed_scenarios = []
58
+
59
+ def feature(self, feature):
60
+ self.feature_summary[feature.status.name] += 1
61
+ self.duration += feature.duration
62
+ for scenario in feature:
63
+ if isinstance(scenario, ScenarioOutline):
64
+ self.process_scenario_outline(scenario)
65
+ else:
66
+ self.process_scenario(scenario)
67
+
68
+ def end(self):
69
+ # -- SHOW FAILED SCENARIOS (optional):
70
+ if self.show_failed_scenarios and self.failed_scenarios:
71
+ self.stream.write("\nFailing scenarios:\n")
72
+ for scenario in self.failed_scenarios:
73
+ self.stream.write(u" %s %s\n" % (
74
+ scenario.location, scenario.name))
75
+ self.stream.write("\n")
76
+
77
+ # -- SHOW SUMMARY COUNTS:
78
+ self.stream.write(format_summary("feature", self.feature_summary))
79
+ self.stream.write(format_summary("scenario", self.scenario_summary))
80
+ self.stream.write(format_summary("step", self.step_summary))
81
+ timings = (int(self.duration / 60.0), self.duration % 60)
82
+ self.stream.write('Took %dm%02.3fs\n' % timings)
83
+
84
+ def process_scenario(self, scenario):
85
+ if scenario.status == Status.failed:
86
+ self.failed_scenarios.append(scenario)
87
+
88
+ self.scenario_summary[scenario.status.name] += 1
89
+ for step in scenario:
90
+ self.step_summary[step.status.name] += 1
91
+
92
+ def process_scenario_outline(self, scenario_outline):
93
+ for scenario in scenario_outline.scenarios:
94
+ self.process_scenario(scenario)
@@ -0,0 +1,753 @@
1
+ # -*- coding: UTF-8 -*-
2
+ """
3
+ This module provides Runner class to run behave feature files (or model elements).
4
+ """
5
+
6
+ from __future__ import absolute_import, print_function, with_statement
7
+ import contextlib
8
+ import os.path
9
+ import sys
10
+ import warnings
11
+ import weakref
12
+ import six
13
+ from behave import matchers
14
+ from behave.step_registry import setup_step_decorators, registry as the_step_registry
15
+ from behave.formatter._registry import make_formatters
16
+ from behave.configuration import ConfigError
17
+ from behave.capture import CaptureController
18
+ from behave.runner_util import collect_feature_locations, parse_features
19
+ from behave._types import ExceptionUtil
20
+ if six.PY2:
21
+ # -- USE PYTHON3 BACKPORT: With unicode traceback support.
22
+ import traceback2 as traceback
23
+ else:
24
+ import traceback
25
+
26
+
27
+
28
+ class ContextMaskWarning(UserWarning):
29
+ """Raised if a context variable is being overwritten in some situations.
30
+
31
+ If the variable was originally set by user code then this will be raised if
32
+ *behave* overwites the value.
33
+
34
+ If the variable was originally set by *behave* then this will be raised if
35
+ user code overwites the value.
36
+ """
37
+ pass
38
+
39
+
40
+ class Context(object):
41
+ """Hold contextual information during the running of tests.
42
+
43
+ This object is a place to store information related to the tests you're
44
+ running. You may add arbitrary attributes to it of whatever value you need.
45
+
46
+ During the running of your tests the object will have additional layers of
47
+ namespace added and removed automatically. There is a "root" namespace and
48
+ additional namespaces for features and scenarios.
49
+
50
+ Certain names are used by *behave*; be wary of using them yourself as
51
+ *behave* may overwrite the value you set. These names are:
52
+
53
+ .. attribute:: feature
54
+
55
+ This is set when we start testing a new feature and holds a
56
+ :class:`~behave.model.Feature`. It will not be present outside of a
57
+ feature (i.e. within the scope of the environment before_all and
58
+ after_all).
59
+
60
+ .. attribute:: scenario
61
+
62
+ This is set when we start testing a new scenario (including the
63
+ individual scenarios of a scenario outline) and holds a
64
+ :class:`~behave.model.Scenario`. It will not be present outside of the
65
+ scope of a scenario.
66
+
67
+ .. attribute:: tags
68
+
69
+ The current set of active tags (as a Python set containing instances of
70
+ :class:`~behave.model.Tag` which are basically just glorified strings)
71
+ combined from the feature and scenario. This attribute will not be
72
+ present outside of a feature scope.
73
+
74
+ .. attribute:: aborted
75
+
76
+ This is set to true in the root namespace when the user aborts a test run
77
+ (:exc:`KeyboardInterrupt` exception). Initially: False.
78
+
79
+ .. attribute:: failed
80
+
81
+ This is set to true in the root namespace as soon as a step fails.
82
+ Initially: False.
83
+
84
+ .. attribute:: table
85
+
86
+ This is set at the step level and holds any :class:`~behave.model.Table`
87
+ associated with the step.
88
+
89
+ .. attribute:: text
90
+
91
+ This is set at the step level and holds any multiline text associated
92
+ with the step.
93
+
94
+ .. attribute:: config
95
+
96
+ The configuration of *behave* as determined by configuration files and
97
+ command-line options. The attributes of this object are the same as the
98
+ `configuration file section names`_.
99
+
100
+ .. attribute:: active_outline
101
+
102
+ This is set for each scenario in a scenario outline and references the
103
+ :class:`~behave.model.Row` that is active for the current scenario. It is
104
+ present mostly for debugging, but may be useful otherwise.
105
+
106
+ .. attribute:: log_capture
107
+
108
+ If logging capture is enabled then this attribute contains the captured
109
+ logging as an instance of :class:`~behave.log_capture.LoggingCapture`.
110
+ It is not present if logging is not being captured.
111
+
112
+ .. attribute:: stdout_capture
113
+
114
+ If stdout capture is enabled then this attribute contains the captured
115
+ output as a StringIO instance. It is not present if stdout is not being
116
+ captured.
117
+
118
+ .. attribute:: stderr_capture
119
+
120
+ If stderr capture is enabled then this attribute contains the captured
121
+ output as a StringIO instance. It is not present if stderr is not being
122
+ captured.
123
+
124
+ If an attempt made by user code to overwrite one of these variables, or
125
+ indeed by *behave* to overwite a user-set variable, then a
126
+ :class:`behave.runner.ContextMaskWarning` warning will be raised.
127
+
128
+ You may use the "in" operator to test whether a certain value has been set
129
+ on the context, for example:
130
+
131
+ "feature" in context
132
+
133
+ checks whether there is a "feature" value in the context.
134
+
135
+ Values may be deleted from the context using "del" but only at the level
136
+ they are set. You can't delete a value set by a feature at a scenario level
137
+ but you can delete a value set for a scenario in that scenario.
138
+
139
+ .. _`configuration file section names`: behave.html#configuration-files
140
+ """
141
+ # pylint: disable=too-many-instance-attributes
142
+ BEHAVE = "behave"
143
+ USER = "user"
144
+
145
+ def __init__(self, runner):
146
+ self._runner = weakref.proxy(runner)
147
+ self._config = runner.config
148
+ d = self._root = {
149
+ "aborted": False,
150
+ "failed": False,
151
+ "config": self._config,
152
+ "active_outline": None,
153
+ }
154
+ self._stack = [d]
155
+ self._record = {}
156
+ self._origin = {}
157
+ self._mode = self.BEHAVE
158
+ self.feature = None
159
+ # -- RECHECK: If needed
160
+ self.text = None
161
+ self.table = None
162
+ self.stdout_capture = None
163
+ self.stderr_capture = None
164
+ self.log_capture = None
165
+
166
+ def _push(self):
167
+ self._stack.insert(0, {})
168
+
169
+ def _pop(self):
170
+ self._stack.pop(0)
171
+
172
+ def _use_with_behave_mode(self):
173
+ """Provides a context manager for using the context in BEHAVE mode."""
174
+ return use_context_with_mode(self, Context.BEHAVE)
175
+
176
+ def use_with_user_mode(self):
177
+ """Provides a context manager for using the context in USER mode."""
178
+ return use_context_with_mode(self, Context.USER)
179
+
180
+ def user_mode(self):
181
+ warnings.warn("Use 'use_with_user_mode()' instead",
182
+ PendingDeprecationWarning, stacklevel=2)
183
+ return self.use_with_user_mode()
184
+
185
+ def _set_root_attribute(self, attr, value):
186
+ for frame in self.__dict__["_stack"]:
187
+ if frame is self.__dict__["_root"]:
188
+ continue
189
+ if attr in frame:
190
+ record = self.__dict__["_record"][attr]
191
+ params = {
192
+ "attr": attr,
193
+ "filename": record[0],
194
+ "line": record[1],
195
+ "function": record[3],
196
+ }
197
+ self._emit_warning(attr, params)
198
+
199
+ self.__dict__["_root"][attr] = value
200
+ if attr not in self._origin:
201
+ self._origin[attr] = self._mode
202
+
203
+ def _emit_warning(self, attr, params):
204
+ msg = ""
205
+ if self._mode is self.BEHAVE and self._origin[attr] is not self.BEHAVE:
206
+ msg = "behave runner is masking context attribute '%(attr)s' " \
207
+ "originally set in %(function)s (%(filename)s:%(line)s)"
208
+ elif self._mode is self.USER:
209
+ if self._origin[attr] is not self.USER:
210
+ msg = "user code is masking context attribute '%(attr)s' " \
211
+ "originally set by behave"
212
+ elif self._config.verbose:
213
+ msg = "user code is masking context attribute " \
214
+ "'%(attr)s'; see the tutorial for what this means"
215
+ if msg:
216
+ msg = msg % params
217
+ warnings.warn(msg, ContextMaskWarning, stacklevel=3)
218
+
219
+ def _dump(self, pretty=False, prefix=" "):
220
+ for level, frame in enumerate(self._stack):
221
+ print("%sLevel %d" % (prefix, level))
222
+ if pretty:
223
+ for name in sorted(frame.keys()):
224
+ value = frame[name]
225
+ print("%s %-15s = %r" % (prefix, name, value))
226
+ else:
227
+ print(prefix + repr(frame))
228
+
229
+ def __getattr__(self, attr):
230
+ if attr[0] == "_":
231
+ return self.__dict__[attr]
232
+ for frame in self._stack:
233
+ if attr in frame:
234
+ return frame[attr]
235
+ msg = "'{0}' object has no attribute '{1}'"
236
+ msg = msg.format(self.__class__.__name__, attr)
237
+ raise AttributeError(msg)
238
+
239
+ def __setattr__(self, attr, value):
240
+ if attr[0] == "_":
241
+ self.__dict__[attr] = value
242
+ return
243
+
244
+ for frame in self._stack[1:]:
245
+ if attr in frame:
246
+ record = self._record[attr]
247
+ params = {
248
+ "attr": attr,
249
+ "filename": record[0],
250
+ "line": record[1],
251
+ "function": record[3],
252
+ }
253
+ self._emit_warning(attr, params)
254
+
255
+ stack_limit = 2
256
+ if six.PY2:
257
+ stack_limit += 1 # Due to traceback2 usage.
258
+ stack_frame = traceback.extract_stack(limit=stack_limit)[0]
259
+ self._record[attr] = stack_frame
260
+ frame = self._stack[0]
261
+ frame[attr] = value
262
+ if attr not in self._origin:
263
+ self._origin[attr] = self._mode
264
+
265
+ def __delattr__(self, attr):
266
+ frame = self._stack[0]
267
+ if attr in frame:
268
+ del frame[attr]
269
+ del self._record[attr]
270
+ else:
271
+ msg = "'{0}' object has no attribute '{1}' at the current level"
272
+ msg = msg.format(self.__class__.__name__, attr)
273
+ raise AttributeError(msg)
274
+
275
+ def __contains__(self, attr):
276
+ if attr[0] == "_":
277
+ return attr in self.__dict__
278
+ for frame in self._stack:
279
+ if attr in frame:
280
+ return True
281
+ return False
282
+
283
+ def execute_steps(self, steps_text):
284
+ """The steps identified in the "steps" text string will be parsed and
285
+ executed in turn just as though they were defined in a feature file.
286
+
287
+ If the execute_steps call fails (either through error or failure
288
+ assertion) then the step invoking it will fail.
289
+
290
+ ValueError will be raised if this is invoked outside a feature context.
291
+
292
+ Returns boolean False if the steps are not parseable, True otherwise.
293
+ """
294
+ assert isinstance(steps_text, six.text_type), "Steps must be unicode."
295
+ if not self.feature:
296
+ raise ValueError("execute_steps() called outside of feature")
297
+
298
+ # -- PREPARE: Save original context data for current step.
299
+ # Needed if step definition that called this method uses .table/.text
300
+ original_table = getattr(self, "table", None)
301
+ original_text = getattr(self, "text", None)
302
+
303
+ self.feature.parser.variant = "steps"
304
+ steps = self.feature.parser.parse_steps(steps_text)
305
+ with self._use_with_behave_mode():
306
+ for step in steps:
307
+ passed = step.run(self._runner, quiet=True, capture=False)
308
+ if not passed:
309
+ # -- ISSUE #96: Provide more substep info to diagnose problem.
310
+ step_line = u"%s %s" % (step.keyword, step.name)
311
+ message = "%s SUB-STEP: %s" % \
312
+ (step.status.name.upper(), step_line)
313
+ if step.error_message:
314
+ message += "\nSubstep info: %s\n" % step.error_message
315
+ message += u"Traceback (of failed substep):\n"
316
+ message += u"".join(traceback.format_tb(step.exc_traceback))
317
+ # message += u"\nTraceback (of context.execute_steps()):"
318
+ assert False, message
319
+
320
+ # -- FINALLY: Restore original context data for current step.
321
+ self.table = original_table
322
+ self.text = original_text
323
+ return True
324
+
325
+
326
+ @contextlib.contextmanager
327
+ def use_context_with_mode(context, mode):
328
+ """Switch context to BEHAVE or USER mode.
329
+ Provides a context manager for switching between the two context modes.
330
+
331
+ .. sourcecode:: python
332
+
333
+ context = Context()
334
+ with use_context_with_mode(context, Context.BEHAVE):
335
+ ... # Do something
336
+ # -- POSTCONDITION: Original context._mode is restored.
337
+
338
+ :param context: Context object to use.
339
+ :param mode: Mode to apply to context object.
340
+ """
341
+ # pylint: disable=protected-access
342
+ assert mode in (Context.BEHAVE, Context.USER)
343
+ current_mode = context._mode
344
+ try:
345
+ context._mode = mode
346
+ yield
347
+ finally:
348
+ # -- RESTORE: Initial current_mode
349
+ # Even if an AssertionError/Exception is raised.
350
+ context._mode = current_mode
351
+
352
+
353
+
354
+ def exec_file(filename, globals_=None, locals_=None):
355
+ if globals_ is None:
356
+ globals_ = {}
357
+ if locals_ is None:
358
+ locals_ = globals_
359
+ locals_["__file__"] = filename
360
+ with open(filename, "rb") as f:
361
+ # pylint: disable=exec-used
362
+ filename2 = os.path.relpath(filename, os.getcwd())
363
+ code = compile(f.read(), filename2, "exec", dont_inherit=True)
364
+ exec(code, globals_, locals_)
365
+
366
+
367
+ def path_getrootdir(path):
368
+ """
369
+ Extract rootdir from path in a platform independent way.
370
+
371
+ POSIX-PATH EXAMPLE:
372
+ rootdir = path_getrootdir("/foo/bar/one.feature")
373
+ assert rootdir == "/"
374
+
375
+ WINDOWS-PATH EXAMPLE:
376
+ rootdir = path_getrootdir("D:\\foo\\bar\\one.feature")
377
+ assert rootdir == r"D:\"
378
+ """
379
+ drive, _ = os.path.splitdrive(path)
380
+ if drive:
381
+ # -- WINDOWS:
382
+ return drive + os.path.sep
383
+ # -- POSIX:
384
+ return os.path.sep
385
+
386
+
387
+ class PathManager(object):
388
+ """
389
+ Context manager to add paths to sys.path (python search path) within a scope
390
+ """
391
+ def __init__(self, paths=None):
392
+ self.initial_paths = paths or []
393
+ self.paths = None
394
+
395
+ def __enter__(self):
396
+ self.paths = list(self.initial_paths)
397
+ sys.path = self.paths + sys.path
398
+
399
+ def __exit__(self, *crap):
400
+ for path in self.paths:
401
+ sys.path.remove(path)
402
+ self.paths = None
403
+
404
+ def add(self, path):
405
+ if self.paths is None:
406
+ # -- CALLED OUTSIDE OF CONTEXT:
407
+ self.initial_paths.append(path)
408
+ else:
409
+ sys.path.insert(0, path)
410
+ self.paths.append(path)
411
+
412
+
413
+ class ModelRunner(object):
414
+ """
415
+ Test runner for a behave model (features).
416
+ Provides the core functionality of a test runner and
417
+ the functional API needed by model elements.
418
+
419
+ .. attribute:: aborted
420
+
421
+ This is set to true when the user aborts a test run
422
+ (:exc:`KeyboardInterrupt` exception). Initially: False.
423
+ Stored as derived attribute in :attr:`Context.aborted`.
424
+ """
425
+ # pylint: disable=too-many-instance-attributes
426
+
427
+ def __init__(self, config, features=None, step_registry=None):
428
+ self.config = config
429
+ self.features = features or []
430
+ self.hooks = {}
431
+ self.formatters = []
432
+ self.undefined_steps = []
433
+ self.step_registry = step_registry
434
+ self.capture_controller = CaptureController(config)
435
+
436
+ self.context = None
437
+ self.feature = None
438
+ self.hook_failures = 0
439
+
440
+ # @property
441
+ def _get_aborted(self):
442
+ value = False
443
+ if self.context:
444
+ value = self.context.aborted
445
+ return value
446
+
447
+ # @aborted.setter
448
+ def _set_aborted(self, value):
449
+ # pylint: disable=protected-access
450
+ assert self.context, "REQUIRE: context, but context=%r" % self.context
451
+ self.context._set_root_attribute("aborted", bool(value))
452
+
453
+ aborted = property(_get_aborted, _set_aborted,
454
+ doc="Indicates that test run is aborted by the user.")
455
+
456
+ def run_hook(self, name, context, *args):
457
+ if not self.config.dry_run and (name in self.hooks):
458
+ try:
459
+ with context.user_mode():
460
+ self.hooks[name](context, *args)
461
+ # except KeyboardInterrupt:
462
+ # self.aborted = True
463
+ # if name not in ("before_all", "after_all"):
464
+ # raise
465
+ except Exception as e: # pylint: disable=broad-except
466
+ # -- HANDLE HOOK ERRORS:
467
+ use_traceback = False
468
+ if self.config.verbose:
469
+ use_traceback = True
470
+ ExceptionUtil.set_traceback(e)
471
+ extra = u""
472
+ if "tag" in name:
473
+ extra = "(tag=%s)" % args[0]
474
+
475
+ error_text = ExceptionUtil.describe(e, use_traceback).rstrip()
476
+ error_message = u"HOOK-ERROR in %s%s: %s" % (name, extra, error_text)
477
+ print(error_message)
478
+ self.hook_failures += 1
479
+ if "tag" in name:
480
+ # -- SCENARIO or FEATURE
481
+ statement = getattr(context, "scenario", context.feature)
482
+ elif "all" in name:
483
+ # -- ABORT EXECUTION: For before_all/after_all
484
+ self.aborted = True
485
+ statement = None
486
+ else:
487
+ # -- CASE: feature, scenario, step
488
+ statement = args[0]
489
+
490
+ if statement:
491
+ # -- CASE: feature, scenario, step
492
+ statement.hook_failed = True
493
+ if statement.error_message:
494
+ # -- NOTE: One exception/failure is already stored.
495
+ # Append only error message.
496
+ statement.error_message += u"\n"+ error_message
497
+ else:
498
+ # -- FIRST EXCEPTION/FAILURE:
499
+ statement.store_exception_context(e)
500
+ statement.error_message = error_message
501
+
502
+ def setup_capture(self):
503
+ if not self.context:
504
+ self.context = Context(self)
505
+ self.capture_controller.setup_capture(self.context)
506
+
507
+ def start_capture(self):
508
+ self.capture_controller.start_capture()
509
+
510
+ def stop_capture(self):
511
+ self.capture_controller.stop_capture()
512
+
513
+ def teardown_capture(self):
514
+ self.capture_controller.teardown_capture()
515
+
516
+ def run_model(self, features=None):
517
+ # pylint: disable=too-many-branches
518
+ if not self.context:
519
+ self.context = Context(self)
520
+ if self.step_registry is None:
521
+ self.step_registry = the_step_registry
522
+ if features is None:
523
+ features = self.features
524
+
525
+ # -- ENSURE: context.execute_steps() works in weird cases (hooks, ...)
526
+ context = self.context
527
+ self.hook_failures = 0
528
+ self.setup_capture()
529
+ self.run_hook("before_all", context)
530
+
531
+ run_feature = not self.aborted
532
+ failed_count = 0
533
+ undefined_steps_initial_size = len(self.undefined_steps)
534
+ for feature in features:
535
+ if run_feature:
536
+ try:
537
+ self.feature = feature
538
+ for formatter in self.formatters:
539
+ formatter.uri(feature.filename)
540
+
541
+ failed = feature.run(self)
542
+ if failed:
543
+ failed_count += 1
544
+ if self.config.stop or self.aborted:
545
+ # -- FAIL-EARLY: After first failure.
546
+ run_feature = False
547
+ except KeyboardInterrupt:
548
+ self.aborted = True
549
+ failed_count += 1
550
+ run_feature = False
551
+
552
+ # -- ALWAYS: Report run/not-run feature to reporters.
553
+ # REQUIRED-FOR: Summary to keep track of untested features.
554
+ for reporter in self.config.reporters:
555
+ reporter.feature(feature)
556
+
557
+ # -- AFTER-ALL:
558
+ if self.aborted:
559
+ print("\nABORTED: By user.")
560
+ for formatter in self.formatters:
561
+ formatter.close()
562
+ self.run_hook("after_all", self.context)
563
+ for reporter in self.config.reporters:
564
+ reporter.end()
565
+
566
+ failed = ((failed_count > 0) or self.aborted or (self.hook_failures > 0)
567
+ or (len(self.undefined_steps) > undefined_steps_initial_size))
568
+ return failed
569
+
570
+ def run(self):
571
+ """
572
+ Implements the run method by running the model.
573
+ """
574
+ self.context = Context(self)
575
+ return self.run_model()
576
+
577
+
578
+ class Runner(ModelRunner):
579
+ """
580
+ Standard test runner for behave:
581
+
582
+ * setup paths
583
+ * loads environment hooks
584
+ * loads step definitions
585
+ * select feature files, parses them and creates model (elements)
586
+ """
587
+ def __init__(self, config):
588
+ super(Runner, self).__init__(config)
589
+ self.path_manager = PathManager()
590
+ self.base_dir = None
591
+
592
+
593
+ def setup_paths(self):
594
+ # pylint: disable=too-many-branches, too-many-statements
595
+ if self.config.paths:
596
+ if self.config.verbose:
597
+ print("Supplied path:", \
598
+ ", ".join('"%s"' % path for path in self.config.paths))
599
+ first_path = self.config.paths[0]
600
+ if hasattr(first_path, "filename"):
601
+ # -- BETTER: isinstance(first_path, FileLocation):
602
+ first_path = first_path.filename
603
+ base_dir = first_path
604
+ if base_dir.startswith("@"):
605
+ # -- USE: behave @features.txt
606
+ base_dir = base_dir[1:]
607
+ file_locations = self.feature_locations()
608
+ if file_locations:
609
+ base_dir = os.path.dirname(file_locations[0].filename)
610
+ base_dir = os.path.abspath(base_dir)
611
+
612
+ # supplied path might be to a feature file
613
+ if os.path.isfile(base_dir):
614
+ if self.config.verbose:
615
+ print("Primary path is to a file so using its directory")
616
+ base_dir = os.path.dirname(base_dir)
617
+ else:
618
+ if self.config.verbose:
619
+ print('Using default path "./features"')
620
+ base_dir = os.path.abspath("features")
621
+
622
+ # Get the root. This is not guaranteed to be "/" because Windows.
623
+ root_dir = path_getrootdir(base_dir)
624
+ new_base_dir = base_dir
625
+ steps_dir = self.config.steps_dir
626
+ environment_file = self.config.environment_file
627
+
628
+ while True:
629
+ if self.config.verbose:
630
+ print("Trying base directory:", new_base_dir)
631
+
632
+ if os.path.isdir(os.path.join(new_base_dir, steps_dir)):
633
+ break
634
+ if os.path.isfile(os.path.join(new_base_dir, environment_file)):
635
+ break
636
+ if new_base_dir == root_dir:
637
+ break
638
+
639
+ new_base_dir = os.path.dirname(new_base_dir)
640
+
641
+ if new_base_dir == root_dir:
642
+ if self.config.verbose:
643
+ if not self.config.paths:
644
+ print('ERROR: Could not find "%s" directory. '\
645
+ 'Please specify where to find your features.' % \
646
+ steps_dir)
647
+ else:
648
+ print('ERROR: Could not find "%s" directory in your '\
649
+ 'specified path "%s"' % (steps_dir, base_dir))
650
+
651
+ message = 'No %s directory in %r' % (steps_dir, base_dir)
652
+ raise ConfigError(message)
653
+
654
+ base_dir = new_base_dir
655
+ self.config.base_dir = base_dir
656
+
657
+ for dirpath, dirnames, filenames in os.walk(base_dir):
658
+ if [fn for fn in filenames if fn.endswith(".feature")]:
659
+ break
660
+ else:
661
+ if self.config.verbose:
662
+ if not self.config.paths:
663
+ print('ERROR: Could not find any "<name>.feature" files. '\
664
+ 'Please specify where to find your features.')
665
+ else:
666
+ print('ERROR: Could not find any "<name>.feature" files '\
667
+ 'in your specified path "%s"' % base_dir)
668
+ raise ConfigError('No feature files in %r' % base_dir)
669
+
670
+ self.base_dir = base_dir
671
+ self.path_manager.add(base_dir)
672
+ if not self.config.paths:
673
+ self.config.paths = [base_dir]
674
+
675
+ if base_dir != os.getcwd():
676
+ self.path_manager.add(os.getcwd())
677
+
678
+ def before_all_default_hook(self, context):
679
+ """
680
+ Default implementation for :func:`before_all()` hook.
681
+ Setup the logging subsystem based on the configuration data.
682
+ """
683
+ # pylint: disable=no-self-use
684
+ context.config.setup_logging()
685
+
686
+ def load_hooks(self, filename=None):
687
+ filename = filename or self.config.environment_file
688
+ hooks_path = os.path.join(self.base_dir, filename)
689
+ if os.path.exists(hooks_path):
690
+ exec_file(hooks_path, self.hooks)
691
+
692
+ if "before_all" not in self.hooks:
693
+ self.hooks["before_all"] = self.before_all_default_hook
694
+
695
+ def load_step_definitions(self, extra_step_paths=None):
696
+ if extra_step_paths is None:
697
+ extra_step_paths = []
698
+ step_globals = {
699
+ "use_step_matcher": matchers.use_step_matcher,
700
+ "step_matcher": matchers.step_matcher, # -- DEPRECATING
701
+ }
702
+ setup_step_decorators(step_globals)
703
+
704
+ # -- Allow steps to import other stuff from the steps dir
705
+ # NOTE: Default matcher can be overridden in "environment.py" hook.
706
+ steps_dir = os.path.join(self.base_dir, self.config.steps_dir)
707
+ paths = [steps_dir] + list(extra_step_paths)
708
+ with PathManager(paths):
709
+ default_matcher = matchers.current_matcher
710
+ for path in paths:
711
+ for name in sorted(os.listdir(path)):
712
+ if name.endswith(".py"):
713
+ # -- LOAD STEP DEFINITION:
714
+ # Reset to default matcher after each step-definition.
715
+ # A step-definition may change the matcher 0..N times.
716
+ # ENSURE: Each step definition has clean globals.
717
+ # try:
718
+ step_module_globals = step_globals.copy()
719
+ exec_file(os.path.join(path, name), step_module_globals)
720
+ matchers.current_matcher = default_matcher
721
+ # except Exception as e:
722
+ # e_text = _text(e)
723
+ # print("Exception %s: %s" % \
724
+ # (e.__class__.__name__, e_text))
725
+ # raise
726
+
727
+ def feature_locations(self):
728
+ return collect_feature_locations(self.config.paths)
729
+
730
+ def run(self):
731
+ with self.path_manager:
732
+ self.setup_paths()
733
+ return self.run_with_paths()
734
+
735
+ def run_with_paths(self):
736
+ self.context = Context(self)
737
+ self.load_hooks()
738
+ self.load_step_definitions()
739
+
740
+ # -- ENSURE: context.execute_steps() works in weird cases (hooks, ...)
741
+ # self.setup_capture()
742
+ # self.run_hook("before_all", self.context)
743
+
744
+ # -- STEP: Parse all feature files (by using their file location).
745
+ feature_locations = [filename for filename in self.feature_locations()
746
+ if not self.config.exclude(filename)]
747
+ features = parse_features(feature_locations, language=self.config.lang)
748
+ self.features.extend(features)
749
+
750
+ # -- STEP: Run all features.
751
+ stream_openers = self.config.outputs
752
+ self.formatters = make_formatters(self.config, stream_openers)
753
+ return self.run_model()