cucumber 1.3.10 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.rspec +1 -1
  4. data/.travis.yml +4 -3
  5. data/CONTRIBUTING.md +9 -0
  6. data/Gemfile +9 -2
  7. data/History.md +212 -22
  8. data/LICENSE +2 -2
  9. data/README.md +4 -4
  10. data/Rakefile +10 -1
  11. data/bin/cucumber +1 -5
  12. data/cucumber.gemspec +10 -13
  13. data/cucumber.yml +14 -24
  14. data/examples/{ramaze → i18n/el}/Rakefile +1 -1
  15. data/examples/i18n/el/features/addition.feature +17 -0
  16. data/examples/i18n/el/features/division.feature +10 -0
  17. data/examples/i18n/el/features/step_definitions/calculator_steps.rb +24 -0
  18. data/examples/i18n/el/lib/calculator.rb +14 -0
  19. data/examples/i18n/fr/Rakefile +3 -1
  20. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +2 -2
  21. data/examples/i18n/ht/Rakefile +6 -0
  22. data/examples/i18n/ht/features/adisyon.feature +17 -0
  23. data/examples/i18n/ht/features/divizyon.feature +10 -0
  24. data/examples/i18n/ht/features/step_definitions/kalkilatris_steps.rb +25 -0
  25. data/examples/i18n/ht/lib/kalkilatris.rb +14 -0
  26. data/examples/i18n/zh-CN/features/{step_definitons → step_definitions}/calculator_steps.rb +4 -4
  27. data/examples/tcl/features/step_definitions/fib_steps.rb +1 -1
  28. data/{legacy_features → features/docs}/api/list_step_defs_as_json.feature +14 -14
  29. data/{legacy_features → features/docs}/api/run_cli_main_with_existing_runtime.feature +5 -10
  30. data/features/{backtraces.feature → docs/cli/backtraces.feature} +2 -2
  31. data/features/docs/cli/dry_run.feature +73 -0
  32. data/features/docs/cli/exclude_files.feature +18 -0
  33. data/features/docs/cli/execute_with_tag_filter.feature +117 -0
  34. data/features/docs/cli/randomize.feature +46 -0
  35. data/features/docs/cli/require.feature +27 -0
  36. data/features/docs/cli/run_scenarios_matching_name.feature +104 -0
  37. data/features/docs/cli/run_specific_scenarios.feature +75 -0
  38. data/features/docs/cli/showing_differences.feature +43 -0
  39. data/features/docs/cli/specifying_multiple_formatters.feature +44 -0
  40. data/features/docs/cli/strict_mode.feature +64 -0
  41. data/features/{nested_steps.feature → docs/defining_steps/nested_steps.feature} +52 -6
  42. data/features/{nested_steps_i18n.feature → docs/defining_steps/nested_steps_i18n.feature} +0 -2
  43. data/features/{step_definitions.feature → docs/defining_steps/one_line_step_definitions.feature} +3 -3
  44. data/features/docs/defining_steps/printing_messages.feature +148 -0
  45. data/features/docs/defining_steps/skip_scenario.feature +62 -0
  46. data/features/docs/defining_steps/snippets.feature +56 -0
  47. data/{legacy_features → features/docs/defining_steps}/table_diffing.feature +21 -16
  48. data/features/{transforms.feature → docs/defining_steps/transforms.feature} +2 -2
  49. data/{legacy_features/exception_in_after_block.feature → features/docs/exception_in_after_hook.feature} +25 -26
  50. data/{legacy_features/exception_in_after_step_block.feature → features/docs/exception_in_after_step_hook.feature} +22 -24
  51. data/features/docs/exception_in_around_hook.feature +80 -0
  52. data/{legacy_features/exception_in_before_block.feature → features/docs/exception_in_before_hook.feature} +18 -20
  53. data/features/docs/extending_cucumber/custom_filter.feature +29 -0
  54. data/features/docs/extending_cucumber/custom_formatter.feature +94 -0
  55. data/features/docs/formatters/debug_formatter.feature +47 -0
  56. data/features/{formatter_step_file_colon_line.feature → docs/formatters/formatter_step_file_colon_line.feature} +2 -4
  57. data/features/{html_formatter.feature → docs/formatters/html_formatter.feature} +10 -14
  58. data/features/docs/formatters/json_formatter.feature +760 -0
  59. data/features/docs/formatters/junit_formatter.feature +316 -0
  60. data/features/docs/formatters/pretty_formatter.feature +73 -0
  61. data/features/{progress_formatter.feature → docs/formatters/progress_formatter.feature} +1 -1
  62. data/features/docs/formatters/rerun_formatter.feature +136 -0
  63. data/features/docs/formatters/usage_formatter.feature +102 -0
  64. data/features/docs/getting_started.feature +27 -0
  65. data/features/{background.feature → docs/gherkin/background.feature} +149 -91
  66. data/features/{doc_strings.feature → docs/gherkin/doc_strings.feature} +1 -0
  67. data/features/docs/gherkin/expand_option_for_outlines.feature +46 -0
  68. data/features/docs/gherkin/language_from_header.feature +32 -0
  69. data/features/docs/gherkin/outlines.feature +158 -0
  70. data/features/docs/gherkin/unicode_table.feature +32 -0
  71. data/features/docs/gherkin/using_descriptions.feature +88 -0
  72. data/features/docs/gherkin/using_star_notation.feature +37 -0
  73. data/{legacy_features → features/docs}/post_configuration_hook.feature +17 -18
  74. data/{legacy_features → features/docs}/profiles.feature +30 -36
  75. data/{legacy_features → features/docs}/rake_task.feature +30 -41
  76. data/features/{raketask.feature → docs/raketask.feature} +6 -13
  77. data/{legacy_features/wire_protocol_erb.feature → features/docs/wire_protocol/erb_configuration.feature} +7 -8
  78. data/features/docs/wire_protocol/handle_unexpected_response.feature +30 -0
  79. data/features/docs/wire_protocol/invoke_message.feature +216 -0
  80. data/features/docs/wire_protocol/readme.md +26 -0
  81. data/features/docs/wire_protocol/snippets_message.feature +51 -0
  82. data/features/docs/wire_protocol/step_matches_message.feature +81 -0
  83. data/{legacy_features/wire_protocol_table_diffing.feature → features/docs/wire_protocol/table_diffing.feature} +19 -12
  84. data/{legacy_features/wire_protocol_tags.feature → features/docs/wire_protocol/tags.feature} +7 -7
  85. data/{legacy_features/wire_protocol_timeouts.feature → features/docs/wire_protocol/timeouts.feature} +7 -6
  86. data/{legacy_features → features/docs}/work_in_progress.feature +52 -54
  87. data/features/docs/writing_support_code/after_hooks.feature +80 -0
  88. data/{legacy_features → features/docs/writing_support_code}/around_hooks.feature +56 -28
  89. data/features/docs/writing_support_code/before_hook.feature +65 -0
  90. data/features/docs/writing_support_code/hook_order.feature +61 -0
  91. data/features/{load_path.feature → docs/writing_support_code/load_path.feature} +3 -0
  92. data/features/docs/writing_support_code/state.feature +32 -0
  93. data/features/docs/writing_support_code/tagged_hooks.feature +95 -0
  94. data/features/lib/step_definitions/aruba_steps.rb +22 -0
  95. data/features/lib/step_definitions/cucumber_steps.rb +50 -0
  96. data/features/{step_definitions → lib/step_definitions}/iso-8859-1_steps.rb +3 -15
  97. data/features/lib/step_definitions/json_steps.rb +7 -0
  98. data/features/lib/step_definitions/junit_steps.rb +13 -0
  99. data/features/lib/step_definitions/language_steps.rb +4 -5
  100. data/features/lib/step_definitions/profile_steps.rb +15 -0
  101. data/features/lib/step_definitions/ruby_steps.rb +3 -0
  102. data/features/lib/step_definitions/wire_steps.rb +58 -0
  103. data/features/lib/support/env.rb +21 -0
  104. data/{legacy_features → features/lib}/support/fake_wire_server.rb +10 -7
  105. data/features/{support → lib/support}/feature_factory.rb +1 -1
  106. data/features/lib/support/normalise_output.rb +33 -0
  107. data/gem_tasks/cov.rake +5 -0
  108. data/gem_tasks/cucumber.rake +3 -8
  109. data/gem_tasks/rspec.rake +0 -2
  110. data/lib/cucumber/ast.rb +8 -25
  111. data/lib/cucumber/cli/configuration.rb +33 -37
  112. data/lib/cucumber/cli/main.rb +14 -27
  113. data/lib/cucumber/cli/options.rb +22 -60
  114. data/lib/cucumber/cli/profile_loader.rb +1 -1
  115. data/lib/cucumber/configuration.rb +4 -0
  116. data/lib/cucumber/constantize.rb +7 -6
  117. data/lib/cucumber/core_ext/instance_exec.rb +7 -38
  118. data/lib/cucumber/core_ext/proc.rb +1 -1
  119. data/lib/cucumber/encoding.rb +5 -0
  120. data/lib/cucumber/errors.rb +21 -10
  121. data/lib/cucumber/file_specs.rb +37 -0
  122. data/lib/cucumber/filters/activate_steps.rb +33 -0
  123. data/lib/cucumber/filters/apply_after_hooks.rb +9 -0
  124. data/lib/cucumber/filters/apply_after_step_hooks.rb +12 -0
  125. data/lib/cucumber/filters/apply_around_hooks.rb +12 -0
  126. data/lib/cucumber/filters/apply_before_hooks.rb +9 -0
  127. data/lib/cucumber/filters/gated_receiver.rb +25 -0
  128. data/lib/cucumber/filters/prepare_world.rb +45 -0
  129. data/lib/cucumber/filters/quit.rb +28 -0
  130. data/lib/cucumber/filters/randomizer.rb +40 -0
  131. data/lib/cucumber/filters/tag_limits/test_case_index.rb +31 -0
  132. data/lib/cucumber/filters/tag_limits/verifier.rb +59 -0
  133. data/lib/cucumber/filters/tag_limits.rb +45 -0
  134. data/lib/cucumber/filters.rb +9 -0
  135. data/lib/cucumber/formatter/ansicolor.rb +0 -8
  136. data/lib/cucumber/formatter/console.rb +66 -36
  137. data/lib/cucumber/formatter/debug.rb +10 -8
  138. data/lib/cucumber/formatter/fanout.rb +27 -0
  139. data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +122 -12
  140. data/lib/cucumber/formatter/html.rb +67 -18
  141. data/lib/cucumber/formatter/ignore_missing_messages.rb +20 -0
  142. data/lib/cucumber/formatter/interceptor.rb +17 -3
  143. data/lib/cucumber/formatter/json.rb +1 -1
  144. data/lib/cucumber/formatter/junit.rb +105 -5
  145. data/lib/cucumber/formatter/legacy_api/adapter.rb +1060 -0
  146. data/lib/cucumber/formatter/legacy_api/ast.rb +376 -0
  147. data/lib/cucumber/formatter/legacy_api/results.rb +51 -0
  148. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +30 -0
  149. data/lib/cucumber/formatter/pretty.rb +16 -8
  150. data/lib/cucumber/formatter/progress.rb +10 -0
  151. data/lib/cucumber/formatter/rerun.rb +14 -71
  152. data/lib/cucumber/formatter/unicode.rb +8 -21
  153. data/lib/cucumber/formatter/usage.rb +7 -1
  154. data/lib/cucumber/hooks.rb +97 -0
  155. data/lib/cucumber/language_support/language_methods.rb +0 -54
  156. data/lib/cucumber/{ast/table.rb → multiline_argument/data_table.rb} +77 -84
  157. data/lib/cucumber/multiline_argument/doc_string.rb +10 -0
  158. data/lib/cucumber/multiline_argument.rb +74 -0
  159. data/lib/cucumber/platform.rb +21 -20
  160. data/lib/cucumber/project_initializer.rb +43 -0
  161. data/lib/cucumber/rake/task.rb +3 -54
  162. data/lib/cucumber/rb_support/rb_hook.rb +2 -2
  163. data/lib/cucumber/rb_support/rb_language.rb +4 -34
  164. data/lib/cucumber/rb_support/rb_step_definition.rb +11 -2
  165. data/lib/cucumber/rb_support/rb_transform.rb +3 -1
  166. data/lib/cucumber/rb_support/rb_world.rb +13 -20
  167. data/lib/cucumber/rb_support/snippet.rb +61 -20
  168. data/lib/cucumber/rspec/doubles.rb +9 -6
  169. data/lib/cucumber/running_test_case.rb +115 -0
  170. data/lib/cucumber/runtime/after_hooks.rb +24 -0
  171. data/lib/cucumber/runtime/before_hooks.rb +23 -0
  172. data/lib/cucumber/runtime/for_programming_languages.rb +14 -10
  173. data/lib/cucumber/runtime/step_hooks.rb +22 -0
  174. data/lib/cucumber/runtime/support_code.rb +78 -21
  175. data/lib/cucumber/runtime/user_interface.rb +4 -0
  176. data/lib/cucumber/runtime.rb +153 -98
  177. data/lib/cucumber/step_match.rb +27 -3
  178. data/lib/cucumber/term/ansicolor.rb +1 -9
  179. data/lib/cucumber/wire_support/wire_language.rb +23 -9
  180. data/lib/cucumber/wire_support/wire_packet.rb +1 -1
  181. data/lib/cucumber/wire_support/wire_protocol/requests.rb +13 -5
  182. data/lib/cucumber/wire_support/wire_step_definition.rb +1 -8
  183. data/lib/cucumber.rb +8 -6
  184. data/spec/cucumber/cli/configuration_spec.rb +165 -134
  185. data/spec/cucumber/cli/main_spec.rb +36 -99
  186. data/spec/cucumber/cli/options_spec.rb +238 -272
  187. data/spec/cucumber/cli/profile_loader_spec.rb +18 -7
  188. data/spec/cucumber/configuration_spec.rb +3 -3
  189. data/spec/cucumber/constantize_spec.rb +2 -1
  190. data/spec/cucumber/core_ext/instance_exec_spec.rb +4 -0
  191. data/spec/cucumber/core_ext/proc_spec.rb +32 -43
  192. data/spec/cucumber/file_specs_spec.rb +60 -0
  193. data/spec/cucumber/filters/activate_steps_spec.rb +57 -0
  194. data/spec/cucumber/filters/gated_receiver_spec.rb +47 -0
  195. data/spec/cucumber/filters/tag_limits/test_case_index_spec.rb +38 -0
  196. data/spec/cucumber/filters/tag_limits/verifier_spec.rb +57 -0
  197. data/spec/cucumber/filters/tag_limits_spec.rb +59 -0
  198. data/spec/cucumber/formatter/ansicolor_spec.rb +11 -10
  199. data/spec/cucumber/formatter/debug_spec.rb +64 -0
  200. data/spec/cucumber/formatter/duration_spec.rb +6 -6
  201. data/spec/cucumber/formatter/html_spec.rb +233 -39
  202. data/spec/cucumber/formatter/interceptor_spec.rb +38 -31
  203. data/spec/cucumber/formatter/junit_spec.rb +213 -151
  204. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +2090 -0
  205. data/spec/cucumber/formatter/pretty_spec.rb +481 -49
  206. data/spec/cucumber/formatter/progress_spec.rb +63 -16
  207. data/spec/cucumber/formatter/rerun_spec.rb +107 -0
  208. data/spec/cucumber/formatter/spec_helper.rb +32 -17
  209. data/spec/cucumber/hooks_spec.rb +30 -0
  210. data/spec/cucumber/{ast/table_spec.rb → multiline_argument/data_table_spec.rb} +128 -208
  211. data/spec/cucumber/project_initializer_spec.rb +87 -0
  212. data/spec/cucumber/rake/forked_spec.rb +13 -22
  213. data/spec/cucumber/rb_support/rb_language_spec.rb +78 -69
  214. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +90 -44
  215. data/spec/cucumber/rb_support/rb_transform_spec.rb +24 -3
  216. data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +6 -4
  217. data/spec/cucumber/rb_support/snippet_spec.rb +47 -38
  218. data/spec/cucumber/running_test_case_spec.rb +83 -0
  219. data/spec/cucumber/runtime/for_programming_languages_spec.rb +18 -13
  220. data/spec/cucumber/runtime/support_code_spec.rb +29 -29
  221. data/spec/cucumber/runtime_spec.rb +35 -34
  222. data/spec/cucumber/step_match_spec.rb +30 -20
  223. data/spec/cucumber/wire_support/configuration_spec.rb +8 -5
  224. data/spec/cucumber/wire_support/connection_spec.rb +12 -8
  225. data/spec/cucumber/wire_support/wire_exception_spec.rb +14 -8
  226. data/spec/cucumber/wire_support/wire_language_spec.rb +8 -9
  227. data/spec/cucumber/wire_support/wire_packet_spec.rb +17 -13
  228. data/spec/cucumber/world/pending_spec.rb +36 -36
  229. data/spec/simplecov_setup.rb +18 -0
  230. data/spec/spec_helper.rb +6 -13
  231. metadata +348 -350
  232. data/.gitattributes +0 -1
  233. data/.ruby-version +0 -1
  234. data/examples/python/README.textile +0 -8
  235. data/examples/python/Rakefile +0 -4
  236. data/examples/python/features/fibonacci.feature +0 -19
  237. data/examples/python/features/step_definitions/fib_steps.py +0 -11
  238. data/examples/python/lib/fib.py +0 -7
  239. data/examples/ramaze/README.textile +0 -7
  240. data/examples/ramaze/app.rb +0 -21
  241. data/examples/ramaze/features/add.feature +0 -11
  242. data/examples/ramaze/features/step_definitions/add_steps.rb +0 -15
  243. data/examples/ramaze/features/support/env.rb +0 -32
  244. data/examples/ramaze/layout/default.html.erb +0 -8
  245. data/examples/ramaze/view/index.html.erb +0 -5
  246. data/examples/ruby2python/README.textile +0 -8
  247. data/examples/ruby2python/Rakefile +0 -4
  248. data/examples/ruby2python/features/fibonacci.feature +0 -19
  249. data/examples/ruby2python/features/step_definitions/fib_steps.rb +0 -7
  250. data/examples/ruby2python/features/support/env.rb +0 -21
  251. data/examples/ruby2python/lib/fib.py +0 -7
  252. data/examples/v8/Rakefile +0 -6
  253. data/examples/v8/features/fibonacci.feature +0 -43
  254. data/examples/v8/features/step_definitions/fib_steps.js +0 -49
  255. data/examples/v8/features/support/env.js +0 -14
  256. data/examples/v8/lib/fibonacci.js +0 -19
  257. data/features/.cucumber/stepdefs.json +0 -627
  258. data/features/assertions.feature +0 -73
  259. data/features/autoformat_profile_output.feature +0 -23
  260. data/features/before_hook.feature +0 -43
  261. data/features/bootstrap.feature +0 -27
  262. data/features/custom_formatter.feature +0 -41
  263. data/features/drb_server_integration.feature +0 -63
  264. data/features/execute_with_tag_filter.feature +0 -63
  265. data/features/formatter_callbacks.feature +0 -189
  266. data/features/json_formatter.feature +0 -338
  267. data/features/parsing.feature +0 -18
  268. data/features/pretty_formatter.feature +0 -31
  269. data/features/rerun_formatter.feature +0 -35
  270. data/features/run_specific_scenarios.feature +0 -47
  271. data/features/stats_formatters.feature +0 -73
  272. data/features/step_definitions/cucumber-features/cucumber_ruby_mappings.rb +0 -197
  273. data/features/step_definitions/cucumber_steps.rb +0 -55
  274. data/features/step_definitions/drb_steps.rb +0 -3
  275. data/features/support/env.rb +0 -57
  276. data/features/tagged_hooks.feature +0 -59
  277. data/fixtures/json/features/background.feature +0 -7
  278. data/fixtures/json/features/embed.feature +0 -4
  279. data/fixtures/json/features/one_passing_one_failing.feature +0 -11
  280. data/fixtures/json/features/step_definitions/steps.rb +0 -32
  281. data/fixtures/json/features/tables.feature +0 -13
  282. data/fixtures/junit/features/one_passing_one_failing.feature +0 -8
  283. data/fixtures/junit/features/pending.feature +0 -7
  284. data/fixtures/junit/features/scenario_outline.feature +0 -9
  285. data/fixtures/junit/features/some_subdirectory/one_passing_one_failing.feature +0 -8
  286. data/fixtures/junit/features/step_definitions/steps.rb +0 -11
  287. data/fixtures/self_test/README.textile +0 -6
  288. data/fixtures/self_test/Rakefile +0 -6
  289. data/fixtures/self_test/features/call_undefined_step_from_step_def.feature +0 -7
  290. data/fixtures/self_test/features/failing_expectation.feature +0 -4
  291. data/fixtures/self_test/features/lots_of_undefined.feature +0 -8
  292. data/fixtures/self_test/features/multiline_name.feature +0 -27
  293. data/fixtures/self_test/features/outline_sample.feature +0 -15
  294. data/fixtures/self_test/features/sample.feature +0 -21
  295. data/fixtures/self_test/features/search_sample.feature +0 -32
  296. data/fixtures/self_test/features/step_definitions/sample_steps.rb +0 -84
  297. data/fixtures/self_test/features/support/bubble_256x256.png +0 -0
  298. data/fixtures/self_test/features/support/env.rb +0 -26
  299. data/fixtures/self_test/features/tags_sample.feature +0 -17
  300. data/fixtures/self_test/features/tons_of_cukes.feature +0 -52
  301. data/fixtures/self_test/features/undefined_multiline_args.feature +0 -12
  302. data/fixtures/self_test/list-of-features.txt +0 -1
  303. data/fixtures/steps_library/features/step_definitions/steps_lib1.rb +0 -8
  304. data/fixtures/steps_library/features/step_definitions/steps_lib2.rb +0 -8
  305. data/fixtures/tickets/Rakefile +0 -20
  306. data/fixtures/tickets/features/172.feature +0 -28
  307. data/fixtures/tickets/features/177/1.feature +0 -28
  308. data/fixtures/tickets/features/177/2.feature +0 -20
  309. data/fixtures/tickets/features/177/3.feature +0 -18
  310. data/fixtures/tickets/features/180.feature +0 -7
  311. data/fixtures/tickets/features/229/tagged_hooks.feature +0 -8
  312. data/fixtures/tickets/features/229/tagged_hooks.rb +0 -14
  313. data/fixtures/tickets/features/236.feature +0 -13
  314. data/fixtures/tickets/features/241.feature +0 -12
  315. data/fixtures/tickets/features/246.feature +0 -4
  316. data/fixtures/tickets/features/248.feature +0 -11
  317. data/fixtures/tickets/features/270/back.feature +0 -14
  318. data/fixtures/tickets/features/270/back.steps.rb +0 -14
  319. data/fixtures/tickets/features/272/hooks.feature +0 -26
  320. data/fixtures/tickets/features/272/hooks_steps.rb +0 -53
  321. data/fixtures/tickets/features/279/py_string_indent.feature +0 -25
  322. data/fixtures/tickets/features/279/py_string_indent.steps.rb +0 -12
  323. data/fixtures/tickets/features/279/wrong.feature_ +0 -11
  324. data/fixtures/tickets/features/301/filter_background_tagged_hooks.feature +0 -6
  325. data/fixtures/tickets/features/301/filter_background_tagged_hooks_steps.rb +0 -12
  326. data/fixtures/tickets/features/306/only_background.feature +0 -4
  327. data/fixtures/tickets/features/around_timeout.feature +0 -6
  328. data/fixtures/tickets/features/gherkin_67.feature +0 -12
  329. data/fixtures/tickets/features/gherkin_68.feature +0 -4
  330. data/fixtures/tickets/features/half_manual.feature +0 -11
  331. data/fixtures/tickets/features/lib/eatting_machine.rb +0 -18
  332. data/fixtures/tickets/features/lib/pantry.rb +0 -20
  333. data/fixtures/tickets/features/scenario_outline.feature +0 -95
  334. data/fixtures/tickets/features/step_definitons/246_steps.rb +0 -3
  335. data/fixtures/tickets/features/step_definitons/248_steps.rb +0 -15
  336. data/fixtures/tickets/features/step_definitons/around_timeout_steps.rb +0 -9
  337. data/fixtures/tickets/features/step_definitons/half_manual_steps.rb +0 -11
  338. data/fixtures/tickets/features/step_definitons/scenario_outline_steps.rb +0 -42
  339. data/fixtures/tickets/features/step_definitons/tickets_steps.rb +0 -88
  340. data/fixtures/tickets/features/table_diffing.feature +0 -13
  341. data/fixtures/tickets/features/tickets.feature +0 -28
  342. data/fixtures/tickets/features.html +0 -138
  343. data/gem_tasks/yard/default/layout/html/bubble_32x32.png +0 -0
  344. data/gem_tasks/yard/default/layout/html/footer.erb +0 -5
  345. data/gem_tasks/yard/default/layout/html/index.erb +0 -1
  346. data/gem_tasks/yard/default/layout/html/layout.erb +0 -25
  347. data/gem_tasks/yard/default/layout/html/logo.erb +0 -1
  348. data/gem_tasks/yard/default/layout/html/setup.rb +0 -4
  349. data/gem_tasks/yard.rake +0 -40
  350. data/legacy_features/README.md +0 -14
  351. data/legacy_features/announce.feature +0 -152
  352. data/legacy_features/bug_371.feature +0 -32
  353. data/legacy_features/bug_464.feature +0 -16
  354. data/legacy_features/bug_475.feature +0 -42
  355. data/legacy_features/bug_585_tab_indentation.feature +0 -22
  356. data/legacy_features/bug_600.feature +0 -73
  357. data/legacy_features/cucumber_cli.feature +0 -584
  358. data/legacy_features/cucumber_cli_outlines.feature +0 -117
  359. data/legacy_features/default_snippets.feature +0 -43
  360. data/legacy_features/diffing.feature +0 -25
  361. data/legacy_features/drb_server_integration.feature +0 -174
  362. data/legacy_features/exclude_files.feature +0 -20
  363. data/legacy_features/expand.feature +0 -60
  364. data/legacy_features/junit_formatter.feature +0 -214
  365. data/legacy_features/language_from_header.feature +0 -30
  366. data/legacy_features/listener_debugger_formatter.feature +0 -42
  367. data/legacy_features/multiline_names.feature +0 -44
  368. data/legacy_features/report_called_undefined_steps.feature +0 -35
  369. data/legacy_features/rerun_formatter.feature +0 -52
  370. data/legacy_features/simplest.feature +0 -11
  371. data/legacy_features/snippet.feature +0 -23
  372. data/legacy_features/snippets_when_using_star_keyword.feature +0 -38
  373. data/legacy_features/step_definitions/cucumber_steps.rb +0 -179
  374. data/legacy_features/step_definitions/extra_steps.rb +0 -2
  375. data/legacy_features/step_definitions/simplest_steps.rb +0 -3
  376. data/legacy_features/step_definitions/wire_steps.rb +0 -34
  377. data/legacy_features/support/env.rb +0 -161
  378. data/legacy_features/support/env.rb.simplest +0 -7
  379. data/legacy_features/table_mapping.feature +0 -34
  380. data/legacy_features/transform.feature +0 -245
  381. data/legacy_features/unicode_table.feature +0 -35
  382. data/legacy_features/wire_protocol.feature +0 -332
  383. data/lib/README.rdoc +0 -12
  384. data/lib/cucumber/ast/background.rb +0 -116
  385. data/lib/cucumber/ast/comment.rb +0 -31
  386. data/lib/cucumber/ast/doc_string.rb +0 -61
  387. data/lib/cucumber/ast/empty_background.rb +0 -33
  388. data/lib/cucumber/ast/examples.rb +0 -49
  389. data/lib/cucumber/ast/feature.rb +0 -99
  390. data/lib/cucumber/ast/features.rb +0 -38
  391. data/lib/cucumber/ast/has_steps.rb +0 -74
  392. data/lib/cucumber/ast/location.rb +0 -41
  393. data/lib/cucumber/ast/multiline_argument.rb +0 -30
  394. data/lib/cucumber/ast/names.rb +0 -13
  395. data/lib/cucumber/ast/outline_table.rb +0 -194
  396. data/lib/cucumber/ast/scenario.rb +0 -103
  397. data/lib/cucumber/ast/scenario_outline.rb +0 -146
  398. data/lib/cucumber/ast/step.rb +0 -122
  399. data/lib/cucumber/ast/step_collection.rb +0 -92
  400. data/lib/cucumber/ast/step_invocation.rb +0 -196
  401. data/lib/cucumber/ast/tags.rb +0 -28
  402. data/lib/cucumber/ast/tree_walker.rb +0 -191
  403. data/lib/cucumber/ast/visitor.rb +0 -11
  404. data/lib/cucumber/broadcaster.rb +0 -13
  405. data/lib/cucumber/cli/drb_client.rb +0 -43
  406. data/lib/cucumber/feature_file.rb +0 -94
  407. data/lib/cucumber/formatter/ordered_xml_markup.rb +0 -24
  408. data/lib/cucumber/js_support/js_dsl.js +0 -57
  409. data/lib/cucumber/js_support/js_language.rb +0 -185
  410. data/lib/cucumber/js_support/js_snippets.rb +0 -27
  411. data/lib/cucumber/parser/gherkin_builder.rb +0 -284
  412. data/lib/cucumber/parser.rb +0 -2
  413. data/lib/cucumber/py_support/py_dsl.py +0 -10
  414. data/lib/cucumber/py_support/py_language.py +0 -10
  415. data/lib/cucumber/py_support/py_language.rb +0 -80
  416. data/lib/cucumber/runtime/features_loader.rb +0 -62
  417. data/lib/cucumber/runtime/results.rb +0 -64
  418. data/lib/cucumber/step_mother.rb +0 -10
  419. data/spec/cucumber/ast/background_spec.rb +0 -122
  420. data/spec/cucumber/ast/doc_string_spec.rb +0 -40
  421. data/spec/cucumber/ast/feature_factory.rb +0 -72
  422. data/spec/cucumber/ast/feature_spec.rb +0 -63
  423. data/spec/cucumber/ast/features_spec.rb +0 -51
  424. data/spec/cucumber/ast/outline_table_spec.rb +0 -21
  425. data/spec/cucumber/ast/scenario_outline_spec.rb +0 -74
  426. data/spec/cucumber/ast/step_spec.rb +0 -68
  427. data/spec/cucumber/ast/tree_walker_spec.rb +0 -19
  428. data/spec/cucumber/broadcaster_spec.rb +0 -15
  429. data/spec/cucumber/cli/drb_client_spec.rb +0 -76
  430. data/spec/cucumber/rake/rcov_spec.rb +0 -71
  431. data/spec/cucumber/runtime/results_spec.rb +0 -81
  432. data/spec/cucumber/wire_support/wire_step_definition_spec.rb +0 -20
  433. /data/examples/i18n/ar/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  434. /data/examples/i18n/bg/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  435. /data/examples/i18n/ca/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  436. /data/examples/i18n/cs/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  437. /data/examples/i18n/da/features/{step_definitons → step_definitions}/lommeregner_steps.rb +0 -0
  438. /data/examples/i18n/de/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  439. /data/examples/i18n/en/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  440. /data/examples/i18n/eo/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  441. /data/examples/i18n/es/features/{step_definitons → step_definitions}/calculador_steps.rb +0 -0
  442. /data/examples/i18n/fi/features/{step_definitons → step_definitions}/laskin_steps.rb +0 -0
  443. /data/examples/i18n/he/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  444. /data/examples/i18n/hi/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  445. /data/examples/i18n/hu/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  446. /data/examples/i18n/id/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  447. /data/examples/i18n/it/features/{step_definitons → step_definitions}/calcolatrice_steps.rb +0 -0
  448. /data/examples/i18n/ja/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  449. /data/examples/i18n/ko/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  450. /data/examples/i18n/lt/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  451. /data/examples/i18n/lv/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  452. /data/examples/i18n/no/features/{step_definitons → step_definitions}/kalkulator_steps.rb +0 -0
  453. /data/examples/i18n/pl/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  454. /data/examples/i18n/ro/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  455. /data/examples/i18n/ru/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  456. /data/examples/i18n/sk/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  457. /data/examples/i18n/sr-Cyrl/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  458. /data/examples/i18n/sr-Latn/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  459. /data/examples/i18n/sv/features/{step_definitons → step_definitions}/kalkulator_steps.rb +0 -0
  460. /data/examples/i18n/tr/features/{step_definitons → step_definitions}/hesap_makinesi_adimlari.rb +0 -0
  461. /data/examples/i18n/uk/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  462. /data/examples/i18n/uz/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  463. /data/examples/i18n/zh-TW/features/{step_definitons → step_definitions}/calculator_steps.rb +0 -0
  464. /data/features/{nested_steps_with_second_arg.feature → docs/defining_steps/nested_steps_with_second_arg.feature} +0 -0
  465. /data/features/{iso-8859-1.feature → docs/iso-8859-1.feature} +0 -0
@@ -0,0 +1,31 @@
1
+ module Cucumber
2
+ module Filters
3
+ class TagLimits
4
+
5
+ class TestCaseIndex
6
+ def initialize
7
+ @index = Hash.new { |hash, key| hash[key] = [] }
8
+ end
9
+
10
+ def add(test_case)
11
+ test_case.tags.map(&:name).each do |tag_name|
12
+ index[tag_name] << test_case
13
+ end
14
+ end
15
+
16
+ def count_by_tag_name(tag_name)
17
+ index[tag_name].count
18
+ end
19
+
20
+ def locations_of_tag_name(tag_name)
21
+ index[tag_name].map(&:location)
22
+ end
23
+
24
+ private
25
+
26
+ attr_accessor :index
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,59 @@
1
+ module Cucumber
2
+ module Filters
3
+ class TagLimits
4
+
5
+ class Verifier
6
+ def initialize(tag_limits)
7
+ @tag_limits = tag_limits
8
+ end
9
+
10
+ def verify!(test_case_index)
11
+ breaches = collect_breaches(test_case_index)
12
+ raise TagLimitExceededError.new(*breaches) unless breaches.empty?
13
+ end
14
+
15
+ private
16
+
17
+ def collect_breaches(test_case_index)
18
+ tag_limits.reduce([]) do |breaches, (tag_name, limit)|
19
+ breaches.tap do |breaches|
20
+ if test_case_index.count_by_tag_name(tag_name) > limit
21
+ breaches << Breach.new(tag_name, limit, test_case_index.locations_of_tag_name(tag_name))
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ attr_reader :tag_limits
28
+
29
+ class Breach
30
+ INDENT = (" " * 2).freeze
31
+
32
+ def initialize(tag_name, limit, locations)
33
+ @tag_name = tag_name
34
+ @limit = limit
35
+ @locations = locations
36
+ end
37
+
38
+ def to_s
39
+ [
40
+ "#{tag_name} occurred #{tag_count} times, but the limit was set to #{limit}",
41
+ *locations.map(&:to_s)
42
+ ].join("\n#{INDENT}")
43
+ end
44
+
45
+ private
46
+
47
+ def tag_count
48
+ locations.count
49
+ end
50
+
51
+ attr_reader :tag_name
52
+ attr_reader :limit
53
+ attr_reader :locations
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,45 @@
1
+ require "cucumber/filters/gated_receiver"
2
+ require "cucumber/filters/tag_limits/test_case_index"
3
+ require "cucumber/filters/tag_limits/verifier"
4
+
5
+ module Cucumber
6
+ module Filters
7
+ class TagLimitExceededError < StandardError
8
+ def initialize(*limit_breaches)
9
+ super(limit_breaches.map(&:to_s).join("\n"))
10
+ end
11
+ end
12
+
13
+ class TagLimits
14
+ def initialize(tag_limits, receiver=nil)
15
+ @tag_limits = tag_limits
16
+ @gated_receiver = GatedReceiver.new(receiver)
17
+ @test_case_index = TestCaseIndex.new
18
+ @verifier = Verifier.new(@tag_limits)
19
+ end
20
+
21
+ def test_case(test_case)
22
+ gated_receiver.test_case(test_case)
23
+ test_case_index.add(test_case)
24
+ self
25
+ end
26
+
27
+ def done
28
+ verifier.verify!(test_case_index)
29
+ gated_receiver.done
30
+ self
31
+ end
32
+
33
+ def with_receiver(receiver)
34
+ self.class.new(@tag_limits, receiver)
35
+ end
36
+
37
+ private
38
+
39
+ attr_reader :gated_receiver
40
+ attr_reader :test_case_index
41
+ attr_reader :verifier
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,9 @@
1
+ require 'cucumber/filters/activate_steps'
2
+ require 'cucumber/filters/apply_after_step_hooks'
3
+ require 'cucumber/filters/apply_before_hooks'
4
+ require 'cucumber/filters/apply_after_hooks'
5
+ require 'cucumber/filters/apply_around_hooks'
6
+ require 'cucumber/filters/prepare_world'
7
+ require 'cucumber/filters/quit'
8
+ require 'cucumber/filters/randomizer'
9
+ require 'cucumber/filters/tag_limits'
@@ -1,14 +1,6 @@
1
1
  require 'cucumber/platform'
2
2
  require 'cucumber/term/ansicolor'
3
3
 
4
- if Cucumber::IRONRUBY
5
- begin
6
- require 'iron-term-ansicolor'
7
- rescue LoadError
8
- STDERR.puts %{*** WARNING: You must "igem install iron-term-ansicolor" to get coloured ouput in on IronRuby}
9
- end
10
- end
11
-
12
4
  if Cucumber::WINDOWS_MRI
13
5
  unless ENV['ANSICON']
14
6
  STDERR.puts %{*** WARNING: You must use ANSICON 1.31 or higher (https://github.com/adoxa/ansicon/) to get coloured output on Windows}
@@ -32,7 +32,7 @@ module Cucumber
32
32
 
33
33
  def format_step(keyword, step_match, status, source_indent)
34
34
  comment = if source_indent
35
- c = (' # ' + step_match.file_colon_line).indent(source_indent)
35
+ c = ('# ' + step_match.file_colon_line).indent(source_indent)
36
36
  format_string(c, :comment)
37
37
  else
38
38
  ''
@@ -77,17 +77,9 @@ module Cucumber
77
77
  end
78
78
 
79
79
  def print_stats(features, options)
80
- @failures = runtime.scenarios(:failed).select { |s| s.is_a?(Cucumber::Ast::Scenario) || s.is_a?(Cucumber::Ast::OutlineTable::ExampleRow) }
81
- @failures.collect! { |s| (s.is_a?(Cucumber::Ast::OutlineTable::ExampleRow)) ? s.scenario_outline : s }
82
-
83
- if !@failures.empty?
84
- @io.puts format_string("Failing Scenarios:", :failed)
85
- @failures.each do |failure|
86
- profiles_string = options.custom_profiles.empty? ? '' : (options.custom_profiles.map{|profile| "-p #{profile}" }).join(' ') + ' '
87
- source = options[:source] ? format_string(" # Scenario: " + failure.name, :comment) : ''
88
- @io.puts format_string("cucumber #{profiles_string}" + failure.file_colon_line, :failed) + source
89
- end
90
- @io.puts
80
+ failures = collect_failing_scenarios(runtime)
81
+ if !failures.empty?
82
+ print_failing_scenarios(failures, options.custom_profiles, options[:source])
91
83
  end
92
84
 
93
85
  @io.puts scenario_summary(runtime) {|status_count, status| format_string(status_count, status)}
@@ -95,11 +87,38 @@ module Cucumber
95
87
 
96
88
  @io.puts(format_duration(features.duration)) if features && features.duration
97
89
 
90
+ if runtime.configuration.randomize?
91
+ @io.puts
92
+ @io.puts "Randomized with seed #{runtime.configuration.seed}"
93
+ end
94
+
98
95
  @io.flush
99
96
  end
100
97
 
98
+ def collect_failing_scenarios(runtime)
99
+ # TODO: brittle - stop coupling to types
100
+ scenario_class = LegacyApi::Ast::Scenario
101
+ example_table_class = Core::Ast::ExamplesTable
102
+
103
+ runtime.scenarios(:failed).select do |s|
104
+ [scenario_class, example_table_class].include?(s.class)
105
+ end.map do |s|
106
+ s.is_a?(example_table_class)? s.scenario_outline : s
107
+ end
108
+ end
109
+
110
+ def print_failing_scenarios(failures, custom_profiles, given_source)
111
+ @io.puts format_string("Failing Scenarios:", :failed)
112
+ failures.each do |failure|
113
+ profiles_string = custom_profiles.empty? ? '' : (custom_profiles.map{|profile| "-p #{profile}" }).join(' ') + ' '
114
+ source = given_source ? format_string(" # " + failure.name, :comment) : ''
115
+ @io.puts format_string("cucumber #{profiles_string}" + failure.location, :failed) + source
116
+ end
117
+ @io.puts
118
+ end
119
+
101
120
  def print_exception(e, status, indent)
102
- message = "#{e.message} (#{e.class})"
121
+ message = "#{e.message} (#{e.class})".force_encoding("UTF-8")
103
122
  if ENV['CUCUMBER_TRUNCATE_OUTPUT']
104
123
  message = linebreaks(message, ENV['CUCUMBER_TRUNCATE_OUTPUT'].to_i)
105
124
  end
@@ -113,29 +132,29 @@ module Cucumber
113
132
  s.gsub(/.{1,#{max}}(?:\s|\Z)/){($& + 5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n")}.rstrip
114
133
  end
115
134
 
135
+ def collect_snippet_data(test_step, result)
136
+ # collect snippet data for undefined steps
137
+ unless hook?(test_step)
138
+ keyword = test_step.source.last.actual_keyword(@previous_step_keyword)
139
+ @previous_step_keyword = keyword
140
+ if result.undefined?
141
+ @snippets_input << Console::SnippetData.new(keyword, test_step.source.last)
142
+ end
143
+ end
144
+ end
145
+
116
146
  def print_snippets(options)
117
147
  return unless options[:snippets]
118
- undefined = runtime.steps(:undefined)
119
- return if undefined.empty?
148
+ return if runtime.steps(:undefined).empty?
120
149
 
121
- unknown_programming_language = runtime.unknown_programming_language?
122
- snippets = undefined.map do |step|
123
- step_name = Undefined === step.exception ? step.exception.step_name : step.name
124
- step_multiline_class = step.multiline_arg ? step.multiline_arg.class : nil
125
- snippet = @runtime.snippet_text(step.actual_keyword, step_name, step_multiline_class)
126
- snippet
127
- end.compact.uniq
150
+ snippets = @snippets_input.map do |data|
151
+ @runtime.snippet_text(data.actual_keyword, data.step.name, data.step.multiline_arg)
152
+ end.uniq
128
153
 
129
154
  text = "\nYou can implement step definitions for undefined steps with these snippets:\n\n"
130
155
  text += snippets.join("\n\n")
131
156
  @io.puts format_string(text, :undefined)
132
157
 
133
- if unknown_programming_language
134
- @io.puts format_string("\nIf you want snippets in a different programming language," +
135
- "\njust make sure a file with the appropriate file extension" +
136
- "\nexists where cucumber looks for step definitions.", :failed)
137
- end
138
-
139
158
  @io.puts
140
159
  @io.flush
141
160
  end
@@ -202,16 +221,27 @@ module Cucumber
202
221
  @io.puts "Using the #{profiles_sentence} profile#{'s' if profiles.size> 1}..."
203
222
  end
204
223
 
205
- private
224
+ private
206
225
 
207
- FORMATS = Hash.new{ |hash, format| hash[format] = method(format).to_proc }
226
+ FORMATS = Hash.new{ |hash, format| hash[format] = method(format).to_proc }
208
227
 
209
- def format_for(*keys)
210
- key = keys.join('_').to_sym
211
- fmt = FORMATS[key]
212
- raise "No format for #{key.inspect}: #{FORMATS.inspect}" if fmt.nil?
213
- fmt
214
- end
228
+ def format_for(*keys)
229
+ key = keys.join('_').to_sym
230
+ fmt = FORMATS[key]
231
+ raise "No format for #{key.inspect}: #{FORMATS.inspect}" if fmt.nil?
232
+ fmt
233
+ end
234
+
235
+ def hook?(test_step)
236
+ not test_step.source.last.respond_to?(:actual_keyword)
237
+ end
238
+
239
+ class SnippetData
240
+ attr_reader :actual_keyword, :step
241
+ def initialize(actual_keyword, step)
242
+ @actual_keyword, @step = actual_keyword, step
243
+ end
244
+ end
215
245
 
216
246
  end
217
247
  end
@@ -6,7 +6,11 @@ module Cucumber
6
6
  class Debug
7
7
  def initialize(runtime, io, options)
8
8
  @io = io
9
- @indent = 0
9
+ end
10
+
11
+ def log(message)
12
+ return unless ENV['DEBUG']
13
+ @io.puts "* #{message}"
10
14
  end
11
15
 
12
16
  def respond_to?(*args)
@@ -14,19 +18,17 @@ module Cucumber
14
18
  end
15
19
 
16
20
  def method_missing(name, *args)
17
- @indent -= 2 if name.to_s =~ /^after/
18
21
  print(name)
19
- @indent += 2 if name.to_s =~ /^before/
22
+ end
23
+
24
+ def puts(*args)
25
+ print("puts")
20
26
  end
21
27
 
22
28
  private
23
29
 
24
30
  def print(text)
25
- @io.puts "#{indent}#{text}"
26
- end
27
-
28
- def indent
29
- (' ' * @indent)
31
+ @io.puts text
30
32
  end
31
33
  end
32
34
  end
@@ -0,0 +1,27 @@
1
+ module Cucumber
2
+ module Formatter
3
+
4
+ # Forwards any messages sent to this object to all recipients
5
+ # that respond to that message.
6
+ class Fanout < BasicObject
7
+ attr_reader :recipients
8
+ private :recipients
9
+
10
+ def initialize(recipients)
11
+ @recipients = recipients
12
+ end
13
+
14
+ def method_missing(message, *args)
15
+ recipients.each do |recipient|
16
+ recipient.send(message, *args) if recipient.respond_to?(message)
17
+ end
18
+ end
19
+
20
+ def respond_to_missing?(name, include_private = false)
21
+ recipients.any? { |recipient| recipient.respond_to?(name, include_private) }
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+ end
@@ -6,9 +6,12 @@ module Cucumber
6
6
  # Adapts Cucumber formatter events to Gherkin formatter events
7
7
  # This class will disappear when Cucumber is based on Gherkin's model.
8
8
  class GherkinFormatterAdapter
9
- def initialize(gherkin_formatter, print_empty_match)
9
+ def initialize(gherkin_formatter, print_empty_match, options)
10
10
  @gf = gherkin_formatter
11
11
  @print_empty_match = print_empty_match
12
+ @options = options
13
+ @delayed_messages = []
14
+ @delayed_embeddings = []
12
15
  end
13
16
 
14
17
  def before_feature(feature)
@@ -23,19 +26,59 @@ module Cucumber
23
26
 
24
27
  def before_feature_element(feature_element)
25
28
  case(feature_element)
26
- when Ast::Scenario
29
+ when Core::Ast::Scenario
27
30
  @outline = false
28
31
  @gf.scenario(feature_element.gherkin_statement)
29
- when Ast::ScenarioOutline
32
+ when Core::Ast::ScenarioOutline
30
33
  @outline = true
31
- @gf.scenario_outline(feature_element.gherkin_statement)
34
+ if @options[:expand]
35
+ @in_instantiated_scenario = false
36
+ @current_scenario_hash = to_hash(feature_element.gherkin_statement)
37
+ else
38
+ @gf.scenario_outline(feature_element.gherkin_statement)
39
+ end
32
40
  else
33
41
  raise "Bad type: #{feature_element.class}"
34
42
  end
35
43
  end
36
44
 
45
+ def before_test_case(test_case)
46
+ @delay_output = true
47
+ end
48
+
49
+ def scenario_name(keyword, name, file_colon_line, source_indent)
50
+ if @outline and @options[:expand]
51
+ return if not @in_instantiated_scenario
52
+ if @new_example_table
53
+ @example_row = 1
54
+ @new_example_table = false
55
+ else
56
+ @example_row += 1
57
+ end
58
+ example_row_hash = @current_example_rows[@example_row].to_hash
59
+ scenario = Gherkin::Formatter::Model::Scenario.new(
60
+ @current_scenario_hash['comments'],
61
+ @current_scenario_hash['tags'],
62
+ @current_scenario_hash['keyword'],
63
+ @current_scenario_hash['name'],
64
+ @current_scenario_hash['description'],
65
+ example_row_hash['line'],
66
+ example_row_hash['id'])
67
+ @gf.scenario(scenario)
68
+ end
69
+ end
70
+
37
71
  def before_step(step)
38
- @gf.step(step.gherkin_statement)
72
+ unless @outline and @options[:expand]
73
+ @gf.step(step.gherkin_statement)
74
+ pass_delayed_output
75
+ @delay_output = false
76
+ else
77
+ if @in_instantiated_scenario
78
+ @current_step_hash = to_hash(step.gherkin_statement)
79
+ @delay_output = true
80
+ end
81
+ end
39
82
  if @print_empty_match
40
83
  if(@outline)
41
84
  match = Gherkin::Formatter::Model::Match.new(step.gherkin_statement.outline_args, nil)
@@ -44,7 +87,6 @@ module Cucumber
44
87
  end
45
88
  @gf.match(match)
46
89
  end
47
- @step_time = Time.now
48
90
  end
49
91
 
50
92
  def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
@@ -55,23 +97,53 @@ module Cucumber
55
97
  # Trick the formatter to believe that's what was printed previously so we get arg highlights on #result
56
98
  @gf.instance_variable_set('@match', match)
57
99
  else
58
- @gf.match(match)
100
+ unless @outline and @options[:expand]
101
+ @gf.match(match)
102
+ end
59
103
  end
60
104
 
61
105
  error_message = exception ? "#{exception.message} (#{exception.class})\n#{exception.backtrace.join("\n")}" : nil
62
106
  unless @outline
63
107
  @gf.result(Gherkin::Formatter::Model::Result.new(status, nil, error_message))
108
+ else
109
+ if @options[:expand] and @in_instantiated_scenario
110
+ @current_match = match
111
+ @current_result = Gherkin::Formatter::Model::Result.new(status, nil, error_message)
112
+ end
113
+ end
114
+ end
115
+
116
+ def step_name(keyword, step_match, status, source_indent, background, file_colon_line)
117
+ if @outline and @options[:expand] and @in_instantiated_scenario
118
+ @gf.step(Gherkin::Formatter::Model::Step.new(
119
+ @current_step_hash['comments'],
120
+ @current_step_hash['keyword'],
121
+ step_match.format_args(),
122
+ file_colon_line.split(':')[1].to_i,
123
+ @current_step_hash['rows'],
124
+ @current_step_hash['doc_string']))
125
+ pass_delayed_output
126
+ @delay_output = false
127
+ @gf.match(@current_match)
128
+ @gf.result(@current_result)
64
129
  end
65
130
  end
66
131
 
67
132
  def before_examples(examples)
68
- @gf.examples(examples.gherkin_statement)
133
+ unless @options[:expand]
134
+ @gf.examples(examples.gherkin_statement)
135
+ else
136
+ @in_instantiated_scenario = true
137
+ @new_example_table = true
138
+ @current_example_rows = to_hash(examples.gherkin_statement)['rows']
139
+ end
69
140
  end
70
141
 
71
142
  #used for capturing duration
72
143
  def after_step(step)
73
- step_finish = (Time.now - @step_time)
74
- @gf.append_duration(step_finish)
144
+ unless @outline and @options[:expand] and not @in_instantiated_scenario
145
+ step.duration.tap { |duration| @gf.append_duration(duration.nanoseconds / 10 ** 9.0) }
146
+ end
75
147
  end
76
148
 
77
149
  def after_feature(feature)
@@ -83,11 +155,49 @@ module Cucumber
83
155
  end
84
156
 
85
157
  def embed(file, mime_type, label)
86
- data = File.open(file, 'rb') { |f| f.read }
158
+ if File.file?(file)
159
+ data = File.open(file, 'rb') { |f| f.read }
160
+ else
161
+ if mime_type =~ /;base64$/
162
+ mime_type = mime_type[0..-8]
163
+ data = Base64.decode64(file)
164
+ else
165
+ data = file
166
+ end
167
+ end
87
168
  if defined?(JRUBY_VERSION)
88
169
  data = data.to_java_bytes
89
170
  end
90
- @gf.embedding(mime_type, data)
171
+ unless @delay_output
172
+ @gf.embedding(mime_type, data)
173
+ else
174
+ @delayed_embeddings.push [mime_type, data]
175
+ end
176
+ end
177
+
178
+ def puts(message)
179
+ unless @delay_output
180
+ @gf.write(message)
181
+ else
182
+ @delayed_messages.push message
183
+ end
184
+ end
185
+
186
+ private
187
+
188
+ def to_hash(gherkin_statement)
189
+ if defined?(JRUBY_VERSION)
190
+ gherkin_statement.toMap()
191
+ else
192
+ gherkin_statement.to_hash
193
+ end
194
+ end
195
+
196
+ def pass_delayed_output
197
+ @delayed_messages.each { |message| @gf.write(message) }
198
+ @delayed_embeddings.each { |embed_data| @gf.embedding(embed_data[0], embed_data[1]) }
199
+ @delayed_messages = []
200
+ @delayed_embeddings = []
91
201
  end
92
202
  end
93
203
  end