busser-behave 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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()