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,1074 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # pylint: disable=too-many-lines, line-too-long
3
+
4
+ from __future__ import absolute_import, print_function, with_statement
5
+ from collections import defaultdict
6
+ from platform import python_implementation
7
+ import os.path
8
+ import sys
9
+ import warnings
10
+ import tempfile
11
+ import unittest
12
+ import six
13
+ from six import StringIO
14
+
15
+ from mock import Mock, patch
16
+ from nose.tools import * # pylint: disable=wildcard-import, unused-wildcard-import
17
+
18
+ from behave.model import Table
19
+ from behave.step_registry import StepRegistry
20
+ from behave import parser, runner
21
+ from behave.configuration import ConfigError
22
+ from behave.formatter.base import StreamOpener
23
+
24
+
25
+ # -- CONVENIENCE-ALIAS:
26
+ _text = six.text_type
27
+
28
+
29
+ class TestContext(unittest.TestCase):
30
+ # pylint: disable=invalid-name, protected-access, no-self-use
31
+
32
+ def setUp(self):
33
+ r = Mock()
34
+ self.config = r.config = Mock()
35
+ r.config.verbose = False
36
+ self.context = runner.Context(r)
37
+
38
+ def test_user_mode_shall_restore_behave_mode(self):
39
+ # -- CASE: No exception is raised.
40
+ initial_mode = runner.Context.BEHAVE
41
+ eq_(self.context._mode, initial_mode)
42
+ with self.context.user_mode():
43
+ eq_(self.context._mode, runner.Context.USER)
44
+ self.context.thing = "stuff"
45
+ eq_(self.context._mode, initial_mode)
46
+
47
+ def test_user_mode_shall_restore_behave_mode_if_assert_fails(self):
48
+ initial_mode = runner.Context.BEHAVE
49
+ eq_(self.context._mode, initial_mode)
50
+ try:
51
+ with self.context.user_mode():
52
+ eq_(self.context._mode, runner.Context.USER)
53
+ assert False, "XFAIL"
54
+ except AssertionError:
55
+ eq_(self.context._mode, initial_mode)
56
+
57
+ def test_user_mode_shall_restore_behave_mode_if_exception_is_raised(self):
58
+ initial_mode = runner.Context.BEHAVE
59
+ eq_(self.context._mode, initial_mode)
60
+ try:
61
+ with self.context.user_mode():
62
+ eq_(self.context._mode, runner.Context.USER)
63
+ raise RuntimeError("XFAIL")
64
+ except RuntimeError:
65
+ eq_(self.context._mode, initial_mode)
66
+
67
+ def test_use_with_user_mode__shall_restore_initial_mode(self):
68
+ # -- CASE: No exception is raised.
69
+ # pylint: disable=protected-access
70
+ initial_mode = runner.Context.BEHAVE
71
+ self.context._mode = initial_mode
72
+ with self.context.use_with_user_mode():
73
+ eq_(self.context._mode, runner.Context.USER)
74
+ self.context.thing = "stuff"
75
+ eq_(self.context._mode, initial_mode)
76
+
77
+ def test_use_with_user_mode__shall_restore_initial_mode_with_error(self):
78
+ # -- CASE: Exception is raised.
79
+ # pylint: disable=protected-access
80
+ initial_mode = runner.Context.BEHAVE
81
+ self.context._mode = initial_mode
82
+ try:
83
+ with self.context.use_with_user_mode():
84
+ eq_(self.context._mode, runner.Context.USER)
85
+ raise RuntimeError("XFAIL")
86
+ except RuntimeError:
87
+ eq_(self.context._mode, initial_mode)
88
+
89
+ def test_use_with_behave_mode__shall_restore_initial_mode(self):
90
+ # -- CASE: No exception is raised.
91
+ # pylint: disable=protected-access
92
+ initial_mode = runner.Context.USER
93
+ self.context._mode = initial_mode
94
+ with self.context._use_with_behave_mode():
95
+ eq_(self.context._mode, runner.Context.BEHAVE)
96
+ self.context.thing = "stuff"
97
+ eq_(self.context._mode, initial_mode)
98
+
99
+ def test_use_with_behave_mode__shall_restore_initial_mode_with_error(self):
100
+ # -- CASE: Exception is raised.
101
+ # pylint: disable=protected-access
102
+ initial_mode = runner.Context.USER
103
+ self.context._mode = initial_mode
104
+ try:
105
+ with self.context._use_with_behave_mode():
106
+ eq_(self.context._mode, runner.Context.BEHAVE)
107
+ raise RuntimeError("XFAIL")
108
+ except RuntimeError:
109
+ eq_(self.context._mode, initial_mode)
110
+
111
+ def test_context_contains(self):
112
+ eq_("thing" in self.context, False)
113
+ self.context.thing = "stuff"
114
+ eq_("thing" in self.context, True)
115
+ self.context._push()
116
+ eq_("thing" in self.context, True)
117
+
118
+ def test_attribute_set_at_upper_level_visible_at_lower_level(self):
119
+ self.context.thing = "stuff"
120
+ self.context._push()
121
+ eq_(self.context.thing, "stuff")
122
+
123
+ def test_attribute_set_at_lower_level_not_visible_at_upper_level(self):
124
+ self.context._push()
125
+ self.context.thing = "stuff"
126
+ self.context._pop()
127
+ assert getattr(self.context, "thing", None) is None
128
+
129
+ def test_attributes_set_at_upper_level_visible_at_lower_level(self):
130
+ self.context.thing = "stuff"
131
+ self.context._push()
132
+ eq_(self.context.thing, "stuff")
133
+ self.context.other_thing = "more stuff"
134
+ self.context._push()
135
+ eq_(self.context.thing, "stuff")
136
+ eq_(self.context.other_thing, "more stuff")
137
+ self.context.third_thing = "wombats"
138
+ self.context._push()
139
+ eq_(self.context.thing, "stuff")
140
+ eq_(self.context.other_thing, "more stuff")
141
+ eq_(self.context.third_thing, "wombats")
142
+
143
+ def test_attributes_set_at_lower_level_not_visible_at_upper_level(self):
144
+ self.context.thing = "stuff"
145
+
146
+ self.context._push()
147
+ self.context.other_thing = "more stuff"
148
+
149
+ self.context._push()
150
+ self.context.third_thing = "wombats"
151
+ eq_(self.context.thing, "stuff")
152
+ eq_(self.context.other_thing, "more stuff")
153
+ eq_(self.context.third_thing, "wombats")
154
+
155
+ self.context._pop()
156
+ eq_(self.context.thing, "stuff")
157
+ eq_(self.context.other_thing, "more stuff")
158
+ assert getattr(self.context, "third_thing", None) is None, "%s is not None" % self.context.third_thing
159
+
160
+ self.context._pop()
161
+ eq_(self.context.thing, "stuff")
162
+ assert getattr(self.context, "other_thing", None) is None, "%s is not None" % self.context.other_thing
163
+ assert getattr(self.context, "third_thing", None) is None, "%s is not None" % self.context.third_thing
164
+
165
+ def test_masking_existing_user_attribute_when_verbose_causes_warning(self):
166
+ warns = []
167
+
168
+ def catch_warning(*args, **kwargs):
169
+ warns.append(args[0])
170
+
171
+ old_showwarning = warnings.showwarning
172
+ warnings.showwarning = catch_warning
173
+
174
+ # pylint: disable=protected-access
175
+ self.config.verbose = True
176
+ with self.context.use_with_user_mode():
177
+ self.context.thing = "stuff"
178
+ self.context._push()
179
+ self.context.thing = "other stuff"
180
+
181
+ warnings.showwarning = old_showwarning
182
+
183
+ print(repr(warns))
184
+ assert warns, "warns is empty!"
185
+ warning = warns[0]
186
+ assert isinstance(warning, runner.ContextMaskWarning), "warning is not a ContextMaskWarning"
187
+ info = warning.args[0]
188
+ assert info.startswith("user code"), "%r doesn't start with 'user code'" % info
189
+ assert "'thing'" in info, "%r not in %r" % ("'thing'", info)
190
+ assert "tutorial" in info, '"tutorial" not in %r' % (info, )
191
+
192
+ def test_masking_existing_user_attribute_when_not_verbose_causes_no_warning(self):
193
+ warns = []
194
+
195
+ def catch_warning(*args, **kwargs):
196
+ warns.append(args[0])
197
+
198
+ old_showwarning = warnings.showwarning
199
+ warnings.showwarning = catch_warning
200
+
201
+ # explicit
202
+ # pylint: disable=protected-access
203
+ self.config.verbose = False
204
+ with self.context.use_with_user_mode():
205
+ self.context.thing = "stuff"
206
+ self.context._push()
207
+ self.context.thing = "other stuff"
208
+
209
+ warnings.showwarning = old_showwarning
210
+
211
+ assert not warns
212
+
213
+ def test_behave_masking_user_attribute_causes_warning(self):
214
+ warns = []
215
+
216
+ def catch_warning(*args, **kwargs):
217
+ warns.append(args[0])
218
+
219
+ old_showwarning = warnings.showwarning
220
+ warnings.showwarning = catch_warning
221
+
222
+ with self.context.use_with_user_mode():
223
+ self.context.thing = "stuff"
224
+ # pylint: disable=protected-access
225
+ self.context._push()
226
+ self.context.thing = "other stuff"
227
+
228
+ warnings.showwarning = old_showwarning
229
+
230
+ print(repr(warns))
231
+ assert warns, "OOPS: warns is empty, but expected non-empty"
232
+ warning = warns[0]
233
+ assert isinstance(warning, runner.ContextMaskWarning), "warning is not a ContextMaskWarning"
234
+ info = warning.args[0]
235
+ assert info.startswith("behave runner"), "%r doesn't start with 'behave runner'" % info
236
+ assert "'thing'" in info, "%r not in %r" % ("'thing'", info)
237
+ filename = __file__.rsplit(".", 1)[0]
238
+ if python_implementation() == "Jython":
239
+ filename = filename.replace("$py", ".py")
240
+ assert filename in info, "%r not in %r" % (filename, info)
241
+
242
+ def test_setting_root_attribute_that_masks_existing_causes_warning(self):
243
+ # pylint: disable=protected-access
244
+ warns = []
245
+
246
+ def catch_warning(*args, **kwargs):
247
+ warns.append(args[0])
248
+
249
+ old_showwarning = warnings.showwarning
250
+ warnings.showwarning = catch_warning
251
+
252
+ with self.context.use_with_user_mode():
253
+ self.context._push()
254
+ self.context.thing = "teak"
255
+ self.context._set_root_attribute("thing", "oak")
256
+
257
+ warnings.showwarning = old_showwarning
258
+
259
+ print(repr(warns))
260
+ assert warns
261
+ warning = warns[0]
262
+ assert isinstance(warning, runner.ContextMaskWarning)
263
+ info = warning.args[0]
264
+ assert info.startswith("behave runner"), "%r doesn't start with 'behave runner'" % info
265
+ assert "'thing'" in info, "%r not in %r" % ("'thing'", info)
266
+ filename = __file__.rsplit(".", 1)[0]
267
+ if python_implementation() == "Jython":
268
+ filename = filename.replace("$py", ".py")
269
+ assert filename in info, "%r not in %r" % (filename, info)
270
+
271
+ def test_context_deletable(self):
272
+ eq_("thing" in self.context, False)
273
+ self.context.thing = "stuff"
274
+ eq_("thing" in self.context, True)
275
+ del self.context.thing
276
+ eq_("thing" in self.context, False)
277
+
278
+ @raises(AttributeError)
279
+ def test_context_deletable_raises(self):
280
+ # pylint: disable=protected-access
281
+ eq_("thing" in self.context, False)
282
+ self.context.thing = "stuff"
283
+ eq_("thing" in self.context, True)
284
+ self.context._push()
285
+ eq_("thing" in self.context, True)
286
+ del self.context.thing
287
+
288
+ class ExampleSteps(object):
289
+ text = None
290
+ table = None
291
+
292
+ @staticmethod
293
+ def step_passes(context): # pylint: disable=unused-argument
294
+ pass
295
+
296
+ @staticmethod
297
+ def step_fails(context): # pylint: disable=unused-argument
298
+ assert False, "XFAIL"
299
+
300
+ @classmethod
301
+ def step_with_text(cls, context):
302
+ assert context.text is not None, "REQUIRE: multi-line text"
303
+ cls.text = context.text
304
+
305
+ @classmethod
306
+ def step_with_table(cls, context):
307
+ assert context.table, "REQUIRE: table"
308
+ cls.table = context.table
309
+
310
+ @classmethod
311
+ def register_steps_with(cls, step_registry):
312
+ # pylint: disable=bad-whitespace
313
+ step_definitions = [
314
+ ("step", "a step passes", cls.step_passes),
315
+ ("step", "a step fails", cls.step_fails),
316
+ ("step", "a step with text", cls.step_with_text),
317
+ ("step", "a step with a table", cls.step_with_table),
318
+ ]
319
+ for keyword, string, func in step_definitions:
320
+ step_registry.add_step_definition(keyword, string, func)
321
+
322
+ class TestContext_ExecuteSteps(unittest.TestCase):
323
+ """
324
+ Test the behave.runner.Context.execute_steps() functionality.
325
+ """
326
+ # pylint: disable=invalid-name, no-self-use
327
+ step_registry = None
328
+
329
+ def setUp(self):
330
+ if not self.step_registry:
331
+ # -- SETUP ONCE:
332
+ self.step_registry = StepRegistry()
333
+ ExampleSteps.register_steps_with(self.step_registry)
334
+ ExampleSteps.text = None
335
+ ExampleSteps.table = None
336
+
337
+ runner_ = Mock()
338
+ self.config = runner_.config = Mock()
339
+ runner_.config.verbose = False
340
+ runner_.config.stdout_capture = False
341
+ runner_.config.stderr_capture = False
342
+ runner_.config.log_capture = False
343
+ runner_.step_registry = self.step_registry
344
+
345
+ self.context = runner.Context(runner_)
346
+ runner_.context = self.context
347
+ self.context.feature = Mock()
348
+ self.context.feature.parser = parser.Parser()
349
+ self.context.runner = runner_
350
+ # self.context.text = None
351
+ # self.context.table = None
352
+
353
+ def test_execute_steps_with_simple_steps(self):
354
+ doc = u"""
355
+ Given a step passes
356
+ Then a step passes
357
+ """.lstrip()
358
+ with patch("behave.step_registry.registry", self.step_registry):
359
+ result = self.context.execute_steps(doc)
360
+ eq_(result, True)
361
+
362
+ def test_execute_steps_with_failing_step(self):
363
+ doc = u"""
364
+ Given a step passes
365
+ When a step fails
366
+ Then a step passes
367
+ """.lstrip()
368
+ with patch("behave.step_registry.registry", self.step_registry):
369
+ try:
370
+ result = self.context.execute_steps(doc)
371
+ except AssertionError as e:
372
+ ok_("FAILED SUB-STEP: When a step fails" in _text(e))
373
+
374
+ def test_execute_steps_with_undefined_step(self):
375
+ doc = u"""
376
+ Given a step passes
377
+ When a step is undefined
378
+ Then a step passes
379
+ """.lstrip()
380
+ with patch("behave.step_registry.registry", self.step_registry):
381
+ try:
382
+ result = self.context.execute_steps(doc)
383
+ except AssertionError as e:
384
+ ok_("UNDEFINED SUB-STEP: When a step is undefined" in _text(e))
385
+
386
+ def test_execute_steps_with_text(self):
387
+ doc = u'''
388
+ Given a step passes
389
+ When a step with text:
390
+ """
391
+ Lorem ipsum
392
+ Ipsum lorem
393
+ """
394
+ Then a step passes
395
+ '''.lstrip()
396
+ with patch("behave.step_registry.registry", self.step_registry):
397
+ result = self.context.execute_steps(doc)
398
+ expected_text = "Lorem ipsum\nIpsum lorem"
399
+ eq_(result, True)
400
+ eq_(expected_text, ExampleSteps.text)
401
+
402
+ def test_execute_steps_with_table(self):
403
+ doc = u"""
404
+ Given a step with a table:
405
+ | Name | Age |
406
+ | Alice | 12 |
407
+ | Bob | 23 |
408
+ Then a step passes
409
+ """.lstrip()
410
+ with patch("behave.step_registry.registry", self.step_registry):
411
+ # pylint: disable=bad-whitespace, bad-continuation
412
+ result = self.context.execute_steps(doc)
413
+ expected_table = Table([u"Name", u"Age"], 0, [
414
+ [u"Alice", u"12"],
415
+ [u"Bob", u"23"],
416
+ ])
417
+ eq_(result, True)
418
+ eq_(expected_table, ExampleSteps.table)
419
+
420
+ def test_context_table_is_restored_after_execute_steps_without_table(self):
421
+ doc = u"""
422
+ Given a step passes
423
+ Then a step passes
424
+ """.lstrip()
425
+ with patch("behave.step_registry.registry", self.step_registry):
426
+ original_table = "<ORIGINAL_TABLE>"
427
+ self.context.table = original_table
428
+ self.context.execute_steps(doc)
429
+ eq_(self.context.table, original_table)
430
+
431
+ def test_context_table_is_restored_after_execute_steps_with_table(self):
432
+ doc = u"""
433
+ Given a step with a table:
434
+ | Name | Age |
435
+ | Alice | 12 |
436
+ | Bob | 23 |
437
+ Then a step passes
438
+ """.lstrip()
439
+ with patch("behave.step_registry.registry", self.step_registry):
440
+ original_table = "<ORIGINAL_TABLE>"
441
+ self.context.table = original_table
442
+ self.context.execute_steps(doc)
443
+ eq_(self.context.table, original_table)
444
+
445
+ def test_context_text_is_restored_after_execute_steps_without_text(self):
446
+ doc = u"""
447
+ Given a step passes
448
+ Then a step passes
449
+ """.lstrip()
450
+ with patch("behave.step_registry.registry", self.step_registry):
451
+ original_text = "<ORIGINAL_TEXT>"
452
+ self.context.text = original_text
453
+ self.context.execute_steps(doc)
454
+ eq_(self.context.text, original_text)
455
+
456
+ def test_context_text_is_restored_after_execute_steps_with_text(self):
457
+ doc = u'''
458
+ Given a step passes
459
+ When a step with text:
460
+ """
461
+ Lorem ipsum
462
+ Ipsum lorem
463
+ """
464
+ '''.lstrip()
465
+ with patch("behave.step_registry.registry", self.step_registry):
466
+ original_text = "<ORIGINAL_TEXT>"
467
+ self.context.text = original_text
468
+ self.context.execute_steps(doc)
469
+ eq_(self.context.text, original_text)
470
+
471
+
472
+ @raises(ValueError)
473
+ def test_execute_steps_should_fail_when_called_without_feature(self):
474
+ doc = u"""
475
+ Given a passes
476
+ Then a step passes
477
+ """.lstrip()
478
+ with patch("behave.step_registry.registry", self.step_registry):
479
+ self.context.feature = None
480
+ self.context.execute_steps(doc)
481
+
482
+
483
+ def create_mock_config():
484
+ config = Mock()
485
+ config.steps_dir = "steps"
486
+ config.environment_file = "environment.py"
487
+ return config
488
+
489
+
490
+ class TestRunner(object):
491
+ # pylint: disable=invalid-name, no-self-use
492
+
493
+ def test_load_hooks_execfiles_hook_file(self):
494
+ with patch("behave.runner.exec_file") as ef:
495
+ with patch("os.path.exists") as exists:
496
+ exists.return_value = True
497
+ base_dir = "fake/path"
498
+ hooks_path = os.path.join(base_dir, "environment.py")
499
+
500
+ r = runner.Runner(create_mock_config())
501
+ r.base_dir = base_dir
502
+ r.load_hooks()
503
+
504
+ exists.assert_called_with(hooks_path)
505
+ ef.assert_called_with(hooks_path, r.hooks)
506
+
507
+ def test_run_hook_runs_a_hook_that_exists(self):
508
+ config = Mock()
509
+ r = runner.Runner(config)
510
+ # XXX r.config = Mock()
511
+ r.config.stdout_capture = False
512
+ r.config.stderr_capture = False
513
+ r.config.dry_run = False
514
+ r.hooks["before_lunch"] = hook = Mock()
515
+ args = (runner.Context(Mock()), Mock(), Mock())
516
+ r.run_hook("before_lunch", *args)
517
+
518
+ hook.assert_called_with(*args)
519
+
520
+ def test_run_hook_does_not_runs_a_hook_that_exists_if_dry_run(self):
521
+ r = runner.Runner(None)
522
+ r.config = Mock()
523
+ r.config.dry_run = True
524
+ r.hooks["before_lunch"] = hook = Mock()
525
+ args = (runner.Context(Mock()), Mock(), Mock())
526
+ r.run_hook("before_lunch", *args)
527
+
528
+ assert len(hook.call_args_list) == 0
529
+
530
+ def test_setup_capture_creates_stringio_for_stdout(self):
531
+ r = runner.Runner(Mock())
532
+ r.config.stdout_capture = True
533
+ r.config.log_capture = False
534
+ r.context = Mock()
535
+
536
+ r.setup_capture()
537
+
538
+ assert r.capture_controller.stdout_capture is not None
539
+ assert isinstance(r.capture_controller.stdout_capture, StringIO)
540
+
541
+ def test_setup_capture_does_not_create_stringio_if_not_wanted(self):
542
+ r = runner.Runner(Mock())
543
+ r.config.stdout_capture = False
544
+ r.config.stderr_capture = False
545
+ r.config.log_capture = False
546
+
547
+ r.setup_capture()
548
+
549
+ assert r.capture_controller.stdout_capture is None
550
+
551
+ @patch("behave.capture.LoggingCapture")
552
+ def test_setup_capture_creates_memory_handler_for_logging(self, handler):
553
+ r = runner.Runner(Mock())
554
+ r.config.stdout_capture = False
555
+ r.config.log_capture = True
556
+ r.context = Mock()
557
+
558
+ r.setup_capture()
559
+
560
+ assert r.capture_controller.log_capture is not None
561
+ handler.assert_called_with(r.config)
562
+ r.capture_controller.log_capture.inveigle.assert_called_with()
563
+
564
+ def test_setup_capture_does_not_create_memory_handler_if_not_wanted(self):
565
+ r = runner.Runner(Mock())
566
+ r.config.stdout_capture = False
567
+ r.config.stderr_capture = False
568
+ r.config.log_capture = False
569
+
570
+ r.setup_capture()
571
+
572
+ assert r.capture_controller.log_capture is None
573
+
574
+ def test_start_stop_capture_switcheroos_sys_stdout(self):
575
+ old_stdout = sys.stdout
576
+ sys.stdout = new_stdout = Mock()
577
+
578
+ r = runner.Runner(Mock())
579
+ r.config.stdout_capture = True
580
+ r.config.log_capture = False
581
+ r.context = Mock()
582
+
583
+ r.setup_capture()
584
+ r.start_capture()
585
+
586
+ eq_(sys.stdout, r.capture_controller.stdout_capture)
587
+
588
+ r.stop_capture()
589
+
590
+ eq_(sys.stdout, new_stdout)
591
+
592
+ sys.stdout = old_stdout
593
+
594
+ def test_start_stop_capture_leaves_sys_stdout_alone_if_off(self):
595
+ r = runner.Runner(Mock())
596
+ r.config.stdout_capture = False
597
+ r.config.log_capture = False
598
+
599
+ old_stdout = sys.stdout
600
+
601
+ r.start_capture()
602
+
603
+ eq_(sys.stdout, old_stdout)
604
+
605
+ r.stop_capture()
606
+
607
+ eq_(sys.stdout, old_stdout)
608
+
609
+ def test_teardown_capture_removes_log_tap(self):
610
+ r = runner.Runner(Mock())
611
+ r.config.stdout_capture = False
612
+ r.config.log_capture = True
613
+
614
+ r.capture_controller.log_capture = Mock()
615
+
616
+ r.teardown_capture()
617
+
618
+ r.capture_controller.log_capture.abandon.assert_called_with()
619
+
620
+ def test_exec_file(self):
621
+ fn = tempfile.mktemp()
622
+ with open(fn, "w") as f:
623
+ f.write("spam = __file__\n")
624
+ g = {}
625
+ l = {}
626
+ runner.exec_file(fn, g, l)
627
+ assert "__file__" in l
628
+ # pylint: disable=too-many-format-args
629
+ assert "spam" in l, '"spam" variable not set in locals (%r)' % (g, l)
630
+ # pylint: enable=too-many-format-args
631
+ eq_(l["spam"], fn)
632
+
633
+ def test_run_returns_true_if_everything_passed(self):
634
+ r = runner.Runner(Mock())
635
+ r.setup_capture = Mock()
636
+ r.setup_paths = Mock()
637
+ r.run_with_paths = Mock()
638
+ r.run_with_paths.return_value = True
639
+ assert r.run()
640
+
641
+ def test_run_returns_false_if_anything_failed(self):
642
+ r = runner.Runner(Mock())
643
+ r.setup_capture = Mock()
644
+ r.setup_paths = Mock()
645
+ r.run_with_paths = Mock()
646
+ r.run_with_paths.return_value = False
647
+ assert not r.run()
648
+
649
+
650
+ class TestRunWithPaths(unittest.TestCase):
651
+ # pylint: disable=invalid-name, no-self-use
652
+
653
+ def setUp(self):
654
+ self.config = Mock()
655
+ self.config.reporters = []
656
+ self.config.logging_level = None
657
+ self.config.logging_filter = None
658
+ self.config.outputs = [Mock(), StreamOpener(stream=sys.stdout)]
659
+ self.config.format = ["plain", "progress"]
660
+ self.runner = runner.Runner(self.config)
661
+ self.load_hooks = self.runner.load_hooks = Mock()
662
+ self.load_step_definitions = self.runner.load_step_definitions = Mock()
663
+ self.run_hook = self.runner.run_hook = Mock()
664
+ self.run_step = self.runner.run_step = Mock()
665
+ self.feature_locations = self.runner.feature_locations = Mock()
666
+ self.calculate_summaries = self.runner.calculate_summaries = Mock()
667
+
668
+ self.formatter_class = patch("behave.formatter.pretty.PrettyFormatter")
669
+ formatter_class = self.formatter_class.start()
670
+ formatter_class.return_value = self.formatter = Mock()
671
+
672
+ def tearDown(self):
673
+ self.formatter_class.stop()
674
+
675
+ def test_loads_hooks_and_step_definitions(self):
676
+ self.feature_locations.return_value = []
677
+ self.runner.run_with_paths()
678
+
679
+ assert self.load_hooks.called
680
+ assert self.load_step_definitions.called
681
+
682
+ def test_runs_before_all_and_after_all_hooks(self):
683
+ # Make runner.feature_locations() and runner.run_hook() the same mock so
684
+ # we can make sure things happen in the right order.
685
+ self.runner.feature_locations = self.run_hook
686
+ self.runner.feature_locations.return_value = []
687
+ self.runner.context = Mock()
688
+ self.runner.run_with_paths()
689
+
690
+ eq_(self.run_hook.call_args_list, [
691
+ ((), {}),
692
+ (("before_all", self.runner.context), {}),
693
+ (("after_all", self.runner.context), {}),
694
+ ])
695
+
696
+ @patch("behave.parser.parse_file")
697
+ @patch("os.path.abspath")
698
+ def test_parses_feature_files_and_appends_to_feature_list(self, abspath,
699
+ parse_file):
700
+ feature_locations = ["one", "two", "three"]
701
+ feature = Mock()
702
+ feature.tags = []
703
+ feature.__iter__ = Mock(return_value=iter([]))
704
+ feature.run.return_value = False
705
+ self.runner.feature_locations.return_value = feature_locations
706
+ abspath.side_effect = lambda x: x.upper()
707
+ self.config.lang = "fritz"
708
+ self.config.format = ["plain"]
709
+ self.config.outputs = [StreamOpener(stream=sys.stdout)]
710
+ self.config.output.encoding = None
711
+ self.config.exclude = lambda s: False
712
+ self.config.junit = False
713
+ self.config.summary = False
714
+ parse_file.return_value = feature
715
+
716
+ self.runner.run_with_paths()
717
+
718
+ expected_parse_file_args = \
719
+ [((x.upper(),), {"language": "fritz"}) for x in feature_locations]
720
+ eq_(parse_file.call_args_list, expected_parse_file_args)
721
+ eq_(self.runner.features, [feature] * 3)
722
+
723
+
724
+ class FsMock(object):
725
+ def __init__(self, *paths):
726
+ self.base = os.path.abspath(".")
727
+ self.sep = os.path.sep
728
+
729
+ # This bit of gymnastics is to support Windows. We feed in a bunch of
730
+ # paths in places using FsMock that assume that POSIX-style paths
731
+ # work. This is faster than fixing all of those but at some point we
732
+ # should totally do it properly with os.path.join() and all that.
733
+ def full_split(path):
734
+ bits = []
735
+
736
+ while path:
737
+ path, bit = os.path.split(path)
738
+ bits.insert(0, bit)
739
+
740
+ return bits
741
+
742
+ paths = [os.path.join(self.base, *full_split(path)) for path in paths]
743
+ print(repr(paths))
744
+ self.paths = paths
745
+ self.files = set()
746
+ self.dirs = defaultdict(list)
747
+ separators = [sep for sep in (os.path.sep, os.path.altsep) if sep]
748
+ for path in paths:
749
+ if path[-1] in separators:
750
+ self.dirs[path[:-1]] = []
751
+ d, p = os.path.split(path[:-1])
752
+ while d and p:
753
+ self.dirs[d].append(p)
754
+ d, p = os.path.split(d)
755
+ else:
756
+ self.files.add(path)
757
+ d, f = os.path.split(path)
758
+ self.dirs[d].append(f)
759
+ self.calls = []
760
+
761
+ def listdir(self, dir):
762
+ # pylint: disable=W0622
763
+ # W0622 Redefining built-in dir
764
+ self.calls.append(("listdir", dir))
765
+ return self.dirs.get(dir, [])
766
+
767
+ def isfile(self, path):
768
+ self.calls.append(("isfile", path))
769
+ return path in self.files
770
+
771
+ def isdir(self, path):
772
+ self.calls.append(("isdir", path))
773
+ return path in self.dirs
774
+
775
+ def exists(self, path):
776
+ self.calls.append(("exists", path))
777
+ return path in self.dirs or path in self.files
778
+
779
+ def walk(self, path, locations=None):
780
+ if locations is None:
781
+ assert path in self.dirs, "%s not in %s" % (path, self.dirs)
782
+ locations = []
783
+ dirnames = []
784
+ filenames = []
785
+ for e in self.dirs[path]:
786
+ if os.path.join(path, e) in self.dirs:
787
+ dirnames.append(e)
788
+ self.walk(os.path.join(path, e), locations)
789
+ else:
790
+ filenames.append(e)
791
+ locations.append((path, dirnames, filenames))
792
+ return locations
793
+
794
+ # utilities that we need
795
+ # pylint: disable=no-self-use
796
+ def dirname(self, path, orig=os.path.dirname):
797
+ return orig(path)
798
+
799
+ def abspath(self, path, orig=os.path.abspath):
800
+ return orig(path)
801
+
802
+ def join(self, x, y, orig=os.path.join):
803
+ return orig(x, y)
804
+
805
+ def split(self, path, orig=os.path.split):
806
+ return orig(path)
807
+
808
+ def splitdrive(self, path, orig=os.path.splitdrive):
809
+ return orig(path)
810
+
811
+
812
+ class TestFeatureDirectory(object):
813
+ # pylint: disable=invalid-name, no-self-use
814
+
815
+ def test_default_path_no_steps(self):
816
+ config = create_mock_config()
817
+ config.paths = []
818
+ config.verbose = True
819
+ r = runner.Runner(config)
820
+
821
+ fs = FsMock()
822
+
823
+ # will look for a "features" directory and not find one
824
+ with patch("os.path", fs):
825
+ assert_raises(ConfigError, r.setup_paths)
826
+
827
+ ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
828
+
829
+ def test_default_path_no_features(self):
830
+ config = create_mock_config()
831
+ config.paths = []
832
+ config.verbose = True
833
+ r = runner.Runner(config)
834
+
835
+ fs = FsMock("features/steps/")
836
+ with patch("os.path", fs):
837
+ with patch("os.walk", fs.walk):
838
+ assert_raises(ConfigError, r.setup_paths)
839
+
840
+ def test_default_path(self):
841
+ config = create_mock_config()
842
+ config.paths = []
843
+ config.verbose = True
844
+ r = runner.Runner(config)
845
+
846
+ fs = FsMock("features/steps/", "features/foo.feature")
847
+
848
+ with patch("os.path", fs):
849
+ with patch("os.walk", fs.walk):
850
+ with r.path_manager:
851
+ r.setup_paths()
852
+
853
+ eq_(r.base_dir, os.path.abspath("features"))
854
+
855
+ def test_supplied_feature_file(self):
856
+ config = create_mock_config()
857
+ config.paths = ["foo.feature"]
858
+ config.verbose = True
859
+ r = runner.Runner(config)
860
+ r.context = Mock()
861
+
862
+ fs = FsMock("steps/", "foo.feature")
863
+
864
+ with patch("os.path", fs):
865
+ with patch("os.walk", fs.walk):
866
+ with r.path_manager:
867
+ r.setup_paths()
868
+ ok_(("isdir", os.path.join(fs.base, "steps")) in fs.calls)
869
+ ok_(("isfile", os.path.join(fs.base, "foo.feature")) in fs.calls)
870
+
871
+ eq_(r.base_dir, fs.base)
872
+
873
+ def test_supplied_feature_file_no_steps(self):
874
+ config = create_mock_config()
875
+ config.paths = ["foo.feature"]
876
+ config.verbose = True
877
+ r = runner.Runner(config)
878
+
879
+ fs = FsMock("foo.feature")
880
+
881
+ with patch("os.path", fs):
882
+ with patch("os.walk", fs.walk):
883
+ with r.path_manager:
884
+ assert_raises(ConfigError, r.setup_paths)
885
+
886
+ def test_supplied_feature_directory(self):
887
+ config = create_mock_config()
888
+ config.paths = ["spam"]
889
+ config.verbose = True
890
+ r = runner.Runner(config)
891
+
892
+ fs = FsMock("spam/", "spam/steps/", "spam/foo.feature")
893
+
894
+ with patch("os.path", fs):
895
+ with patch("os.walk", fs.walk):
896
+ with r.path_manager:
897
+ r.setup_paths()
898
+
899
+ ok_(("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls)
900
+
901
+ eq_(r.base_dir, os.path.join(fs.base, "spam"))
902
+
903
+ def test_supplied_feature_directory_no_steps(self):
904
+ config = create_mock_config()
905
+ config.paths = ["spam"]
906
+ config.verbose = True
907
+ r = runner.Runner(config)
908
+
909
+ fs = FsMock("spam/", "spam/foo.feature")
910
+
911
+ with patch("os.path", fs):
912
+ with patch("os.walk", fs.walk):
913
+ assert_raises(ConfigError, r.setup_paths)
914
+
915
+ ok_(("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls)
916
+
917
+ def test_supplied_feature_directory_missing(self):
918
+ config = create_mock_config()
919
+ config.paths = ["spam"]
920
+ config.verbose = True
921
+ r = runner.Runner(config)
922
+
923
+ fs = FsMock()
924
+
925
+ with patch("os.path", fs):
926
+ with patch("os.walk", fs.walk):
927
+ assert_raises(ConfigError, r.setup_paths)
928
+
929
+
930
+ class TestFeatureDirectoryLayout2(object):
931
+ # pylint: disable=invalid-name, no-self-use
932
+
933
+ def test_default_path(self):
934
+ config = create_mock_config()
935
+ config.paths = []
936
+ config.verbose = True
937
+ r = runner.Runner(config)
938
+
939
+ fs = FsMock(
940
+ "features/",
941
+ "features/steps/",
942
+ "features/group1/",
943
+ "features/group1/foo.feature",
944
+ )
945
+
946
+ with patch("os.path", fs):
947
+ with patch("os.walk", fs.walk):
948
+ with r.path_manager:
949
+ r.setup_paths()
950
+
951
+ eq_(r.base_dir, os.path.abspath("features"))
952
+
953
+ def test_supplied_root_directory(self):
954
+ config = create_mock_config()
955
+ config.paths = ["features"]
956
+ config.verbose = True
957
+ r = runner.Runner(config)
958
+
959
+ fs = FsMock(
960
+ "features/",
961
+ "features/group1/",
962
+ "features/group1/foo.feature",
963
+ "features/steps/",
964
+ )
965
+
966
+ with patch("os.path", fs):
967
+ with patch("os.walk", fs.walk):
968
+ with r.path_manager:
969
+ r.setup_paths()
970
+
971
+ ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
972
+ eq_(r.base_dir, os.path.join(fs.base, "features"))
973
+
974
+ def test_supplied_root_directory_no_steps(self):
975
+ config = create_mock_config()
976
+ config.paths = ["features"]
977
+ config.verbose = True
978
+ r = runner.Runner(config)
979
+
980
+ fs = FsMock(
981
+ "features/",
982
+ "features/group1/",
983
+ "features/group1/foo.feature",
984
+ )
985
+
986
+ with patch("os.path", fs):
987
+ with patch("os.walk", fs.walk):
988
+ with r.path_manager:
989
+ assert_raises(ConfigError, r.setup_paths)
990
+
991
+ ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
992
+ eq_(r.base_dir, None)
993
+
994
+
995
+ def test_supplied_feature_file(self):
996
+ config = create_mock_config()
997
+ config.paths = ["features/group1/foo.feature"]
998
+ config.verbose = True
999
+ r = runner.Runner(config)
1000
+ r.context = Mock()
1001
+
1002
+ fs = FsMock(
1003
+ "features/",
1004
+ "features/group1/",
1005
+ "features/group1/foo.feature",
1006
+ "features/steps/",
1007
+ )
1008
+
1009
+ with patch("os.path", fs):
1010
+ with patch("os.walk", fs.walk):
1011
+ with r.path_manager:
1012
+ r.setup_paths()
1013
+
1014
+ ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
1015
+ ok_(("isfile", os.path.join(fs.base, "features", "group1", "foo.feature")) in fs.calls)
1016
+ eq_(r.base_dir, fs.join(fs.base, "features"))
1017
+
1018
+ def test_supplied_feature_file_no_steps(self):
1019
+ config = create_mock_config()
1020
+ config.paths = ["features/group1/foo.feature"]
1021
+ config.verbose = True
1022
+ r = runner.Runner(config)
1023
+
1024
+ fs = FsMock(
1025
+ "features/",
1026
+ "features/group1/",
1027
+ "features/group1/foo.feature",
1028
+ )
1029
+
1030
+ with patch("os.path", fs):
1031
+ with patch("os.walk", fs.walk):
1032
+ with r.path_manager:
1033
+ assert_raises(ConfigError, r.setup_paths)
1034
+
1035
+ def test_supplied_feature_directory(self):
1036
+ config = create_mock_config()
1037
+ config.paths = ["features/group1"]
1038
+ config.verbose = True
1039
+ r = runner.Runner(config)
1040
+
1041
+ fs = FsMock(
1042
+ "features/",
1043
+ "features/group1/",
1044
+ "features/group1/foo.feature",
1045
+ "features/steps/",
1046
+ )
1047
+
1048
+ with patch("os.path", fs):
1049
+ with patch("os.walk", fs.walk):
1050
+ with r.path_manager:
1051
+ r.setup_paths()
1052
+
1053
+ ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
1054
+ eq_(r.base_dir, os.path.join(fs.base, "features"))
1055
+
1056
+
1057
+ def test_supplied_feature_directory_no_steps(self):
1058
+ config = create_mock_config()
1059
+ config.paths = ["features/group1"]
1060
+ config.verbose = True
1061
+ r = runner.Runner(config)
1062
+
1063
+ fs = FsMock(
1064
+ "features/",
1065
+ "features/group1/",
1066
+ "features/group1/foo.feature",
1067
+ )
1068
+
1069
+ with patch("os.path", fs):
1070
+ with patch("os.walk", fs.walk):
1071
+ assert_raises(ConfigError, r.setup_paths)
1072
+
1073
+ ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
1074
+