cucumber 3.0.0.pre.2 → 4.0.0.rc.5

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 (541) hide show
  1. checksums.yaml +5 -5
  2. data/{History.md → CHANGELOG.md} +267 -14
  3. data/CONTRIBUTING.md +4 -21
  4. data/README.md +14 -15
  5. data/bin/cucumber +2 -1
  6. data/lib/autotest/cucumber.rb +1 -0
  7. data/lib/autotest/cucumber_mixin.rb +36 -40
  8. data/lib/autotest/cucumber_rails.rb +1 -0
  9. data/lib/autotest/cucumber_rails_rspec.rb +1 -0
  10. data/lib/autotest/cucumber_rails_rspec2.rb +1 -0
  11. data/lib/autotest/cucumber_rspec.rb +1 -0
  12. data/lib/autotest/cucumber_rspec2.rb +1 -0
  13. data/lib/autotest/discover.rb +1 -0
  14. data/lib/cucumber.rb +2 -1
  15. data/lib/cucumber/cli/configuration.rb +8 -7
  16. data/lib/cucumber/cli/main.rb +14 -14
  17. data/lib/cucumber/cli/options.rb +141 -120
  18. data/lib/cucumber/cli/profile_loader.rb +50 -29
  19. data/lib/cucumber/cli/rerun_file.rb +1 -0
  20. data/lib/cucumber/configuration.rb +40 -30
  21. data/lib/cucumber/constantize.rb +8 -10
  22. data/lib/cucumber/core_ext/string.rb +1 -0
  23. data/lib/cucumber/deprecate.rb +33 -9
  24. data/lib/cucumber/encoding.rb +2 -1
  25. data/lib/cucumber/errors.rb +10 -8
  26. data/lib/cucumber/events.rb +14 -9
  27. data/lib/cucumber/events/envelope.rb +9 -0
  28. data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
  29. data/lib/cucumber/events/gherkin_source_read.rb +1 -4
  30. data/lib/cucumber/events/hook_test_step_created.rb +13 -0
  31. data/lib/cucumber/events/step_activated.rb +6 -6
  32. data/lib/cucumber/events/step_definition_registered.rb +4 -8
  33. data/lib/cucumber/events/test_case_created.rb +13 -0
  34. data/lib/cucumber/events/test_case_finished.rb +1 -5
  35. data/lib/cucumber/events/test_case_ready.rb +12 -0
  36. data/lib/cucumber/events/{test_case_starting.rb → test_case_started.rb} +1 -5
  37. data/lib/cucumber/events/test_run_finished.rb +2 -3
  38. data/lib/cucumber/events/{test_run_starting.rb → test_run_started.rb} +3 -5
  39. data/lib/cucumber/events/test_step_created.rb +13 -0
  40. data/lib/cucumber/events/test_step_finished.rb +0 -6
  41. data/lib/cucumber/events/{test_step_starting.rb → test_step_started.rb} +2 -8
  42. data/lib/cucumber/file_specs.rb +7 -6
  43. data/lib/cucumber/filters.rb +3 -1
  44. data/lib/cucumber/filters/activate_steps.rb +11 -5
  45. data/lib/cucumber/filters/apply_after_hooks.rb +1 -0
  46. data/lib/cucumber/filters/apply_after_step_hooks.rb +1 -0
  47. data/lib/cucumber/filters/apply_around_hooks.rb +1 -0
  48. data/lib/cucumber/filters/apply_before_hooks.rb +1 -0
  49. data/lib/cucumber/filters/broadcast_test_case_ready_event.rb +12 -0
  50. data/lib/cucumber/filters/{broadcast_test_run_starting_event.rb → broadcast_test_run_started_event.rb} +4 -3
  51. data/lib/cucumber/filters/gated_receiver.rb +1 -2
  52. data/lib/cucumber/filters/prepare_world.rb +6 -13
  53. data/lib/cucumber/filters/quit.rb +3 -7
  54. data/lib/cucumber/filters/randomizer.rb +6 -7
  55. data/lib/cucumber/filters/retry.rb +2 -2
  56. data/lib/cucumber/filters/tag_limits.rb +2 -2
  57. data/lib/cucumber/filters/tag_limits/test_case_index.rb +1 -2
  58. data/lib/cucumber/filters/tag_limits/verifier.rb +3 -6
  59. data/lib/cucumber/formatter/ansicolor.rb +33 -37
  60. data/lib/cucumber/formatter/ast_lookup.rb +165 -0
  61. data/lib/cucumber/formatter/backtrace_filter.rb +10 -10
  62. data/lib/cucumber/formatter/console.rb +37 -74
  63. data/lib/cucumber/formatter/console_counts.rb +4 -9
  64. data/lib/cucumber/formatter/console_issues.rb +10 -7
  65. data/lib/cucumber/formatter/duration.rb +2 -1
  66. data/lib/cucumber/formatter/duration_extractor.rb +4 -2
  67. data/lib/cucumber/formatter/errors.rb +6 -0
  68. data/lib/cucumber/formatter/fail_fast.rb +9 -6
  69. data/lib/cucumber/formatter/fanout.rb +3 -3
  70. data/lib/cucumber/formatter/html.rb +11 -603
  71. data/lib/cucumber/formatter/http_io.rb +93 -0
  72. data/lib/cucumber/formatter/ignore_missing_messages.rb +2 -4
  73. data/lib/cucumber/formatter/interceptor.rb +10 -12
  74. data/lib/cucumber/formatter/io.rb +19 -12
  75. data/lib/cucumber/formatter/json.rb +106 -112
  76. data/lib/cucumber/formatter/junit.rb +81 -76
  77. data/lib/cucumber/formatter/message.rb +22 -0
  78. data/lib/cucumber/formatter/message_builder.rb +241 -0
  79. data/lib/cucumber/formatter/pretty.rb +353 -153
  80. data/lib/cucumber/formatter/progress.rb +30 -33
  81. data/lib/cucumber/formatter/query/hook_by_test_step.rb +31 -0
  82. data/lib/cucumber/formatter/query/pickle_by_test.rb +26 -0
  83. data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +26 -0
  84. data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +40 -0
  85. data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +40 -0
  86. data/lib/cucumber/formatter/rerun.rb +24 -5
  87. data/lib/cucumber/formatter/stepdefs.rb +2 -2
  88. data/lib/cucumber/formatter/steps.rb +4 -5
  89. data/lib/cucumber/formatter/summary.rb +18 -11
  90. data/lib/cucumber/formatter/unicode.rb +16 -18
  91. data/lib/cucumber/formatter/usage.rb +30 -26
  92. data/lib/cucumber/gherkin/data_table_parser.rb +18 -6
  93. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +83 -86
  94. data/lib/cucumber/gherkin/formatter/escaping.rb +13 -12
  95. data/lib/cucumber/gherkin/i18n.rb +1 -0
  96. data/lib/cucumber/gherkin/steps_parser.rb +18 -8
  97. data/lib/cucumber/glue/dsl.rb +13 -26
  98. data/lib/cucumber/glue/hook.rb +35 -11
  99. data/lib/cucumber/glue/invoke_in_world.rb +15 -20
  100. data/lib/cucumber/glue/proto_world.rb +48 -42
  101. data/lib/cucumber/glue/registry_and_more.rb +58 -23
  102. data/lib/cucumber/glue/snippet.rb +23 -26
  103. data/lib/cucumber/glue/step_definition.rb +51 -28
  104. data/lib/cucumber/glue/world_factory.rb +2 -4
  105. data/lib/cucumber/hooks.rb +27 -17
  106. data/lib/cucumber/load_path.rb +1 -0
  107. data/lib/cucumber/multiline_argument.rb +7 -17
  108. data/lib/cucumber/multiline_argument/data_table.rb +113 -82
  109. data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +8 -12
  110. data/lib/cucumber/multiline_argument/doc_string.rb +2 -1
  111. data/lib/cucumber/platform.rb +4 -3
  112. data/lib/cucumber/project_initializer.rb +2 -2
  113. data/lib/cucumber/rake/task.rb +28 -21
  114. data/lib/cucumber/rspec/disable_option_parser.rb +10 -8
  115. data/lib/cucumber/rspec/doubles.rb +1 -0
  116. data/lib/cucumber/running_test_case.rb +4 -54
  117. data/lib/cucumber/runtime.rb +32 -63
  118. data/lib/cucumber/runtime/after_hooks.rb +9 -4
  119. data/lib/cucumber/runtime/before_hooks.rb +9 -4
  120. data/lib/cucumber/runtime/for_programming_languages.rb +12 -9
  121. data/lib/cucumber/runtime/step_hooks.rb +5 -2
  122. data/lib/cucumber/runtime/support_code.rb +16 -22
  123. data/lib/cucumber/runtime/user_interface.rb +12 -23
  124. data/lib/cucumber/step_definition_light.rb +6 -4
  125. data/lib/cucumber/step_definitions.rb +3 -2
  126. data/lib/cucumber/step_match.rb +29 -14
  127. data/lib/cucumber/step_match_search.rb +10 -10
  128. data/lib/cucumber/term/ansicolor.rb +39 -39
  129. data/lib/cucumber/unit.rb +1 -0
  130. data/lib/cucumber/version +1 -1
  131. data/lib/simplecov_setup.rb +1 -0
  132. metadata +206 -678
  133. data/.coveralls.yml +0 -1
  134. data/.cucumberproignore +0 -6
  135. data/.github/ISSUE_TEMPLATE.md +0 -48
  136. data/.github/PULL_REQUEST_TEMPLATE.md +0 -39
  137. data/.rspec +0 -1
  138. data/.rubocop.yml +0 -13
  139. data/.rubocop_todo.yml +0 -1075
  140. data/.ruby-gemset +0 -1
  141. data/.travis.yml +0 -69
  142. data/.yardopts +0 -1
  143. data/Gemfile +0 -28
  144. data/Rakefile +0 -32
  145. data/appveyor.yml +0 -26
  146. data/cucumber.gemspec +0 -52
  147. data/cucumber.yml +0 -19
  148. data/examples/i18n/README.textile +0 -3
  149. data/examples/i18n/Rakefile +0 -33
  150. data/examples/i18n/ar/Rakefile +0 -6
  151. data/examples/i18n/ar/features/addition.feature +0 -17
  152. data/examples/i18n/ar/features/step_definitions/calculator_steps.rb +0 -24
  153. data/examples/i18n/ar/lib/calculator.rb +0 -11
  154. data/examples/i18n/bg/Rakefile +0 -6
  155. data/examples/i18n/bg/features/addition.feature +0 -12
  156. data/examples/i18n/bg/features/consecutive_calculations.feature +0 -19
  157. data/examples/i18n/bg/features/division.feature +0 -17
  158. data/examples/i18n/bg/features/step_definitions/calculator_steps.rb +0 -24
  159. data/examples/i18n/bg/features/support/env.rb +0 -5
  160. data/examples/i18n/bg/features/support/world.rb +0 -8
  161. data/examples/i18n/bg/lib/calculator.rb +0 -24
  162. data/examples/i18n/ca/Rakefile +0 -6
  163. data/examples/i18n/ca/features/step_definitions/calculator_steps.rb +0 -21
  164. data/examples/i18n/ca/features/suma.feature +0 -17
  165. data/examples/i18n/ca/lib/calculadora.rb +0 -16
  166. data/examples/i18n/cs/Rakefile +0 -6
  167. data/examples/i18n/cs/features/addition.feature +0 -17
  168. data/examples/i18n/cs/features/division.feature +0 -11
  169. data/examples/i18n/cs/features/step_definitions/calculator_steps.rb +0 -24
  170. data/examples/i18n/cs/lib/calculator.rb +0 -14
  171. data/examples/i18n/da/Rakefile +0 -6
  172. data/examples/i18n/da/features/sammenlaegning.feature +0 -18
  173. data/examples/i18n/da/features/step_definitions/lommeregner_steps.rb +0 -24
  174. data/examples/i18n/da/lib/lommeregner.rb +0 -11
  175. data/examples/i18n/de/Rakefile +0 -6
  176. data/examples/i18n/de/features/addition.feature +0 -17
  177. data/examples/i18n/de/features/division.feature +0 -10
  178. data/examples/i18n/de/features/step_definitions/calculator_steps.rb +0 -24
  179. data/examples/i18n/de/lib/calculator.rb +0 -14
  180. data/examples/i18n/el/Rakefile +0 -6
  181. data/examples/i18n/el/features/addition.feature +0 -17
  182. data/examples/i18n/el/features/division.feature +0 -10
  183. data/examples/i18n/el/features/step_definitions/calculator_steps.rb +0 -24
  184. data/examples/i18n/el/lib/calculator.rb +0 -14
  185. data/examples/i18n/en-lol/Rakefile +0 -4
  186. data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +0 -16
  187. data/examples/i18n/en-lol/features/stuffing.feature +0 -8
  188. data/examples/i18n/en-lol/features/support/env.rb +0 -7
  189. data/examples/i18n/en-lol/lib/basket.rb +0 -12
  190. data/examples/i18n/en-lol/lib/belly.rb +0 -11
  191. data/examples/i18n/en/Rakefile +0 -6
  192. data/examples/i18n/en/features/addition.feature +0 -17
  193. data/examples/i18n/en/features/division.feature +0 -10
  194. data/examples/i18n/en/features/step_definitions/calculator_steps.rb +0 -24
  195. data/examples/i18n/en/lib/calculator.rb +0 -14
  196. data/examples/i18n/eo/Rakefile +0 -6
  197. data/examples/i18n/eo/features/adicio.feature +0 -17
  198. data/examples/i18n/eo/features/divido.feature +0 -10
  199. data/examples/i18n/eo/features/step_definitions/calculator_steps.rb +0 -24
  200. data/examples/i18n/eo/lib/calculator.rb +0 -14
  201. data/examples/i18n/es/Rakefile +0 -6
  202. data/examples/i18n/es/features/adicion.feature +0 -17
  203. data/examples/i18n/es/features/step_definitions/calculador_steps.rb +0 -21
  204. data/examples/i18n/es/lib/calculador.rb +0 -14
  205. data/examples/i18n/et/Rakefile +0 -6
  206. data/examples/i18n/et/features/jagamine.feature +0 -10
  207. data/examples/i18n/et/features/liitmine.feature +0 -17
  208. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +0 -24
  209. data/examples/i18n/et/lib/kalkulaator.rb +0 -14
  210. data/examples/i18n/fi/Rakefile +0 -6
  211. data/examples/i18n/fi/features/jakolasku.feature +0 -10
  212. data/examples/i18n/fi/features/step_definitions/laskin_steps.rb +0 -24
  213. data/examples/i18n/fi/features/yhteenlasku.feature +0 -17
  214. data/examples/i18n/fi/lib/laskin.rb +0 -14
  215. data/examples/i18n/fr/Rakefile +0 -8
  216. data/examples/i18n/fr/features/addition.feature +0 -18
  217. data/examples/i18n/fr/features/addition2.feature +0 -17
  218. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +0 -32
  219. data/examples/i18n/fr/features/support/env.rb +0 -5
  220. data/examples/i18n/fr/lib/calculatrice.rb +0 -10
  221. data/examples/i18n/he/Rakefile +0 -6
  222. data/examples/i18n/he/features/addition.feature +0 -17
  223. data/examples/i18n/he/features/division.feature +0 -10
  224. data/examples/i18n/he/features/step_definitions/calculator_steps.rb +0 -24
  225. data/examples/i18n/he/lib/calculator.rb +0 -15
  226. data/examples/i18n/hi/Rakefile +0 -6
  227. data/examples/i18n/hi/features/addition.feature +0 -16
  228. data/examples/i18n/hi/features/division.feature +0 -10
  229. data/examples/i18n/hi/features/step_definitions/calculator_steps.rb +0 -24
  230. data/examples/i18n/hi/lib/calculator.rb +0 -15
  231. data/examples/i18n/ht/Rakefile +0 -6
  232. data/examples/i18n/ht/features/adisyon.feature +0 -17
  233. data/examples/i18n/ht/features/divizyon.feature +0 -10
  234. data/examples/i18n/ht/features/step_definitions/kalkilatris_steps.rb +0 -25
  235. data/examples/i18n/ht/lib/kalkilatris.rb +0 -14
  236. data/examples/i18n/hu/Rakefile +0 -6
  237. data/examples/i18n/hu/features/osszeadas.feature +0 -17
  238. data/examples/i18n/hu/features/osztas.feature +0 -10
  239. data/examples/i18n/hu/features/step_definitions/calculator_steps.rb +0 -25
  240. data/examples/i18n/hu/lib/calculator.rb +0 -14
  241. data/examples/i18n/id/Rakefile +0 -6
  242. data/examples/i18n/id/features/addition.feature +0 -17
  243. data/examples/i18n/id/features/division.feature +0 -10
  244. data/examples/i18n/id/features/step_definitions/calculator_steps.rb +0 -24
  245. data/examples/i18n/id/lib/calculator.rb +0 -14
  246. data/examples/i18n/it/Rakefile +0 -6
  247. data/examples/i18n/it/features/somma.feature +0 -11
  248. data/examples/i18n/it/features/step_definitions/calcolatrice_steps.rb +0 -24
  249. data/examples/i18n/it/lib/calcolatrice.rb +0 -11
  250. data/examples/i18n/ja/Rakefile +0 -6
  251. data/examples/i18n/ja/features/addition.feature +0 -17
  252. data/examples/i18n/ja/features/division.feature +0 -10
  253. data/examples/i18n/ja/features/step_definitions/calculator_steps.rb +0 -19
  254. data/examples/i18n/ja/features/support/env.rb +0 -5
  255. data/examples/i18n/ja/lib/calculator.rb +0 -14
  256. data/examples/i18n/ko/Rakefile +0 -6
  257. data/examples/i18n/ko/features/addition.feature +0 -17
  258. data/examples/i18n/ko/features/division.feature +0 -11
  259. data/examples/i18n/ko/features/step_definitions/calculator_steps.rb +0 -24
  260. data/examples/i18n/ko/lib/calculator.rb +0 -14
  261. data/examples/i18n/lt/Rakefile +0 -6
  262. data/examples/i18n/lt/features/addition.feature +0 -17
  263. data/examples/i18n/lt/features/division.feature +0 -10
  264. data/examples/i18n/lt/features/step_definitions/calculator_steps.rb +0 -24
  265. data/examples/i18n/lt/lib/calculator.rb +0 -14
  266. data/examples/i18n/lv/Rakefile +0 -6
  267. data/examples/i18n/lv/features/addition.feature +0 -17
  268. data/examples/i18n/lv/features/division.feature +0 -10
  269. data/examples/i18n/lv/features/step_definitions/calculator_steps.rb +0 -24
  270. data/examples/i18n/lv/lib/calculator.rb +0 -14
  271. data/examples/i18n/no/Rakefile +0 -6
  272. data/examples/i18n/no/features/step_definitions/kalkulator_steps.rb +0 -17
  273. data/examples/i18n/no/features/summering.feature +0 -19
  274. data/examples/i18n/no/features/support/env.rb +0 -6
  275. data/examples/i18n/no/lib/kalkulator.rb +0 -11
  276. data/examples/i18n/pl/Rakefile +0 -6
  277. data/examples/i18n/pl/features/addition.feature +0 -17
  278. data/examples/i18n/pl/features/division.feature +0 -10
  279. data/examples/i18n/pl/features/step_definitions/calculator_steps.rb +0 -24
  280. data/examples/i18n/pl/features/support/env.rb +0 -5
  281. data/examples/i18n/pl/lib/calculator.rb +0 -14
  282. data/examples/i18n/pt/Rakefile +0 -6
  283. data/examples/i18n/pt/features/adicao.feature +0 -11
  284. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +0 -20
  285. data/examples/i18n/pt/features/support/env.rb +0 -5
  286. data/examples/i18n/pt/lib/calculadora.rb +0 -10
  287. data/examples/i18n/ro/Rakefile +0 -6
  288. data/examples/i18n/ro/features/adunare.feature +0 -12
  289. data/examples/i18n/ro/features/step_definitions/calculator_steps.rb +0 -21
  290. data/examples/i18n/ro/lib/calculator.rb +0 -11
  291. data/examples/i18n/ru/Rakefile +0 -6
  292. data/examples/i18n/ru/features/addition.feature +0 -11
  293. data/examples/i18n/ru/features/consecutive_calculations.feature +0 -17
  294. data/examples/i18n/ru/features/division.feature +0 -16
  295. data/examples/i18n/ru/features/step_definitions/calculator_steps.rb +0 -19
  296. data/examples/i18n/ru/features/support/env.rb +0 -5
  297. data/examples/i18n/ru/features/support/world.rb +0 -8
  298. data/examples/i18n/ru/lib/calculator.rb +0 -24
  299. data/examples/i18n/sk/Rakefile +0 -6
  300. data/examples/i18n/sk/features/addition.feature +0 -17
  301. data/examples/i18n/sk/features/division.feature +0 -10
  302. data/examples/i18n/sk/features/step_definitions/calculator_steps.rb +0 -24
  303. data/examples/i18n/sk/lib/calculator.rb +0 -14
  304. data/examples/i18n/sr-Cyrl/Rakefile +0 -6
  305. data/examples/i18n/sr-Cyrl/features/sabiranje.feature +0 -18
  306. data/examples/i18n/sr-Cyrl/features/step_definitions/calculator_steps.rb +0 -20
  307. data/examples/i18n/sr-Cyrl/features/support/env.rb +0 -5
  308. data/examples/i18n/sr-Cyrl/lib/calculator.rb +0 -12
  309. data/examples/i18n/sr-Latn/Rakefile +0 -6
  310. data/examples/i18n/sr-Latn/features/sabiranje.feature +0 -18
  311. data/examples/i18n/sr-Latn/features/step_definitions/calculator_steps.rb +0 -24
  312. data/examples/i18n/sr-Latn/lib/calculator.rb +0 -12
  313. data/examples/i18n/sv/Rakefile +0 -6
  314. data/examples/i18n/sv/features/step_definitions/kalkulator_steps.rb +0 -24
  315. data/examples/i18n/sv/features/summering.feature +0 -18
  316. data/examples/i18n/sv/lib/kalkulator.rb +0 -11
  317. data/examples/i18n/tr/Rakefile +0 -6
  318. data/examples/i18n/tr/features/bolme.feature +0 -10
  319. data/examples/i18n/tr/features/step_definitions/hesap_makinesi_adimlari.rb +0 -24
  320. data/examples/i18n/tr/features/toplama.feature +0 -18
  321. data/examples/i18n/tr/lib/hesap_makinesi.rb +0 -15
  322. data/examples/i18n/uk/Rakefile +0 -6
  323. data/examples/i18n/uk/features/addition.feature +0 -11
  324. data/examples/i18n/uk/features/consecutive_calculations.feature +0 -17
  325. data/examples/i18n/uk/features/division.feature +0 -16
  326. data/examples/i18n/uk/features/step_definitions/calculator_steps.rb +0 -19
  327. data/examples/i18n/uk/features/support/env.rb +0 -5
  328. data/examples/i18n/uk/features/support/world.rb +0 -8
  329. data/examples/i18n/uk/lib/calculator.rb +0 -24
  330. data/examples/i18n/uz/Rakefile +0 -6
  331. data/examples/i18n/uz/features/addition.feature +0 -10
  332. data/examples/i18n/uz/features/consecutive_calculations.feature +0 -17
  333. data/examples/i18n/uz/features/division.feature +0 -17
  334. data/examples/i18n/uz/features/step_definitions/calculator_steps.rb +0 -19
  335. data/examples/i18n/uz/features/support/env.rb +0 -5
  336. data/examples/i18n/uz/features/support/world.rb +0 -8
  337. data/examples/i18n/uz/lib/calculator.rb +0 -24
  338. data/examples/i18n/zh-CN/Rakefile +0 -4
  339. data/examples/i18n/zh-CN/features/addition.feature +0 -18
  340. data/examples/i18n/zh-CN/features/step_definitions/calculator_steps.rb +0 -26
  341. data/examples/i18n/zh-CN/lib/calculator.rb +0 -10
  342. data/examples/i18n/zh-TW/Rakefile +0 -4
  343. data/examples/i18n/zh-TW/features/addition.feature +0 -17
  344. data/examples/i18n/zh-TW/features/division.feature +0 -11
  345. data/examples/i18n/zh-TW/features/step_definitions/calculator_steps.rb +0 -24
  346. data/examples/i18n/zh-TW/lib/calculator.rb +0 -14
  347. data/examples/rspec_doubles/Rakefile +0 -4
  348. data/examples/rspec_doubles/features/mocking.feature +0 -9
  349. data/examples/rspec_doubles/features/step_definitions/calvin_steps.rb +0 -19
  350. data/examples/rspec_doubles/features/support/env.rb +0 -12
  351. data/examples/sinatra/README.textile +0 -13
  352. data/examples/sinatra/Rakefile +0 -6
  353. data/examples/sinatra/app.rb +0 -14
  354. data/examples/sinatra/features/add.feature +0 -11
  355. data/examples/sinatra/features/step_definitions/add_steps.rb +0 -15
  356. data/examples/sinatra/features/support/env.rb +0 -10
  357. data/examples/sinatra/views/add.erb +0 -7
  358. data/examples/sinatra/views/layout.erb +0 -8
  359. data/examples/tcl/README.textile +0 -11
  360. data/examples/tcl/Rakefile +0 -6
  361. data/examples/tcl/features/fibonnacci.feature +0 -17
  362. data/examples/tcl/features/step_definitions/fib_steps.rb +0 -7
  363. data/examples/tcl/features/support/env.rb +0 -6
  364. data/examples/tcl/src/fib.tcl +0 -3
  365. data/examples/test_unit/Gemfile +0 -4
  366. data/examples/test_unit/Rakefile +0 -6
  367. data/examples/test_unit/features/step_definitions/test_unit_steps.rb +0 -20
  368. data/examples/test_unit/features/test_unit.feature +0 -9
  369. data/examples/watir/README.textile +0 -16
  370. data/examples/watir/Rakefile +0 -12
  371. data/examples/watir/cucumber.yml +0 -1
  372. data/examples/watir/features/search.feature +0 -12
  373. data/examples/watir/features/step_definitions/search_steps.rb +0 -26
  374. data/examples/watir/features/support/env.rb +0 -35
  375. data/examples/watir/features/support/screenshots.rb +0 -47
  376. data/features/docs/api/list_step_defs_as_json.feature +0 -64
  377. data/features/docs/api/listen_for_events.feature +0 -59
  378. data/features/docs/api/run_cli_main_with_existing_runtime.feature +0 -27
  379. data/features/docs/cli/backtraces.feature +0 -36
  380. data/features/docs/cli/dry_run.feature +0 -73
  381. data/features/docs/cli/exclude_files.feature +0 -18
  382. data/features/docs/cli/execute_with_tag_filter.feature +0 -117
  383. data/features/docs/cli/fail_fast.feature +0 -48
  384. data/features/docs/cli/finding_steps.feature +0 -28
  385. data/features/docs/cli/help.feature +0 -8
  386. data/features/docs/cli/i18n.feature +0 -42
  387. data/features/docs/cli/randomize.feature +0 -140
  388. data/features/docs/cli/require.feature +0 -27
  389. data/features/docs/cli/retry_failing_tests.feature +0 -92
  390. data/features/docs/cli/run_scenarios_matching_name.feature +0 -105
  391. data/features/docs/cli/run_specific_scenarios.feature +0 -77
  392. data/features/docs/cli/showing_differences.feature +0 -43
  393. data/features/docs/cli/specifying_multiple_formatters.feature +0 -68
  394. data/features/docs/cli/strict_mode.feature +0 -70
  395. data/features/docs/defining_steps/nested_steps.feature +0 -181
  396. data/features/docs/defining_steps/nested_steps_i18n.feature +0 -37
  397. data/features/docs/defining_steps/nested_steps_with_second_arg.feature +0 -56
  398. data/features/docs/defining_steps/one_line_step_definitions.feature +0 -65
  399. data/features/docs/defining_steps/printing_messages.feature +0 -147
  400. data/features/docs/defining_steps/skip_scenario.feature +0 -31
  401. data/features/docs/defining_steps/snippets.feature +0 -56
  402. data/features/docs/defining_steps/table_diffing.feature +0 -50
  403. data/features/docs/events/gherkin_source_read_event.feature +0 -43
  404. data/features/docs/events/step_activated_event.feature +0 -36
  405. data/features/docs/events/step_definition_registered_event.feature +0 -29
  406. data/features/docs/events/test_case_finished_event.feature +0 -35
  407. data/features/docs/events/test_case_starting_event.feature +0 -54
  408. data/features/docs/events/test_run_finished_event.feature +0 -40
  409. data/features/docs/events/test_run_starting_event.feature +0 -41
  410. data/features/docs/events/test_step_finished_event.feature +0 -47
  411. data/features/docs/events/test_step_starting_event.feature +0 -43
  412. data/features/docs/exception_in_after_hook.feature +0 -127
  413. data/features/docs/exception_in_after_step_hook.feature +0 -104
  414. data/features/docs/exception_in_around_hook.feature +0 -80
  415. data/features/docs/exception_in_before_hook.feature +0 -98
  416. data/features/docs/extending_cucumber/custom_filter.feature +0 -29
  417. data/features/docs/extending_cucumber/custom_formatter.feature +0 -122
  418. data/features/docs/formatters/api_methods.feature +0 -37
  419. data/features/docs/formatters/formatter_step_file_colon_line.feature +0 -44
  420. data/features/docs/formatters/html_formatter.feature +0 -91
  421. data/features/docs/formatters/json_formatter.feature +0 -767
  422. data/features/docs/formatters/junit_formatter.feature +0 -455
  423. data/features/docs/formatters/pretty_formatter.feature +0 -74
  424. data/features/docs/formatters/progress_formatter.feature +0 -32
  425. data/features/docs/formatters/rerun_formatter.feature +0 -190
  426. data/features/docs/formatters/summary_formatter.feature +0 -35
  427. data/features/docs/formatters/usage_formatter.feature +0 -101
  428. data/features/docs/getting_started.feature +0 -28
  429. data/features/docs/gherkin/background.feature +0 -548
  430. data/features/docs/gherkin/doc_strings.feature +0 -76
  431. data/features/docs/gherkin/expand_option_for_outlines.feature +0 -47
  432. data/features/docs/gherkin/language_from_header.feature +0 -32
  433. data/features/docs/gherkin/outlines.feature +0 -160
  434. data/features/docs/gherkin/unicode_table.feature +0 -33
  435. data/features/docs/gherkin/using_descriptions.feature +0 -83
  436. data/features/docs/gherkin/using_star_notation.feature +0 -37
  437. data/features/docs/iso-8859-1.feature +0 -6
  438. data/features/docs/post_configuration_hook.feature +0 -33
  439. data/features/docs/profiles.feature +0 -120
  440. data/features/docs/rake_task.feature +0 -146
  441. data/features/docs/raketask.feature +0 -46
  442. data/features/docs/work_in_progress.feature +0 -157
  443. data/features/docs/writing_support_code/after_hooks.feature +0 -102
  444. data/features/docs/writing_support_code/after_step_hooks.feature +0 -55
  445. data/features/docs/writing_support_code/around_hooks.feature +0 -266
  446. data/features/docs/writing_support_code/before_hook.feature +0 -66
  447. data/features/docs/writing_support_code/hook_order.feature +0 -63
  448. data/features/docs/writing_support_code/load_path.feature +0 -17
  449. data/features/docs/writing_support_code/parameter_types.feature +0 -75
  450. data/features/docs/writing_support_code/state.feature +0 -32
  451. data/features/docs/writing_support_code/tagged_hooks.feature +0 -95
  452. data/features/docs/writing_support_code/world.feature +0 -129
  453. data/features/lib/step_definitions/aruba_steps.rb +0 -21
  454. data/features/lib/step_definitions/cli_steps.rb +0 -4
  455. data/features/lib/step_definitions/cucumber_steps.rb +0 -75
  456. data/features/lib/step_definitions/iso-8859-1_steps.rb +0 -13
  457. data/features/lib/step_definitions/json_steps.rb +0 -8
  458. data/features/lib/step_definitions/junit_steps.rb +0 -14
  459. data/features/lib/step_definitions/language_steps.rb +0 -9
  460. data/features/lib/step_definitions/profile_steps.rb +0 -16
  461. data/features/lib/step_definitions/retry_steps.rb +0 -55
  462. data/features/lib/step_definitions/ruby_steps.rb +0 -4
  463. data/features/lib/support/env.rb +0 -22
  464. data/features/lib/support/fake_wire_server.rb +0 -86
  465. data/features/lib/support/feature_factory.rb +0 -68
  466. data/features/lib/support/normalise_output.rb +0 -52
  467. data/features/lib/support/parameter_types.rb +0 -8
  468. data/gem_tasks/contributors.rake +0 -19
  469. data/gem_tasks/cov.rake +0 -6
  470. data/gem_tasks/downloads.rb +0 -8
  471. data/gem_tasks/environment.rake +0 -4
  472. data/gem_tasks/examples.rake +0 -12
  473. data/gem_tasks/fix_cr_lf.rake +0 -11
  474. data/gem_tasks/flog.rake +0 -5
  475. data/gem_tasks/rspec.rake +0 -7
  476. data/gem_tasks/sass.rake +0 -5
  477. data/gem_tasks/stats +0 -16
  478. data/gem_tasks/versions.txt +0 -74
  479. data/lib/cucumber/formatter/cucumber.css +0 -286
  480. data/lib/cucumber/formatter/cucumber.sass +0 -247
  481. data/lib/cucumber/formatter/hook_query_visitor.rb +0 -41
  482. data/lib/cucumber/formatter/html_builder.rb +0 -110
  483. data/lib/cucumber/formatter/inline-js.js +0 -30
  484. data/lib/cucumber/formatter/jquery-min.js +0 -154
  485. data/lib/cucumber/formatter/json_pretty.rb +0 -11
  486. data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1012
  487. data/lib/cucumber/formatter/legacy_api/ast.rb +0 -386
  488. data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
  489. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
  490. data/lib/cucumber/step_argument.rb +0 -24
  491. data/scripts/invite-collaborator +0 -40
  492. data/scripts/update-history +0 -83
  493. data/spec/cucumber/cli/configuration_spec.rb +0 -434
  494. data/spec/cucumber/cli/main_spec.rb +0 -84
  495. data/spec/cucumber/cli/options_spec.rb +0 -445
  496. data/spec/cucumber/cli/profile_loader_spec.rb +0 -66
  497. data/spec/cucumber/cli/rerun_spec.rb +0 -86
  498. data/spec/cucumber/configuration_spec.rb +0 -148
  499. data/spec/cucumber/constantize_spec.rb +0 -20
  500. data/spec/cucumber/events_spec.rb +0 -9
  501. data/spec/cucumber/file_specs_spec.rb +0 -61
  502. data/spec/cucumber/filters/activate_steps_spec.rb +0 -152
  503. data/spec/cucumber/filters/gated_receiver_spec.rb +0 -48
  504. data/spec/cucumber/filters/retry_spec.rb +0 -98
  505. data/spec/cucumber/filters/tag_limits/test_case_index_spec.rb +0 -39
  506. data/spec/cucumber/filters/tag_limits/verifier_spec.rb +0 -58
  507. data/spec/cucumber/filters/tag_limits_spec.rb +0 -60
  508. data/spec/cucumber/formatter/ansicolor_spec.rb +0 -33
  509. data/spec/cucumber/formatter/backtrace_filter_spec.rb +0 -32
  510. data/spec/cucumber/formatter/console_counts_spec.rb +0 -14
  511. data/spec/cucumber/formatter/duration_spec.rb +0 -23
  512. data/spec/cucumber/formatter/fail_fast_spec.rb +0 -88
  513. data/spec/cucumber/formatter/html_spec.rb +0 -543
  514. data/spec/cucumber/formatter/interceptor_spec.rb +0 -137
  515. data/spec/cucumber/formatter/json_spec.rb +0 -840
  516. data/spec/cucumber/formatter/junit_spec.rb +0 -251
  517. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +0 -2187
  518. data/spec/cucumber/formatter/pretty_spec.rb +0 -920
  519. data/spec/cucumber/formatter/progress_spec.rb +0 -170
  520. data/spec/cucumber/formatter/rerun_spec.rb +0 -97
  521. data/spec/cucumber/formatter/spec_helper.rb +0 -84
  522. data/spec/cucumber/glue/proto_world_spec.rb +0 -63
  523. data/spec/cucumber/glue/registry_and_more_spec.rb +0 -213
  524. data/spec/cucumber/glue/snippet_spec.rb +0 -174
  525. data/spec/cucumber/glue/step_definition_spec.rb +0 -207
  526. data/spec/cucumber/hooks_spec.rb +0 -31
  527. data/spec/cucumber/multiline_argument/data_table_spec.rb +0 -648
  528. data/spec/cucumber/project_initializer_spec.rb +0 -88
  529. data/spec/cucumber/rake/forked_spec.rb +0 -54
  530. data/spec/cucumber/rake/task_spec.rb +0 -86
  531. data/spec/cucumber/running_test_case_spec.rb +0 -140
  532. data/spec/cucumber/runtime/for_programming_languages_spec.rb +0 -8
  533. data/spec/cucumber/runtime/support_code_spec.rb +0 -17
  534. data/spec/cucumber/runtime_spec.rb +0 -21
  535. data/spec/cucumber/sell_cucumbers.feature +0 -19
  536. data/spec/cucumber/step_argument_spec.rb +0 -19
  537. data/spec/cucumber/step_match_search_spec.rb +0 -113
  538. data/spec/cucumber/step_match_spec.rb +0 -86
  539. data/spec/cucumber/world/pending_spec.rb +0 -48
  540. data/spec/spec_helper.rb +0 -30
  541. data/spec/support/standard_step_actions.rb +0 -19
@@ -0,0 +1,93 @@
1
+ require 'net/http'
2
+
3
+ module Cucumber
4
+ module Formatter
5
+ class HTTPIO
6
+ class << self
7
+ # Returns an IO that will write to a HTTP request's body
8
+ def open(url, https_verify_mode = nil)
9
+ @https_verify_mode = https_verify_mode
10
+ uri, method, headers = build_uri_method_headers(url)
11
+
12
+ @req = build_request(uri, method, headers)
13
+ @http = build_client(uri, https_verify_mode)
14
+
15
+ read_io, write_io = IO.pipe
16
+ @req.body_stream = read_io
17
+
18
+ class << write_io
19
+ attr_writer :request_thread
20
+
21
+ def start_request(http, req)
22
+ @req_thread = Thread.new do
23
+ begin
24
+ res = http.request(req)
25
+ raise StandardError, "request to #{req.uri} failed with status #{res.code}" if res.code.to_i >= 400
26
+ rescue StandardError => e
27
+ @http_error = e
28
+ end
29
+ end
30
+ end
31
+
32
+ def close
33
+ super
34
+ begin
35
+ @req_thread.join
36
+ rescue StandardError
37
+ nil
38
+ end
39
+ raise @http_error unless @http_error.nil?
40
+ end
41
+ end
42
+ write_io.start_request(@http, @req)
43
+
44
+ write_io
45
+ end
46
+
47
+ def build_uri_method_headers(url)
48
+ uri = URI(url)
49
+ query_pairs = uri.query ? URI.decode_www_form(uri.query) : []
50
+
51
+ # Build headers from query parameters prefixed with http- and extract HTTP method
52
+ http_query_pairs = query_pairs.select { |pair| pair[0] =~ /^http-/ }
53
+ http_query_hash_without_prefix = Hash[http_query_pairs.map do |pair|
54
+ [
55
+ pair[0][5..-1].downcase, # remove http- prefix
56
+ pair[1]
57
+ ]
58
+ end]
59
+ method = http_query_hash_without_prefix.delete('method') || 'POST'
60
+ headers = {
61
+ 'transfer-encoding' => 'chunked'
62
+ }.merge(http_query_hash_without_prefix)
63
+
64
+ # Update the query with the http-* parameters removed
65
+ remaining_query_pairs = query_pairs - http_query_pairs
66
+ new_query_hash = Hash[remaining_query_pairs]
67
+ uri.query = URI.encode_www_form(new_query_hash) unless new_query_hash.empty?
68
+ [uri, method, headers]
69
+ end
70
+
71
+ private
72
+
73
+ def build_request(uri, method, headers)
74
+ method_class_name = "#{method[0].upcase}#{method[1..-1].downcase}"
75
+ req = Net::HTTP.const_get(method_class_name).new(uri)
76
+ headers.each do |header, value|
77
+ req[header] = value
78
+ end
79
+ req
80
+ end
81
+
82
+ def build_client(uri, https_verify_mode)
83
+ http = Net::HTTP.new(uri.hostname, uri.port)
84
+ if uri.scheme == 'https'
85
+ http.use_ssl = true
86
+ http.verify_mode = https_verify_mode if https_verify_mode
87
+ end
88
+ http
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -1,21 +1,19 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Cucumber
3
4
  module Formatter
4
-
5
5
  class IgnoreMissingMessages < BasicObject
6
6
  def initialize(receiver)
7
7
  @receiver = receiver
8
8
  end
9
9
 
10
10
  def method_missing(message, *args)
11
- @receiver.send(message, *args) if @receiver.respond_to?(message)
11
+ @receiver.respond_to?(message) ? @receiver.send(message, *args) : super
12
12
  end
13
13
 
14
14
  def respond_to_missing?(name, include_private = false)
15
15
  @receiver.respond_to?(name, include_private)
16
16
  end
17
17
  end
18
-
19
18
  end
20
19
  end
21
-
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'thread'
3
2
 
4
3
  module Cucumber
5
4
  module Formatter
@@ -8,7 +7,7 @@ module Cucumber
8
7
  attr_reader :pipe
9
8
  def initialize(pipe)
10
9
  @pipe = pipe
11
- @buffer = []
10
+ @buffer = StringIO.new
12
11
  @wrapped = true
13
12
  end
14
13
 
@@ -19,9 +18,9 @@ module Cucumber
19
18
  end
20
19
  end
21
20
 
22
- def buffer
21
+ def buffer_string
23
22
  lock.synchronize do
24
- return @buffer.dup
23
+ return @buffer.string.dup
25
24
  end
26
25
  end
27
26
 
@@ -31,17 +30,15 @@ module Cucumber
31
30
  end
32
31
 
33
32
  def method_missing(method, *args, &blk)
34
- @pipe.send(method, *args, &blk)
33
+ @pipe.send(method, *args, &blk) || super
35
34
  end
36
35
 
37
- def respond_to?(method, include_private=false)
36
+ def respond_to_missing?(method, include_private = false)
38
37
  super || @pipe.respond_to?(method, include_private)
39
38
  end
40
39
 
41
40
  def self.validate_pipe(pipe)
42
- unless [:stdout, :stderr].include? pipe
43
- raise ArgumentError, '#wrap only accepts :stderr or :stdout'
44
- end
41
+ raise ArgumentError, '#wrap only accepts :stderr or :stdout' unless %i[stdout stderr].include? pipe
45
42
  end
46
43
 
47
44
  def self.unwrap!(pipe)
@@ -63,17 +60,18 @@ module Cucumber
63
60
 
64
61
  case pipe
65
62
  when :stderr
66
- $stderr = self.new($stderr)
63
+ $stderr = new($stderr)
67
64
  return $stderr
68
65
  when :stdout
69
- $stdout = self.new($stdout)
66
+ $stdout = new($stdout)
70
67
  return $stdout
71
68
  end
72
69
  end
73
70
 
74
71
  private
72
+
75
73
  def lock
76
- @lock||=Mutex.new
74
+ @lock ||= Mutex.new
77
75
  end
78
76
  end
79
77
  end
@@ -1,34 +1,41 @@
1
1
  # frozen_string_literal: true
2
+
3
+ require 'cucumber/formatter/http_io'
4
+
2
5
  module Cucumber
3
6
  module Formatter
4
7
  module Io
5
8
  module_function
6
9
 
7
- def ensure_io(path_or_io)
8
- return nil if path_or_io.nil?
9
- return path_or_io if path_or_io.respond_to?(:write)
10
- file = File.open(path_or_io, Cucumber.file_mode('w'))
10
+ def ensure_io(path_or_url_or_io)
11
+ return nil if path_or_url_or_io.nil?
12
+ return path_or_url_or_io if path_or_url_or_io.respond_to?(:write)
13
+ io = if path_or_url_or_io.match(%r{^https?://})
14
+ HTTPIO.open(path_or_url_or_io)
15
+ else
16
+ File.open(path_or_url_or_io, Cucumber.file_mode('w'))
17
+ end
11
18
  at_exit do
12
- unless file.closed?
13
- file.flush
14
- file.close
19
+ unless io.closed?
20
+ io.flush
21
+ io.close
15
22
  end
16
23
  end
17
- file
24
+ io
18
25
  end
19
26
 
20
27
  def ensure_file(path, name)
21
- raise "You *must* specify --out FILE for the #{name} formatter" unless String === path
28
+ raise "You *must* specify --out FILE for the #{name} formatter" unless String == path.class
22
29
  raise "I can't write #{name} to a directory - it has to be a file" if File.directory?(path)
23
- raise "I can't write #{name} to a file in the non-existing directory #{File.dirname(path)}" if !File.directory?(File.dirname(path))
30
+ raise "I can't write #{name} to a file in the non-existing directory #{File.dirname(path)}" unless File.directory?(File.dirname(path))
24
31
  ensure_io(path)
25
32
  end
26
33
 
27
34
  def ensure_dir(path, name)
28
- raise "You *must* specify --out DIR for the #{name} formatter" unless String === path
35
+ raise "You *must* specify --out DIR for the #{name} formatter" unless String == path.class
29
36
  raise "I can't write #{name} reports to a file - it has to be a directory" if File.file?(path)
30
37
  FileUtils.mkdir_p(path) unless File.directory?(path)
31
- path
38
+ File.absolute_path path
32
39
  end
33
40
  end
34
41
  end
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
- require 'multi_json'
2
+
3
+ require 'json'
3
4
  require 'base64'
4
5
  require 'cucumber/formatter/backtrace_filter'
5
6
  require 'cucumber/formatter/io'
6
- require 'cucumber/formatter/hook_query_visitor'
7
+ require 'cucumber/formatter/ast_lookup'
8
+ require 'cucumber/deprecate'
7
9
 
8
10
  module Cucumber
9
11
  module Formatter
@@ -12,47 +14,59 @@ module Cucumber
12
14
  include Io
13
15
 
14
16
  def initialize(config)
17
+ Cucumber::Deprecate::CliOption.deprecate(
18
+ config.error_stream,
19
+ '--format=json',
20
+ "Please use --format=message and stand-alone json-formatter.\n" \
21
+ 'json-formatter homepage: https://github.com/cucumber/cucumber/tree/master/json-formatter#cucumber-json-formatter',
22
+ '5.0.0'
23
+ )
24
+
15
25
  @io = ensure_io(config.out_stream)
26
+ @ast_lookup = AstLookup.new(config)
16
27
  @feature_hashes = []
17
- config.on_event :test_case_starting, &method(:on_test_case_starting)
28
+ @step_or_hook_hash = {}
29
+ config.on_event :test_case_started, &method(:on_test_case_started)
18
30
  config.on_event :test_case_finished, &method(:on_test_case_finished)
19
- config.on_event :test_step_starting, &method(:on_test_step_starting)
31
+ config.on_event :test_step_started, &method(:on_test_step_started)
20
32
  config.on_event :test_step_finished, &method(:on_test_step_finished)
21
33
  config.on_event :test_run_finished, &method(:on_test_run_finished)
22
34
  end
23
35
 
24
- def on_test_case_starting(event)
36
+ def on_test_case_started(event)
25
37
  test_case = event.test_case
26
- builder = Builder.new(test_case)
27
- unless same_feature_as_previous_test_case?(test_case.feature)
38
+ builder = Builder.new(test_case, @ast_lookup)
39
+ unless same_feature_as_previous_test_case?(test_case)
28
40
  @feature_hash = builder.feature_hash
29
41
  @feature_hashes << @feature_hash
30
42
  end
31
43
  @test_case_hash = builder.test_case_hash
32
44
  if builder.background?
45
+ @in_background = true
33
46
  feature_elements << builder.background_hash
34
47
  @element_hash = builder.background_hash
35
48
  else
49
+ @in_background = false
36
50
  feature_elements << @test_case_hash
37
51
  @element_hash = @test_case_hash
38
52
  end
39
53
  @any_step_failed = false
40
54
  end
41
55
 
42
- def on_test_step_starting(event)
56
+ def on_test_step_started(event)
43
57
  test_step = event.test_step
44
58
  return if internal_hook?(test_step)
45
- hook_query = HookQueryVisitor.new(test_step)
46
- if hook_query.hook?
59
+ if test_step.hook?
47
60
  @step_or_hook_hash = {}
48
- hooks_of_type(hook_query) << @step_or_hook_hash
61
+ hooks_of_type(test_step) << @step_or_hook_hash
49
62
  return
50
63
  end
51
64
  if first_step_after_background?(test_step)
65
+ @in_background = false
52
66
  feature_elements << @test_case_hash
53
67
  @element_hash = @test_case_hash
54
68
  end
55
- @step_or_hook_hash = create_step_hash(test_step.source.last)
69
+ @step_or_hook_hash = create_step_hash(test_step)
56
70
  steps << @step_or_hook_hash
57
71
  @step_hash = @step_or_hook_hash
58
72
  end
@@ -72,44 +86,42 @@ module Cucumber
72
86
  end
73
87
 
74
88
  def on_test_run_finished(_event)
75
- @io.write(MultiJson.dump(@feature_hashes, pretty: true))
89
+ @io.write(JSON.generate(@feature_hashes, pretty: true))
76
90
  end
77
91
 
78
- def puts(message)
79
- test_step_output << message
80
- end
81
-
82
- def embed(src, mime_type, _label)
92
+ def attach(src, mime_type)
93
+ if mime_type == 'text/x.cucumber.log+plain'
94
+ test_step_output << src
95
+ return
96
+ end
83
97
  if File.file?(src)
84
- content = File.open(src, 'rb') { |f| f.read }
98
+ content = File.open(src, 'rb', &:read)
85
99
  data = encode64(content)
100
+ elsif mime_type =~ /;base64$/
101
+ mime_type = mime_type[0..-8]
102
+ data = src
86
103
  else
87
- if mime_type =~ /;base64$/
88
- mime_type = mime_type[0..-8]
89
- data = src
90
- else
91
- data = encode64(src)
92
- end
104
+ data = encode64(src)
93
105
  end
94
106
  test_step_embeddings << { mime_type: mime_type, data: data }
95
107
  end
96
108
 
97
109
  private
98
110
 
99
- def same_feature_as_previous_test_case?(feature)
100
- current_feature[:uri] == feature.file && current_feature[:line] == feature.location.line
111
+ def same_feature_as_previous_test_case?(test_case)
112
+ current_feature[:uri] == test_case.location.file
101
113
  end
102
114
 
103
115
  def first_step_after_background?(test_step)
104
- test_step.source[1].name != @element_hash[:name]
116
+ @in_background && test_step.location.lines.max >= @test_case_hash[:line]
105
117
  end
106
118
 
107
119
  def internal_hook?(test_step)
108
- test_step.source.last.location.file.include?('lib/cucumber/')
120
+ test_step.location.file.include?('lib/cucumber/')
109
121
  end
110
122
 
111
123
  def current_feature
112
- @feature_hash ||= {}
124
+ @feature_hash ||= {} # rubocop:disable Naming/MemoizedInstanceVariableName
113
125
  end
114
126
 
115
127
  def feature_elements
@@ -120,16 +132,16 @@ module Cucumber
120
132
  @element_hash[:steps] ||= []
121
133
  end
122
134
 
123
- def hooks_of_type(hook_query)
124
- case hook_query.type
125
- when :before
126
- return before_hooks
127
- when :after
128
- return after_hooks
129
- when :after_step
130
- return after_step_hooks
135
+ def hooks_of_type(hook_step)
136
+ case hook_step.text
137
+ when 'Before hook'
138
+ before_hooks
139
+ when 'After hook'
140
+ after_hooks
141
+ when 'AfterStep hook'
142
+ after_step_hooks
131
143
  else
132
- fail 'Unkown hook type ' + hook_query.type.to_s
144
+ raise 'Unknown hook type ' + hook_step.to_s
133
145
  end
134
146
  end
135
147
 
@@ -157,20 +169,20 @@ module Cucumber
157
169
  @step_or_hook_hash[:embeddings] ||= []
158
170
  end
159
171
 
160
- def create_step_hash(step_source)
172
+ def create_step_hash(test_step)
173
+ step_source = @ast_lookup.step_source(test_step).step
161
174
  step_hash = {
162
175
  keyword: step_source.keyword,
163
- name: step_source.name,
164
- line: step_source.location.line
176
+ name: test_step.text,
177
+ line: test_step.location.lines.min
165
178
  }
166
- step_hash[:comments] = Formatter.create_comments_array(step_source.comments) unless step_source.comments.empty?
167
- step_hash[:doc_string] = create_doc_string_hash(step_source.multiline_arg) if step_source.multiline_arg.doc_string?
168
- step_hash[:rows] = create_data_table_value(step_source.multiline_arg) if step_source.multiline_arg.data_table?
179
+ step_hash[:doc_string] = create_doc_string_hash(step_source.doc_string) unless step_source.doc_string.nil?
180
+ step_hash[:rows] = create_data_table_value(step_source.data_table) unless step_source.data_table.nil?
169
181
  step_hash
170
182
  end
171
183
 
172
184
  def create_doc_string_hash(doc_string)
173
- content_type = doc_string.content_type ? doc_string.content_type : ''
185
+ content_type = doc_string.media_type || ''
174
186
  {
175
187
  value: doc_string.content,
176
188
  content_type: content_type,
@@ -179,14 +191,15 @@ module Cucumber
179
191
  end
180
192
 
181
193
  def create_data_table_value(data_table)
182
- data_table.raw.map do |row|
183
- { cells: row }
194
+ data_table.rows.map do |row|
195
+ { cells: row.cells.map(&:value) }
184
196
  end
185
197
  end
186
198
 
187
199
  def add_match_and_result(test_step, result)
188
200
  @step_or_hook_hash[:match] = create_match_hash(test_step, result)
189
201
  @step_or_hook_hash[:result] = create_result_hash(result)
202
+ result.embeddings.each { |e| embed(e['src'], e['mime_type'], e['label']) } if result.respond_to?(:embeddings)
190
203
  end
191
204
 
192
205
  def add_failed_around_hook(result)
@@ -224,113 +237,94 @@ module Cucumber
224
237
  class Builder
225
238
  attr_reader :feature_hash, :background_hash, :test_case_hash
226
239
 
227
- def initialize(test_case)
240
+ def initialize(test_case, ast_lookup)
228
241
  @background_hash = nil
229
- test_case.describe_source_to(self)
230
- test_case.feature.background.describe_to(self)
242
+ uri = test_case.location.file
243
+ feature = ast_lookup.gherkin_document(uri).feature
244
+ feature(feature, uri)
245
+ background(feature.children.first.background) unless feature.children.first.background.nil?
246
+ scenario(ast_lookup.scenario_source(test_case), test_case)
231
247
  end
232
248
 
233
249
  def background?
234
250
  @background_hash != nil
235
251
  end
236
252
 
237
- def feature(feature)
253
+ def feature(feature, uri)
238
254
  @feature_hash = {
239
- uri: feature.file,
240
- id: create_id(feature),
255
+ id: create_id(feature.name),
256
+ uri: uri,
241
257
  keyword: feature.keyword,
242
258
  name: feature.name,
243
- description: feature.description,
259
+ description: value_or_empty_string(feature.description),
244
260
  line: feature.location.line
245
261
  }
246
- unless feature.tags.empty?
247
- @feature_hash[:tags] = create_tags_array(feature.tags)
248
- @test_case_hash[:tags] = if @test_case_hash[:tags]
249
- @feature_hash[:tags] + @test_case_hash[:tags]
250
- else
251
- @feature_hash[:tags]
252
- end
253
- end
254
- @feature_hash[:comments] = Formatter.create_comments_array(feature.comments) unless feature.comments.empty?
255
- @test_case_hash[:id].insert(0, @feature_hash[:id] + ';')
262
+ return if feature.tags.empty?
263
+ @feature_hash[:tags] = create_tags_array_from_hash_array(feature.tags)
256
264
  end
257
265
 
258
266
  def background(background)
259
267
  @background_hash = {
260
268
  keyword: background.keyword,
261
269
  name: background.name,
262
- description: background.description,
270
+ description: value_or_empty_string(background.description),
263
271
  line: background.location.line,
264
272
  type: 'background'
265
273
  }
266
- @background_hash[:comments] = Formatter.create_comments_array(background.comments) unless background.comments.empty?
267
274
  end
268
275
 
269
- def scenario(scenario)
276
+ def scenario(scenario_source, test_case)
277
+ scenario = scenario_source.type == :Scenario ? scenario_source.scenario : scenario_source.scenario_outline
270
278
  @test_case_hash = {
271
- id: create_id(scenario),
279
+ id: "#{@feature_hash[:id]};#{create_id_from_scenario_source(scenario_source)}",
272
280
  keyword: scenario.keyword,
273
- name: scenario.name,
274
- description: scenario.description,
275
- line: scenario.location.line,
281
+ name: test_case.name,
282
+ description: value_or_empty_string(scenario.description),
283
+ line: test_case.location.lines.max,
276
284
  type: 'scenario'
277
285
  }
278
- @test_case_hash[:tags] = create_tags_array(scenario.tags) unless scenario.tags.empty?
279
- @test_case_hash[:comments] = Formatter.create_comments_array(scenario.comments) unless scenario.comments.empty?
286
+ @test_case_hash[:tags] = create_tags_array_from_tags_array(test_case.tags) unless test_case.tags.empty?
280
287
  end
281
288
 
282
- def scenario_outline(scenario)
283
- @test_case_hash = {
284
- id: create_id(scenario) + ';' + @example_id,
285
- keyword: scenario.keyword,
286
- name: scenario.name,
287
- description: scenario.description,
288
- line: @row.location.line,
289
- type: 'scenario'
290
- }
291
- tags = []
292
- tags += create_tags_array(scenario.tags) unless scenario.tags.empty?
293
- tags += @examples_table_tags if @examples_table_tags
294
- @test_case_hash[:tags] = tags unless tags.empty?
295
- comments = []
296
- comments += Formatter.create_comments_array(scenario.comments) unless scenario.comments.empty?
297
- comments += @examples_table_comments if @examples_table_comments
298
- comments += @row_comments if @row_comments
299
- @test_case_hash[:comments] = comments unless comments.empty?
300
- end
289
+ private
301
290
 
302
- def examples_table(examples_table)
303
- # the json file have traditionally used the header row as row 1,
304
- # wheras cucumber-ruby-core used the first example row as row 1.
305
- @example_id = create_id(examples_table) + ";#{@row.number + 1}"
291
+ def value_or_empty_string(value)
292
+ value.nil? ? '' : value
293
+ end
306
294
 
307
- @examples_table_tags = create_tags_array(examples_table.tags) unless examples_table.tags.empty?
308
- @examples_table_comments = Formatter.create_comments_array(examples_table.comments) unless examples_table.comments.empty?
295
+ def create_id(name)
296
+ name.downcase.tr(' ', '-')
309
297
  end
310
298
 
311
- def examples_table_row(row)
312
- @row = row
313
- @row_comments = Formatter.create_comments_array(row.comments) unless row.comments.empty?
299
+ def create_id_from_scenario_source(scenario_source)
300
+ if scenario_source.type == :Scenario
301
+ create_id(scenario_source.scenario.name)
302
+ else
303
+ scenario_outline_name = scenario_source.scenario_outline.name
304
+ examples_name = scenario_source.examples.name
305
+ row_number = calculate_row_number(scenario_source)
306
+ "#{create_id(scenario_outline_name)};#{create_id(examples_name)};#{row_number}"
307
+ end
314
308
  end
315
309
 
316
- private
310
+ def calculate_row_number(scenario_source)
311
+ scenario_source.examples.table_body.each_with_index do |row, index|
312
+ return index + 2 if row == scenario_source.row
313
+ end
314
+ end
317
315
 
318
- def create_id(element)
319
- element.name.downcase.tr(' ', '-')
316
+ def create_tags_array_from_hash_array(tags)
317
+ tags_array = []
318
+ tags.each { |tag| tags_array << { name: tag.name, line: tag.location.line } }
319
+ tags_array
320
320
  end
321
321
 
322
- def create_tags_array(tags)
322
+ def create_tags_array_from_tags_array(tags)
323
323
  tags_array = []
324
324
  tags.each { |tag| tags_array << { name: tag.name, line: tag.location.line } }
325
325
  tags_array
326
326
  end
327
327
  end
328
328
  end
329
-
330
- def self.create_comments_array(comments)
331
- comments_array = []
332
- comments.each { |comment| comments_array << { value: comment.to_s.strip, line: comment.location.line } }
333
- comments_array
334
- end
335
329
  end
336
330
  end