cucumber 2.99.0 → 3.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 (395) hide show
  1. checksums.yaml +4 -4
  2. data/.cucumberproignore +6 -0
  3. data/.gitattributes +32 -0
  4. data/.github/ISSUE_TEMPLATE.md +1 -1
  5. data/.github/PULL_REQUEST_TEMPLATE.md +1 -0
  6. data/.rubocop.yml +13 -0
  7. data/.rubocop_todo.yml +991 -0
  8. data/.travis.yml +56 -10
  9. data/{History.md → CHANGELOG.md} +166 -32
  10. data/CONTRIBUTING.md +21 -1
  11. data/Gemfile +18 -5
  12. data/README.md +13 -4
  13. data/Rakefile +12 -2
  14. data/appveyor.yml +27 -0
  15. data/bin/cucumber +2 -1
  16. data/cucumber.gemspec +15 -10
  17. data/cucumber.yml +10 -11
  18. data/examples/i18n/Rakefile +1 -1
  19. data/examples/i18n/ar/features/step_definitions/calculator_steps.rb +8 -3
  20. data/examples/i18n/ar/lib/calculator.rb +2 -2
  21. data/examples/i18n/bg/features/step_definitions/calculator_steps.rb +6 -6
  22. data/examples/i18n/bg/features/support/env.rb +6 -1
  23. data/examples/i18n/bg/lib/calculator.rb +2 -1
  24. data/examples/i18n/ca/features/step_definitions/calculator_steps.rb +10 -5
  25. data/examples/i18n/ca/lib/calculadora.rb +2 -2
  26. data/examples/i18n/cs/features/step_definitions/calculator_steps.rb +10 -5
  27. data/examples/i18n/cs/lib/calculator.rb +3 -3
  28. data/examples/i18n/da/features/step_definitions/lommeregner_steps.rb +10 -5
  29. data/examples/i18n/da/lib/lommeregner.rb +2 -2
  30. data/examples/i18n/de/features/step_definitions/calculator_steps.rb +10 -5
  31. data/examples/i18n/de/lib/calculator.rb +2 -2
  32. data/examples/i18n/el/features/step_definitions/calculator_steps.rb +10 -5
  33. data/examples/i18n/el/lib/calculator.rb +2 -2
  34. data/examples/i18n/en/features/step_definitions/calculator_steps.rb +9 -4
  35. data/examples/i18n/en/lib/calculator.rb +2 -2
  36. data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +4 -4
  37. data/examples/i18n/en-lol/features/support/env.rb +6 -2
  38. data/examples/i18n/en-lol/lib/basket.rb +2 -2
  39. data/examples/i18n/en-lol/lib/belly.rb +2 -2
  40. data/examples/i18n/eo/features/step_definitions/calculator_steps.rb +9 -4
  41. data/examples/i18n/eo/lib/calculator.rb +2 -2
  42. data/examples/i18n/es/features/step_definitions/calculador_steps.rb +10 -5
  43. data/examples/i18n/es/lib/calculador.rb +2 -2
  44. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +10 -5
  45. data/examples/i18n/et/lib/kalkulaator.rb +3 -3
  46. data/examples/i18n/fi/features/step_definitions/laskin_steps.rb +9 -4
  47. data/examples/i18n/fi/lib/laskin.rb +1 -1
  48. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +8 -8
  49. data/examples/i18n/fr/features/support/env.rb +7 -2
  50. data/examples/i18n/fr/lib/calculatrice.rb +2 -2
  51. data/examples/i18n/he/features/step_definitions/calculator_steps.rb +10 -5
  52. data/examples/i18n/he/lib/calculator.rb +1 -1
  53. data/examples/i18n/hi/features/step_definitions/calculator_steps.rb +9 -4
  54. data/examples/i18n/hi/lib/calculator.rb +1 -1
  55. data/examples/i18n/ht/features/step_definitions/kalkilatris_steps.rb +9 -5
  56. data/examples/i18n/ht/lib/kalkilatris.rb +2 -2
  57. data/examples/i18n/hu/features/step_definitions/calculator_steps.rb +10 -5
  58. data/examples/i18n/hu/lib/calculator.rb +1 -1
  59. data/examples/i18n/id/features/step_definitions/calculator_steps.rb +10 -5
  60. data/examples/i18n/id/lib/calculator.rb +2 -2
  61. data/examples/i18n/it/features/step_definitions/calcolatrice_steps.rb +10 -5
  62. data/examples/i18n/it/lib/calcolatrice.rb +3 -3
  63. data/examples/i18n/ja/features/step_definitions/calculator_steps.rb +3 -3
  64. data/examples/i18n/ja/features/support/env.rb +7 -2
  65. data/examples/i18n/ja/lib/calculator.rb +2 -2
  66. data/examples/i18n/ko/features/step_definitions/calculator_steps.rb +10 -5
  67. data/examples/i18n/ko/lib/calculator.rb +2 -2
  68. data/examples/i18n/lt/features/step_definitions/calculator_steps.rb +10 -5
  69. data/examples/i18n/lt/lib/calculator.rb +2 -2
  70. data/examples/i18n/lv/features/step_definitions/calculator_steps.rb +10 -5
  71. data/examples/i18n/lv/lib/calculator.rb +2 -2
  72. data/examples/i18n/no/features/step_definitions/kalkulator_steps.rb +3 -3
  73. data/examples/i18n/no/features/support/env.rb +7 -2
  74. data/examples/i18n/no/lib/kalkulator.rb +2 -2
  75. data/examples/i18n/pl/features/step_definitions/calculator_steps.rb +10 -5
  76. data/examples/i18n/pl/features/support/env.rb +6 -1
  77. data/examples/i18n/pl/lib/calculator.rb +2 -2
  78. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +3 -3
  79. data/examples/i18n/pt/features/support/env.rb +7 -2
  80. data/examples/i18n/pt/lib/calculadora.rb +1 -1
  81. data/examples/i18n/ro/features/step_definitions/calculator_steps.rb +11 -6
  82. data/examples/i18n/ro/lib/calculator.rb +1 -1
  83. data/examples/i18n/ru/features/step_definitions/calculator_steps.rb +5 -5
  84. data/examples/i18n/ru/features/support/env.rb +6 -1
  85. data/examples/i18n/ru/lib/calculator.rb +2 -1
  86. data/examples/i18n/sk/features/step_definitions/calculator_steps.rb +10 -5
  87. data/examples/i18n/sk/lib/calculator.rb +2 -2
  88. data/examples/i18n/sr-Cyrl/features/step_definitions/calculator_steps.rb +3 -3
  89. data/examples/i18n/sr-Cyrl/features/support/env.rb +7 -2
  90. data/examples/i18n/sr-Cyrl/lib/calculator.rb +2 -2
  91. data/examples/i18n/sr-Latn/features/step_definitions/calculator_steps.rb +10 -5
  92. data/examples/i18n/sr-Latn/lib/calculator.rb +2 -2
  93. data/examples/i18n/sv/features/step_definitions/kalkulator_steps.rb +9 -4
  94. data/examples/i18n/sv/lib/kalkulator.rb +2 -2
  95. data/examples/i18n/tr/features/step_definitions/hesap_makinesi_adimlari.rb +10 -5
  96. data/examples/i18n/tr/lib/hesap_makinesi.rb +2 -2
  97. data/examples/i18n/uk/features/step_definitions/calculator_steps.rb +4 -4
  98. data/examples/i18n/uk/features/support/env.rb +6 -1
  99. data/examples/i18n/uk/lib/calculator.rb +2 -1
  100. data/examples/i18n/uz/features/step_definitions/calculator_steps.rb +4 -4
  101. data/examples/i18n/uz/features/support/env.rb +6 -1
  102. data/examples/i18n/uz/lib/calculator.rb +2 -1
  103. data/examples/i18n/zh-CN/features/step_definitions/calculator_steps.rb +11 -6
  104. data/examples/i18n/zh-CN/lib/calculator.rb +2 -2
  105. data/examples/i18n/zh-TW/features/step_definitions/calculator_steps.rb +10 -5
  106. data/examples/i18n/zh-TW/lib/calculator.rb +2 -2
  107. data/examples/rspec_doubles/features/step_definitions/calvin_steps.rb +3 -3
  108. data/examples/sinatra/features/step_definitions/add_steps.rb +4 -4
  109. data/examples/sinatra/features/support/env.rb +6 -1
  110. data/examples/tcl/features/step_definitions/fib_steps.rb +2 -2
  111. data/examples/tcl/features/support/env.rb +2 -1
  112. data/examples/test_unit/features/step_definitions/test_unit_steps.rb +4 -4
  113. data/examples/watir/features/step_definitions/search_steps.rb +6 -5
  114. data/examples/watir/features/support/env.rb +5 -1
  115. data/examples/watir/features/support/screenshots.rb +5 -5
  116. data/features/docs/api/list_step_defs_as_json.feature +21 -7
  117. data/features/docs/api/listen_for_events.feature +9 -8
  118. data/features/docs/api/run_cli_main_with_existing_runtime.feature +1 -0
  119. data/features/docs/cli/dry_run.feature +3 -0
  120. data/features/docs/cli/execute_with_tag_filter.feature +8 -6
  121. data/features/docs/cli/fail_fast.feature +2 -0
  122. data/features/docs/cli/help.feature +8 -0
  123. data/features/docs/{gherkin/language_help.feature → cli/i18n.feature} +6 -6
  124. data/features/docs/cli/randomize.feature +2 -2
  125. data/features/docs/cli/retry_failing_tests.feature +75 -15
  126. data/features/docs/cli/run_scenarios_matching_name.feature +1 -0
  127. data/features/docs/cli/specifying_multiple_formatters.feature +3 -0
  128. data/features/docs/cli/strict_mode.feature +6 -0
  129. data/features/docs/defining_steps/ambiguous_steps.feature +89 -0
  130. data/features/docs/defining_steps/nested_steps.feature +5 -1
  131. data/features/docs/defining_steps/nested_steps_i18n.feature +3 -0
  132. data/features/docs/defining_steps/nested_steps_with_second_arg.feature +2 -0
  133. data/features/docs/defining_steps/printing_messages.feature +1 -2
  134. data/features/docs/defining_steps/skip_scenario.feature +1 -34
  135. data/features/docs/defining_steps/snippets.feature +18 -18
  136. data/features/docs/events/gherkin_source_read_event.feature +43 -0
  137. data/features/docs/events/step_activated_event.feature +36 -0
  138. data/features/docs/events/step_definition_registered_event.feature +29 -0
  139. data/features/docs/events/test_case_finished_event.feature +35 -0
  140. data/features/docs/events/test_case_started_event.feature +54 -0
  141. data/features/docs/events/test_run_finished_event.feature +40 -0
  142. data/features/docs/events/test_run_started_event.feature +41 -0
  143. data/features/docs/events/test_step_finished_event.feature +47 -0
  144. data/features/docs/events/test_step_started_event.feature +43 -0
  145. data/features/docs/exception_in_after_hook.feature +3 -2
  146. data/features/docs/exception_in_after_step_hook.feature +2 -0
  147. data/features/docs/exception_in_around_hook.feature +2 -0
  148. data/features/docs/exception_in_before_hook.feature +3 -1
  149. data/features/docs/extending_cucumber/custom_formatter.feature +12 -48
  150. data/features/docs/formatters/json_formatter.feature +4 -4
  151. data/features/docs/formatters/junit_formatter.feature +7 -6
  152. data/features/docs/formatters/pretty_formatter.feature +1 -0
  153. data/features/docs/formatters/progress_formatter.feature +1 -0
  154. data/features/docs/formatters/rerun_formatter.feature +2 -0
  155. data/features/docs/formatters/summary_formatter.feature +35 -0
  156. data/features/docs/formatters/usage_formatter.feature +3 -0
  157. data/features/docs/getting_started.feature +2 -1
  158. data/features/docs/gherkin/background.feature +5 -5
  159. data/features/docs/gherkin/doc_strings.feature +2 -0
  160. data/features/docs/gherkin/expand_option_for_outlines.feature +1 -0
  161. data/features/docs/gherkin/outlines.feature +6 -4
  162. data/features/docs/gherkin/unicode_table.feature +2 -1
  163. data/features/docs/gherkin/using_descriptions.feature +1 -0
  164. data/features/docs/gherkin/using_star_notation.feature +1 -1
  165. data/features/docs/post_configuration_hook.feature +1 -17
  166. data/features/docs/rake_task.feature +5 -0
  167. data/features/docs/raketask.feature +3 -1
  168. data/features/docs/work_in_progress.feature +5 -2
  169. data/features/docs/writing_support_code/after_step_hooks.feature +3 -1
  170. data/features/docs/writing_support_code/around_hooks.feature +6 -0
  171. data/features/docs/writing_support_code/before_hook.feature +1 -0
  172. data/features/docs/writing_support_code/hook_order.feature +3 -1
  173. data/features/docs/writing_support_code/parameter_types.feature +53 -0
  174. data/features/docs/writing_support_code/tagged_hooks.feature +1 -1
  175. data/features/docs/writing_support_code/world.feature +129 -0
  176. data/features/lib/step_definitions/aruba_steps.rb +5 -10
  177. data/features/lib/step_definitions/cli_steps.rb +4 -0
  178. data/features/lib/step_definitions/cucumber_steps.rb +9 -12
  179. data/features/lib/step_definitions/iso-8859-1_steps.rb +9 -5
  180. data/features/lib/step_definitions/json_steps.rb +2 -1
  181. data/features/lib/step_definitions/junit_steps.rb +2 -1
  182. data/features/lib/step_definitions/language_steps.rb +3 -2
  183. data/features/lib/step_definitions/profile_steps.rb +7 -6
  184. data/features/lib/step_definitions/retry_steps.rb +33 -13
  185. data/features/lib/step_definitions/ruby_steps.rb +2 -1
  186. data/features/lib/support/env.rb +3 -2
  187. data/features/lib/support/fake_wire_server.rb +17 -3
  188. data/features/lib/support/feature_factory.rb +2 -1
  189. data/features/lib/support/normalise_output.rb +14 -12
  190. data/features/lib/support/parameter_types.rb +5 -0
  191. data/gem_tasks/contributors.rake +10 -6
  192. data/gem_tasks/cov.rake +1 -0
  193. data/gem_tasks/downloads.rb +1 -0
  194. data/gem_tasks/environment.rake +2 -5
  195. data/gem_tasks/examples.rake +3 -2
  196. data/gem_tasks/fix_cr_lf.rake +19 -7
  197. data/gem_tasks/flog.rake +4 -3
  198. data/gem_tasks/rspec.rake +2 -1
  199. data/gem_tasks/sass.rake +2 -1
  200. data/lib/autotest/cucumber.rb +1 -0
  201. data/lib/autotest/cucumber_mixin.rb +17 -16
  202. data/lib/autotest/cucumber_rails.rb +1 -0
  203. data/lib/autotest/cucumber_rails_rspec.rb +1 -0
  204. data/lib/autotest/cucumber_rails_rspec2.rb +1 -0
  205. data/lib/autotest/cucumber_rspec.rb +1 -0
  206. data/lib/autotest/cucumber_rspec2.rb +1 -0
  207. data/lib/autotest/discover.rb +3 -2
  208. data/lib/cucumber/cli/configuration.rb +12 -21
  209. data/lib/cucumber/cli/main.rb +8 -7
  210. data/lib/cucumber/cli/options.rb +341 -217
  211. data/lib/cucumber/cli/profile_loader.rb +26 -21
  212. data/lib/cucumber/cli/rerun_file.rb +1 -0
  213. data/lib/cucumber/configuration.rb +54 -37
  214. data/lib/cucumber/constantize.rb +2 -1
  215. data/lib/cucumber/core_ext/string.rb +2 -1
  216. data/lib/cucumber/deprecate.rb +4 -3
  217. data/lib/cucumber/encoding.rb +1 -0
  218. data/lib/cucumber/errors.rb +3 -1
  219. data/lib/cucumber/events/gherkin_source_read.rb +17 -0
  220. data/lib/cucumber/events/{step_match.rb → step_activated.rb} +5 -2
  221. data/lib/cucumber/events/step_definition_registered.rb +24 -0
  222. data/lib/cucumber/events/test_case_finished.rb +18 -0
  223. data/lib/cucumber/events/test_case_started.rb +15 -0
  224. data/lib/cucumber/events/test_run_finished.rb +12 -0
  225. data/lib/cucumber/events/test_run_started.rb +16 -0
  226. data/lib/cucumber/events/test_step_finished.rb +20 -0
  227. data/lib/cucumber/events/test_step_started.rb +17 -0
  228. data/lib/cucumber/events.rb +23 -3
  229. data/lib/cucumber/file_specs.rb +1 -0
  230. data/lib/cucumber/filters/activate_steps.rb +8 -3
  231. data/lib/cucumber/filters/apply_after_hooks.rb +1 -0
  232. data/lib/cucumber/filters/apply_after_step_hooks.rb +1 -0
  233. data/lib/cucumber/filters/apply_around_hooks.rb +1 -0
  234. data/lib/cucumber/filters/apply_before_hooks.rb +1 -0
  235. data/lib/cucumber/filters/broadcast_test_run_started_event.rb +27 -0
  236. data/lib/cucumber/filters/gated_receiver.rb +1 -0
  237. data/lib/cucumber/filters/prepare_world.rb +1 -0
  238. data/lib/cucumber/filters/quit.rb +1 -0
  239. data/lib/cucumber/filters/randomizer.rb +1 -0
  240. data/lib/cucumber/filters/retry.rb +4 -4
  241. data/lib/cucumber/filters/tag_limits/test_case_index.rb +1 -0
  242. data/lib/cucumber/filters/tag_limits/verifier.rb +2 -1
  243. data/lib/cucumber/filters/tag_limits.rb +4 -3
  244. data/lib/cucumber/filters.rb +3 -0
  245. data/lib/cucumber/formatter/ansicolor.rb +9 -11
  246. data/lib/cucumber/formatter/backtrace_filter.rb +21 -8
  247. data/lib/cucumber/formatter/console.rb +72 -66
  248. data/lib/cucumber/formatter/console_counts.rb +44 -0
  249. data/lib/cucumber/formatter/console_issues.rb +58 -0
  250. data/lib/cucumber/formatter/duration.rb +2 -1
  251. data/lib/cucumber/formatter/duration_extractor.rb +1 -0
  252. data/lib/cucumber/formatter/fail_fast.rb +4 -2
  253. data/lib/cucumber/formatter/fanout.rb +1 -0
  254. data/lib/cucumber/formatter/hook_query_visitor.rb +1 -0
  255. data/lib/cucumber/formatter/html.rb +175 -249
  256. data/lib/cucumber/formatter/html_builder.rb +120 -0
  257. data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -0
  258. data/lib/cucumber/formatter/inline-js.js +30 -0
  259. data/lib/cucumber/formatter/interceptor.rb +3 -2
  260. data/lib/cucumber/formatter/io.rb +2 -1
  261. data/lib/cucumber/formatter/json.rb +33 -30
  262. data/lib/cucumber/formatter/json_pretty.rb +1 -0
  263. data/lib/cucumber/formatter/junit.rb +26 -24
  264. data/lib/cucumber/formatter/legacy_api/adapter.rb +81 -69
  265. data/lib/cucumber/formatter/legacy_api/ast.rb +27 -22
  266. data/lib/cucumber/formatter/legacy_api/results.rb +7 -8
  267. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +1 -0
  268. data/lib/cucumber/formatter/pretty.rb +24 -18
  269. data/lib/cucumber/formatter/progress.rb +55 -13
  270. data/lib/cucumber/formatter/rerun.rb +15 -18
  271. data/lib/cucumber/formatter/stepdefs.rb +1 -0
  272. data/lib/cucumber/formatter/steps.rb +2 -1
  273. data/lib/cucumber/formatter/summary.rb +43 -20
  274. data/lib/cucumber/formatter/unicode.rb +2 -1
  275. data/lib/cucumber/formatter/usage.rb +33 -28
  276. data/lib/cucumber/gherkin/data_table_parser.rb +1 -0
  277. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +2 -1
  278. data/lib/cucumber/gherkin/formatter/escaping.rb +2 -1
  279. data/lib/cucumber/gherkin/i18n.rb +1 -0
  280. data/lib/cucumber/gherkin/steps_parser.rb +1 -0
  281. data/lib/cucumber/{rb_support/rb_dsl.rb → glue/dsl.rb} +41 -30
  282. data/lib/cucumber/glue/hook.rb +43 -0
  283. data/lib/cucumber/glue/invoke_in_world.rb +70 -0
  284. data/lib/cucumber/glue/proto_world.rb +220 -0
  285. data/lib/cucumber/{rb_support/rb_language.rb → glue/registry_and_more.rb} +60 -90
  286. data/lib/cucumber/{rb_support → glue}/snippet.rb +64 -26
  287. data/lib/cucumber/glue/step_definition.rb +143 -0
  288. data/lib/cucumber/glue/world_factory.rb +23 -0
  289. data/lib/cucumber/hooks.rb +9 -8
  290. data/lib/cucumber/load_path.rb +1 -0
  291. data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +158 -0
  292. data/lib/cucumber/multiline_argument/data_table.rb +47 -181
  293. data/lib/cucumber/multiline_argument/doc_string.rb +1 -0
  294. data/lib/cucumber/multiline_argument.rb +6 -15
  295. data/lib/cucumber/platform.rb +4 -5
  296. data/lib/cucumber/project_initializer.rb +3 -2
  297. data/lib/cucumber/rake/task.rb +19 -14
  298. data/lib/cucumber/rspec/disable_option_parser.rb +2 -1
  299. data/lib/cucumber/rspec/doubles.rb +2 -1
  300. data/lib/cucumber/running_test_case.rb +3 -27
  301. data/lib/cucumber/runtime/after_hooks.rb +2 -1
  302. data/lib/cucumber/runtime/before_hooks.rb +1 -0
  303. data/lib/cucumber/runtime/for_programming_languages.rb +2 -36
  304. data/lib/cucumber/runtime/step_hooks.rb +1 -0
  305. data/lib/cucumber/runtime/support_code.rb +21 -16
  306. data/lib/cucumber/runtime/user_interface.rb +10 -16
  307. data/lib/cucumber/runtime.rb +49 -32
  308. data/lib/cucumber/step_argument.rb +1 -2
  309. data/lib/cucumber/step_definition_light.rb +2 -0
  310. data/lib/cucumber/step_definitions.rb +1 -0
  311. data/lib/cucumber/step_match.rb +30 -15
  312. data/lib/cucumber/step_match_search.rb +3 -3
  313. data/lib/cucumber/term/ansicolor.rb +2 -1
  314. data/lib/cucumber/unit.rb +1 -0
  315. data/lib/cucumber/version +1 -1
  316. data/lib/cucumber.rb +1 -13
  317. data/lib/simplecov_setup.rb +2 -1
  318. data/scripts/invite-collaborator +40 -0
  319. data/scripts/update-changelog +86 -0
  320. data/spec/cucumber/cli/configuration_spec.rb +109 -98
  321. data/spec/cucumber/cli/main_spec.rb +8 -7
  322. data/spec/cucumber/cli/options_spec.rb +114 -79
  323. data/spec/cucumber/cli/profile_loader_spec.rb +25 -5
  324. data/spec/cucumber/cli/rerun_spec.rb +21 -20
  325. data/spec/cucumber/configuration_spec.rb +48 -47
  326. data/spec/cucumber/constantize_spec.rb +3 -2
  327. data/spec/cucumber/events_spec.rb +9 -0
  328. data/spec/cucumber/file_specs_spec.rb +26 -25
  329. data/spec/cucumber/filters/activate_steps_spec.rb +25 -22
  330. data/spec/cucumber/filters/gated_receiver_spec.rb +7 -6
  331. data/spec/cucumber/filters/retry_spec.rb +42 -23
  332. data/spec/cucumber/filters/tag_limits/test_case_index_spec.rb +12 -11
  333. data/spec/cucumber/filters/tag_limits/verifier_spec.rb +15 -14
  334. data/spec/cucumber/filters/tag_limits_spec.rb +9 -8
  335. data/spec/cucumber/formatter/ansicolor_spec.rb +10 -9
  336. data/spec/cucumber/formatter/backtrace_filter_spec.rb +32 -0
  337. data/spec/cucumber/formatter/console_counts_spec.rb +14 -0
  338. data/spec/cucumber/formatter/duration_spec.rb +4 -3
  339. data/spec/cucumber/formatter/fail_fast_spec.rb +27 -27
  340. data/spec/cucumber/formatter/html_spec.rb +65 -60
  341. data/spec/cucumber/formatter/interceptor_spec.rb +1 -0
  342. data/spec/cucumber/formatter/json_spec.rb +71 -97
  343. data/spec/cucumber/formatter/junit_spec.rb +46 -47
  344. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +134 -141
  345. data/spec/cucumber/formatter/pretty_spec.rb +105 -117
  346. data/spec/cucumber/formatter/progress_spec.rb +22 -21
  347. data/spec/cucumber/formatter/rerun_spec.rb +70 -64
  348. data/spec/cucumber/formatter/spec_helper.rb +14 -12
  349. data/spec/cucumber/{rb_support/rb_world_spec.rb → glue/proto_world_spec.rb} +22 -6
  350. data/spec/cucumber/glue/registry_and_more_spec.rb +213 -0
  351. data/spec/cucumber/{rb_support → glue}/snippet_spec.rb +62 -25
  352. data/spec/cucumber/glue/step_definition_spec.rb +207 -0
  353. data/spec/cucumber/hooks_spec.rb +5 -4
  354. data/spec/cucumber/multiline_argument/data_table_spec.rb +179 -129
  355. data/spec/cucumber/project_initializer_spec.rb +12 -11
  356. data/spec/cucumber/rake/forked_spec.rb +22 -17
  357. data/spec/cucumber/rake/task_spec.rb +21 -20
  358. data/spec/cucumber/running_test_case_spec.rb +36 -35
  359. data/spec/cucumber/runtime/for_programming_languages_spec.rb +2 -30
  360. data/spec/cucumber/runtime/support_code_spec.rb +1 -0
  361. data/spec/cucumber/runtime_spec.rb +3 -2
  362. data/spec/cucumber/step_argument_spec.rb +6 -5
  363. data/spec/cucumber/step_match_search_spec.rb +32 -41
  364. data/spec/cucumber/step_match_spec.rb +34 -33
  365. data/spec/cucumber/world/pending_spec.rb +12 -11
  366. data/spec/spec_helper.rb +1 -0
  367. data/spec/support/standard_step_actions.rb +2 -1
  368. metadata +132 -61
  369. data/features/docs/formatters/debug_formatter.feature +0 -47
  370. data/features/docs/formatters/formatter_step_file_colon_line.feature +0 -44
  371. data/features/docs/writing_support_code/transforms.feature +0 -98
  372. data/features/lib/step_definitions/wire_steps.rb +0 -58
  373. data/gem_tasks/cucumber.rake +0 -25
  374. data/lib/cucumber/ast.rb +0 -13
  375. data/lib/cucumber/core_ext/instance_exec.rb +0 -70
  376. data/lib/cucumber/events/after_test_case.rb +0 -25
  377. data/lib/cucumber/events/after_test_step.rb +0 -30
  378. data/lib/cucumber/events/before_test_case.rb +0 -18
  379. data/lib/cucumber/events/before_test_step.rb +0 -23
  380. data/lib/cucumber/events/bus.rb +0 -86
  381. data/lib/cucumber/events/finished_testing.rb +0 -9
  382. data/lib/cucumber/formatter/debug.rb +0 -35
  383. data/lib/cucumber/formatter/event_bus_report.rb +0 -38
  384. data/lib/cucumber/rb_support/rb_hook.rb +0 -19
  385. data/lib/cucumber/rb_support/rb_step_definition.rb +0 -131
  386. data/lib/cucumber/rb_support/rb_transform.rb +0 -59
  387. data/lib/cucumber/rb_support/rb_world.rb +0 -149
  388. data/spec/cucumber/core_ext/instance_exec_spec.rb +0 -4
  389. data/spec/cucumber/events/bus_spec.rb +0 -94
  390. data/spec/cucumber/formatter/debug_spec.rb +0 -64
  391. data/spec/cucumber/formatter/event_bus_report_spec.rb +0 -88
  392. data/spec/cucumber/rb_support/rb_language_spec.rb +0 -243
  393. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +0 -199
  394. data/spec/cucumber/rb_support/rb_transform_spec.rb +0 -46
  395. data/spec/cucumber_spec.rb +0 -39
@@ -1,6 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  require 'forwardable'
2
3
  require 'cucumber/core/ast/doc_string'
3
- require 'cucumber/core/ast/data_table'
4
4
 
5
5
  module Cucumber
6
6
  class Runtime
@@ -26,41 +26,7 @@ module Cucumber
26
26
 
27
27
  def_delegators :@support_code,
28
28
  :invoke_dynamic_steps,
29
- :invoke_dynamic_step,
30
- :load_programming_language
31
-
32
- # Returns a Cucumber::MultilineArgument::DataTable for +text_or_table+, which can either
33
- # be a String:
34
- #
35
- # table(%{
36
- # | account | description | amount |
37
- # | INT-100 | Taxi | 114 |
38
- # | CUC-101 | Peeler | 22 |
39
- # })
40
- #
41
- # or a 2D Array:
42
- #
43
- # table([
44
- # %w{ account description amount },
45
- # %w{ INT-100 Taxi 114 },
46
- # %w{ CUC-101 Peeler 22 }
47
- # ])
48
- #
49
- def table(text_or_table, file=nil, line=0)
50
- if !file
51
- location = Core::Ast::Location.of_caller
52
- else
53
- location = Core::Ast::Location.new(file, line)
54
- end
55
- MultilineArgument::DataTable.from(text_or_table, location)
56
- end
57
-
58
- # Returns a Cucumber::MultilineArgument::DocString for +body+.
59
- #
60
- def doc_string(body, content_type='', line_offset=0)
61
- location = Core::Ast::Location.of_caller
62
- MultilineArgument.doc_string(body, content_type, location)
63
- end
29
+ :invoke_dynamic_step
64
30
  end
65
31
  end
66
32
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Cucumber
2
3
  class Runtime
3
4
  class StepHooks
@@ -1,9 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  require 'cucumber/constantize'
2
3
  require 'cucumber/runtime/for_programming_languages'
3
4
  require 'cucumber/runtime/step_hooks'
4
5
  require 'cucumber/runtime/before_hooks'
5
6
  require 'cucumber/runtime/after_hooks'
6
- require 'cucumber/events/step_match'
7
7
  require 'cucumber/gherkin/steps_parser'
8
8
  require 'cucumber/step_match_search'
9
9
 
@@ -30,9 +30,11 @@ module Cucumber
30
30
  end
31
31
 
32
32
  def multiline_arg(step, location)
33
- if argument = step[:argument]
33
+ argument = step[:argument]
34
+
35
+ if argument
34
36
  if argument[:type] == :DocString
35
- MultilineArgument.doc_string(argument[:content], argument[:content_type], location)
37
+ MultilineArgument.from(argument[:content], location, argument[:content_type])
36
38
  else
37
39
  MultilineArgument::DataTable.from(argument[:rows].map { |row| row[:cells].map { |cell| cell[:value] } })
38
40
  end
@@ -44,11 +46,13 @@ module Cucumber
44
46
 
45
47
  include Constantize
46
48
 
47
- attr_reader :ruby
49
+ attr_reader :registry
50
+
48
51
  def initialize(user_interface, configuration=Configuration.default)
49
52
  @configuration = configuration
53
+ # TODO: needs a better name, or inlining its methods
50
54
  @runtime_facade = Runtime::ForProgrammingLanguages.new(self, user_interface)
51
- @ruby = Cucumber::RbSupport::RbLanguage.new(@runtime_facade, @configuration)
55
+ @registry = Cucumber::Glue::RegistryAndMore.new(@runtime_facade, @configuration)
52
56
  end
53
57
 
54
58
  def configure(new_configuration)
@@ -61,7 +65,7 @@ module Cucumber
61
65
  # Given I have 8 cukes in my belly
62
66
  # Then I should not be thirsty
63
67
  # })
64
- def invoke_dynamic_steps(steps_text, i18n, location)
68
+ def invoke_dynamic_steps(steps_text, i18n, _location)
65
69
  parser = Cucumber::Gherkin::StepsParser.new(StepInvoker.new(self), i18n.iso_code)
66
70
  parser.parse(steps_text)
67
71
  end
@@ -72,7 +76,7 @@ module Cucumber
72
76
  # steps which are compiled into test steps before execution.
73
77
  #
74
78
  # These are commonly called nested steps.
75
- def invoke_dynamic_step(step_name, multiline_argument, location=nil)
79
+ def invoke_dynamic_step(step_name, multiline_argument, _location=nil)
76
80
  matches = step_matches(step_name)
77
81
  raise UndefinedDynamicStep, step_name if matches.empty?
78
82
  matches.first.invoke(multiline_argument)
@@ -92,39 +96,40 @@ module Cucumber
92
96
  end
93
97
 
94
98
  def unmatched_step_definitions
95
- @ruby.unmatched_step_definitions
99
+ registry.unmatched_step_definitions
96
100
  end
97
101
 
98
102
  def fire_hook(name, *args)
99
- @ruby.send(name, *args)
103
+ # TODO: kill with fire
104
+ registry.send(name, *args)
100
105
  end
101
106
 
102
107
  def step_definitions
103
- @ruby.step_definitions
108
+ registry.step_definitions
104
109
  end
105
110
 
106
111
  def find_after_step_hooks(test_case)
107
112
  scenario = RunningTestCase.new(test_case)
108
- hooks = @ruby.hooks_for(:after_step, scenario)
113
+ hooks = registry.hooks_for(:after_step, scenario)
109
114
  StepHooks.new hooks
110
115
  end
111
116
 
112
117
  def apply_before_hooks(test_case)
113
118
  scenario = RunningTestCase.new(test_case)
114
- hooks = @ruby.hooks_for(:before, scenario)
119
+ hooks = registry.hooks_for(:before, scenario)
115
120
  BeforeHooks.new(hooks, scenario).apply_to(test_case)
116
121
  end
117
122
 
118
123
  def apply_after_hooks(test_case)
119
124
  scenario = RunningTestCase.new(test_case)
120
- hooks = @ruby.hooks_for(:after, scenario)
125
+ hooks = registry.hooks_for(:after, scenario)
121
126
  AfterHooks.new(hooks, scenario).apply_to(test_case)
122
127
  end
123
128
 
124
129
  def find_around_hooks(test_case)
125
130
  scenario = RunningTestCase.new(test_case)
126
131
 
127
- @ruby.hooks_for(:around, scenario).map do |hook|
132
+ registry.hooks_for(:around, scenario).map do |hook|
128
133
  Hooks.around_hook(test_case.source) do |run_scenario|
129
134
  hook.invoke('Around', scenario, &run_scenario)
130
135
  end
@@ -134,12 +139,12 @@ module Cucumber
134
139
  private
135
140
 
136
141
  def step_matches(step_name)
137
- StepMatchSearch.new(@ruby.method(:step_matches), @configuration).call(step_name)
142
+ StepMatchSearch.new(registry.method(:step_matches), @configuration).call(step_name)
138
143
  end
139
144
 
140
145
  def load_file(file)
141
146
  log.debug(" * #{file}\n")
142
- @ruby.load_code_file(file)
147
+ registry.load_code_file(file)
143
148
  end
144
149
 
145
150
  def log
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'timeout'
2
3
 
3
4
  module Cucumber
@@ -6,10 +7,6 @@ module Cucumber
6
7
  module UserInterface
7
8
  attr_writer :visitor
8
9
 
9
- def visitor=(visitor)
10
- @visitor = visitor
11
- end
12
-
13
10
  # Output +messages+ alongside the formatted output.
14
11
  # This is an alternative to using Kernel#puts - it will display
15
12
  # nicer, and in all outputs (in case you use several formatters)
@@ -36,18 +33,15 @@ module Cucumber
36
33
  STDOUT.flush
37
34
  puts(question)
38
35
 
39
- if(Cucumber::JRUBY)
40
- answer = jruby_gets(timeout_seconds)
41
- else
42
- answer = mri_gets(timeout_seconds)
43
- end
36
+ answer = if(Cucumber::JRUBY)
37
+ jruby_gets(timeout_seconds)
38
+ else
39
+ mri_gets(timeout_seconds)
40
+ end
44
41
 
45
- if(answer)
46
- puts(answer)
47
- answer
48
- else
49
- raise("Waited for input for #{timeout_seconds} seconds, then timed out.")
50
- end
42
+ raise("Waited for input for #{timeout_seconds} seconds, then timed out.") unless answer
43
+ puts(answer)
44
+ answer
51
45
  end
52
46
 
53
47
  # Embed +src+ of MIME type +mime_type+ into the output. The +src+ argument may
@@ -58,7 +52,7 @@ module Cucumber
58
52
  @visitor.embed(src, mime_type, label)
59
53
  end
60
54
 
61
- private
55
+ private
62
56
 
63
57
  def mri_gets(timeout_seconds)
64
58
  begin
@@ -1,4 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
2
3
  require 'fileutils'
3
4
  require 'multi_json'
4
5
  require 'cucumber/configuration'
@@ -7,14 +8,13 @@ require 'cucumber/formatter/duration'
7
8
  require 'cucumber/file_specs'
8
9
  require 'cucumber/filters'
9
10
  require 'cucumber/formatter/fanout'
10
- require 'cucumber/formatter/event_bus_report'
11
11
  require 'cucumber/gherkin/i18n'
12
12
  require 'cucumber/step_match_search'
13
13
 
14
14
  module Cucumber
15
15
  module FixRuby21Bug9285
16
16
  def message
17
- String(super).gsub("@ rb_sysopen ", "")
17
+ String(super).gsub('@ rb_sysopen ', '')
18
18
  end
19
19
  end
20
20
 
@@ -30,8 +30,14 @@ module Cucumber
30
30
  class FileNotFoundException < FileException
31
31
  end
32
32
 
33
- class FeatureFolderNotFoundException < FileException
34
- include FixRuby21Bug9285 if Cucumber::RUBY_2_1 || Cucumber::RUBY_2_2 || Cucumber::RUBY_2_3
33
+ class FeatureFolderNotFoundException < Exception
34
+ def initialize(path)
35
+ @path = path
36
+ end
37
+
38
+ def message
39
+ "No such file or directory - #{@path}"
40
+ end
35
41
  end
36
42
 
37
43
  require 'cucumber/core'
@@ -61,10 +67,12 @@ module Cucumber
61
67
  load_step_definitions
62
68
  install_wire_plugin
63
69
  fire_after_configuration_hook
70
+ # TODO: can we remove this state?
64
71
  self.visitor = report
65
72
 
66
- receiver = Test::Runner.new(report)
73
+ receiver = Test::Runner.new(@configuration.event_bus)
67
74
  compile features, receiver, filters
75
+ @configuration.notify :test_run_finished
68
76
  end
69
77
 
70
78
  def features_paths
@@ -87,22 +95,22 @@ module Cucumber
87
95
  @support_code.unmatched_step_definitions
88
96
  end
89
97
 
90
- def begin_scenario(scenario)
91
- @support_code.fire_hook(:begin_scenario, scenario)
98
+ def begin_scenario(test_case)
99
+ @support_code.fire_hook(:begin_scenario, test_case)
92
100
  end
93
101
 
94
- def end_scenario(scenario)
102
+ def end_scenario(_scenario)
95
103
  @support_code.fire_hook(:end_scenario)
96
104
  end
97
105
 
98
106
  # Returns Ast::DocString for +string_without_triple_quotes+.
99
107
  #
100
- def doc_string(string_without_triple_quotes, content_type='', line_offset=0)
108
+ def doc_string(string_without_triple_quotes, content_type='', _line_offset=0)
101
109
  location = Core::Ast::Location.of_caller
102
110
  Core::Ast::DocString.new(string_without_triple_quotes, content_type, location)
103
111
  end
104
112
 
105
- private
113
+ private
106
114
 
107
115
  def fire_after_configuration_hook #:nodoc
108
116
  @support_code.fire_hook(:after_configuration, @configuration)
@@ -112,6 +120,7 @@ module Cucumber
112
120
  def features
113
121
  @features ||= feature_files.map do |path|
114
122
  source = NormalisedEncodingFile.read(path)
123
+ @configuration.notify :gherkin_source_read, path, source
115
124
  Cucumber::Core::Gherkin::Document.new(path, source)
116
125
  end
117
126
  end
@@ -138,13 +147,13 @@ module Cucumber
138
147
  set_encoding
139
148
  rescue Errno::EACCES => e
140
149
  raise FileNotFoundException.new(e, File.expand_path(path))
141
- rescue Errno::ENOENT => e
142
- raise FeatureFolderNotFoundException.new(e, path)
150
+ rescue Errno::ENOENT
151
+ raise FeatureFolderNotFoundException.new(path)
143
152
  end
144
153
  end
145
154
 
146
155
  def read
147
- @file.read.encode("UTF-8")
156
+ @file.read.encode('UTF-8')
148
157
  end
149
158
 
150
159
  private
@@ -169,17 +178,13 @@ module Cucumber
169
178
  require 'cucumber/core/report/summary'
170
179
  def report
171
180
  return @report if @report
172
- reports = [summary_report, event_bus_report] + formatters
181
+ reports = [summary_report] + formatters
173
182
  reports << fail_fast_report if @configuration.fail_fast?
174
183
  @report ||= Formatter::Fanout.new(reports)
175
184
  end
176
185
 
177
186
  def summary_report
178
- @summary_report ||= Core::Report::Summary.new
179
- end
180
-
181
- def event_bus_report
182
- @event_bus_report ||= Formatter::EventBusReport.new(@configuration)
187
+ @summary_report ||= Core::Report::Summary.new(@configuration.event_bus)
183
188
  end
184
189
 
185
190
  def fail_fast_report
@@ -187,34 +192,44 @@ module Cucumber
187
192
  end
188
193
 
189
194
  def formatters
190
- @formatters ||= @configuration.formatter_factories { |factory, path_or_io, options|
191
- create_formatter(factory, path_or_io, options)
192
- }
195
+ @formatters ||=
196
+ @configuration.formatter_factories do |factory, formatter_options, path_or_io, options|
197
+ create_formatter(factory, formatter_options, path_or_io, options)
198
+ end
193
199
  end
194
200
 
195
- def create_formatter(factory, path_or_io, options)
201
+ def create_formatter(factory, formatter_options, path_or_io, cli_options)
196
202
  if !legacy_formatter?(factory)
197
- return factory.new(@configuration) if path_or_io.nil?
198
- return factory.new(@configuration.with_options(out_stream: path_or_io))
203
+ if accept_options?(factory)
204
+ return factory.new(@configuration, formatter_options) if path_or_io.nil?
205
+ return factory.new(@configuration.with_options(out_stream: path_or_io),
206
+ formatter_options)
207
+ else
208
+ return factory.new(@configuration) if path_or_io.nil?
209
+ return factory.new(@configuration.with_options(out_stream: path_or_io))
210
+ end
199
211
  end
200
212
  results = Formatter::LegacyApi::Results.new
201
213
  runtime_facade = Formatter::LegacyApi::RuntimeFacade.new(results, @support_code, @configuration)
202
- formatter = factory.new(runtime_facade, path_or_io, options)
214
+ formatter = factory.new(runtime_facade, path_or_io, cli_options)
203
215
  Formatter::LegacyApi::Adapter.new(
204
216
  Formatter::IgnoreMissingMessages.new(formatter),
205
217
  results, @configuration)
206
218
  end
207
219
 
208
- def legacy_formatter?(factory)
220
+ def accept_options?(factory)
209
221
  factory.instance_method(:initialize).arity > 1
210
222
  end
211
223
 
224
+ def legacy_formatter?(factory)
225
+ factory.instance_method(:initialize).arity > 2
226
+ end
227
+
212
228
  def failure?
213
229
  if @configuration.wip?
214
230
  summary_report.test_cases.total_passed > 0
215
231
  else
216
- summary_report.test_cases.total_failed > 0 || summary_report.test_steps.total_failed > 0 ||
217
- (@configuration.strict? && (summary_report.test_steps.total_undefined > 0 || summary_report.test_steps.total_pending > 0))
232
+ !summary_report.ok?(@configuration.strict)
218
233
  end
219
234
  end
220
235
  public :failure?
@@ -230,9 +245,8 @@ module Cucumber
230
245
  filters << Cucumber::Core::Test::NameFilter.new(name_regexps)
231
246
  filters << Cucumber::Core::Test::LocationsFilter.new(filespecs.locations)
232
247
  filters << Filters::Randomizer.new(@configuration.seed) if @configuration.randomize?
233
- filters << Filters::Quit.new
234
- # TODO: can we just use RbLanguages's step definitions directly?
235
- step_match_search = StepMatchSearch.new(@support_code.ruby.method(:step_matches), @configuration)
248
+ # TODO: can we just use Glue::RegistryAndMore's step definitions directly?
249
+ step_match_search = StepMatchSearch.new(@support_code.registry.method(:step_matches), @configuration)
236
250
  filters << Filters::ActivateSteps.new(step_match_search, @configuration)
237
251
  @configuration.filters.each do |filter|
238
252
  filters << filter
@@ -242,6 +256,9 @@ module Cucumber
242
256
  filters << Filters::ApplyBeforeHooks.new(@support_code)
243
257
  filters << Filters::ApplyAfterHooks.new(@support_code)
244
258
  filters << Filters::ApplyAroundHooks.new(@support_code)
259
+ filters << Filters::BroadcastTestRunStartedEvent.new(@configuration)
260
+ filters << Filters::Quit.new
261
+ filters << Filters::Retry.new(@configuration)
245
262
  # need to do this last so it becomes the first test step
246
263
  filters << Filters::PrepareWorld.new(self)
247
264
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Cucumber
2
3
  # Defines the location and value of a captured argument from the step
3
4
  # text
@@ -11,8 +12,6 @@ module Cucumber
11
12
  offset = match.offset(n)[0]
12
13
  new(offset, val)
13
14
  end
14
- else
15
- nil
16
15
  end
17
16
  end
18
17
 
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  module Cucumber
3
+ # TODO: pointless, ancient, kill with fire.
2
4
  # Only used for keeping track of available and invoked step definitions
3
5
  # in a way that also works for other programming languages (i.e. cuke4duke)
4
6
  # Used for reporting purposes only (usage formatter).
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Cucumber
2
3
  class StepDefinitions
3
4
  def initialize(configuration = Configuration.default)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'cucumber/multiline_argument'
2
3
 
3
4
  module Cucumber
@@ -12,7 +13,7 @@ module Cucumber
12
13
  end
13
14
 
14
15
  def args
15
- @step_arguments.map{|g| g.val }
16
+ @step_arguments.map{|g| g.value }
16
17
  end
17
18
 
18
19
  def activate(test_step)
@@ -55,30 +56,31 @@ module Cucumber
55
56
  end
56
57
 
57
58
  def backtrace_line
58
- "#{file_colon_line}:in `#{@step_definition.regexp_source}'"
59
+ "#{file_colon_line}:in `#{@step_definition.expression}'"
59
60
  end
60
61
 
61
62
  def text_length
62
- @step_definition.regexp_source.unpack('U*').length
63
+ @step_definition.expression.source.to_s.unpack('U*').length
63
64
  end
64
65
 
65
66
  def replace_arguments(string, step_arguments, format, &proc)
66
67
  s = string.dup
67
68
  offset = past_offset = 0
68
69
  step_arguments.each do |step_argument|
69
- next if step_argument.offset.nil? || step_argument.offset < past_offset
70
+ group = step_argument.group
71
+ next if group.value.nil? || group.start < past_offset
70
72
 
71
73
  replacement = if block_given?
72
- proc.call(step_argument.val)
73
- elsif Proc === format
74
- format.call(step_argument.val)
75
- else
76
- format % step_argument.val
77
- end
78
-
79
- s[step_argument.offset + offset, step_argument.val.length] = replacement
80
- offset += replacement.unpack('U*').length - step_argument.val.unpack('U*').length
81
- past_offset = step_argument.offset + step_argument.val.length
74
+ proc.call(group.value)
75
+ elsif Proc === format
76
+ format.call(group.value)
77
+ else
78
+ format % group.value
79
+ end
80
+
81
+ s[group.start + offset, group.value.length] = replacement
82
+ offset += replacement.unpack('U*').length - group.value.unpack('U*').length
83
+ past_offset = group.start + group.value.length
82
84
  end
83
85
  s
84
86
  end
@@ -107,7 +109,7 @@ module Cucumber
107
109
  @name = name
108
110
  end
109
111
 
110
- def format_args(*args)
112
+ def format_args(*_args)
111
113
  @name
112
114
  end
113
115
 
@@ -138,4 +140,17 @@ module Cucumber
138
140
  return test_step
139
141
  end
140
142
  end
143
+
144
+ class AmbiguousStepMatch
145
+
146
+ def initialize(error)
147
+ @error = error
148
+ end
149
+
150
+ def activate(test_step)
151
+ return test_step.with_action { raise @error }
152
+ end
153
+
154
+ end
155
+
141
156
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Cucumber
2
3
  module StepMatchSearch
3
4
  def self.new(search, configuration)
@@ -32,8 +33,8 @@ module Cucumber
32
33
 
33
34
  private
34
35
 
35
- def best_matches(step_name, step_matches) #:nodoc:
36
- no_groups = step_matches.select {|step_match| step_match.args.length == 0}
36
+ def best_matches(_step_name, step_matches) #:nodoc:
37
+ no_groups = step_matches.select {|step_match| step_match.args.empty?}
37
38
  max_arg_length = step_matches.map {|step_match| step_match.args.length }.max
38
39
  top_groups = step_matches.select {|step_match| step_match.args.length == max_arg_length }
39
40
 
@@ -64,4 +65,3 @@ module Cucumber
64
65
 
65
66
  end
66
67
  end
67
-
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Cucumber
2
3
  module Term
3
4
  # The ANSIColor module can be used for namespacing and mixed into your own
@@ -32,7 +33,7 @@ module Cucumber
32
33
  [ :on_blue , 44 ],
33
34
  [ :on_magenta , 45 ],
34
35
  [ :on_cyan , 46 ],
35
- [ :on_white , 47 ],
36
+ [ :on_white , 47 ]
36
37
  ]
37
38
 
38
39
  ATTRIBUTE_NAMES = ATTRIBUTES.transpose.first
data/lib/cucumber/unit.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Cucumber
2
3
  class Unit
3
4
  def initialize(step_collection)
data/lib/cucumber/version CHANGED
@@ -1 +1 @@
1
- 2.99.0
1
+ 3.0.0
data/lib/cucumber.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'yaml'
2
3
  require 'cucumber/encoding'
3
4
  require 'cucumber/platform'
@@ -20,18 +21,5 @@ module Cucumber
20
21
  def logger=(logger)
21
22
  @log = logger
22
23
  end
23
-
24
- if Cucumber::RUBY_1_9
25
- # Backported from Ruby 2.0 to 1.9
26
- def Hash(other)
27
- return {} if other.nil? || other == []
28
- raise TypeError, "can't convert #{other.class} into Hash" unless other.respond_to?(:to_hash)
29
- other.to_hash
30
- end
31
- else
32
- def Hash(other)
33
- Kernel::Hash(other)
34
- end
35
- end
36
24
  end
37
25
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  if ENV['SIMPLECOV']
2
3
  begin
3
4
  # Suppress warnings in order not to pollute stdout which tests expectations rely on
@@ -13,6 +14,6 @@ if ENV['SIMPLECOV']
13
14
  add_filter '/features/'
14
15
  end
15
16
  rescue LoadError
16
- warn("Unable to load simplecov")
17
+ warn('Unable to load simplecov')
17
18
  end
18
19
  end
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+ require 'octokit'
3
+
4
+ class Team
5
+ attr_reader :gh, :name
6
+
7
+ def initialize(gh, name)
8
+ @gh = gh
9
+ @name = name
10
+ end
11
+
12
+ def add_member(login)
13
+ gh.add_team_membership(id, login)
14
+ end
15
+
16
+ def id
17
+ team['id']
18
+ end
19
+
20
+ def team
21
+ @team ||= gh.organization_teams('cucumber').
22
+ find { |team| team['name'] == name } || raise("Unable to find a team named #{name}")
23
+ end
24
+ end
25
+
26
+ begin
27
+ token = ENV['GITHUB_TOKEN'] || raise('You need to set GITHUB_TOKEN')
28
+ login = (ARGV[0] || raise("syntax: #{$0} <COLLABORATOR_LOGIN>")).to_s
29
+
30
+ gh = Octokit::Client.new(access_token: token)
31
+ [
32
+ Team.new(gh, 'cucumber-ruby'),
33
+ Team.new(gh, 'collaborators')
34
+ ].each { |team|
35
+ team.add_member(login)
36
+ }
37
+
38
+ rescue StandardError => error
39
+ abort error.message
40
+ end