cucumber 2.0.0.rc.4 → 4.0.0.rc.2

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 (518) hide show
  1. checksums.yaml +5 -5
  2. data/{History.md → CHANGELOG.md} +734 -283
  3. data/CONTRIBUTING.md +26 -23
  4. data/LICENSE +1 -1
  5. data/README.md +25 -8
  6. data/bin/cucumber +3 -3
  7. data/lib/autotest/cucumber.rb +2 -0
  8. data/lib/autotest/cucumber_mixin.rb +45 -48
  9. data/lib/autotest/cucumber_rails.rb +2 -0
  10. data/lib/autotest/cucumber_rails_rspec.rb +2 -0
  11. data/lib/autotest/cucumber_rails_rspec2.rb +2 -0
  12. data/lib/autotest/cucumber_rspec.rb +2 -0
  13. data/lib/autotest/cucumber_rspec2.rb +2 -0
  14. data/lib/autotest/discover.rb +4 -2
  15. data/lib/cucumber.rb +3 -9
  16. data/lib/cucumber/cli/configuration.rb +23 -106
  17. data/lib/cucumber/cli/main.rb +45 -25
  18. data/lib/cucumber/cli/options.rb +411 -223
  19. data/lib/cucumber/cli/profile_loader.rb +64 -38
  20. data/lib/cucumber/cli/rerun_file.rb +31 -0
  21. data/lib/cucumber/configuration.rb +240 -8
  22. data/lib/cucumber/constantize.rb +9 -10
  23. data/lib/cucumber/core_ext/string.rb +3 -1
  24. data/lib/cucumber/deprecate.rb +30 -0
  25. data/lib/cucumber/encoding.rb +7 -0
  26. data/lib/cucumber/errors.rb +17 -8
  27. data/lib/cucumber/events.rb +40 -0
  28. data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
  29. data/lib/cucumber/events/gherkin_source_read.rb +14 -0
  30. data/lib/cucumber/events/step_activated.rb +26 -0
  31. data/lib/cucumber/events/step_definition_registered.rb +20 -0
  32. data/lib/cucumber/events/test_case_finished.rb +14 -0
  33. data/lib/cucumber/events/test_case_started.rb +11 -0
  34. data/lib/cucumber/events/test_run_finished.rb +11 -0
  35. data/lib/cucumber/events/test_run_started.rb +14 -0
  36. data/lib/cucumber/events/test_step_finished.rb +14 -0
  37. data/lib/cucumber/events/test_step_started.rb +11 -0
  38. data/lib/cucumber/file_specs.rb +8 -6
  39. data/lib/cucumber/filters.rb +4 -0
  40. data/lib/cucumber/filters/activate_steps.rb +48 -7
  41. data/lib/cucumber/filters/apply_after_hooks.rb +2 -0
  42. data/lib/cucumber/filters/apply_after_step_hooks.rb +2 -0
  43. data/lib/cucumber/filters/apply_around_hooks.rb +2 -0
  44. data/lib/cucumber/filters/apply_before_hooks.rb +2 -0
  45. data/lib/cucumber/filters/broadcast_test_run_started_event.rb +28 -0
  46. data/lib/cucumber/filters/gated_receiver.rb +2 -2
  47. data/lib/cucumber/filters/prepare_world.rb +13 -11
  48. data/lib/cucumber/filters/quit.rb +4 -7
  49. data/lib/cucumber/filters/randomizer.rb +10 -5
  50. data/lib/cucumber/filters/retry.rb +32 -0
  51. data/lib/cucumber/filters/tag_limits.rb +6 -5
  52. data/lib/cucumber/filters/tag_limits/test_case_index.rb +2 -2
  53. data/lib/cucumber/filters/tag_limits/verifier.rb +5 -7
  54. data/lib/cucumber/formatter/ansicolor.rb +39 -45
  55. data/lib/cucumber/formatter/ast_lookup.rb +165 -0
  56. data/lib/cucumber/formatter/backtrace_filter.rb +54 -0
  57. data/lib/cucumber/formatter/console.rb +93 -115
  58. data/lib/cucumber/formatter/console_counts.rb +39 -0
  59. data/lib/cucumber/formatter/console_issues.rb +61 -0
  60. data/lib/cucumber/formatter/duration.rb +3 -1
  61. data/lib/cucumber/formatter/duration_extractor.rb +31 -0
  62. data/lib/cucumber/formatter/fail_fast.rb +23 -0
  63. data/lib/cucumber/formatter/fanout.rb +4 -3
  64. data/lib/cucumber/formatter/ignore_missing_messages.rb +3 -4
  65. data/lib/cucumber/formatter/interceptor.rb +13 -14
  66. data/lib/cucumber/formatter/io.rb +10 -5
  67. data/lib/cucumber/formatter/json.rb +310 -8
  68. data/lib/cucumber/formatter/junit.rb +175 -110
  69. data/lib/cucumber/formatter/pretty.rb +359 -154
  70. data/lib/cucumber/formatter/progress.rb +78 -72
  71. data/lib/cucumber/formatter/rerun.rb +34 -17
  72. data/lib/cucumber/formatter/stepdefs.rb +3 -2
  73. data/lib/cucumber/formatter/steps.rb +7 -7
  74. data/lib/cucumber/formatter/summary.rb +50 -20
  75. data/lib/cucumber/formatter/unicode.rb +17 -18
  76. data/lib/cucumber/formatter/usage.rb +61 -54
  77. data/lib/cucumber/gherkin/data_table_parser.rb +44 -0
  78. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +97 -0
  79. data/lib/cucumber/gherkin/formatter/escaping.rb +19 -0
  80. data/lib/cucumber/gherkin/i18n.rb +17 -0
  81. data/lib/cucumber/gherkin/steps_parser.rb +42 -0
  82. data/lib/cucumber/{rb_support/rb_dsl.rb → glue/dsl.rb} +47 -26
  83. data/lib/cucumber/glue/hook.rb +51 -0
  84. data/lib/cucumber/glue/invoke_in_world.rb +65 -0
  85. data/lib/cucumber/glue/proto_world.rb +219 -0
  86. data/lib/cucumber/glue/registry_and_more.rb +192 -0
  87. data/lib/cucumber/glue/snippet.rb +205 -0
  88. data/lib/cucumber/glue/step_definition.rb +142 -0
  89. data/lib/cucumber/glue/world_factory.rb +21 -0
  90. data/lib/cucumber/hooks.rb +34 -21
  91. data/lib/cucumber/load_path.rb +2 -0
  92. data/lib/cucumber/multiline_argument.rb +10 -24
  93. data/lib/cucumber/multiline_argument/data_table.rb +157 -253
  94. data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +154 -0
  95. data/lib/cucumber/multiline_argument/doc_string.rb +3 -2
  96. data/lib/cucumber/platform.rb +7 -10
  97. data/lib/cucumber/project_initializer.rb +44 -0
  98. data/lib/cucumber/rake/task.rb +37 -29
  99. data/lib/cucumber/rspec/disable_option_parser.rb +11 -8
  100. data/lib/cucumber/rspec/doubles.rb +3 -1
  101. data/lib/cucumber/running_test_case.rb +60 -0
  102. data/lib/cucumber/runtime.rb +84 -78
  103. data/lib/cucumber/runtime/after_hooks.rb +10 -7
  104. data/lib/cucumber/runtime/before_hooks.rb +12 -6
  105. data/lib/cucumber/runtime/for_programming_languages.rb +14 -44
  106. data/lib/cucumber/runtime/step_hooks.rb +8 -4
  107. data/lib/cucumber/runtime/support_code.rb +55 -159
  108. data/lib/cucumber/runtime/user_interface.rb +15 -24
  109. data/lib/cucumber/step_definition_light.rb +10 -6
  110. data/lib/cucumber/step_definitions.rb +6 -4
  111. data/lib/cucumber/step_match.rb +58 -38
  112. data/lib/cucumber/step_match_search.rb +67 -0
  113. data/lib/cucumber/term/ansicolor.rb +40 -39
  114. data/lib/cucumber/unit.rb +2 -0
  115. data/lib/cucumber/version +1 -0
  116. data/{spec → lib}/simplecov_setup.rb +3 -1
  117. metadata +260 -607
  118. data/.coveralls.yml +0 -1
  119. data/.rspec +0 -1
  120. data/.ruby-gemset +0 -1
  121. data/.travis.yml +0 -18
  122. data/.yardopts +0 -1
  123. data/Gemfile +0 -11
  124. data/Rakefile +0 -22
  125. data/bin/cuke +0 -60
  126. data/cucumber.gemspec +0 -50
  127. data/cucumber.yml +0 -20
  128. data/examples/i18n/README.textile +0 -3
  129. data/examples/i18n/Rakefile +0 -33
  130. data/examples/i18n/ar/Rakefile +0 -6
  131. data/examples/i18n/ar/features/addition.feature +0 -17
  132. data/examples/i18n/ar/features/step_definitions/calculator_steps.rb +0 -24
  133. data/examples/i18n/ar/lib/calculator.rb +0 -11
  134. data/examples/i18n/bg/Rakefile +0 -6
  135. data/examples/i18n/bg/features/addition.feature +0 -12
  136. data/examples/i18n/bg/features/consecutive_calculations.feature +0 -19
  137. data/examples/i18n/bg/features/division.feature +0 -17
  138. data/examples/i18n/bg/features/step_definitions/calculator_steps.rb +0 -24
  139. data/examples/i18n/bg/features/support/env.rb +0 -5
  140. data/examples/i18n/bg/features/support/world.rb +0 -8
  141. data/examples/i18n/bg/lib/calculator.rb +0 -24
  142. data/examples/i18n/ca/Rakefile +0 -6
  143. data/examples/i18n/ca/features/step_definitions/calculator_steps.rb +0 -21
  144. data/examples/i18n/ca/features/suma.feature +0 -17
  145. data/examples/i18n/ca/lib/calculadora.rb +0 -16
  146. data/examples/i18n/cs/Rakefile +0 -6
  147. data/examples/i18n/cs/features/addition.feature +0 -17
  148. data/examples/i18n/cs/features/division.feature +0 -11
  149. data/examples/i18n/cs/features/step_definitions/calculator_steps.rb +0 -24
  150. data/examples/i18n/cs/lib/calculator.rb +0 -14
  151. data/examples/i18n/da/Rakefile +0 -6
  152. data/examples/i18n/da/features/sammenlaegning.feature +0 -18
  153. data/examples/i18n/da/features/step_definitions/lommeregner_steps.rb +0 -24
  154. data/examples/i18n/da/lib/lommeregner.rb +0 -11
  155. data/examples/i18n/de/Rakefile +0 -6
  156. data/examples/i18n/de/features/addition.feature +0 -17
  157. data/examples/i18n/de/features/division.feature +0 -10
  158. data/examples/i18n/de/features/step_definitions/calculator_steps.rb +0 -24
  159. data/examples/i18n/de/lib/calculator.rb +0 -14
  160. data/examples/i18n/el/Rakefile +0 -6
  161. data/examples/i18n/el/features/addition.feature +0 -17
  162. data/examples/i18n/el/features/division.feature +0 -10
  163. data/examples/i18n/el/features/step_definitions/calculator_steps.rb +0 -24
  164. data/examples/i18n/el/lib/calculator.rb +0 -14
  165. data/examples/i18n/en-lol/Rakefile +0 -4
  166. data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +0 -16
  167. data/examples/i18n/en-lol/features/stuffing.feature +0 -8
  168. data/examples/i18n/en-lol/features/support/env.rb +0 -7
  169. data/examples/i18n/en-lol/lib/basket.rb +0 -12
  170. data/examples/i18n/en-lol/lib/belly.rb +0 -11
  171. data/examples/i18n/en/Rakefile +0 -6
  172. data/examples/i18n/en/features/addition.feature +0 -17
  173. data/examples/i18n/en/features/division.feature +0 -10
  174. data/examples/i18n/en/features/step_definitions/calculator_steps.rb +0 -24
  175. data/examples/i18n/en/lib/calculator.rb +0 -14
  176. data/examples/i18n/eo/Rakefile +0 -6
  177. data/examples/i18n/eo/features/adicio.feature +0 -17
  178. data/examples/i18n/eo/features/divido.feature +0 -10
  179. data/examples/i18n/eo/features/step_definitions/calculator_steps.rb +0 -24
  180. data/examples/i18n/eo/lib/calculator.rb +0 -14
  181. data/examples/i18n/es/Rakefile +0 -6
  182. data/examples/i18n/es/features/adicion.feature +0 -17
  183. data/examples/i18n/es/features/step_definitions/calculador_steps.rb +0 -21
  184. data/examples/i18n/es/lib/calculador.rb +0 -14
  185. data/examples/i18n/et/Rakefile +0 -6
  186. data/examples/i18n/et/features/jagamine.feature +0 -10
  187. data/examples/i18n/et/features/liitmine.feature +0 -17
  188. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +0 -24
  189. data/examples/i18n/et/lib/kalkulaator.rb +0 -14
  190. data/examples/i18n/fi/Rakefile +0 -6
  191. data/examples/i18n/fi/features/jakolasku.feature +0 -10
  192. data/examples/i18n/fi/features/step_definitions/laskin_steps.rb +0 -24
  193. data/examples/i18n/fi/features/yhteenlasku.feature +0 -17
  194. data/examples/i18n/fi/lib/laskin.rb +0 -14
  195. data/examples/i18n/fr/Rakefile +0 -8
  196. data/examples/i18n/fr/features/addition.feature +0 -18
  197. data/examples/i18n/fr/features/addition2.feature +0 -17
  198. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +0 -32
  199. data/examples/i18n/fr/features/support/env.rb +0 -5
  200. data/examples/i18n/fr/lib/calculatrice.rb +0 -10
  201. data/examples/i18n/he/Rakefile +0 -6
  202. data/examples/i18n/he/features/addition.feature +0 -17
  203. data/examples/i18n/he/features/division.feature +0 -10
  204. data/examples/i18n/he/features/step_definitions/calculator_steps.rb +0 -24
  205. data/examples/i18n/he/lib/calculator.rb +0 -15
  206. data/examples/i18n/hi/Rakefile +0 -6
  207. data/examples/i18n/hi/features/addition.feature +0 -16
  208. data/examples/i18n/hi/features/division.feature +0 -10
  209. data/examples/i18n/hi/features/step_definitions/calculator_steps.rb +0 -24
  210. data/examples/i18n/hi/lib/calculator.rb +0 -15
  211. data/examples/i18n/hu/Rakefile +0 -6
  212. data/examples/i18n/hu/features/osszeadas.feature +0 -17
  213. data/examples/i18n/hu/features/osztas.feature +0 -10
  214. data/examples/i18n/hu/features/step_definitions/calculator_steps.rb +0 -25
  215. data/examples/i18n/hu/lib/calculator.rb +0 -14
  216. data/examples/i18n/id/Rakefile +0 -6
  217. data/examples/i18n/id/features/addition.feature +0 -17
  218. data/examples/i18n/id/features/division.feature +0 -10
  219. data/examples/i18n/id/features/step_definitions/calculator_steps.rb +0 -24
  220. data/examples/i18n/id/lib/calculator.rb +0 -14
  221. data/examples/i18n/it/Rakefile +0 -6
  222. data/examples/i18n/it/features/somma.feature +0 -11
  223. data/examples/i18n/it/features/step_definitions/calcolatrice_steps.rb +0 -24
  224. data/examples/i18n/it/lib/calcolatrice.rb +0 -11
  225. data/examples/i18n/ja/Rakefile +0 -6
  226. data/examples/i18n/ja/features/addition.feature +0 -17
  227. data/examples/i18n/ja/features/division.feature +0 -10
  228. data/examples/i18n/ja/features/step_definitions/calculator_steps.rb +0 -19
  229. data/examples/i18n/ja/features/support/env.rb +0 -5
  230. data/examples/i18n/ja/lib/calculator.rb +0 -14
  231. data/examples/i18n/ko/Rakefile +0 -6
  232. data/examples/i18n/ko/features/addition.feature +0 -17
  233. data/examples/i18n/ko/features/division.feature +0 -11
  234. data/examples/i18n/ko/features/step_definitions/calculator_steps.rb +0 -24
  235. data/examples/i18n/ko/lib/calculator.rb +0 -14
  236. data/examples/i18n/lt/Rakefile +0 -6
  237. data/examples/i18n/lt/features/addition.feature +0 -17
  238. data/examples/i18n/lt/features/division.feature +0 -10
  239. data/examples/i18n/lt/features/step_definitions/calculator_steps.rb +0 -24
  240. data/examples/i18n/lt/lib/calculator.rb +0 -14
  241. data/examples/i18n/lv/Rakefile +0 -6
  242. data/examples/i18n/lv/features/addition.feature +0 -17
  243. data/examples/i18n/lv/features/division.feature +0 -10
  244. data/examples/i18n/lv/features/step_definitions/calculator_steps.rb +0 -24
  245. data/examples/i18n/lv/lib/calculator.rb +0 -14
  246. data/examples/i18n/no/Rakefile +0 -6
  247. data/examples/i18n/no/features/step_definitions/kalkulator_steps.rb +0 -17
  248. data/examples/i18n/no/features/summering.feature +0 -19
  249. data/examples/i18n/no/features/support/env.rb +0 -6
  250. data/examples/i18n/no/lib/kalkulator.rb +0 -11
  251. data/examples/i18n/pl/Rakefile +0 -6
  252. data/examples/i18n/pl/features/addition.feature +0 -17
  253. data/examples/i18n/pl/features/division.feature +0 -10
  254. data/examples/i18n/pl/features/step_definitions/calculator_steps.rb +0 -24
  255. data/examples/i18n/pl/features/support/env.rb +0 -5
  256. data/examples/i18n/pl/lib/calculator.rb +0 -14
  257. data/examples/i18n/pt/Rakefile +0 -6
  258. data/examples/i18n/pt/features/adicao.feature +0 -11
  259. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +0 -20
  260. data/examples/i18n/pt/features/support/env.rb +0 -5
  261. data/examples/i18n/pt/lib/calculadora.rb +0 -10
  262. data/examples/i18n/ro/Rakefile +0 -6
  263. data/examples/i18n/ro/features/adunare.feature +0 -12
  264. data/examples/i18n/ro/features/step_definitions/calculator_steps.rb +0 -21
  265. data/examples/i18n/ro/lib/calculator.rb +0 -11
  266. data/examples/i18n/ru/Rakefile +0 -6
  267. data/examples/i18n/ru/features/addition.feature +0 -11
  268. data/examples/i18n/ru/features/consecutive_calculations.feature +0 -17
  269. data/examples/i18n/ru/features/division.feature +0 -16
  270. data/examples/i18n/ru/features/step_definitions/calculator_steps.rb +0 -19
  271. data/examples/i18n/ru/features/support/env.rb +0 -5
  272. data/examples/i18n/ru/features/support/world.rb +0 -8
  273. data/examples/i18n/ru/lib/calculator.rb +0 -24
  274. data/examples/i18n/sk/Rakefile +0 -6
  275. data/examples/i18n/sk/features/addition.feature +0 -17
  276. data/examples/i18n/sk/features/division.feature +0 -10
  277. data/examples/i18n/sk/features/step_definitions/calculator_steps.rb +0 -24
  278. data/examples/i18n/sk/lib/calculator.rb +0 -14
  279. data/examples/i18n/sr-Cyrl/Rakefile +0 -6
  280. data/examples/i18n/sr-Cyrl/features/sabiranje.feature +0 -18
  281. data/examples/i18n/sr-Cyrl/features/step_definitions/calculator_steps.rb +0 -20
  282. data/examples/i18n/sr-Cyrl/features/support/env.rb +0 -5
  283. data/examples/i18n/sr-Cyrl/lib/calculator.rb +0 -12
  284. data/examples/i18n/sr-Latn/Rakefile +0 -6
  285. data/examples/i18n/sr-Latn/features/sabiranje.feature +0 -18
  286. data/examples/i18n/sr-Latn/features/step_definitions/calculator_steps.rb +0 -24
  287. data/examples/i18n/sr-Latn/lib/calculator.rb +0 -12
  288. data/examples/i18n/sv/Rakefile +0 -6
  289. data/examples/i18n/sv/features/step_definitions/kalkulator_steps.rb +0 -24
  290. data/examples/i18n/sv/features/summering.feature +0 -18
  291. data/examples/i18n/sv/lib/kalkulator.rb +0 -11
  292. data/examples/i18n/tr/Rakefile +0 -6
  293. data/examples/i18n/tr/features/bolme.feature +0 -10
  294. data/examples/i18n/tr/features/step_definitions/hesap_makinesi_adimlari.rb +0 -24
  295. data/examples/i18n/tr/features/toplama.feature +0 -18
  296. data/examples/i18n/tr/lib/hesap_makinesi.rb +0 -15
  297. data/examples/i18n/uk/Rakefile +0 -6
  298. data/examples/i18n/uk/features/addition.feature +0 -11
  299. data/examples/i18n/uk/features/consecutive_calculations.feature +0 -17
  300. data/examples/i18n/uk/features/division.feature +0 -16
  301. data/examples/i18n/uk/features/step_definitions/calculator_steps.rb +0 -19
  302. data/examples/i18n/uk/features/support/env.rb +0 -5
  303. data/examples/i18n/uk/features/support/world.rb +0 -8
  304. data/examples/i18n/uk/lib/calculator.rb +0 -24
  305. data/examples/i18n/uz/Rakefile +0 -6
  306. data/examples/i18n/uz/features/addition.feature +0 -10
  307. data/examples/i18n/uz/features/consecutive_calculations.feature +0 -17
  308. data/examples/i18n/uz/features/division.feature +0 -17
  309. data/examples/i18n/uz/features/step_definitions/calculator_steps.rb +0 -19
  310. data/examples/i18n/uz/features/support/env.rb +0 -5
  311. data/examples/i18n/uz/features/support/world.rb +0 -8
  312. data/examples/i18n/uz/lib/calculator.rb +0 -24
  313. data/examples/i18n/zh-CN/Rakefile +0 -4
  314. data/examples/i18n/zh-CN/features/addition.feature +0 -18
  315. data/examples/i18n/zh-CN/features/step_definitions/calculator_steps.rb +0 -26
  316. data/examples/i18n/zh-CN/lib/calculator.rb +0 -10
  317. data/examples/i18n/zh-TW/Rakefile +0 -4
  318. data/examples/i18n/zh-TW/features/addition.feature +0 -17
  319. data/examples/i18n/zh-TW/features/division.feature +0 -11
  320. data/examples/i18n/zh-TW/features/step_definitions/calculator_steps.rb +0 -24
  321. data/examples/i18n/zh-TW/lib/calculator.rb +0 -14
  322. data/examples/rspec_doubles/Rakefile +0 -4
  323. data/examples/rspec_doubles/features/mocking.feature +0 -9
  324. data/examples/rspec_doubles/features/step_definitions/calvin_steps.rb +0 -19
  325. data/examples/rspec_doubles/features/support/env.rb +0 -12
  326. data/examples/sinatra/README.textile +0 -13
  327. data/examples/sinatra/Rakefile +0 -6
  328. data/examples/sinatra/app.rb +0 -14
  329. data/examples/sinatra/features/add.feature +0 -11
  330. data/examples/sinatra/features/step_definitions/add_steps.rb +0 -15
  331. data/examples/sinatra/features/support/env.rb +0 -10
  332. data/examples/sinatra/views/add.erb +0 -7
  333. data/examples/sinatra/views/layout.erb +0 -8
  334. data/examples/tcl/README.textile +0 -11
  335. data/examples/tcl/Rakefile +0 -6
  336. data/examples/tcl/features/fibonnacci.feature +0 -17
  337. data/examples/tcl/features/step_definitions/fib_steps.rb +0 -7
  338. data/examples/tcl/features/support/env.rb +0 -6
  339. data/examples/tcl/src/fib.tcl +0 -3
  340. data/examples/test_unit/Gemfile +0 -4
  341. data/examples/test_unit/Rakefile +0 -6
  342. data/examples/test_unit/features/step_definitions/test_unit_steps.rb +0 -20
  343. data/examples/test_unit/features/test_unit.feature +0 -9
  344. data/examples/watir/README.textile +0 -16
  345. data/examples/watir/Rakefile +0 -12
  346. data/examples/watir/cucumber.yml +0 -1
  347. data/examples/watir/features/search.feature +0 -12
  348. data/examples/watir/features/step_definitions/search_steps.rb +0 -26
  349. data/examples/watir/features/support/env.rb +0 -35
  350. data/examples/watir/features/support/screenshots.rb +0 -47
  351. data/features/docs/api/list_step_defs_as_json.feature +0 -50
  352. data/features/docs/api/run_cli_main_with_existing_runtime.feature +0 -29
  353. data/features/docs/cli/backtraces.feature +0 -36
  354. data/features/docs/cli/dry_run.feature +0 -25
  355. data/features/docs/cli/exclude_files.feature +0 -19
  356. data/features/docs/cli/execute_with_tag_filter.feature +0 -117
  357. data/features/docs/cli/randomize.feature +0 -46
  358. data/features/docs/cli/require.feature +0 -27
  359. data/features/docs/cli/run_scenarios_matching_name.feature +0 -104
  360. data/features/docs/cli/run_specific_scenarios.feature +0 -130
  361. data/features/docs/cli/showing_differences.feature +0 -43
  362. data/features/docs/cli/specifying_multiple_formatters.feature +0 -44
  363. data/features/docs/cli/strict_mode.feature +0 -41
  364. data/features/docs/defining_steps/nested_steps.feature +0 -129
  365. data/features/docs/defining_steps/nested_steps_i18n.feature +0 -34
  366. data/features/docs/defining_steps/nested_steps_with_second_arg.feature +0 -73
  367. data/features/docs/defining_steps/one_line_step_definitions.feature +0 -65
  368. data/features/docs/defining_steps/printing_messages.feature +0 -148
  369. data/features/docs/defining_steps/skip_scenario.feature +0 -62
  370. data/features/docs/defining_steps/snippets.feature +0 -56
  371. data/features/docs/defining_steps/table_diffing.feature +0 -50
  372. data/features/docs/defining_steps/transforms.feature +0 -63
  373. data/features/docs/exception_in_after_hook.feature +0 -126
  374. data/features/docs/exception_in_after_step_hook.feature +0 -102
  375. data/features/docs/exception_in_before_hook.feature +0 -96
  376. data/features/docs/extending_cucumber/custom_filter.feature +0 -29
  377. data/features/docs/extending_cucumber/custom_formatter.feature +0 -94
  378. data/features/docs/formatters/debug_formatter.feature +0 -47
  379. data/features/docs/formatters/formatter_step_file_colon_line.feature +0 -44
  380. data/features/docs/formatters/html_formatter.feature +0 -90
  381. data/features/docs/formatters/json_formatter.feature +0 -696
  382. data/features/docs/formatters/junit_formatter.feature +0 -276
  383. data/features/docs/formatters/pretty_formatter.feature +0 -73
  384. data/features/docs/formatters/progress_formatter.feature +0 -31
  385. data/features/docs/formatters/rerun_formatter.feature +0 -136
  386. data/features/docs/formatters/usage_formatter.feature +0 -102
  387. data/features/docs/getting_started.feature +0 -27
  388. data/features/docs/gherkin/background.feature +0 -559
  389. data/features/docs/gherkin/doc_strings.feature +0 -74
  390. data/features/docs/gherkin/expand_option_for_outlines.feature +0 -46
  391. data/features/docs/gherkin/language_from_header.feature +0 -32
  392. data/features/docs/gherkin/language_help.feature +0 -37
  393. data/features/docs/gherkin/outlines.feature +0 -158
  394. data/features/docs/gherkin/unicode_table.feature +0 -32
  395. data/features/docs/gherkin/using_descriptions.feature +0 -88
  396. data/features/docs/gherkin/using_star_notation.feature +0 -37
  397. data/features/docs/iso-8859-1.feature +0 -6
  398. data/features/docs/post_configuration_hook.feature +0 -49
  399. data/features/docs/profiles.feature +0 -120
  400. data/features/docs/rake_task.feature +0 -141
  401. data/features/docs/raketask.feature +0 -44
  402. data/features/docs/report_called_undefined_steps.feature +0 -57
  403. data/features/docs/wire_protocol.feature +0 -337
  404. data/features/docs/wire_protocol_erb.feature +0 -56
  405. data/features/docs/wire_protocol_table_diffing.feature +0 -125
  406. data/features/docs/wire_protocol_tags.feature +0 -86
  407. data/features/docs/wire_protocol_timeouts.feature +0 -63
  408. data/features/docs/work_in_progress.feature +0 -154
  409. data/features/docs/writing_support_code/after_hooks.feature +0 -56
  410. data/features/docs/writing_support_code/around_hooks.feature +0 -229
  411. data/features/docs/writing_support_code/before_hook.feature +0 -61
  412. data/features/docs/writing_support_code/hook_order.feature +0 -61
  413. data/features/docs/writing_support_code/load_path.feature +0 -17
  414. data/features/docs/writing_support_code/state.feature +0 -32
  415. data/features/docs/writing_support_code/tagged_hooks.feature +0 -57
  416. data/features/lib/step_definitions/aruba_steps.rb +0 -22
  417. data/features/lib/step_definitions/cucumber_steps.rb +0 -50
  418. data/features/lib/step_definitions/iso-8859-1_steps.rb +0 -12
  419. data/features/lib/step_definitions/json_steps.rb +0 -7
  420. data/features/lib/step_definitions/junit_steps.rb +0 -13
  421. data/features/lib/step_definitions/language_steps.rb +0 -8
  422. data/features/lib/step_definitions/profile_steps.rb +0 -15
  423. data/features/lib/step_definitions/ruby_steps.rb +0 -3
  424. data/features/lib/step_definitions/wire_steps.rb +0 -41
  425. data/features/lib/support/env.rb +0 -21
  426. data/features/lib/support/fake_wire_server.rb +0 -77
  427. data/features/lib/support/feature_factory.rb +0 -67
  428. data/features/lib/support/normalise_output.rb +0 -33
  429. data/gem_tasks/contributors.rake +0 -15
  430. data/gem_tasks/cov.rake +0 -5
  431. data/gem_tasks/cucumber.rake +0 -25
  432. data/gem_tasks/downloads.rb +0 -7
  433. data/gem_tasks/environment.rake +0 -7
  434. data/gem_tasks/examples.rake +0 -11
  435. data/gem_tasks/fix_cr_lf.rake +0 -10
  436. data/gem_tasks/flog.rake +0 -4
  437. data/gem_tasks/rspec.rake +0 -6
  438. data/gem_tasks/sass.rake +0 -4
  439. data/gem_tasks/stats +0 -16
  440. data/gem_tasks/versions.txt +0 -74
  441. data/lib/cucumber/ast.rb +0 -13
  442. data/lib/cucumber/ast/facade.rb +0 -117
  443. data/lib/cucumber/core_ext/instance_exec.rb +0 -70
  444. data/lib/cucumber/core_ext/proc.rb +0 -36
  445. data/lib/cucumber/formatter/cucumber.css +0 -285
  446. data/lib/cucumber/formatter/cucumber.sass +0 -247
  447. data/lib/cucumber/formatter/debug.rb +0 -35
  448. data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +0 -201
  449. data/lib/cucumber/formatter/gpretty.rb +0 -24
  450. data/lib/cucumber/formatter/html.rb +0 -674
  451. data/lib/cucumber/formatter/jquery-min.js +0 -154
  452. data/lib/cucumber/formatter/json_pretty.rb +0 -10
  453. data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1024
  454. data/lib/cucumber/formatter/legacy_api/ast.rb +0 -376
  455. data/lib/cucumber/formatter/legacy_api/results.rb +0 -51
  456. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -30
  457. data/lib/cucumber/language_support.rb +0 -30
  458. data/lib/cucumber/language_support/language_methods.rb +0 -71
  459. data/lib/cucumber/rb_support/rb_hook.rb +0 -18
  460. data/lib/cucumber/rb_support/rb_language.rb +0 -160
  461. data/lib/cucumber/rb_support/rb_step_definition.rb +0 -122
  462. data/lib/cucumber/rb_support/rb_transform.rb +0 -59
  463. data/lib/cucumber/rb_support/rb_world.rb +0 -142
  464. data/lib/cucumber/rb_support/regexp_argument_matcher.rb +0 -21
  465. data/lib/cucumber/rb_support/snippet.rb +0 -149
  466. data/lib/cucumber/wire_support/configuration.rb +0 -38
  467. data/lib/cucumber/wire_support/connection.rb +0 -61
  468. data/lib/cucumber/wire_support/request_handler.rb +0 -32
  469. data/lib/cucumber/wire_support/wire_exception.rb +0 -32
  470. data/lib/cucumber/wire_support/wire_language.rb +0 -68
  471. data/lib/cucumber/wire_support/wire_packet.rb +0 -34
  472. data/lib/cucumber/wire_support/wire_protocol.rb +0 -43
  473. data/lib/cucumber/wire_support/wire_protocol/requests.rb +0 -133
  474. data/lib/cucumber/wire_support/wire_step_definition.rb +0 -19
  475. data/spec/cucumber/cli/configuration_spec.rb +0 -503
  476. data/spec/cucumber/cli/main_spec.rb +0 -105
  477. data/spec/cucumber/cli/options_spec.rb +0 -335
  478. data/spec/cucumber/cli/profile_loader_spec.rb +0 -46
  479. data/spec/cucumber/configuration_spec.rb +0 -23
  480. data/spec/cucumber/constantize_spec.rb +0 -19
  481. data/spec/cucumber/core_ext/proc_spec.rb +0 -69
  482. data/spec/cucumber/file_specs_spec.rb +0 -60
  483. data/spec/cucumber/filters/activate_steps_spec.rb +0 -57
  484. data/spec/cucumber/filters/gated_receiver_spec.rb +0 -47
  485. data/spec/cucumber/filters/tag_limits/test_case_index_spec.rb +0 -38
  486. data/spec/cucumber/filters/tag_limits/verifier_spec.rb +0 -57
  487. data/spec/cucumber/filters/tag_limits_spec.rb +0 -59
  488. data/spec/cucumber/formatter/ansicolor_spec.rb +0 -32
  489. data/spec/cucumber/formatter/debug_spec.rb +0 -64
  490. data/spec/cucumber/formatter/duration_spec.rb +0 -22
  491. data/spec/cucumber/formatter/html_spec.rb +0 -459
  492. data/spec/cucumber/formatter/interceptor_spec.rb +0 -136
  493. data/spec/cucumber/formatter/junit_spec.rb +0 -196
  494. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +0 -2002
  495. data/spec/cucumber/formatter/pretty_spec.rb +0 -810
  496. data/spec/cucumber/formatter/progress_spec.rb +0 -85
  497. data/spec/cucumber/formatter/rerun_spec.rb +0 -107
  498. data/spec/cucumber/formatter/spec_helper.rb +0 -67
  499. data/spec/cucumber/hooks_spec.rb +0 -30
  500. data/spec/cucumber/multiline_argument/data_table_spec.rb +0 -514
  501. data/spec/cucumber/rake/forked_spec.rb +0 -53
  502. data/spec/cucumber/rb_support/rb_language_spec.rb +0 -279
  503. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +0 -152
  504. data/spec/cucumber/rb_support/rb_transform_spec.rb +0 -46
  505. data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +0 -22
  506. data/spec/cucumber/rb_support/snippet_spec.rb +0 -137
  507. data/spec/cucumber/runtime/for_programming_languages_spec.rb +0 -36
  508. data/spec/cucumber/runtime/support_code_spec.rb +0 -123
  509. data/spec/cucumber/runtime_spec.rb +0 -46
  510. data/spec/cucumber/sell_cucumbers.feature +0 -19
  511. data/spec/cucumber/step_match_spec.rb +0 -79
  512. data/spec/cucumber/wire_support/configuration_spec.rb +0 -64
  513. data/spec/cucumber/wire_support/connection_spec.rb +0 -64
  514. data/spec/cucumber/wire_support/wire_exception_spec.rb +0 -50
  515. data/spec/cucumber/wire_support/wire_language_spec.rb +0 -46
  516. data/spec/cucumber/wire_support/wire_packet_spec.rb +0 -44
  517. data/spec/cucumber/world/pending_spec.rb +0 -46
  518. data/spec/spec_helper.rb +0 -32
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cucumber
2
4
  module Formatter
3
5
  module Duration
@@ -6,7 +8,7 @@ module Cucumber
6
8
  # <tt>time</tt> format.
7
9
  def format_duration(seconds)
8
10
  m, s = seconds.divmod(60)
9
- "#{m}m#{'%.3f' % s}s"
11
+ "#{m}m#{format('%<seconds>.3f', seconds: s)}s"
10
12
  end
11
13
  end
12
14
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cucumber
4
+ module Formatter
5
+ class DurationExtractor
6
+ attr_reader :result_duration
7
+ def initialize(result)
8
+ @result_duration = 0
9
+ result.describe_to(self)
10
+ end
11
+
12
+ def passed(*) end
13
+
14
+ def failed(*) end
15
+
16
+ def undefined(*) end
17
+
18
+ def skipped(*) end
19
+
20
+ def pending(*) end
21
+
22
+ def exception(*) end
23
+
24
+ def duration(duration, *)
25
+ duration.tap { |dur| @result_duration = dur.nanoseconds / 10**9.0 }
26
+ end
27
+
28
+ def embed(*) end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cucumber/formatter/io'
4
+ require 'cucumber/formatter/console'
5
+
6
+ module Cucumber
7
+ module Formatter
8
+ class FailFast
9
+ def initialize(configuration)
10
+ @previous_test_case = nil
11
+ configuration.on_event :test_case_finished do |event|
12
+ test_case, result = *event.attributes
13
+ if test_case != @previous_test_case
14
+ @previous_test_case = event.test_case
15
+ Cucumber.wants_to_quit = true unless result.ok?(configuration.strict)
16
+ elsif result.passed?
17
+ Cucumber.wants_to_quit = false
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cucumber
2
4
  module Formatter
3
-
4
5
  # Forwards any messages sent to this object to all recipients
5
6
  # that respond to that message.
6
7
  class Fanout < BasicObject
@@ -12,6 +13,8 @@ module Cucumber
12
13
  end
13
14
 
14
15
  def method_missing(message, *args)
16
+ super unless recipients
17
+
15
18
  recipients.each do |recipient|
16
19
  recipient.send(message, *args) if recipient.respond_to?(message)
17
20
  end
@@ -20,8 +23,6 @@ module Cucumber
20
23
  def respond_to_missing?(name, include_private = false)
21
24
  recipients.any? { |recipient| recipient.respond_to?(name, include_private) }
22
25
  end
23
-
24
26
  end
25
-
26
27
  end
27
28
  end
@@ -1,20 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cucumber
2
4
  module Formatter
3
-
4
5
  class IgnoreMissingMessages < BasicObject
5
6
  def initialize(receiver)
6
7
  @receiver = receiver
7
8
  end
8
9
 
9
10
  def method_missing(message, *args)
10
- @receiver.send(message, *args) if @receiver.respond_to?(message)
11
+ @receiver.respond_to?(message) ? @receiver.send(message, *args) : super
11
12
  end
12
13
 
13
14
  def respond_to_missing?(name, include_private = false)
14
15
  @receiver.respond_to?(name, include_private)
15
16
  end
16
17
  end
17
-
18
18
  end
19
19
  end
20
-
@@ -1,4 +1,4 @@
1
- require 'thread'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Cucumber
4
4
  module Formatter
@@ -7,20 +7,20 @@ module Cucumber
7
7
  attr_reader :pipe
8
8
  def initialize(pipe)
9
9
  @pipe = pipe
10
- @buffer = []
10
+ @buffer = StringIO.new
11
11
  @wrapped = true
12
12
  end
13
13
 
14
14
  def write(str)
15
- lock.synchronize do
15
+ lock.synchronize do
16
16
  @buffer << str if @wrapped
17
17
  return @pipe.write(str)
18
18
  end
19
19
  end
20
20
 
21
- def buffer
21
+ def buffer_string
22
22
  lock.synchronize do
23
- return @buffer.dup
23
+ return @buffer.string.dup
24
24
  end
25
25
  end
26
26
 
@@ -30,17 +30,15 @@ module Cucumber
30
30
  end
31
31
 
32
32
  def method_missing(method, *args, &blk)
33
- @pipe.send(method, *args, &blk)
33
+ @pipe.send(method, *args, &blk) || super
34
34
  end
35
35
 
36
- def respond_to?(method, include_private=false)
36
+ def respond_to_missing?(method, include_private = false)
37
37
  super || @pipe.respond_to?(method, include_private)
38
38
  end
39
39
 
40
40
  def self.validate_pipe(pipe)
41
- unless [:stdout, :stderr].include? pipe
42
- raise ArgumentError, '#wrap only accepts :stderr or :stdout'
43
- end
41
+ raise ArgumentError, '#wrap only accepts :stderr or :stdout' unless %i[stdout stderr].include? pipe
44
42
  end
45
43
 
46
44
  def self.unwrap!(pipe)
@@ -62,17 +60,18 @@ module Cucumber
62
60
 
63
61
  case pipe
64
62
  when :stderr
65
- $stderr = self.new($stderr)
63
+ $stderr = new($stderr)
66
64
  return $stderr
67
65
  when :stdout
68
- $stdout = self.new($stdout)
66
+ $stdout = new($stdout)
69
67
  return $stdout
70
68
  end
71
69
  end
72
70
 
73
- private
71
+ private
72
+
74
73
  def lock
75
- @lock||=Mutex.new
74
+ @lock ||= Mutex.new
76
75
  end
77
76
  end
78
77
  end
@@ -1,7 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cucumber
2
4
  module Formatter
3
5
  module Io
4
- def ensure_io(path_or_io, name)
6
+ module_function
7
+
8
+ def ensure_io(path_or_io)
5
9
  return nil if path_or_io.nil?
6
10
  return path_or_io if path_or_io.respond_to?(:write)
7
11
  file = File.open(path_or_io, Cucumber.file_mode('w'))
@@ -15,16 +19,17 @@ module Cucumber
15
19
  end
16
20
 
17
21
  def ensure_file(path, name)
18
- raise "You *must* specify --out FILE for the #{name} formatter" unless String === path
22
+ raise "You *must* specify --out FILE for the #{name} formatter" unless String == path.class
19
23
  raise "I can't write #{name} to a directory - it has to be a file" if File.directory?(path)
20
- ensure_io(path, name)
24
+ raise "I can't write #{name} to a file in the non-existing directory #{File.dirname(path)}" unless File.directory?(File.dirname(path))
25
+ ensure_io(path)
21
26
  end
22
27
 
23
28
  def ensure_dir(path, name)
24
- raise "You *must* specify --out DIR for the #{name} formatter" unless String === path
29
+ raise "You *must* specify --out DIR for the #{name} formatter" unless String == path.class
25
30
  raise "I can't write #{name} reports to a file - it has to be a directory" if File.file?(path)
26
31
  FileUtils.mkdir_p(path) unless File.directory?(path)
27
- path
32
+ File.absolute_path path
28
33
  end
29
34
  end
30
35
  end
@@ -1,19 +1,321 @@
1
- require 'cucumber/formatter/gherkin_formatter_adapter'
1
+ # frozen_string_literal: true
2
+
3
+ require 'multi_json'
4
+ require 'base64'
5
+ require 'cucumber/formatter/backtrace_filter'
2
6
  require 'cucumber/formatter/io'
3
- require 'gherkin/formatter/argument'
4
- require 'gherkin/formatter/json_formatter'
7
+ require 'cucumber/formatter/ast_lookup'
5
8
 
6
9
  module Cucumber
7
10
  module Formatter
8
11
  # The formatter used for <tt>--format json</tt>
9
- class Json < GherkinFormatterAdapter
12
+ class Json
10
13
  include Io
11
14
 
12
- def initialize(runtime, io, options)
13
- @io = ensure_io(io, "json")
14
- super(Gherkin::Formatter::JSONFormatter.new(@io), false, options)
15
+ def initialize(config)
16
+ @io = ensure_io(config.out_stream)
17
+ @ast_lookup = AstLookup.new(config)
18
+ @feature_hashes = []
19
+ @step_or_hook_hash = {}
20
+ config.on_event :test_case_started, &method(:on_test_case_started)
21
+ config.on_event :test_case_finished, &method(:on_test_case_finished)
22
+ config.on_event :test_step_started, &method(:on_test_step_started)
23
+ config.on_event :test_step_finished, &method(:on_test_step_finished)
24
+ config.on_event :test_run_finished, &method(:on_test_run_finished)
25
+ end
26
+
27
+ def on_test_case_started(event)
28
+ test_case = event.test_case
29
+ builder = Builder.new(test_case, @ast_lookup)
30
+ unless same_feature_as_previous_test_case?(test_case)
31
+ @feature_hash = builder.feature_hash
32
+ @feature_hashes << @feature_hash
33
+ end
34
+ @test_case_hash = builder.test_case_hash
35
+ if builder.background?
36
+ @in_background = true
37
+ feature_elements << builder.background_hash
38
+ @element_hash = builder.background_hash
39
+ else
40
+ @in_background = false
41
+ feature_elements << @test_case_hash
42
+ @element_hash = @test_case_hash
43
+ end
44
+ @any_step_failed = false
45
+ end
46
+
47
+ def on_test_step_started(event)
48
+ test_step = event.test_step
49
+ return if internal_hook?(test_step)
50
+ if test_step.hook?
51
+ @step_or_hook_hash = {}
52
+ hooks_of_type(test_step) << @step_or_hook_hash
53
+ return
54
+ end
55
+ if first_step_after_background?(test_step)
56
+ @in_background = false
57
+ feature_elements << @test_case_hash
58
+ @element_hash = @test_case_hash
59
+ end
60
+ @step_or_hook_hash = create_step_hash(test_step)
61
+ steps << @step_or_hook_hash
62
+ @step_hash = @step_or_hook_hash
63
+ end
64
+
65
+ def on_test_step_finished(event)
66
+ test_step, result = *event.attributes
67
+ result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
68
+ return if internal_hook?(test_step)
69
+ add_match_and_result(test_step, result)
70
+ @any_step_failed = true if result.failed?
71
+ end
72
+
73
+ def on_test_case_finished(event)
74
+ _test_case, result = *event.attributes
75
+ result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
76
+ add_failed_around_hook(result) if result.failed? && !@any_step_failed
77
+ end
78
+
79
+ def on_test_run_finished(_event)
80
+ @io.write(MultiJson.dump(@feature_hashes, pretty: true))
81
+ end
82
+
83
+ def puts(message)
84
+ test_step_output << message
85
+ end
86
+
87
+ def embed(src, mime_type, _label)
88
+ if File.file?(src)
89
+ content = File.open(src, 'rb', &:read)
90
+ data = encode64(content)
91
+ elsif mime_type =~ /;base64$/
92
+ mime_type = mime_type[0..-8]
93
+ data = src
94
+ else
95
+ data = encode64(src)
96
+ end
97
+ test_step_embeddings << { mime_type: mime_type, data: data }
98
+ end
99
+
100
+ private
101
+
102
+ def same_feature_as_previous_test_case?(test_case)
103
+ current_feature[:uri] == test_case.location.file
104
+ end
105
+
106
+ def first_step_after_background?(test_step)
107
+ @in_background && test_step.location.lines.max >= @test_case_hash[:line]
108
+ end
109
+
110
+ def internal_hook?(test_step)
111
+ test_step.location.file.include?('lib/cucumber/')
112
+ end
113
+
114
+ def current_feature
115
+ @feature_hash ||= {} # rubocop:disable Naming/MemoizedInstanceVariableName
116
+ end
117
+
118
+ def feature_elements
119
+ @feature_hash[:elements] ||= []
120
+ end
121
+
122
+ def steps
123
+ @element_hash[:steps] ||= []
124
+ end
125
+
126
+ def hooks_of_type(hook_step)
127
+ case hook_step.text
128
+ when 'Before hook'
129
+ before_hooks
130
+ when 'After hook'
131
+ after_hooks
132
+ when 'AfterStep hook'
133
+ after_step_hooks
134
+ else
135
+ raise 'Unknown hook type ' + hook_step.to_s
136
+ end
137
+ end
138
+
139
+ def before_hooks
140
+ @element_hash[:before] ||= []
141
+ end
142
+
143
+ def after_hooks
144
+ @element_hash[:after] ||= []
145
+ end
146
+
147
+ def around_hooks
148
+ @element_hash[:around] ||= []
149
+ end
150
+
151
+ def after_step_hooks
152
+ @step_hash[:after] ||= []
153
+ end
154
+
155
+ def test_step_output
156
+ @step_or_hook_hash[:output] ||= []
157
+ end
158
+
159
+ def test_step_embeddings
160
+ @step_or_hook_hash[:embeddings] ||= []
161
+ end
162
+
163
+ def create_step_hash(test_step)
164
+ step_source = @ast_lookup.step_source(test_step).step
165
+ step_hash = {
166
+ keyword: step_source.keyword,
167
+ name: test_step.text,
168
+ line: test_step.location.lines.min
169
+ }
170
+ step_hash[:doc_string] = create_doc_string_hash(step_source.doc_string) unless step_source.doc_string.nil?
171
+ step_hash[:rows] = create_data_table_value(step_source.data_table) unless step_source.data_table.nil?
172
+ step_hash
173
+ end
174
+
175
+ def create_doc_string_hash(doc_string)
176
+ content_type = doc_string.content_type || ''
177
+ {
178
+ value: doc_string.content,
179
+ content_type: content_type,
180
+ line: doc_string.location.line
181
+ }
182
+ end
183
+
184
+ def create_data_table_value(data_table)
185
+ data_table.rows.map do |row|
186
+ { cells: row.cells.map(&:value) }
187
+ end
188
+ end
189
+
190
+ def add_match_and_result(test_step, result)
191
+ @step_or_hook_hash[:match] = create_match_hash(test_step, result)
192
+ @step_or_hook_hash[:result] = create_result_hash(result)
193
+ result.embeddings.each { |e| embed(e['src'], e['mime_type'], e['label']) } if result.respond_to?(:embeddings)
194
+ end
195
+
196
+ def add_failed_around_hook(result)
197
+ @step_or_hook_hash = {}
198
+ around_hooks << @step_or_hook_hash
199
+ @step_or_hook_hash[:match] = { location: 'unknown_hook_location:1' }
200
+
201
+ @step_or_hook_hash[:result] = create_result_hash(result)
202
+ end
203
+
204
+ def create_match_hash(test_step, _result)
205
+ { location: test_step.action_location.to_s }
206
+ end
207
+
208
+ def create_result_hash(result)
209
+ result_hash = {
210
+ status: result.to_sym
211
+ }
212
+ result_hash[:error_message] = create_error_message(result) if result.failed? || result.pending?
213
+ result.duration.tap { |duration| result_hash[:duration] = duration.nanoseconds }
214
+ result_hash
215
+ end
216
+
217
+ def create_error_message(result)
218
+ message_element = result.failed? ? result.exception : result
219
+ message = "#{message_element.message} (#{message_element.class})"
220
+ ([message] + message_element.backtrace).join("\n")
221
+ end
222
+
223
+ def encode64(data)
224
+ # strip newlines from the encoded data
225
+ Base64.encode64(data).delete("\n")
226
+ end
227
+
228
+ class Builder
229
+ attr_reader :feature_hash, :background_hash, :test_case_hash
230
+
231
+ def initialize(test_case, ast_lookup)
232
+ @background_hash = nil
233
+ uri = test_case.location.file
234
+ feature = ast_lookup.gherkin_document(uri).feature
235
+ feature(feature, uri)
236
+ background(feature.children.first.background) unless feature.children.first.background.nil?
237
+ scenario(ast_lookup.scenario_source(test_case), test_case)
238
+ end
239
+
240
+ def background?
241
+ @background_hash != nil
242
+ end
243
+
244
+ def feature(feature, uri)
245
+ @feature_hash = {
246
+ id: create_id(feature.name),
247
+ uri: uri,
248
+ keyword: feature.keyword,
249
+ name: feature.name,
250
+ description: value_or_empty_string(feature.description),
251
+ line: feature.location.line
252
+ }
253
+ return if feature.tags.empty?
254
+ @feature_hash[:tags] = create_tags_array_from_hash_array(feature.tags)
255
+ end
256
+
257
+ def background(background)
258
+ @background_hash = {
259
+ keyword: background.keyword,
260
+ name: background.name,
261
+ description: value_or_empty_string(background.description),
262
+ line: background.location.line,
263
+ type: 'background'
264
+ }
265
+ end
266
+
267
+ def scenario(scenario_source, test_case)
268
+ scenario = scenario_source.type == :Scenario ? scenario_source.scenario : scenario_source.scenario_outline
269
+ @test_case_hash = {
270
+ id: "#{@feature_hash[:id]};#{create_id_from_scenario_source(scenario_source)}",
271
+ keyword: scenario.keyword,
272
+ name: test_case.name,
273
+ description: value_or_empty_string(scenario.description),
274
+ line: test_case.location.lines.max,
275
+ type: 'scenario'
276
+ }
277
+ @test_case_hash[:tags] = create_tags_array_from_tags_array(test_case.tags) unless test_case.tags.empty?
278
+ end
279
+
280
+ private
281
+
282
+ def value_or_empty_string(value)
283
+ value.nil? ? '' : value
284
+ end
285
+
286
+ def create_id(name)
287
+ name.downcase.tr(' ', '-')
288
+ end
289
+
290
+ def create_id_from_scenario_source(scenario_source)
291
+ if scenario_source.type == :Scenario
292
+ create_id(scenario_source.scenario.name)
293
+ else
294
+ scenario_outline_name = scenario_source.scenario_outline.name
295
+ examples_name = scenario_source.examples.name
296
+ row_number = calculate_row_number(scenario_source)
297
+ "#{create_id(scenario_outline_name)};#{create_id(examples_name)};#{row_number}"
298
+ end
299
+ end
300
+
301
+ def calculate_row_number(scenario_source)
302
+ scenario_source.examples.table_body.each_with_index do |row, index|
303
+ return index + 2 if row == scenario_source.row
304
+ end
305
+ end
306
+
307
+ def create_tags_array_from_hash_array(tags)
308
+ tags_array = []
309
+ tags.each { |tag| tags_array << { name: tag.name, line: tag.location.line } }
310
+ tags_array
311
+ end
312
+
313
+ def create_tags_array_from_tags_array(tags)
314
+ tags_array = []
315
+ tags.each { |tag| tags_array << { name: tag.name, line: tag.location.line } }
316
+ tags_array
317
+ end
15
318
  end
16
319
  end
17
320
  end
18
321
  end
19
-