cucumber 1.3.20 → 2.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (404) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.rspec +1 -1
  4. data/.travis.yml +1 -2
  5. data/CONTRIBUTING.md +9 -0
  6. data/Gemfile +9 -2
  7. data/History.md +26 -17
  8. data/LICENSE +2 -2
  9. data/README.md +4 -4
  10. data/Rakefile +12 -0
  11. data/bin/cucumber +1 -5
  12. data/bin/cuke +60 -0
  13. data/cucumber.gemspec +10 -15
  14. data/cucumber.yml +14 -26
  15. data/examples/i18n/ar/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  16. data/examples/i18n/bg/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  17. data/examples/i18n/ca/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  18. data/examples/i18n/cs/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  19. data/examples/i18n/da/features/{step_definitons → step_definitions}/lommeregner_steps.rb +0 -0
  20. data/examples/i18n/de/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  21. data/examples/{ramaze → i18n/el}/Rakefile +1 -1
  22. data/examples/i18n/el/features/addition.feature +17 -0
  23. data/examples/i18n/el/features/division.feature +10 -0
  24. data/examples/i18n/el/features/step_definitions/calculator_steps.rb +24 -0
  25. data/examples/i18n/el/lib/calculator.rb +14 -0
  26. data/examples/i18n/en/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  27. data/examples/i18n/eo/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  28. data/examples/i18n/es/features/{step_definitons → step_definitions}/calculador_steps.rb +0 -0
  29. data/examples/i18n/fi/features/{step_definitons → step_definitions}/laskin_steps.rb +0 -0
  30. data/examples/i18n/fr/Rakefile +3 -1
  31. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +2 -2
  32. data/examples/i18n/he/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  33. data/examples/i18n/hi/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  34. data/examples/i18n/hu/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  35. data/examples/i18n/id/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  36. data/examples/i18n/it/features/{step_definitons → step_definitions}/calcolatrice_steps.rb +0 -0
  37. data/examples/i18n/ja/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  38. data/examples/i18n/ko/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  39. data/examples/i18n/lt/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  40. data/examples/i18n/lv/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  41. data/examples/i18n/no/features/{step_definitons → step_definitions}/kalkulator_steps.rb +0 -0
  42. data/examples/i18n/pl/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  43. data/examples/i18n/ro/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  44. data/examples/i18n/ru/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  45. data/examples/i18n/sk/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  46. data/examples/i18n/sr-Cyrl/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  47. data/examples/i18n/sr-Latn/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  48. data/examples/i18n/sv/features/{step_definitons → step_definitions}/kalkulator_steps.rb +0 -0
  49. data/examples/i18n/tr/features/{step_definitons → step_definitions}/hesap_makinesi_adimlari.rb +0 -0
  50. data/examples/i18n/uk/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  51. data/examples/i18n/uz/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  52. data/examples/i18n/zh-CN/features/{step_definitons → step_definitions}/calculator_steps.rb +4 -4
  53. data/examples/i18n/zh-TW/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  54. data/{legacy_features → features/docs}/api/list_step_defs_as_json.feature +14 -14
  55. data/{legacy_features → features/docs}/api/run_cli_main_with_existing_runtime.feature +5 -10
  56. data/features/{backtraces.feature → docs/cli/backtraces.feature} +2 -2
  57. data/features/docs/cli/dry_run.feature +25 -0
  58. data/features/docs/cli/exclude_files.feature +19 -0
  59. data/features/docs/cli/execute_with_tag_filter.feature +117 -0
  60. data/features/docs/cli/randomize.feature +46 -0
  61. data/features/docs/cli/require.feature +27 -0
  62. data/features/docs/cli/run_scenarios_matching_name.feature +104 -0
  63. data/features/docs/cli/run_specific_scenarios.feature +113 -0
  64. data/features/docs/cli/showing_differences.feature +43 -0
  65. data/features/docs/cli/specifying_multiple_formatters.feature +44 -0
  66. data/features/docs/cli/strict_mode.feature +41 -0
  67. data/features/{nested_steps.feature → docs/defining_steps/nested_steps.feature} +3 -5
  68. data/features/{nested_steps_i18n.feature → docs/defining_steps/nested_steps_i18n.feature} +0 -2
  69. data/features/{nested_steps_with_second_arg.feature → docs/defining_steps/nested_steps_with_second_arg.feature} +0 -0
  70. data/features/{step_definitions.feature → docs/defining_steps/one_line_step_definitions.feature} +3 -3
  71. data/features/docs/defining_steps/printing_messages.feature +147 -0
  72. data/features/docs/defining_steps/skip_scenario.feature +33 -0
  73. data/features/docs/defining_steps/snippets.feature +41 -0
  74. data/{legacy_features → features/docs/defining_steps}/table_diffing.feature +15 -15
  75. data/features/{transforms.feature → docs/defining_steps/transforms.feature} +2 -2
  76. data/{legacy_features/exception_in_after_block.feature → features/docs/exception_in_after_hook.feature} +25 -26
  77. data/{legacy_features/exception_in_after_step_block.feature → features/docs/exception_in_after_step_hook.feature} +21 -24
  78. data/{legacy_features/exception_in_before_block.feature → features/docs/exception_in_before_hook.feature} +18 -20
  79. data/features/{custom_formatter.feature → docs/extending_cucumber/custom_formatter.feature} +3 -8
  80. data/features/{formatter_callbacks.feature → docs/extending_cucumber/formatter_callbacks.feature} +185 -4
  81. data/{legacy_features/listener_debugger_formatter.feature → features/docs/formatters/debug_formatter.feature} +13 -15
  82. data/features/{formatter_step_file_colon_line.feature → docs/formatters/formatter_step_file_colon_line.feature} +2 -4
  83. data/features/{html_formatter.feature → docs/formatters/html_formatter.feature} +10 -14
  84. data/features/{json_formatter.feature → docs/formatters/json_formatter.feature} +109 -247
  85. data/features/docs/formatters/junit_formatter.feature +275 -0
  86. data/features/{pretty_formatter.feature → docs/formatters/pretty_formatter.feature} +1 -1
  87. data/features/{progress_formatter.feature → docs/formatters/progress_formatter.feature} +1 -1
  88. data/features/docs/formatters/rerun_formatter.feature +135 -0
  89. data/features/docs/formatters/usage_formatter.feature +102 -0
  90. data/features/docs/getting_started.feature +27 -0
  91. data/features/{background.feature → docs/gherkin/background.feature} +149 -91
  92. data/features/{doc_strings.feature → docs/gherkin/doc_strings.feature} +1 -0
  93. data/features/docs/gherkin/expand_option_for_outlines.feature +46 -0
  94. data/features/docs/gherkin/language_from_header.feature +32 -0
  95. data/features/docs/gherkin/outlines.feature +154 -0
  96. data/features/docs/gherkin/unicode_table.feature +32 -0
  97. data/features/docs/gherkin/using_descriptions.feature +88 -0
  98. data/features/docs/gherkin/using_star_notation.feature +37 -0
  99. data/features/{iso-8859-1.feature → docs/iso-8859-1.feature} +0 -0
  100. data/{legacy_features → features/docs}/post_configuration_hook.feature +17 -18
  101. data/{legacy_features → features/docs}/profiles.feature +30 -36
  102. data/{legacy_features → features/docs}/rake_task.feature +30 -41
  103. data/features/{raketask.feature → docs/raketask.feature} +6 -13
  104. data/features/docs/report_called_undefined_steps.feature +57 -0
  105. data/{legacy_features → features/docs}/wire_protocol.feature +36 -31
  106. data/{legacy_features → features/docs}/wire_protocol_erb.feature +5 -6
  107. data/{legacy_features → features/docs}/wire_protocol_table_diffing.feature +14 -12
  108. data/{legacy_features → features/docs}/wire_protocol_tags.feature +6 -7
  109. data/{legacy_features → features/docs}/wire_protocol_timeouts.feature +6 -6
  110. data/{legacy_features → features/docs}/work_in_progress.feature +52 -54
  111. data/{legacy_features → features/docs/writing_support_code}/around_hooks.feature +25 -28
  112. data/features/docs/writing_support_code/before_hook.feature +61 -0
  113. data/features/docs/writing_support_code/hook_order.feature +61 -0
  114. data/features/{load_path.feature → docs/writing_support_code/load_path.feature} +3 -0
  115. data/features/docs/writing_support_code/state.feature +32 -0
  116. data/features/{tagged_hooks.feature → docs/writing_support_code/tagged_hooks.feature} +11 -13
  117. data/features/lib/step_definitions/aruba_steps.rb +22 -0
  118. data/features/lib/step_definitions/cucumber_steps.rb +50 -0
  119. data/features/{step_definitions → lib/step_definitions}/iso-8859-1_steps.rb +3 -15
  120. data/features/lib/step_definitions/json_steps.rb +7 -0
  121. data/features/lib/step_definitions/junit_steps.rb +13 -0
  122. data/features/lib/step_definitions/language_steps.rb +4 -5
  123. data/features/lib/step_definitions/profile_steps.rb +15 -0
  124. data/features/lib/step_definitions/ruby_steps.rb +3 -0
  125. data/{legacy_features → features/lib}/step_definitions/wire_steps.rb +16 -9
  126. data/features/lib/support/env.rb +21 -0
  127. data/{legacy_features → features/lib}/support/fake_wire_server.rb +0 -0
  128. data/features/{support → lib/support}/feature_factory.rb +1 -1
  129. data/features/lib/support/normalise_output.rb +33 -0
  130. data/gem_tasks/cov.rake +5 -0
  131. data/gem_tasks/cucumber.rake +1 -10
  132. data/gem_tasks/rspec.rake +0 -2
  133. data/gem_tasks/yard.rake +4 -1
  134. data/lib/cucumber.rb +1 -3
  135. data/lib/cucumber/cli/configuration.rb +30 -25
  136. data/lib/cucumber/cli/main.rb +13 -25
  137. data/lib/cucumber/cli/options.rb +15 -57
  138. data/lib/cucumber/configuration.rb +4 -0
  139. data/lib/cucumber/constantize.rb +7 -6
  140. data/lib/cucumber/core_ext/instance_exec.rb +7 -38
  141. data/lib/cucumber/core_ext/proc.rb +1 -1
  142. data/lib/cucumber/errors.rb +3 -1
  143. data/lib/cucumber/file_specs.rb +35 -0
  144. data/lib/cucumber/formatter/console.rb +32 -21
  145. data/lib/cucumber/formatter/debug.rb +5 -0
  146. data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +8 -38
  147. data/lib/cucumber/formatter/html.rb +29 -21
  148. data/lib/cucumber/formatter/junit.rb +10 -7
  149. data/lib/cucumber/formatter/pretty.rb +2 -8
  150. data/lib/cucumber/formatter/rerun.rb +2 -3
  151. data/lib/cucumber/formatter/unicode.rb +8 -21
  152. data/lib/cucumber/formatter/usage.rb +65 -2
  153. data/lib/cucumber/language_support/language_methods.rb +1 -1
  154. data/lib/cucumber/mappings.rb +212 -0
  155. data/lib/cucumber/multiline_argument.rb +115 -0
  156. data/lib/cucumber/platform.rb +21 -22
  157. data/lib/cucumber/rake/task.rb +3 -54
  158. data/lib/cucumber/rb_support/rb_language.rb +2 -5
  159. data/lib/cucumber/rb_support/rb_world.rb +14 -19
  160. data/lib/cucumber/rb_support/snippet.rb +60 -19
  161. data/lib/cucumber/reports/legacy_formatter.rb +1279 -0
  162. data/lib/cucumber/runtime.rb +176 -26
  163. data/lib/cucumber/runtime/for_programming_languages.rb +10 -4
  164. data/lib/cucumber/runtime/gated_receiver.rb +21 -0
  165. data/lib/cucumber/runtime/support_code.rb +9 -7
  166. data/lib/cucumber/runtime/tag_limits.rb +15 -0
  167. data/lib/cucumber/runtime/tag_limits/filter.rb +31 -0
  168. data/lib/cucumber/runtime/tag_limits/test_case_index.rb +29 -0
  169. data/lib/cucumber/runtime/tag_limits/verifier.rb +57 -0
  170. data/lib/cucumber/runtime/user_interface.rb +4 -0
  171. data/lib/cucumber/step_match.rb +3 -3
  172. data/lib/cucumber/term/ansicolor.rb +1 -9
  173. data/lib/cucumber/wire_support/wire_language.rb +23 -9
  174. data/lib/cucumber/wire_support/wire_packet.rb +1 -1
  175. data/lib/cucumber/wire_support/wire_protocol/requests.rb +13 -5
  176. data/lib/cucumber/wire_support/wire_step_definition.rb +1 -8
  177. data/spec/cucumber/cli/configuration_spec.rb +151 -150
  178. data/spec/cucumber/cli/main_spec.rb +36 -99
  179. data/spec/cucumber/cli/options_spec.rb +238 -272
  180. data/spec/cucumber/cli/profile_loader_spec.rb +9 -8
  181. data/spec/cucumber/configuration_spec.rb +3 -3
  182. data/spec/cucumber/constantize_spec.rb +2 -1
  183. data/spec/cucumber/core_ext/proc_spec.rb +32 -43
  184. data/spec/cucumber/file_specs_spec.rb +41 -0
  185. data/spec/cucumber/formatter/ansicolor_spec.rb +11 -10
  186. data/spec/cucumber/formatter/debug_spec.rb +569 -0
  187. data/spec/cucumber/formatter/duration_spec.rb +6 -6
  188. data/spec/cucumber/formatter/html_spec.rb +53 -62
  189. data/spec/cucumber/formatter/interceptor_spec.rb +38 -31
  190. data/spec/cucumber/formatter/junit_spec.rb +34 -28
  191. data/spec/cucumber/formatter/pretty_spec.rb +238 -52
  192. data/spec/cucumber/formatter/progress_spec.rb +2 -2
  193. data/spec/cucumber/formatter/spec_helper.rb +23 -17
  194. data/spec/cucumber/rake/forked_spec.rb +13 -22
  195. data/spec/cucumber/rb_support/rb_language_spec.rb +76 -67
  196. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +63 -42
  197. data/spec/cucumber/rb_support/rb_transform_spec.rb +4 -3
  198. data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +6 -4
  199. data/spec/cucumber/rb_support/snippet_spec.rb +42 -33
  200. data/spec/cucumber/reports/legacy_formatter_spec.rb +1750 -0
  201. data/spec/cucumber/runtime/for_programming_languages_spec.rb +11 -10
  202. data/spec/cucumber/runtime/gated_receiver_spec.rb +47 -0
  203. data/spec/cucumber/runtime/results_spec.rb +33 -26
  204. data/spec/cucumber/runtime/support_code_spec.rb +29 -29
  205. data/spec/cucumber/runtime/tag_limits/filter_spec.rb +59 -0
  206. data/spec/cucumber/runtime/tag_limits/test_case_index_spec.rb +38 -0
  207. data/spec/cucumber/runtime/tag_limits/verifier_spec.rb +57 -0
  208. data/spec/cucumber/runtime_spec.rb +39 -34
  209. data/spec/cucumber/step_match_spec.rb +30 -20
  210. data/spec/cucumber/wire_support/configuration_spec.rb +8 -5
  211. data/spec/cucumber/wire_support/connection_spec.rb +12 -8
  212. data/spec/cucumber/wire_support/wire_exception_spec.rb +14 -8
  213. data/spec/cucumber/wire_support/wire_language_spec.rb +8 -9
  214. data/spec/cucumber/wire_support/wire_packet_spec.rb +17 -13
  215. data/spec/cucumber/world/pending_spec.rb +36 -36
  216. data/spec/simplecov_setup.rb +18 -0
  217. data/spec/spec_helper.rb +3 -9
  218. metadata +298 -507
  219. data/.gitattributes +0 -1
  220. data/.ruby-version +0 -1
  221. data/examples/python/README.textile +0 -8
  222. data/examples/python/Rakefile +0 -4
  223. data/examples/python/features/fibonacci.feature +0 -19
  224. data/examples/python/features/step_definitions/fib_steps.py +0 -11
  225. data/examples/python/lib/fib.py +0 -7
  226. data/examples/ramaze/README.textile +0 -7
  227. data/examples/ramaze/app.rb +0 -21
  228. data/examples/ramaze/features/add.feature +0 -11
  229. data/examples/ramaze/features/step_definitions/add_steps.rb +0 -15
  230. data/examples/ramaze/features/support/env.rb +0 -32
  231. data/examples/ramaze/layout/default.html.erb +0 -8
  232. data/examples/ramaze/view/index.html.erb +0 -5
  233. data/examples/ruby2python/README.textile +0 -8
  234. data/examples/ruby2python/Rakefile +0 -4
  235. data/examples/ruby2python/features/fibonacci.feature +0 -19
  236. data/examples/ruby2python/features/step_definitions/fib_steps.rb +0 -7
  237. data/examples/ruby2python/features/support/env.rb +0 -21
  238. data/examples/ruby2python/lib/fib.py +0 -7
  239. data/examples/v8/Rakefile +0 -6
  240. data/examples/v8/features/fibonacci.feature +0 -43
  241. data/examples/v8/features/step_definitions/fib_steps.js +0 -49
  242. data/examples/v8/features/support/env.js +0 -14
  243. data/examples/v8/lib/fibonacci.js +0 -19
  244. data/features/.cucumber/stepdefs.json +0 -722
  245. data/features/assertions.feature +0 -73
  246. data/features/autoformat_profile_output.feature +0 -23
  247. data/features/before_hook.feature +0 -43
  248. data/features/bootstrap.feature +0 -26
  249. data/features/drb_server_integration.feature +0 -63
  250. data/features/execute_with_tag_filter.feature +0 -63
  251. data/features/parsing.feature +0 -18
  252. data/features/rerun_formatter.feature +0 -99
  253. data/features/run_specific_scenarios.feature +0 -47
  254. data/features/stats_formatters.feature +0 -73
  255. data/features/step_definitions/cucumber-features/cucumber_ruby_mappings.rb +0 -197
  256. data/features/step_definitions/cucumber_steps.rb +0 -57
  257. data/features/step_definitions/drb_steps.rb +0 -3
  258. data/features/support/env.rb +0 -57
  259. data/fixtures/json/features/background.feature +0 -7
  260. data/fixtures/json/features/embed.feature +0 -4
  261. data/fixtures/json/features/one_passing_one_failing.feature +0 -11
  262. data/fixtures/json/features/step_definitions/steps.rb +0 -32
  263. data/fixtures/json/features/tables.feature +0 -13
  264. data/fixtures/junit/features/one_passing_one_failing.feature +0 -8
  265. data/fixtures/junit/features/pending.feature +0 -7
  266. data/fixtures/junit/features/scenario_outline.feature +0 -9
  267. data/fixtures/junit/features/some_subdirectory/one_passing_one_failing.feature +0 -8
  268. data/fixtures/junit/features/step_definitions/steps.rb +0 -11
  269. data/fixtures/self_test/README.textile +0 -6
  270. data/fixtures/self_test/Rakefile +0 -6
  271. data/fixtures/self_test/features/call_undefined_step_from_step_def.feature +0 -7
  272. data/fixtures/self_test/features/failing_expectation.feature +0 -4
  273. data/fixtures/self_test/features/lots_of_undefined.feature +0 -8
  274. data/fixtures/self_test/features/multiline_name.feature +0 -27
  275. data/fixtures/self_test/features/outline_sample.feature +0 -15
  276. data/fixtures/self_test/features/sample.feature +0 -21
  277. data/fixtures/self_test/features/search_sample.feature +0 -32
  278. data/fixtures/self_test/features/step_definitions/sample_steps.rb +0 -84
  279. data/fixtures/self_test/features/support/bubble_256x256.png +0 -0
  280. data/fixtures/self_test/features/support/env.rb +0 -26
  281. data/fixtures/self_test/features/tags_sample.feature +0 -17
  282. data/fixtures/self_test/features/tons_of_cukes.feature +0 -52
  283. data/fixtures/self_test/features/undefined_multiline_args.feature +0 -12
  284. data/fixtures/self_test/list-of-features.txt +0 -1
  285. data/fixtures/steps_library/features/step_definitions/steps_lib1.rb +0 -8
  286. data/fixtures/steps_library/features/step_definitions/steps_lib2.rb +0 -8
  287. data/fixtures/tickets/Rakefile +0 -20
  288. data/fixtures/tickets/features.html +0 -138
  289. data/fixtures/tickets/features/172.feature +0 -28
  290. data/fixtures/tickets/features/177/1.feature +0 -28
  291. data/fixtures/tickets/features/177/2.feature +0 -20
  292. data/fixtures/tickets/features/177/3.feature +0 -18
  293. data/fixtures/tickets/features/180.feature +0 -7
  294. data/fixtures/tickets/features/229/tagged_hooks.feature +0 -8
  295. data/fixtures/tickets/features/229/tagged_hooks.rb +0 -14
  296. data/fixtures/tickets/features/236.feature +0 -13
  297. data/fixtures/tickets/features/241.feature +0 -12
  298. data/fixtures/tickets/features/246.feature +0 -4
  299. data/fixtures/tickets/features/248.feature +0 -11
  300. data/fixtures/tickets/features/270/back.feature +0 -14
  301. data/fixtures/tickets/features/270/back.steps.rb +0 -14
  302. data/fixtures/tickets/features/272/hooks.feature +0 -26
  303. data/fixtures/tickets/features/272/hooks_steps.rb +0 -53
  304. data/fixtures/tickets/features/279/py_string_indent.feature +0 -25
  305. data/fixtures/tickets/features/279/py_string_indent.steps.rb +0 -12
  306. data/fixtures/tickets/features/279/wrong.feature_ +0 -11
  307. data/fixtures/tickets/features/301/filter_background_tagged_hooks.feature +0 -6
  308. data/fixtures/tickets/features/301/filter_background_tagged_hooks_steps.rb +0 -12
  309. data/fixtures/tickets/features/306/only_background.feature +0 -4
  310. data/fixtures/tickets/features/around_timeout.feature +0 -6
  311. data/fixtures/tickets/features/gherkin_67.feature +0 -12
  312. data/fixtures/tickets/features/gherkin_68.feature +0 -4
  313. data/fixtures/tickets/features/half_manual.feature +0 -11
  314. data/fixtures/tickets/features/lib/eatting_machine.rb +0 -18
  315. data/fixtures/tickets/features/lib/pantry.rb +0 -20
  316. data/fixtures/tickets/features/scenario_outline.feature +0 -95
  317. data/fixtures/tickets/features/step_definitons/246_steps.rb +0 -3
  318. data/fixtures/tickets/features/step_definitons/248_steps.rb +0 -15
  319. data/fixtures/tickets/features/step_definitons/around_timeout_steps.rb +0 -9
  320. data/fixtures/tickets/features/step_definitons/half_manual_steps.rb +0 -11
  321. data/fixtures/tickets/features/step_definitons/scenario_outline_steps.rb +0 -42
  322. data/fixtures/tickets/features/step_definitons/tickets_steps.rb +0 -88
  323. data/fixtures/tickets/features/table_diffing.feature +0 -13
  324. data/fixtures/tickets/features/tickets.feature +0 -28
  325. data/legacy_features/README.md +0 -14
  326. data/legacy_features/announce.feature +0 -152
  327. data/legacy_features/bug_371.feature +0 -32
  328. data/legacy_features/bug_464.feature +0 -16
  329. data/legacy_features/bug_475.feature +0 -42
  330. data/legacy_features/bug_585_tab_indentation.feature +0 -22
  331. data/legacy_features/bug_600.feature +0 -73
  332. data/legacy_features/cucumber_cli.feature +0 -584
  333. data/legacy_features/cucumber_cli_outlines.feature +0 -117
  334. data/legacy_features/default_snippets.feature +0 -43
  335. data/legacy_features/diffing.feature +0 -25
  336. data/legacy_features/drb_server_integration.feature +0 -174
  337. data/legacy_features/exclude_files.feature +0 -20
  338. data/legacy_features/expand.feature +0 -60
  339. data/legacy_features/junit_formatter.feature +0 -214
  340. data/legacy_features/language_from_header.feature +0 -30
  341. data/legacy_features/multiline_names.feature +0 -44
  342. data/legacy_features/report_called_undefined_steps.feature +0 -35
  343. data/legacy_features/rerun_formatter.feature +0 -52
  344. data/legacy_features/simplest.feature +0 -11
  345. data/legacy_features/snippet.feature +0 -23
  346. data/legacy_features/snippets_when_using_star_keyword.feature +0 -38
  347. data/legacy_features/step_definitions/cucumber_steps.rb +0 -179
  348. data/legacy_features/step_definitions/extra_steps.rb +0 -2
  349. data/legacy_features/step_definitions/simplest_steps.rb +0 -3
  350. data/legacy_features/support/env.rb +0 -161
  351. data/legacy_features/support/env.rb.simplest +0 -7
  352. data/legacy_features/table_mapping.feature +0 -34
  353. data/legacy_features/transform.feature +0 -245
  354. data/legacy_features/unicode_table.feature +0 -35
  355. data/lib/README.rdoc +0 -12
  356. data/lib/cucumber/ast.rb +0 -30
  357. data/lib/cucumber/ast/background.rb +0 -116
  358. data/lib/cucumber/ast/comment.rb +0 -31
  359. data/lib/cucumber/ast/doc_string.rb +0 -61
  360. data/lib/cucumber/ast/empty_background.rb +0 -33
  361. data/lib/cucumber/ast/examples.rb +0 -49
  362. data/lib/cucumber/ast/feature.rb +0 -99
  363. data/lib/cucumber/ast/features.rb +0 -38
  364. data/lib/cucumber/ast/has_steps.rb +0 -74
  365. data/lib/cucumber/ast/location.rb +0 -41
  366. data/lib/cucumber/ast/multiline_argument.rb +0 -30
  367. data/lib/cucumber/ast/names.rb +0 -13
  368. data/lib/cucumber/ast/outline_table.rb +0 -194
  369. data/lib/cucumber/ast/scenario.rb +0 -103
  370. data/lib/cucumber/ast/scenario_outline.rb +0 -146
  371. data/lib/cucumber/ast/step.rb +0 -122
  372. data/lib/cucumber/ast/step_collection.rb +0 -92
  373. data/lib/cucumber/ast/step_invocation.rb +0 -196
  374. data/lib/cucumber/ast/table.rb +0 -738
  375. data/lib/cucumber/ast/tags.rb +0 -28
  376. data/lib/cucumber/ast/tree_walker.rb +0 -191
  377. data/lib/cucumber/ast/visitor.rb +0 -11
  378. data/lib/cucumber/broadcaster.rb +0 -13
  379. data/lib/cucumber/cli/drb_client.rb +0 -43
  380. data/lib/cucumber/feature_file.rb +0 -101
  381. data/lib/cucumber/formatter/ordered_xml_markup.rb +0 -24
  382. data/lib/cucumber/js_support/js_dsl.js +0 -57
  383. data/lib/cucumber/js_support/js_language.rb +0 -185
  384. data/lib/cucumber/js_support/js_snippets.rb +0 -27
  385. data/lib/cucumber/parser.rb +0 -2
  386. data/lib/cucumber/parser/gherkin_builder.rb +0 -284
  387. data/lib/cucumber/py_support/py_dsl.py +0 -10
  388. data/lib/cucumber/py_support/py_language.py +0 -10
  389. data/lib/cucumber/py_support/py_language.rb +0 -80
  390. data/lib/cucumber/step_mother.rb +0 -10
  391. data/spec/cucumber/ast/background_spec.rb +0 -122
  392. data/spec/cucumber/ast/doc_string_spec.rb +0 -40
  393. data/spec/cucumber/ast/feature_factory.rb +0 -72
  394. data/spec/cucumber/ast/feature_spec.rb +0 -63
  395. data/spec/cucumber/ast/features_spec.rb +0 -51
  396. data/spec/cucumber/ast/outline_table_spec.rb +0 -21
  397. data/spec/cucumber/ast/scenario_outline_spec.rb +0 -74
  398. data/spec/cucumber/ast/step_spec.rb +0 -68
  399. data/spec/cucumber/ast/table_spec.rb +0 -594
  400. data/spec/cucumber/ast/tree_walker_spec.rb +0 -19
  401. data/spec/cucumber/broadcaster_spec.rb +0 -15
  402. data/spec/cucumber/cli/drb_client_spec.rb +0 -76
  403. data/spec/cucumber/rake/rcov_spec.rb +0 -71
  404. data/spec/cucumber/wire_support/wire_step_definition_spec.rb +0 -20
@@ -0,0 +1,1279 @@
1
+ require 'forwardable'
2
+ require 'delegate'
3
+ require 'cucumber/errors'
4
+
5
+ module Cucumber
6
+ module Reports
7
+
8
+ class FormatterWrapper < BasicObject
9
+ attr_reader :formatters
10
+ private :formatters
11
+
12
+ def initialize(formatters)
13
+ @formatters = formatters
14
+ end
15
+
16
+ def method_missing(message, *args)
17
+ formatters.each do |formatter|
18
+ formatter.send(message, *args) if formatter.respond_to?(message)
19
+ end
20
+ end
21
+
22
+ def respond_to_missing?(name, include_private = false)
23
+ formatters.any? { |formatter| formatter.respond_to?(name, include_private) }
24
+ end
25
+
26
+ end
27
+
28
+ LegacyFormatter = Struct.new(:runtime, :formatter) do
29
+
30
+ def initialize(runtime, formatters)
31
+ super runtime, FormatterWrapper.new(formatters)
32
+ end
33
+
34
+ extend Forwardable
35
+
36
+ def_delegators :formatter,
37
+ :embed,
38
+ :ask
39
+ :puts
40
+
41
+ def before_test_case(test_case)
42
+ printer.before_test_case(test_case)
43
+ end
44
+
45
+ def before_test_step(test_step)
46
+ printer.before_test_step(test_step)
47
+ end
48
+
49
+ def after_test_step(test_step, result)
50
+ printer.after_test_step(test_step, result)
51
+ end
52
+
53
+ def after_test_case(test_case, result)
54
+ record_test_case_result(test_case, result)
55
+ printer.after_test_case(test_case, result)
56
+ end
57
+
58
+ def puts(*messages)
59
+ printer.puts(messages)
60
+ end
61
+
62
+ def embed(src, mime_type, label)
63
+ printer.embed(src, mime_type, label)
64
+ end
65
+
66
+ def done
67
+ printer.after
68
+ end
69
+
70
+ private
71
+
72
+ def printer
73
+ @printer ||= FeaturesPrinter.new(formatter, runtime).before
74
+ end
75
+
76
+ def record_test_case_result(test_case, result)
77
+ scenario = LegacyResultBuilder.new(result).scenario(test_case.name, test_case.location)
78
+ runtime.record_result(scenario)
79
+ end
80
+
81
+ require 'cucumber/core/test/timer'
82
+ FeaturesPrinter = Struct.new(:formatter, :runtime) do
83
+ extend Forwardable
84
+
85
+ def before
86
+ timer.start
87
+ formatter.before_features(nil)
88
+ self
89
+ end
90
+
91
+ def before_test_case(test_case)
92
+ test_case.describe_source_to(self)
93
+ @child.before_test_case(test_case)
94
+ end
95
+
96
+ def before_test_step(*args)
97
+ @child.before_test_step(*args)
98
+ end
99
+
100
+ def after_test_step(test_step, result)
101
+ @child.after_test_step(test_step, result)
102
+ end
103
+
104
+ def after_test_case(*args)
105
+ @child.after_test_case(*args)
106
+ end
107
+
108
+ def feature(node, *)
109
+ if node != @current_feature
110
+ @child.after if @child
111
+ @child = FeaturePrinter.new(formatter, runtime, node).before
112
+ @current_feature = node
113
+ end
114
+ end
115
+
116
+ def scenario(node, *)
117
+ end
118
+
119
+ def scenario_outline(node, *)
120
+ end
121
+
122
+ def examples_table(node, *)
123
+ end
124
+
125
+ def examples_table_row(node, *)
126
+ end
127
+
128
+ def after
129
+ @child.after if @child
130
+ formatter.after_features Legacy::Ast::Features.new(timer.sec)
131
+ self
132
+ end
133
+
134
+ def puts(messages)
135
+ @child.puts(messages)
136
+ end
137
+
138
+ def embed(src, mime_type, label)
139
+ @child.embed(src, mime_type, label)
140
+ end
141
+
142
+ private
143
+
144
+ def timer
145
+ @timer ||= Cucumber::Core::Test::Timer.new
146
+ end
147
+ end
148
+
149
+ module TestStepSource
150
+ def self.for(test_step, result)
151
+ collector = Collector.new
152
+ test_step.describe_source_to collector, result
153
+ collector.result.freeze
154
+ end
155
+
156
+ class Collector
157
+ attr_reader :result
158
+
159
+ def initialize
160
+ @result = StepSource.new
161
+ end
162
+
163
+ def method_missing(name, node, step_result, *args)
164
+ result.send "#{name}=", node
165
+ result.send "#{name}_result=", LegacyResultBuilder.new(step_result)
166
+ end
167
+ end
168
+
169
+ require 'ostruct'
170
+ class StepSource < OpenStruct
171
+
172
+ def build_step_invocation(indent, runtime, messages, embeddings)
173
+ step_result.step_invocation(step_match(runtime), step, indent, background, runtime.configuration, messages, embeddings)
174
+ end
175
+
176
+ private
177
+
178
+ def step_match(runtime)
179
+ runtime.step_match(step.name)
180
+ rescue Cucumber::Undefined
181
+ NoStepMatch.new(step, step.name)
182
+ end
183
+
184
+ end
185
+
186
+ end
187
+
188
+ Embedding = Struct.new(:src, :mime_type, :label) do
189
+
190
+ def send_to_formatter(formatter)
191
+ formatter.embed(src, mime_type, label)
192
+ end
193
+ end
194
+
195
+ FeaturePrinter = Struct.new(:formatter, :runtime, :node) do
196
+
197
+ def before
198
+ formatter.before_feature(node)
199
+ Legacy::Ast::Comments.new(node.comments).accept(formatter)
200
+ Legacy::Ast::Tags.new(node.tags).accept(formatter)
201
+ formatter.feature_name node.keyword, indented(node.legacy_conflated_name_and_description)
202
+ @delayed_messages = []
203
+ @delayed_embeddings = []
204
+ self
205
+ end
206
+
207
+ attr_reader :current_test_step_source
208
+
209
+ def before_test_case(test_case)
210
+ @before_hook_result = Legacy::Ast::Node.new
211
+ end
212
+
213
+ def before_test_step(test_step)
214
+ end
215
+
216
+ def after_test_step(test_step, result)
217
+ @current_test_step_source = TestStepSource.for(test_step, result)
218
+ # TODO: stop calling self, and describe source to another object
219
+ test_step.describe_source_to(self, result)
220
+ print_step
221
+ end
222
+
223
+ def after_test_case(*args)
224
+ if current_test_step_source.step_result.nil?
225
+ switch_step_container
226
+ @delayed_messages = []
227
+ @delayed_embeddings = []
228
+ end
229
+ @child.after_test_case
230
+ @previous_test_case_background = @current_test_case_background
231
+ @previous_test_case_scenario_outline = current_test_step_source.scenario_outline
232
+ end
233
+
234
+ def before_hook(location, result)
235
+ @before_hook_result = Legacy::Ast::BeforeHookResult.new(LegacyResultBuilder.new(result))
236
+ end
237
+
238
+ def after_hook(location, result)
239
+ @child.after_hook LegacyResultBuilder.new(result)
240
+ end
241
+
242
+ def after_step_hook(hook, result)
243
+ line = StepBacktraceLine.new(current_test_step_source.step)
244
+ @child.after_step_hook LegacyResultBuilder.new(result).
245
+ append_to_exception_backtrace(line)
246
+ end
247
+
248
+ def background(node, *)
249
+ @current_test_case_background = node
250
+ end
251
+
252
+ def puts(messages)
253
+ @delayed_messages.push *messages
254
+ end
255
+
256
+ def embed(src, mime_type, label)
257
+ @delayed_embeddings.push Embedding.new(src, mime_type, label)
258
+ end
259
+
260
+ def step(*);end
261
+ def scenario(*);end
262
+ def scenario_outline(*);end
263
+ def examples_table(*);end
264
+ def examples_table_row(*);end
265
+ def feature(*);end
266
+
267
+ def after
268
+ @child.after
269
+ formatter.after_feature(node)
270
+ self
271
+ end
272
+
273
+ private
274
+
275
+ attr_reader :before_hook_result
276
+ private :before_hook_result
277
+
278
+ def switch_step_container
279
+ switch_to_child select_step_container(current_test_step_source), current_test_step_source
280
+ end
281
+
282
+ def select_step_container(source)
283
+ if source.background
284
+ if same_background_as_previous_test_case?(source)
285
+ HiddenBackgroundPrinter.new(formatter, runtime, source.background)
286
+ else
287
+ BackgroundPrinter.new(formatter, runtime, source.background, before_hook_result)
288
+ end
289
+ elsif source.scenario
290
+ ScenarioPrinter.new(formatter, runtime, source.scenario, before_hook_result)
291
+ elsif source.scenario_outline
292
+ if same_scenario_outline_as_previous_test_case?(source) and @previous_outline_child
293
+ @previous_outline_child
294
+ else
295
+ ScenarioOutlinePrinter.new(formatter, runtime, source.scenario_outline)
296
+ end
297
+ else
298
+ raise 'unknown step container'
299
+ end
300
+ end
301
+
302
+ def same_background_as_previous_test_case?(source)
303
+ source.background == @previous_test_case_background
304
+ end
305
+
306
+ def same_scenario_outline_as_previous_test_case?(source)
307
+ source.scenario_outline == @previous_test_case_scenario_outline
308
+ end
309
+
310
+ def print_step
311
+ return unless current_test_step_source.step_result
312
+ switch_step_container
313
+
314
+ if current_test_step_source.scenario_outline
315
+ @child.examples_table(current_test_step_source.examples_table)
316
+ @child.examples_table_row(current_test_step_source.examples_table_row, before_hook_result)
317
+ end
318
+
319
+ if @failed_hidden_background_step
320
+ indent = Indent.new(@child.node)
321
+ step_invocation = @failed_hidden_background_step.build_step_invocation(indent, runtime, messages = [], embeddings = [])
322
+ @child.step_invocation(step_invocation, @failed_hidden_background_step)
323
+ @failed_hidden_background_step = nil
324
+ end
325
+
326
+ unless @last_step == current_test_step_source.step
327
+ indent ||= Indent.new(@child.node)
328
+ step_invocation = current_test_step_source.build_step_invocation(indent, runtime, @delayed_messages, @delayed_embeddings)
329
+ runtime.step_visited step_invocation
330
+ @child.step_invocation(step_invocation, current_test_step_source)
331
+ @last_step = current_test_step_source.step
332
+ end
333
+ @delayed_messages = []
334
+ @delayed_embeddings = []
335
+ end
336
+
337
+ def switch_to_child(child, source)
338
+ return if @child == child
339
+ if @child
340
+ if from_first_background(@child)
341
+ @first_background_failed = @child.failed?
342
+ elsif from_hidden_background(@child)
343
+ if not @first_background_failed
344
+ @failed_hidden_background_step = @child.get_failed_step_source
345
+ end
346
+ if @previous_outline_child
347
+ @previous_outline_child.after unless same_scenario_outline_as_previous_test_case?(source)
348
+ end
349
+ end
350
+ unless from_scenario_outline_to_hidden_backgroud(@child, child)
351
+ @child.after
352
+ @previous_outline_child = nil
353
+ else
354
+ @previous_outline_child = @child
355
+ end
356
+ end
357
+ child.before unless to_scenario_outline(child) and same_scenario_outline_as_previous_test_case?(source)
358
+ @child = child
359
+ end
360
+
361
+ def from_scenario_outline_to_hidden_backgroud(from, to)
362
+ from.class.name == "Cucumber::Reports::ScenarioOutlinePrinter" and
363
+ to.class.name == "Cucumber::Reports::HiddenBackgroundPrinter"
364
+ end
365
+
366
+ def from_first_background(from)
367
+ from.class.name == "Cucumber::Reports::BackgroundPrinter"
368
+ end
369
+
370
+ def from_hidden_background(from)
371
+ from.class.name == "Cucumber::Reports::HiddenBackgroundPrinter"
372
+ end
373
+
374
+ def to_scenario_outline(to)
375
+ to.class.name == "Cucumber::Reports::ScenarioOutlinePrinter"
376
+ end
377
+
378
+ def indented(nasty_old_conflation_of_name_and_description)
379
+ indent = ""
380
+ nasty_old_conflation_of_name_and_description.split("\n").map do |l|
381
+ s = "#{indent}#{l}"
382
+ indent = " "
383
+ s
384
+ end.join("\n")
385
+ end
386
+
387
+ end
388
+
389
+ BackgroundPrinter = Struct.new(:formatter, :runtime, :node, :before_hook_result) do
390
+
391
+ def before
392
+ formatter.before_background node
393
+ formatter.background_name node.keyword, node.legacy_conflated_name_and_description, node.location.to_s, indent.of(node)
394
+ before_hook_result.accept(formatter)
395
+ self
396
+ end
397
+
398
+ def after_step_hook(result)
399
+ result.describe_exception_to formatter
400
+ end
401
+
402
+ def step_invocation(step_invocation, source)
403
+ @child ||= StepsPrinter.new(formatter, runtime).before
404
+ @child.step_invocation step_invocation
405
+ if source.step_result.status == :failed
406
+ @failed = true
407
+ end
408
+ end
409
+
410
+ def after
411
+ @child.after if @child
412
+ formatter.after_background(node)
413
+ self
414
+ end
415
+
416
+ def failed?
417
+ @failed
418
+ end
419
+
420
+ private
421
+
422
+ def indent
423
+ @indent ||= Indent.new(node)
424
+ end
425
+ end
426
+
427
+ # Printer to handle background steps for anything but the first scenario in a
428
+ # feature. These steps should not be printed.
429
+ class HiddenBackgroundPrinter < Struct.new(:formatter, :runtime, :node)
430
+ def get_failed_step_source
431
+ return @source_of_failed_step
432
+ end
433
+
434
+ def step_invocation(step_invocation, source)
435
+ if source.step_result.status == :failed
436
+ @source_of_failed_step = source
437
+ end
438
+ end
439
+
440
+ def before;self;end
441
+ def after;self;end
442
+ def before_hook(*);end
443
+ def after_hook(*);end
444
+ def after_step_hook(*);end
445
+ def examples_table(*);end
446
+ def after_test_case(*);end
447
+ end
448
+
449
+ ScenarioPrinter = Struct.new(:formatter, :runtime, :node, :before_hook_result) do
450
+
451
+ def before
452
+ formatter.before_feature_element(node)
453
+ Legacy::Ast::Tags.new(node.tags).accept(formatter)
454
+ formatter.scenario_name node.keyword, node.legacy_conflated_name_and_description, node.location.to_s, indent.of(node)
455
+ before_hook_result.accept(formatter)
456
+ self
457
+ end
458
+
459
+ def step_invocation(step_invocation, source)
460
+ @child ||= StepsPrinter.new(formatter, runtime).before
461
+ @child.step_invocation step_invocation
462
+ @last_step_result = source.step_result
463
+ end
464
+
465
+ def after_hook(result)
466
+ @after_hook_result = result
467
+ end
468
+
469
+ def after_step_hook(result)
470
+ result.describe_exception_to formatter
471
+ end
472
+
473
+ def after_test_case(*args)
474
+ after
475
+ end
476
+
477
+ def after
478
+ return if @done
479
+ @child.after if @child
480
+ # TODO - the last step result might not accurately reflect the
481
+ # overall scenario result.
482
+ scenario = last_step_result.scenario(node.name, node.location)
483
+ @after_hook_result.describe_exception_to(formatter) if @after_hook_result
484
+ formatter.after_feature_element(scenario)
485
+ @done = true
486
+ self
487
+ end
488
+
489
+ private
490
+
491
+ def last_step_result
492
+ @last_step_result || LegacyResultBuilder.new(Core::Test::Result::Unknown.new)
493
+ end
494
+
495
+ def indent
496
+ @indent ||= Indent.new(node)
497
+ end
498
+ end
499
+
500
+ StepsPrinter = Struct.new(:formatter, :runtime) do
501
+ def before
502
+ formatter.before_steps(nil)
503
+ self
504
+ end
505
+
506
+ def step_invocation(step_invocation)
507
+ steps << step_invocation
508
+ step_invocation.accept(formatter)
509
+ self
510
+ end
511
+
512
+ def after
513
+ formatter.after_steps(steps)
514
+ self
515
+ end
516
+
517
+ private
518
+
519
+ def steps
520
+ @steps ||= Legacy::Ast::StepInvocations.new
521
+ end
522
+
523
+ end
524
+
525
+ ScenarioOutlinePrinter = Struct.new(:formatter, :runtime, :node) do
526
+ extend Forwardable
527
+ def_delegators :@child, :after_hook, :after_step_hook
528
+
529
+ def before
530
+ formatter.before_feature_element(node)
531
+ Legacy::Ast::Tags.new(node.tags).accept(formatter)
532
+ formatter.scenario_name node.keyword, node.legacy_conflated_name_and_description, node.location.to_s, indent.of(node)
533
+ OutlineStepsPrinter.new(formatter, runtime, indent).print(node)
534
+ self
535
+ end
536
+
537
+ def after_hook(result)
538
+ @child.after_hook(result)
539
+ end
540
+
541
+ def step_invocation(step_invocation, source)
542
+ node, result = source.step, source.step_result
543
+ @last_step_result = result
544
+ @child.step_invocation(step_invocation, source)
545
+ end
546
+
547
+ def examples_table(examples_table)
548
+ @child ||= ExamplesArrayPrinter.new(formatter, runtime).before
549
+ @child.examples_table(examples_table)
550
+ end
551
+
552
+ def examples_table_row(node, before_hook_result)
553
+ @child.examples_table_row(node, before_hook_result)
554
+ end
555
+
556
+ def after_test_case
557
+ @child.after_test_case
558
+ end
559
+
560
+ def after
561
+ @child.after if @child
562
+ # TODO - the last step result might not accurately reflect the
563
+ # overall scenario result.
564
+ scenario_outline = last_step_result.scenario_outline(node.name, node.location)
565
+ formatter.after_feature_element(scenario_outline)
566
+ self
567
+ end
568
+
569
+ private
570
+
571
+ def last_step_result
572
+ @last_step_result || Core::Test::Result::Unknown.new
573
+ end
574
+
575
+ def indent
576
+ @indent ||= Indent.new(node)
577
+ end
578
+ end
579
+
580
+ OutlineStepsPrinter = Struct.new(:formatter, :runtime, :indent, :outline) do
581
+ def print(node)
582
+ node.describe_to self
583
+ steps_printer.after
584
+ end
585
+
586
+ def scenario_outline(node, &descend)
587
+ descend.call(self)
588
+ end
589
+
590
+ def outline_step(step)
591
+ step_match = NoStepMatch.new(step, step.name)
592
+ step_invocation = LegacyResultBuilder.new(Core::Test::Result::Skipped.new).
593
+ step_invocation(step_match, step, indent, background = nil, runtime.configuration, messages = [], embeddings = [])
594
+ steps_printer.step_invocation step_invocation
595
+ end
596
+
597
+ def examples_table(*);end
598
+
599
+ private
600
+
601
+ def steps_printer
602
+ @steps_printer ||= StepsPrinter.new(formatter).before
603
+ end
604
+ end
605
+
606
+ ExamplesArrayPrinter = Struct.new(:formatter, :runtime) do
607
+ extend Forwardable
608
+ def_delegators :@child, :step_invocation, :after_hook, :after_step_hook, :after_test_case, :examples_table_row
609
+
610
+ def before
611
+ formatter.before_examples_array(:examples_array)
612
+ self
613
+ end
614
+
615
+ def examples_table(examples_table)
616
+ return if examples_table == @current
617
+ @child.after if @child
618
+ @child = ExamplesTablePrinter.new(formatter, runtime, examples_table).before
619
+ @current = examples_table
620
+ end
621
+
622
+ def after
623
+ @child.after if @child
624
+ formatter.after_examples_array
625
+ self
626
+ end
627
+ end
628
+
629
+ ExamplesTablePrinter = Struct.new(:formatter, :runtime, :node) do
630
+ extend Forwardable
631
+ def_delegators :@child, :step_invocation, :after_hook, :after_step_hook, :after_test_case
632
+
633
+ def before
634
+ formatter.before_examples(node)
635
+ formatter.examples_name(node.keyword, node.legacy_conflated_name_and_description)
636
+ formatter.before_outline_table(legacy_table)
637
+ if !runtime.configuration.expand?
638
+ HeaderTableRowPrinter.new(formatter, runtime, ExampleTableRow.new(node.header), Legacy::Ast::Node.new).before.after
639
+ end
640
+ self
641
+ end
642
+
643
+ def examples_table_row(examples_table_row, before_hook_result)
644
+ return if examples_table_row == @current
645
+ @child.after if @child
646
+ row = ExampleTableRow.new(examples_table_row)
647
+ if !runtime.configuration.expand?
648
+ @child = TableRowPrinter.new(formatter, runtime, row, before_hook_result).before
649
+ else
650
+ @child = ExpandTableRowPrinter.new(formatter, runtime, row, before_hook_result).before
651
+ end
652
+ @current = examples_table_row
653
+ end
654
+
655
+ def after_test_case(*args)
656
+ @child.after_test_case
657
+ end
658
+
659
+ def after
660
+ @child.after if @child
661
+ formatter.after_outline_table(node)
662
+ formatter.after_examples(node)
663
+ self
664
+ end
665
+
666
+ private
667
+
668
+ def legacy_table
669
+ LegacyTable.new(node)
670
+ end
671
+
672
+ class ExampleTableRow < SimpleDelegator
673
+ def dom_id
674
+ file_colon_line.gsub(/[\/\.:]/, '_')
675
+ end
676
+ end
677
+
678
+ LegacyTable = Struct.new(:node) do
679
+ def col_width(index)
680
+ max_width = FindMaxWidth.new(index)
681
+ node.describe_to max_width
682
+ max_width.result
683
+ end
684
+
685
+ require 'gherkin/formatter/escaping'
686
+ FindMaxWidth = Struct.new(:index) do
687
+ include ::Gherkin::Formatter::Escaping
688
+
689
+ def examples_table(table, &descend)
690
+ @result = char_length_of(table.header.values[index])
691
+ descend.call(self)
692
+ end
693
+
694
+ def examples_table_row(row, &descend)
695
+ width = char_length_of(row.values[index])
696
+ @result = width if width > result
697
+ end
698
+
699
+ def result
700
+ @result ||= 0
701
+ end
702
+
703
+ private
704
+ def char_length_of(cell)
705
+ escape_cell(cell).unpack('U*').length
706
+ end
707
+ end
708
+ end
709
+ end
710
+
711
+ class TableRowPrinterBase < Struct.new(:formatter, :runtime, :node, :before_hook_result)
712
+ def after_hook(result)
713
+ @after_hook_result = result
714
+ end
715
+
716
+ def after_step_hook(result)
717
+ @after_step_hook_result = result
718
+ end
719
+
720
+ def after_test_case(*args)
721
+ after
722
+ end
723
+
724
+ private
725
+
726
+ def indent
727
+ :not_needed
728
+ end
729
+
730
+ def legacy_table_row
731
+ LegacyExampleTableRow.new(exception, @status, node.values, node.location)
732
+ end
733
+
734
+ def exception
735
+ return nil unless @failed_step
736
+ @failed_step.exception
737
+ end
738
+ end
739
+
740
+ class HeaderTableRowPrinter < TableRowPrinterBase
741
+ def before
742
+ formatter.before_table_row(node)
743
+ self
744
+ end
745
+
746
+ def after
747
+ node.values.each do |value|
748
+ formatter.before_table_cell(value)
749
+ formatter.table_cell_value(value, :skipped_param)
750
+ formatter.after_table_cell(value)
751
+ end
752
+ formatter.after_table_row(legacy_table_row)
753
+ self
754
+ end
755
+ end
756
+
757
+
758
+ class TableRowPrinter < TableRowPrinterBase
759
+ def before
760
+ before_hook_result.accept(formatter)
761
+ formatter.before_table_row(node)
762
+ self
763
+ end
764
+
765
+ def step_invocation(step_invocation, source)
766
+ result = source.step_result
767
+ step_invocation.messages.each { |message| formatter.puts(message) }
768
+ step_invocation.embeddings.each { |embedding| embedding.send_to_formatter(formatter) }
769
+ @failed_step = step_invocation if result.status == :failed
770
+ @status = step_invocation.status unless already_failed?
771
+ end
772
+
773
+ def after
774
+ return if @done
775
+ @child.after if @child
776
+ node.values.each do |value|
777
+ formatter.before_table_cell(value)
778
+ formatter.table_cell_value(value, @status || :skipped)
779
+ formatter.after_table_cell(value)
780
+ end
781
+ formatter.after_table_row(legacy_table_row)
782
+ @after_step_hook_result.describe_exception_to formatter if @after_step_hook_result
783
+ @after_hook_result.describe_exception_to(formatter) if @after_hook_result
784
+ @done = true
785
+ self
786
+ end
787
+
788
+ private
789
+
790
+ def already_failed?
791
+ @status == :failed || @status == :undefined || @status == :pending
792
+ end
793
+ end
794
+
795
+ class ExpandTableRowPrinter < TableRowPrinterBase
796
+ def before
797
+ before_hook_result.accept(formatter)
798
+ self
799
+ end
800
+
801
+ def step_invocation(step_invocation, source)
802
+ result = source.step_result
803
+ @table_row ||= legacy_table_row
804
+ step_invocation.indent.record_width_of(@table_row)
805
+ if !@scenario_name_printed
806
+ print_scenario_name(step_invocation, @table_row)
807
+ @scenario_name_printed = true
808
+ end
809
+ step_invocation.accept(formatter)
810
+ @failed_step = step_invocation if result.status == :failed
811
+ @status = step_invocation.status unless @status == :failed
812
+ end
813
+
814
+ def after
815
+ return if @done
816
+ @child.after if @child
817
+ @after_step_hook_result.describe_exception_to formatter if @after_step_hook_result
818
+ @after_hook_result.describe_exception_to(formatter) if @after_hook_result
819
+ @done = true
820
+ self
821
+ end
822
+
823
+ private
824
+
825
+ def print_scenario_name(step_invocation, table_row)
826
+ formatter.scenario_name table_row.keyword, table_row.name, node.location.to_s, step_invocation.indent.of(table_row)
827
+ end
828
+ end
829
+
830
+ LegacyExampleTableRow = Struct.new(:exception, :status, :cells, :location) do
831
+ def name
832
+ '| ' + cells.join(' | ') + ' |'
833
+ end
834
+
835
+ def failed?
836
+ status == :failed
837
+ end
838
+
839
+ def line
840
+ location.line
841
+ end
842
+
843
+ def keyword
844
+ # This method is only called when used for the scenario name line with
845
+ # the expand option, and on that line the keyword is "Scenario"
846
+ "Scenario"
847
+ end
848
+ end
849
+
850
+ class Indent
851
+ def initialize(node)
852
+ @widths = []
853
+ node.describe_to(self)
854
+ end
855
+
856
+ [:background, :scenario, :scenario_outline].each do |node_name|
857
+ define_method(node_name) do |node, &descend|
858
+ record_width_of node
859
+ descend.call(self)
860
+ end
861
+ end
862
+
863
+ [:step, :outline_step].each do |node_name|
864
+ define_method(node_name) do |node|
865
+ record_width_of node
866
+ end
867
+ end
868
+
869
+ def examples_table(*); end
870
+ def examples_table_row(*); end
871
+
872
+ def of(node)
873
+ # The length of the instantiated steps in --expand mode are currently
874
+ # not included in the calculation of max => make sure to return >= 1
875
+ [1, max - node.name.length - node.keyword.length].max
876
+ end
877
+
878
+ def record_width_of(node)
879
+ @widths << node.keyword.length + node.name.length + 1
880
+ end
881
+
882
+ private
883
+
884
+ def max
885
+ @widths.max
886
+ end
887
+ end
888
+
889
+ class LegacyResultBuilder
890
+ attr_reader :status
891
+ def initialize(result)
892
+ result.describe_to(self)
893
+ end
894
+
895
+ def passed
896
+ @status = :passed
897
+ end
898
+
899
+ def failed
900
+ @status = :failed
901
+ end
902
+
903
+ def undefined
904
+ @status = :undefined
905
+ end
906
+
907
+ def skipped
908
+ @status = :skipped
909
+ end
910
+
911
+ def pending(exception, *)
912
+ @exception = exception
913
+ @status = :pending
914
+ end
915
+
916
+ def exception(exception, *)
917
+ @exception = exception
918
+ end
919
+
920
+ def append_to_exception_backtrace(line)
921
+ @exception.set_backtrace(@exception.backtrace + [line.to_s]) if @exception
922
+ return self
923
+ end
924
+
925
+ def duration(*); end
926
+
927
+ def step_invocation(step_match, step, indent, background, configuration, messages, embeddings)
928
+ Legacy::Ast::StepInvocation.new(step_match, @status, step_exception(step, configuration), indent, background, step, messages, embeddings)
929
+ end
930
+
931
+ def scenario(name, location)
932
+ Legacy::Ast::Scenario.new(@status, name, location)
933
+ end
934
+
935
+ def scenario_outline(name, location)
936
+ Legacy::Ast::ScenarioOutline.new(@status, name, location)
937
+ end
938
+
939
+ def describe_exception_to(formatter)
940
+ formatter.exception(filtered_exception, @status) if @exception
941
+ end
942
+
943
+ private
944
+
945
+ def step_exception(step, configuration)
946
+ return filtered_step_exception(step) if @exception
947
+ return nil unless @status == :undefined && configuration.strict?
948
+ begin
949
+ raise Cucumber::Undefined.new(step.name)
950
+ rescue => exception
951
+ @exception = exception
952
+ filtered_step_exception(step)
953
+ end
954
+ end
955
+
956
+ def filtered_exception
957
+ BacktraceFilter.new(@exception.dup).exception
958
+ end
959
+
960
+ def filtered_step_exception(step)
961
+ exception = filtered_exception
962
+ exception.backtrace << StepBacktraceLine.new(step).to_s
963
+ return exception
964
+ end
965
+ end
966
+
967
+ end
968
+
969
+ class StepBacktraceLine < Struct.new(:step)
970
+ def to_s
971
+ "#{step.location}:in `#{step.keyword}#{step.gherkin_statement.name}'"
972
+ end
973
+ end
974
+
975
+ class BacktraceFilter
976
+ BACKTRACE_FILTER_PATTERNS = \
977
+ [/vendor\/rails|lib\/cucumber|bin\/cucumber:|lib\/rspec|gems\/|minitest|test\/unit|.gem\/ruby|lib\/ruby/]
978
+ if(::Cucumber::JRUBY)
979
+ BACKTRACE_FILTER_PATTERNS << /org\/jruby/
980
+ end
981
+ PWD_PATTERN = /#{::Regexp.escape(::Dir.pwd)}\//m
982
+
983
+ def initialize(exception)
984
+ @exception = exception
985
+ end
986
+
987
+ def exception
988
+ return @exception if ::Cucumber.use_full_backtrace
989
+ @exception.backtrace.each{|line| line.gsub!(PWD_PATTERN, "./")}
990
+
991
+ filtered = (@exception.backtrace || []).reject do |line|
992
+ BACKTRACE_FILTER_PATTERNS.detect { |p| line =~ p }
993
+ end
994
+
995
+ if ::ENV['CUCUMBER_TRUNCATE_OUTPUT']
996
+ # Strip off file locations
997
+ filtered = filtered.map do |line|
998
+ line =~ /(.*):in `/ ? $1 : line
999
+ end
1000
+ end
1001
+
1002
+ @exception.set_backtrace(filtered)
1003
+ @exception
1004
+ end
1005
+ end
1006
+
1007
+
1008
+ # Adapters to pass to the legacy API formatters that provide the interface
1009
+ # of the old AST classes
1010
+ module Legacy
1011
+ module Ast
1012
+
1013
+ # Acts as a null object, or a base class
1014
+ class Node
1015
+ def initialize(node = nil)
1016
+ @node = node
1017
+ end
1018
+
1019
+ def accept(formatter)
1020
+ end
1021
+
1022
+ attr_reader :node
1023
+ private :node
1024
+ end
1025
+
1026
+ Comments = Struct.new(:comments) do
1027
+ def accept(formatter)
1028
+ return if comments.empty?
1029
+ formatter.before_comment comments
1030
+ comments.each do |comment|
1031
+ formatter.comment_line comment.to_s.strip
1032
+ end
1033
+ end
1034
+ end
1035
+
1036
+ class BeforeHookResult
1037
+ def initialize(result)
1038
+ @result = result
1039
+ @already_accepted = false
1040
+ end
1041
+
1042
+ def accept(formatter)
1043
+ unless @already_accepted
1044
+ @result.describe_exception_to(formatter)
1045
+ @already_accepted = true
1046
+ end
1047
+ self
1048
+ end
1049
+ end
1050
+
1051
+ StepInvocation = Struct.new(:step_match,
1052
+ :status,
1053
+ :exception,
1054
+ :indent,
1055
+ :background,
1056
+ :step,
1057
+ :messages,
1058
+ :embeddings) do
1059
+ extend Forwardable
1060
+
1061
+ def_delegators :step, :keyword, :name, :multiline_arg, :location, :gherkin_statement
1062
+
1063
+ def accept(formatter)
1064
+ formatter.before_step(self)
1065
+ messages.each { |message| formatter.puts(message) }
1066
+ embeddings.each { |embedding| embedding.send_to_formatter(formatter) }
1067
+ formatter.before_step_result *step_result_attributes
1068
+ print_step_name(formatter)
1069
+ Legacy::Ast::MultilineArg.for(multiline_arg).accept(formatter)
1070
+ print_exception(formatter)
1071
+ formatter.after_step_result *step_result_attributes
1072
+ formatter.after_step(self)
1073
+ end
1074
+
1075
+ def step_result_attributes
1076
+ [keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line]
1077
+ end
1078
+
1079
+ def failed?
1080
+ status != :passed
1081
+ end
1082
+
1083
+ def passed?
1084
+ status == :passed
1085
+ end
1086
+
1087
+ def dom_id
1088
+
1089
+ end
1090
+
1091
+ def actual_keyword
1092
+ # TODO: This should return the keyword for the snippet
1093
+ # `actual_keyword` translates 'And', 'But', etc. to 'Given', 'When',
1094
+ # 'Then' as appropriate
1095
+ "Given"
1096
+ end
1097
+
1098
+ def file_colon_line
1099
+ location.to_s
1100
+ end
1101
+
1102
+ def backtrace_line
1103
+ step_match.backtrace_line
1104
+ end
1105
+
1106
+ def step_invocation
1107
+ self
1108
+ end
1109
+
1110
+ private
1111
+
1112
+ def source_indent
1113
+ indent.of(self)
1114
+ end
1115
+
1116
+ def print_step_name(formatter)
1117
+ formatter.step_name(
1118
+ keyword,
1119
+ step_match,
1120
+ status,
1121
+ source_indent,
1122
+ background,
1123
+ location.to_s)
1124
+ end
1125
+
1126
+ def print_exception(formatter)
1127
+ return unless exception
1128
+ raise exception if ENV['FAIL_FAST']
1129
+ formatter.exception(exception, status)
1130
+ end
1131
+ end
1132
+
1133
+ class StepInvocations < Array
1134
+ def failed?
1135
+ any?(&:failed?)
1136
+ end
1137
+
1138
+ def passed?
1139
+ all?(&:passed?)
1140
+ end
1141
+
1142
+ def status
1143
+ return :passed if passed?
1144
+ failed_step.status
1145
+ end
1146
+
1147
+ def exception
1148
+ failed_step.exception if failed_step
1149
+ end
1150
+
1151
+ private
1152
+
1153
+ def failed_step
1154
+ detect(&:failed?)
1155
+ end
1156
+ end
1157
+
1158
+ class DataTableRow
1159
+ def initialize(row)
1160
+ @values = row.map(&:value)
1161
+ @line = row.line
1162
+ end
1163
+
1164
+ def dom_id
1165
+ "row_#{line}"
1166
+ end
1167
+
1168
+ def accept(formatter)
1169
+ formatter.before_table_row(self)
1170
+ values.each do |value|
1171
+ formatter.before_table_cell(value)
1172
+ formatter.table_cell_value(value, status)
1173
+ formatter.after_table_cell(value)
1174
+ end
1175
+ formatter.after_table_row(self)
1176
+ end
1177
+
1178
+ def status
1179
+ :skipped
1180
+ end
1181
+
1182
+ def exception
1183
+ nil
1184
+ end
1185
+
1186
+ attr_reader :values, :line
1187
+ private :values, :line
1188
+ end
1189
+
1190
+ Tags = Struct.new(:tags) do
1191
+ def accept(formatter)
1192
+ formatter.before_tags tags
1193
+ tags.each do |tag|
1194
+ formatter.tag_name tag.name
1195
+ end
1196
+ formatter.after_tags tags
1197
+ end
1198
+ end
1199
+
1200
+ Scenario = Struct.new(:status, :name, :location) do
1201
+ def backtrace_line(step_name = "#{name}", line = self.location.line)
1202
+ "#{location.on_line(line)}:in `#{step_name}'"
1203
+ end
1204
+
1205
+ def failed?
1206
+ :failed == status
1207
+ end
1208
+
1209
+ def line
1210
+ location.line
1211
+ end
1212
+ end
1213
+
1214
+ ScenarioOutline = Struct.new(:status, :name, :location) do
1215
+ def backtrace_line(step_name = "#{name}", line = self.location.line)
1216
+ "#{location.on_line(line)}:in `#{step_name}'"
1217
+ end
1218
+
1219
+ def failed?
1220
+ :failed == status
1221
+ end
1222
+
1223
+ def line
1224
+ location.line
1225
+ end
1226
+ end
1227
+
1228
+ module MultilineArg
1229
+ class << self
1230
+ def for(node)
1231
+ Builder.new(node).result
1232
+ end
1233
+ end
1234
+
1235
+ class Builder
1236
+ def initialize(node)
1237
+ node.describe_to(self)
1238
+ end
1239
+
1240
+ def doc_string(node)
1241
+ @result = DocString.new(node)
1242
+ end
1243
+
1244
+ def data_table(node)
1245
+ @result = DataTable.new(node)
1246
+ end
1247
+
1248
+ def result
1249
+ @result || Node.new(nil)
1250
+ end
1251
+ end
1252
+
1253
+ class DocString < Node
1254
+ def accept(formatter)
1255
+ formatter.before_multiline_arg node
1256
+ formatter.doc_string(node)
1257
+ formatter.after_multiline_arg node
1258
+ end
1259
+ end
1260
+
1261
+ class DataTable < Node
1262
+ def accept(formatter)
1263
+ formatter.before_multiline_arg node
1264
+ node.cells_rows.each do |row|
1265
+ Legacy::Ast::DataTableRow.new(row).accept(formatter)
1266
+ end
1267
+ formatter.after_multiline_arg node
1268
+ end
1269
+ end
1270
+
1271
+ end
1272
+
1273
+ Features = Struct.new(:duration)
1274
+
1275
+ end
1276
+
1277
+ end
1278
+ end
1279
+ end