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,256 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ This module provides pre-/post-processors for the mod:`behave4cmd0.command_shell`.
5
+ """
6
+
7
+ from __future__ import absolute_import, print_function
8
+ import re
9
+ import sys
10
+ from six import string_types
11
+
12
+
13
+ # -----------------------------------------------------------------------------
14
+ # UTILITY:
15
+ # -----------------------------------------------------------------------------
16
+ def posixpath_normpath(filename):
17
+ if not filename:
18
+ return filename
19
+ return filename.replace("\\", "/").replace("//", "/")
20
+
21
+
22
+ # -----------------------------------------------------------------------------
23
+ # LINE PROCESSORS:
24
+ # -----------------------------------------------------------------------------
25
+ class LineProcessor(object):
26
+ """Function-like object that may perform text-line transformations."""
27
+ def __init__(self, marker=None):
28
+ self.marker = marker
29
+
30
+ def reset(self):
31
+ pass
32
+
33
+ def __call__(self, text):
34
+ return text
35
+
36
+
37
+ class TracebackLineNormalizer(LineProcessor):
38
+ """Line processor that tries to normalize path lines in a traceback dump."""
39
+ marker = "Traceback (most recent call last):"
40
+ file_pattern = re.compile(r'\s\s+File "(?P<path>.*)", line .*')
41
+
42
+ def __init__(self):
43
+ super(TracebackLineNormalizer, self).__init__(self.marker)
44
+ self.traceback_section = False
45
+
46
+ def reset(self):
47
+ self.traceback_section = False
48
+
49
+ def __call__(self, line):
50
+ """Process a line and optionally transform it.
51
+
52
+ :param line: line to process (as text)
53
+ :return: Same line or transformed/normalized line (as text).
54
+ """
55
+ marker = self.marker
56
+ stripped_line = line.strip()
57
+ if marker == stripped_line:
58
+ assert not self.traceback_section
59
+ self.traceback_section = True
60
+ # print("XXX: TRACEBACK-START")
61
+ elif self.traceback_section:
62
+ matched = self.file_pattern.match(line)
63
+ if matched:
64
+ # matched_range = matched.regs[1]
65
+ filename = matched.groups()[0]
66
+ new_filename = posixpath_normpath(filename)
67
+ if new_filename != filename:
68
+ # print("XXX: %r => %r" % (filename, new_filename))
69
+ line = line.replace(filename, new_filename)
70
+ elif not stripped_line or line[0].isalpha():
71
+ # -- DETECTED TRCAEBACK-END: exception-description
72
+ # print("XXX: TRACEBACK-END")
73
+ self.traceback_section = False
74
+ return line
75
+
76
+
77
+ class ExceptionWithPathNormalizer(LineProcessor):
78
+ """Normalize filename path in Exception line (for Windows)."""
79
+ # http://myregexp.com/examples.html
80
+ # Windows File Name Regexp
81
+ # (?i) ^ (?! ^ (PRN | AUX | CLOCK\$ | NUL | CON | COM\d | LPT\d |\..* )(\..+)?$)
82
+ # [ ^\\\./:\ * \?\"<>\|][^\\/:\*\?\"<>\|]{0,254}$
83
+ problematic_path_patterns = [
84
+ 'ConfigError: No steps directory in "(?P<path>.*)"',
85
+ 'ParserError: Failed to parse "(?P<path>.*)"',
86
+ "Error: [Errno 2] No such file or directory: '(?P<path>.*)'",
87
+ ]
88
+
89
+ def __init__(self, pattern, marker_text=None):
90
+ super(ExceptionWithPathNormalizer, self).__init__(marker_text)
91
+ self.pattern = re.compile(pattern, re.UNICODE)
92
+ self.marker = marker_text
93
+
94
+ def __call__(self, line):
95
+ matched = self.pattern.search(line)
96
+ if matched:
97
+ # -- ONLY: One pattern per line should match.
98
+ filename = matched.groupdict()["path"]
99
+ new_filename = posixpath_normpath(filename)
100
+ if new_filename != filename:
101
+ line = line.replace(filename, new_filename)
102
+ return line
103
+
104
+
105
+ # -----------------------------------------------------------------------------
106
+ # COMMAND OUTPUT PROCESSORS:
107
+ # -----------------------------------------------------------------------------
108
+ class CommandPostProcessor(object):
109
+ """Syntactic sugar to mark a command post-processor."""
110
+
111
+
112
+ class CommandOutputProcessor(CommandPostProcessor):
113
+ """Abstract base class functionality for a CommandPostProcessor that
114
+ post-processes the output of a command.
115
+ """
116
+ enabled = True
117
+ output_parts = ("stderr", "stdout")
118
+
119
+ def __init__(self, enabled=None, output_parts=None):
120
+ if enabled is None:
121
+ # -- AUTO-DETECT: Enabled on Windows platform
122
+ enabled = self.__class__.enabled
123
+ if output_parts is None:
124
+ output_parts = self.__class__.output_parts
125
+ self.enabled = enabled
126
+ self.output_parts = output_parts
127
+
128
+ def matches_output(self, text):
129
+ """Abstract method that should be overwritten."""
130
+ # pylint: disable=no-self-use, unused-argument
131
+ return False
132
+
133
+ def process_output(self, text): # pylint: disable=no-self-use
134
+ """Abstract method that should be overwritten."""
135
+ changed = False
136
+ return changed, text
137
+
138
+ def __call__(self, command_result):
139
+ """Core functionality of command output processor.
140
+
141
+ :param command_result: As value object w/ command execution details.
142
+ :return: Command result
143
+ """
144
+ if not self.enabled:
145
+ return command_result
146
+
147
+ changes = 0
148
+ for output_name in self.output_parts:
149
+ output = getattr(command_result, output_name)
150
+ if output and self.matches_output(output):
151
+ changed, new_output = self.process_output(output)
152
+ if changed:
153
+ changes += 1
154
+ setattr(command_result, output_name, new_output)
155
+
156
+ if changes:
157
+ # -- RESET: Composite output
158
+ # pylint: disable=protected-access
159
+ command_result._output = None
160
+ return command_result
161
+
162
+
163
+ class LineCommandOutputProcessor(CommandOutputProcessor):
164
+ """Provides functionality to process text in line-oriented way by using
165
+ a number of line processors. The line processors perform the actual work
166
+ for transforming/normalizing the text.
167
+ """
168
+ enabled = True
169
+ line_processors = [TracebackLineNormalizer()]
170
+
171
+ def __init__(self, line_processors=None):
172
+ if line_processors is None:
173
+ line_processors = self.__class__.line_processors
174
+ super(LineCommandOutputProcessor, self).__init__(self.enabled)
175
+ self.line_processors = line_processors
176
+ self.markers = [p.marker for p in self.line_processors if p.marker]
177
+
178
+ def matches_output(self, text):
179
+ """Indicates it text contains sections of interest.
180
+ :param text: Text to inspect (as string).
181
+ :return: True, if text contains Traceback sections. False, otherwise.
182
+ """
183
+ if self.markers:
184
+ for marker in self.markers:
185
+ if marker in text:
186
+ return True
187
+ # -- OTHERWISE:
188
+ return False
189
+
190
+ def process_output(self, text):
191
+ """Normalizes multi-line text by applying the line processors.
192
+
193
+ :param text: Text to process (as string).
194
+ :return: Tuple (changed : bool, new_text : string)
195
+ """
196
+ new_lines = []
197
+ changed = False
198
+ for line_processor in self.line_processors:
199
+ line_processor.reset()
200
+
201
+ for line in text.splitlines():
202
+ # -- LINE PROCESSING PIPELINE:
203
+ original_line = line
204
+ for line_processor in self.line_processors:
205
+ line = line_processor(line)
206
+
207
+ if line != original_line:
208
+ changed = True
209
+ new_lines.append(line)
210
+
211
+ if changed:
212
+ text = "\n".join(new_lines) + "\n"
213
+ return changed, text
214
+
215
+ class TextProcessor(CommandOutputProcessor):
216
+ """Provides an adapter that uses an :class:`CommandOutputProcessor`
217
+ as text processor (normalizer).
218
+ """
219
+
220
+ def __init__(self, command_output_processor):
221
+ self.command_output_processor = command_output_processor
222
+ self.enabled = self.command_output_processor.enabled
223
+ self.output_parts = self.command_output_processor.output_parts
224
+
225
+ def process_output(self, text):
226
+ return self.command_output_processor.process_output(text)
227
+
228
+ def __call__(self, command_result):
229
+ if isinstance(command_result, string_types):
230
+ text = command_result
231
+ return self.command_output_processor.process_output(text)[1]
232
+ else:
233
+ return self.command_output_processor(command_result)
234
+
235
+
236
+ class BehaveWinCommandOutputProcessor(LineCommandOutputProcessor):
237
+ """Command output post-processor for :mod:`behave` on Windows platform.
238
+ Mostly, normalizes windows paths in output and exceptions to conform to
239
+ POSIX path conventions.
240
+ """
241
+ enabled = sys.platform.startswith("win") or True
242
+ line_processors = [
243
+ TracebackLineNormalizer(),
244
+ ExceptionWithPathNormalizer(
245
+ "ConfigError: No steps directory in '(?P<path>.*)'",
246
+ "ConfigError: No steps directory in"),
247
+ ExceptionWithPathNormalizer(
248
+ 'ParserError: Failed to parse "(?P<path>.*)"',
249
+ "ParserError: Failed to parse"),
250
+ ExceptionWithPathNormalizer(
251
+ "No such file or directory: '(?P<path>.*)'",
252
+ "[Errno 2] No such file or directory:"), # IOError
253
+ ExceptionWithPathNormalizer(
254
+ '^\s*File "(?P<path>.*)", line \d+, in ',
255
+ 'File "'),
256
+ ]
@@ -0,0 +1,532 @@
1
+ # -*- coding -*-
2
+ """
3
+ Provides step definitions to:
4
+
5
+ * run commands, like behave
6
+ * create textual files within a working directory
7
+
8
+ TODO:
9
+ matcher that ignores empty lines and whitespace and has contains comparison
10
+ """
11
+
12
+ from __future__ import absolute_import, print_function
13
+ from behave import given, when, then, step, matchers
14
+ from behave4cmd0 import command_shell, command_util, pathutil, textutil
15
+ from behave4cmd0.pathutil import posixpath_normpath
16
+ from behave4cmd0.command_shell_proc import \
17
+ TextProcessor, BehaveWinCommandOutputProcessor
18
+ import contextlib
19
+ import difflib
20
+ import os
21
+ import shutil
22
+ from hamcrest import assert_that, equal_to, is_not, contains_string
23
+
24
+ # -----------------------------------------------------------------------------
25
+ # INIT:
26
+ # -----------------------------------------------------------------------------
27
+ matchers.register_type(int=int)
28
+ DEBUG = False
29
+ file_contents_normalizer = None
30
+ if BehaveWinCommandOutputProcessor.enabled:
31
+ file_contents_normalizer = TextProcessor(BehaveWinCommandOutputProcessor())
32
+
33
+
34
+ # -----------------------------------------------------------------------------
35
+ # UTILITIES:
36
+ # -----------------------------------------------------------------------------
37
+ @contextlib.contextmanager
38
+ def on_assert_failed_print_details(actual, expected):
39
+ """
40
+ Print text details in case of assertation failed errors.
41
+
42
+ .. sourcecode:: python
43
+
44
+ with on_assert_failed_print_details(actual_text, expected_text):
45
+ assert actual == expected
46
+ """
47
+ try:
48
+ yield
49
+ except AssertionError:
50
+ # diff = difflib.unified_diff(expected.splitlines(), actual.splitlines(),
51
+ # "expected", "actual")
52
+ diff = difflib.ndiff(expected.splitlines(), actual.splitlines())
53
+ diff_text = u"\n".join(diff)
54
+ print(u"DIFF (+ ACTUAL, - EXPECTED):\n{0}\n".format(diff_text))
55
+ if DEBUG:
56
+ print(u"expected:\n{0}\n".format(expected))
57
+ print(u"actual:\n{0}\n".format(actual))
58
+ raise
59
+
60
+ @contextlib.contextmanager
61
+ def on_error_print_details(actual, expected):
62
+ """
63
+ Print text details in case of assertation failed errors.
64
+
65
+ .. sourcecode:: python
66
+
67
+ with on_error_print_details(actual_text, expected_text):
68
+ ... # Do something
69
+ """
70
+ try:
71
+ yield
72
+ except Exception:
73
+ diff = difflib.ndiff(expected.splitlines(), actual.splitlines())
74
+ diff_text = u"\n".join(diff)
75
+ print(u"DIFF (+ ACTUAL, - EXPECTED):\n{0}\n".format(diff_text))
76
+ if DEBUG:
77
+ print(u"expected:\n{0}\n".format(expected))
78
+ print(u"actual:\n{0}".format(actual))
79
+ raise
80
+
81
+ # -----------------------------------------------------------------------------
82
+ # STEPS: WORKING DIR
83
+ # -----------------------------------------------------------------------------
84
+ @given(u'a new working directory')
85
+ def step_a_new_working_directory(context):
86
+ """Creates a new, empty working directory."""
87
+ command_util.ensure_context_attribute_exists(context, "workdir", None)
88
+ # MAYBE: command_util.ensure_workdir_not_exists(context)
89
+ command_util.ensure_workdir_exists(context)
90
+ # OOPS:
91
+ shutil.rmtree(context.workdir, ignore_errors=True)
92
+ command_util.ensure_workdir_exists(context)
93
+
94
+ @given(u'I use the current directory as working directory')
95
+ def step_use_curdir_as_working_directory(context):
96
+ """
97
+ Uses the current directory as working directory
98
+ """
99
+ context.workdir = os.path.abspath(".")
100
+ command_util.ensure_workdir_exists(context)
101
+
102
+ # -----------------------------------------------------------------------------
103
+ # STEPS: Create files with contents
104
+ # -----------------------------------------------------------------------------
105
+ @given(u'a file named "{filename}" and encoding="{encoding}" with')
106
+ def step_a_file_named_filename_and_encoding_with(context, filename, encoding):
107
+ """Creates a textual file with the content provided as docstring."""
108
+ __encoding_is_valid = True
109
+ assert context.text is not None, "ENSURE: multiline text is provided."
110
+ assert not os.path.isabs(filename)
111
+ assert __encoding_is_valid
112
+ command_util.ensure_workdir_exists(context)
113
+ filename2 = os.path.join(context.workdir, filename)
114
+ pathutil.create_textfile_with_contents(filename2, context.text, encoding)
115
+
116
+
117
+ @given(u'a file named "{filename}" with')
118
+ def step_a_file_named_filename_with(context, filename):
119
+ """Creates a textual file with the content provided as docstring."""
120
+ step_a_file_named_filename_and_encoding_with(context, filename, "UTF-8")
121
+
122
+ # -- SPECIAL CASE: For usage with behave steps.
123
+ if filename.endswith(".feature"):
124
+ command_util.ensure_context_attribute_exists(context, "features", [])
125
+ context.features.append(filename)
126
+
127
+
128
+ @given(u'an empty file named "{filename}"')
129
+ def step_an_empty_file_named_filename(context, filename):
130
+ """
131
+ Creates an empty file.
132
+ """
133
+ assert not os.path.isabs(filename)
134
+ command_util.ensure_workdir_exists(context)
135
+ filename2 = os.path.join(context.workdir, filename)
136
+ pathutil.create_textfile_with_contents(filename2, "")
137
+
138
+
139
+ # -----------------------------------------------------------------------------
140
+ # STEPS: Run commands
141
+ # -----------------------------------------------------------------------------
142
+ @when(u'I run "{command}"')
143
+ @when(u'I run `{command}`')
144
+ def step_i_run_command(context, command):
145
+ """
146
+ Run a command as subprocess, collect its output and returncode.
147
+ """
148
+ command_util.ensure_workdir_exists(context)
149
+ context.command_result = command_shell.run(command, cwd=context.workdir)
150
+ command_util.workdir_save_coverage_files(context.workdir)
151
+ if False and DEBUG:
152
+ print(u"run_command: {0}".format(command))
153
+ print(u"run_command.output {0}".format(context.command_result.output))
154
+
155
+ @when(u'I successfully run "{command}"')
156
+ @when(u'I successfully run `{command}`')
157
+ def step_i_successfully_run_command(context, command):
158
+ step_i_run_command(context, command)
159
+ step_it_should_pass(context)
160
+
161
+ @then(u'it should fail with result "{result:int}"')
162
+ def step_it_should_fail_with_result(context, result):
163
+ assert_that(context.command_result.returncode, equal_to(result))
164
+ assert_that(result, is_not(equal_to(0)))
165
+
166
+ @then(u'the command should fail with returncode="{result:int}"')
167
+ def step_it_should_fail_with_returncode(context, result):
168
+ assert_that(context.command_result.returncode, equal_to(result))
169
+ assert_that(result, is_not(equal_to(0)))
170
+
171
+ @then(u'the command returncode is "{result:int}"')
172
+ def step_the_command_returncode_is(context, result):
173
+ assert_that(context.command_result.returncode, equal_to(result))
174
+
175
+ @then(u'the command returncode is non-zero')
176
+ def step_the_command_returncode_is_nonzero(context):
177
+ assert_that(context.command_result.returncode, is_not(equal_to(0)))
178
+
179
+ @then(u'it should pass')
180
+ def step_it_should_pass(context):
181
+ assert_that(context.command_result.returncode, equal_to(0),
182
+ context.command_result.output)
183
+
184
+ @then(u'it should fail')
185
+ def step_it_should_fail(context):
186
+ assert_that(context.command_result.returncode, is_not(equal_to(0)),
187
+ context.command_result.output)
188
+
189
+ @then(u'it should pass with')
190
+ def step_it_should_pass_with(context):
191
+ '''
192
+ EXAMPLE:
193
+ ...
194
+ when I run "behave ..."
195
+ then it should pass with:
196
+ """
197
+ TEXT
198
+ """
199
+ '''
200
+ assert context.text is not None, "ENSURE: multiline text is provided."
201
+ step_command_output_should_contain(context)
202
+ assert_that(context.command_result.returncode, equal_to(0),
203
+ context.command_result.output)
204
+
205
+
206
+ @then(u'it should fail with')
207
+ def step_it_should_fail_with(context):
208
+ '''
209
+ EXAMPLE:
210
+ ...
211
+ when I run "behave ..."
212
+ then it should fail with:
213
+ """
214
+ TEXT
215
+ """
216
+ '''
217
+ assert context.text is not None, "ENSURE: multiline text is provided."
218
+ step_command_output_should_contain(context)
219
+ assert_that(context.command_result.returncode, is_not(equal_to(0)))
220
+
221
+
222
+ # -----------------------------------------------------------------------------
223
+ # STEPS FOR: Output Comparison
224
+ # -----------------------------------------------------------------------------
225
+ @then(u'the command output should contain "{text}"')
226
+ def step_command_output_should_contain_text(context, text):
227
+ '''
228
+ EXAMPLE:
229
+ ...
230
+ Then the command output should contain "TEXT"
231
+ '''
232
+ expected_text = text
233
+ if "{__WORKDIR__}" in expected_text or "{__CWD__}" in expected_text:
234
+ expected_text = textutil.template_substitute(text,
235
+ __WORKDIR__ = posixpath_normpath(context.workdir),
236
+ __CWD__ = posixpath_normpath(os.getcwd())
237
+ )
238
+ actual_output = context.command_result.output
239
+ with on_assert_failed_print_details(actual_output, expected_text):
240
+ textutil.assert_normtext_should_contain(actual_output, expected_text)
241
+
242
+
243
+ @then(u'the command output should not contain "{text}"')
244
+ def step_command_output_should_not_contain_text(context, text):
245
+ '''
246
+ EXAMPLE:
247
+ ...
248
+ then the command output should not contain "TEXT"
249
+ '''
250
+ expected_text = text
251
+ if "{__WORKDIR__}" in text or "{__CWD__}" in text:
252
+ expected_text = textutil.template_substitute(text,
253
+ __WORKDIR__ = posixpath_normpath(context.workdir),
254
+ __CWD__ = posixpath_normpath(os.getcwd())
255
+ )
256
+ actual_output = context.command_result.output
257
+ with on_assert_failed_print_details(actual_output, expected_text):
258
+ textutil.assert_normtext_should_not_contain(actual_output, expected_text)
259
+
260
+
261
+ @then(u'the command output should contain "{text}" {count:d} times')
262
+ def step_command_output_should_contain_text_multiple_times(context, text, count):
263
+ '''
264
+ EXAMPLE:
265
+ ...
266
+ Then the command output should contain "TEXT" 3 times
267
+ '''
268
+ assert count >= 0
269
+ expected_text = text
270
+ if "{__WORKDIR__}" in expected_text or "{__CWD__}" in expected_text:
271
+ expected_text = textutil.template_substitute(text,
272
+ __WORKDIR__ = posixpath_normpath(context.workdir),
273
+ __CWD__ = posixpath_normpath(os.getcwd())
274
+ )
275
+ actual_output = context.command_result.output
276
+ with on_assert_failed_print_details(actual_output, expected_text):
277
+ textutil.assert_normtext_should_contain_multiple_times(actual_output,
278
+ expected_text,
279
+ count)
280
+
281
+ @then(u'the command output should contain exactly "{text}"')
282
+ def step_command_output_should_contain_exactly_text(context, text):
283
+ """
284
+ Verifies that the command output of the last command contains the
285
+ expected text.
286
+
287
+ .. code-block:: gherkin
288
+
289
+ When I run "echo Hello"
290
+ Then the command output should contain "Hello"
291
+ """
292
+ expected_text = text
293
+ if "{__WORKDIR__}" in text or "{__CWD__}" in text:
294
+ expected_text = textutil.template_substitute(text,
295
+ __WORKDIR__ = posixpath_normpath(context.workdir),
296
+ __CWD__ = posixpath_normpath(os.getcwd())
297
+ )
298
+ actual_output = context.command_result.output
299
+ textutil.assert_text_should_contain_exactly(actual_output, expected_text)
300
+
301
+
302
+ @then(u'the command output should not contain exactly "{text}"')
303
+ def step_command_output_should_not_contain_exactly_text(context, text):
304
+ expected_text = text
305
+ if "{__WORKDIR__}" in text or "{__CWD__}" in text:
306
+ expected_text = textutil.template_substitute(text,
307
+ __WORKDIR__ = posixpath_normpath(context.workdir),
308
+ __CWD__ = posixpath_normpath(os.getcwd())
309
+ )
310
+ actual_output = context.command_result.output
311
+ textutil.assert_text_should_not_contain_exactly(actual_output, expected_text)
312
+
313
+
314
+ @then(u'the command output should contain')
315
+ def step_command_output_should_contain(context):
316
+ '''
317
+ EXAMPLE:
318
+ ...
319
+ when I run "behave ..."
320
+ then it should pass
321
+ and the command output should contain:
322
+ """
323
+ TEXT
324
+ """
325
+ '''
326
+ assert context.text is not None, "REQUIRE: multi-line text"
327
+ step_command_output_should_contain_text(context, context.text)
328
+
329
+
330
+ @then(u'the command output should not contain')
331
+ def step_command_output_should_not_contain(context):
332
+ '''
333
+ EXAMPLE:
334
+ ...
335
+ when I run "behave ..."
336
+ then it should pass
337
+ and the command output should not contain:
338
+ """
339
+ TEXT
340
+ """
341
+ '''
342
+ assert context.text is not None, "REQUIRE: multi-line text"
343
+ step_command_output_should_not_contain_text(context, context.text.strip())
344
+
345
+ @then(u'the command output should contain {count:d} times')
346
+ def step_command_output_should_contain_multiple_times(context, count):
347
+ '''
348
+ EXAMPLE:
349
+ ...
350
+ when I run "behave ..."
351
+ then it should pass
352
+ and the command output should contain 2 times:
353
+ """
354
+ TEXT
355
+ """
356
+ '''
357
+ assert context.text is not None, "REQUIRE: multi-line text"
358
+ step_command_output_should_contain_text_multiple_times(context,
359
+ context.text, count)
360
+
361
+ @then(u'the command output should contain exactly')
362
+ def step_command_output_should_contain_exactly_with_multiline_text(context):
363
+ assert context.text is not None, "REQUIRE: multi-line text"
364
+ step_command_output_should_contain_exactly_text(context, context.text)
365
+
366
+
367
+ @then(u'the command output should not contain exactly')
368
+ def step_command_output_should_contain_not_exactly_with_multiline_text(context):
369
+ assert context.text is not None, "REQUIRE: multi-line text"
370
+ step_command_output_should_not_contain_exactly_text(context, context.text)
371
+
372
+
373
+ # -----------------------------------------------------------------------------
374
+ # STEPS FOR: Directories
375
+ # -----------------------------------------------------------------------------
376
+ @step(u'I remove the directory "{directory}"')
377
+ def step_remove_directory(context, directory):
378
+ path_ = directory
379
+ if not os.path.isabs(directory):
380
+ path_ = os.path.join(context.workdir, os.path.normpath(directory))
381
+ if os.path.isdir(path_):
382
+ shutil.rmtree(path_, ignore_errors=True)
383
+ assert_that(not os.path.isdir(path_))
384
+
385
+ @given(u'I ensure that the directory "{directory}" does not exist')
386
+ def step_given_the_directory_should_not_exist(context, directory):
387
+ step_remove_directory(context, directory)
388
+
389
+ @given(u'a directory named "{path}"')
390
+ def step_directory_named_dirname(context, path):
391
+ assert context.workdir, "REQUIRE: context.workdir"
392
+ path_ = os.path.join(context.workdir, os.path.normpath(path))
393
+ if not os.path.exists(path_):
394
+ os.makedirs(path_)
395
+ assert os.path.isdir(path_)
396
+
397
+ @then(u'the directory "{directory}" should exist')
398
+ def step_the_directory_should_exist(context, directory):
399
+ path_ = directory
400
+ if not os.path.isabs(directory):
401
+ path_ = os.path.join(context.workdir, os.path.normpath(directory))
402
+ assert_that(os.path.isdir(path_))
403
+
404
+ @then(u'the directory "{directory}" should not exist')
405
+ def step_the_directory_should_not_exist(context, directory):
406
+ path_ = directory
407
+ if not os.path.isabs(directory):
408
+ path_ = os.path.join(context.workdir, os.path.normpath(directory))
409
+ assert_that(not os.path.isdir(path_))
410
+
411
+ @step(u'the directory "{directory}" exists')
412
+ def step_directory_exists(context, directory):
413
+ """
414
+ Verifies that a directory exists.
415
+
416
+ .. code-block:: gherkin
417
+
418
+ Given the directory "abc.txt" exists
419
+ When the directory "abc.txt" exists
420
+ """
421
+ step_the_directory_should_exist(context, directory)
422
+
423
+ @step(u'the directory "{directory}" does not exist')
424
+ def step_directory_named_does_not_exist(context, directory):
425
+ """
426
+ Verifies that a directory does not exist.
427
+
428
+ .. code-block:: gherkin
429
+
430
+ Given the directory "abc/" does not exist
431
+ When the directory "abc/" does not exist
432
+ """
433
+ step_the_directory_should_not_exist(context, directory)
434
+
435
+ # -----------------------------------------------------------------------------
436
+ # FILE STEPS:
437
+ # -----------------------------------------------------------------------------
438
+ @step(u'a file named "{filename}" exists')
439
+ def step_file_named_filename_exists(context, filename):
440
+ """
441
+ Verifies that a file with this filename exists.
442
+
443
+ .. code-block:: gherkin
444
+
445
+ Given a file named "abc.txt" exists
446
+ When a file named "abc.txt" exists
447
+ """
448
+ step_file_named_filename_should_exist(context, filename)
449
+
450
+ @step(u'a file named "{filename}" does not exist')
451
+ def step_file_named_filename_does_not_exist(context, filename):
452
+ """
453
+ Verifies that a file with this filename does not exist.
454
+
455
+ .. code-block:: gherkin
456
+
457
+ Given a file named "abc.txt" does not exist
458
+ When a file named "abc.txt" does not exist
459
+ """
460
+ step_file_named_filename_should_not_exist(context, filename)
461
+
462
+ @then(u'a file named "{filename}" should exist')
463
+ def step_file_named_filename_should_exist(context, filename):
464
+ command_util.ensure_workdir_exists(context)
465
+ filename_ = pathutil.realpath_with_context(filename, context)
466
+ assert_that(os.path.exists(filename_) and os.path.isfile(filename_))
467
+
468
+ @then(u'a file named "{filename}" should not exist')
469
+ def step_file_named_filename_should_not_exist(context, filename):
470
+ command_util.ensure_workdir_exists(context)
471
+ filename_ = pathutil.realpath_with_context(filename, context)
472
+ assert_that(not os.path.exists(filename_))
473
+
474
+ # -----------------------------------------------------------------------------
475
+ # STEPS FOR FILE CONTENTS:
476
+ # -----------------------------------------------------------------------------
477
+ @then(u'the file "{filename}" should contain "{text}"')
478
+ def step_file_should_contain_text(context, filename, text):
479
+ expected_text = text
480
+ if "{__WORKDIR__}" in text or "{__CWD__}" in text:
481
+ expected_text = textutil.template_substitute(text,
482
+ __WORKDIR__ = posixpath_normpath(context.workdir),
483
+ __CWD__ = posixpath_normpath(os.getcwd())
484
+ )
485
+ file_contents = pathutil.read_file_contents(filename, context=context)
486
+ file_contents = file_contents.rstrip()
487
+ if file_contents_normalizer:
488
+ # -- HACK: Inject TextProcessor as text normalizer
489
+ file_contents = file_contents_normalizer(file_contents)
490
+ with on_assert_failed_print_details(file_contents, expected_text):
491
+ textutil.assert_normtext_should_contain(file_contents, expected_text)
492
+
493
+
494
+ @then(u'the file "{filename}" should not contain "{text}"')
495
+ def step_file_should_not_contain_text(context, filename, text):
496
+ file_contents = pathutil.read_file_contents(filename, context=context)
497
+ file_contents = file_contents.rstrip()
498
+ textutil.assert_normtext_should_not_contain(file_contents, text)
499
+ # XXX assert_that(file_contents, is_not(contains_string(text)))
500
+
501
+
502
+ @then(u'the file "{filename}" should contain')
503
+ def step_file_should_contain_multiline_text(context, filename):
504
+ assert context.text is not None, "REQUIRE: multiline text"
505
+ step_file_should_contain_text(context, filename, context.text)
506
+
507
+
508
+ @then(u'the file "{filename}" should not contain')
509
+ def step_file_should_not_contain_multiline_text(context, filename):
510
+ assert context.text is not None, "REQUIRE: multiline text"
511
+ step_file_should_not_contain_text(context, filename, context.text)
512
+
513
+
514
+ # -----------------------------------------------------------------------------
515
+ # ENVIRONMENT VARIABLES
516
+ # -----------------------------------------------------------------------------
517
+ @step(u'I set the environment variable "{env_name}" to "{env_value}"')
518
+ def step_I_set_the_environment_variable_to(context, env_name, env_value):
519
+ if not hasattr(context, "environ"):
520
+ context.environ = {}
521
+ context.environ[env_name] = env_value
522
+ os.environ[env_name] = env_value
523
+
524
+ @step(u'I remove the environment variable "{env_name}"')
525
+ def step_I_remove_the_environment_variable(context, env_name):
526
+ if not hasattr(context, "environ"):
527
+ context.environ = {}
528
+ context.environ[env_name] = ""
529
+ os.environ[env_name] = ""
530
+ del context.environ[env_name]
531
+ del os.environ[env_name]
532
+