cucumber 3.0.0.pre.1 → 4.0.0.rc.4

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 (533) hide show
  1. checksums.yaml +5 -5
  2. data/{History.md → CHANGELOG.md} +339 -37
  3. data/CONTRIBUTING.md +11 -21
  4. data/README.md +20 -12
  5. data/bin/cucumber +2 -1
  6. data/lib/autotest/cucumber.rb +1 -0
  7. data/lib/autotest/cucumber_mixin.rb +44 -48
  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 +3 -2
  14. data/lib/cucumber.rb +2 -1
  15. data/lib/cucumber/cli/configuration.rb +15 -20
  16. data/lib/cucumber/cli/main.rb +15 -15
  17. data/lib/cucumber/cli/options.rb +249 -197
  18. data/lib/cucumber/cli/profile_loader.rb +63 -38
  19. data/lib/cucumber/cli/rerun_file.rb +1 -0
  20. data/lib/cucumber/configuration.rb +49 -44
  21. data/lib/cucumber/constantize.rb +8 -10
  22. data/lib/cucumber/core_ext/string.rb +2 -1
  23. data/lib/cucumber/deprecate.rb +34 -10
  24. data/lib/cucumber/encoding.rb +2 -1
  25. data/lib/cucumber/errors.rb +10 -8
  26. data/lib/cucumber/events.rb +18 -3
  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 +14 -0
  30. data/lib/cucumber/events/hook_test_step_created.rb +13 -0
  31. data/lib/cucumber/events/{step_match.rb → step_activated.rb} +8 -8
  32. data/lib/cucumber/events/step_definition_registered.rb +5 -9
  33. data/lib/cucumber/events/test_case_created.rb +13 -0
  34. data/lib/cucumber/events/test_case_finished.rb +14 -0
  35. data/lib/cucumber/events/test_case_ready.rb +12 -0
  36. data/lib/cucumber/events/test_case_started.rb +11 -0
  37. data/lib/cucumber/events/test_run_finished.rb +2 -3
  38. data/lib/cucumber/events/test_run_started.rb +14 -0
  39. data/lib/cucumber/events/test_step_created.rb +13 -0
  40. data/lib/cucumber/events/test_step_finished.rb +14 -0
  41. data/lib/cucumber/events/test_step_started.rb +11 -0
  42. data/lib/cucumber/file_specs.rb +7 -6
  43. data/lib/cucumber/filters.rb +3 -0
  44. data/lib/cucumber/filters/activate_steps.rb +12 -6
  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_started_event.rb +28 -0
  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 +3 -3
  56. data/lib/cucumber/filters/tag_limits.rb +5 -5
  57. data/lib/cucumber/filters/tag_limits/test_case_index.rb +1 -2
  58. data/lib/cucumber/filters/tag_limits/verifier.rb +4 -7
  59. data/lib/cucumber/formatter/ansicolor.rb +38 -45
  60. data/lib/cucumber/formatter/ast_lookup.rb +165 -0
  61. data/lib/cucumber/formatter/backtrace_filter.rb +24 -12
  62. data/lib/cucumber/formatter/console.rb +48 -88
  63. data/lib/cucumber/formatter/console_counts.rb +11 -29
  64. data/lib/cucumber/formatter/console_issues.rb +34 -10
  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 +8 -5
  69. data/lib/cucumber/formatter/fanout.rb +3 -3
  70. data/lib/cucumber/formatter/ignore_missing_messages.rb +2 -4
  71. data/lib/cucumber/formatter/interceptor.rb +12 -14
  72. data/lib/cucumber/formatter/io.rb +5 -4
  73. data/lib/cucumber/formatter/json.rb +109 -115
  74. data/lib/cucumber/formatter/junit.rb +85 -80
  75. data/lib/cucumber/formatter/message.rb +246 -0
  76. data/lib/cucumber/formatter/pretty.rb +353 -153
  77. data/lib/cucumber/formatter/progress.rb +34 -38
  78. data/lib/cucumber/formatter/query/hook_by_test_step.rb +31 -0
  79. data/lib/cucumber/formatter/query/pickle_by_test.rb +26 -0
  80. data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +26 -0
  81. data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +40 -0
  82. data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +40 -0
  83. data/lib/cucumber/formatter/rerun.rb +24 -5
  84. data/lib/cucumber/formatter/stepdefs.rb +2 -2
  85. data/lib/cucumber/formatter/steps.rb +5 -6
  86. data/lib/cucumber/formatter/summary.rb +18 -11
  87. data/lib/cucumber/formatter/unicode.rb +16 -18
  88. data/lib/cucumber/formatter/usage.rb +37 -33
  89. data/lib/cucumber/gherkin/data_table_parser.rb +18 -6
  90. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +83 -86
  91. data/lib/cucumber/gherkin/formatter/escaping.rb +13 -12
  92. data/lib/cucumber/gherkin/i18n.rb +1 -0
  93. data/lib/cucumber/gherkin/steps_parser.rb +18 -8
  94. data/lib/cucumber/{rb_support/rb_dsl.rb → glue/dsl.rb} +37 -23
  95. data/lib/cucumber/glue/hook.rb +67 -0
  96. data/lib/cucumber/glue/invoke_in_world.rb +65 -0
  97. data/lib/cucumber/glue/proto_world.rb +231 -0
  98. data/lib/cucumber/glue/registry_and_more.rb +221 -0
  99. data/lib/cucumber/glue/snippet.rb +205 -0
  100. data/lib/cucumber/glue/step_definition.rb +166 -0
  101. data/lib/cucumber/glue/world_factory.rb +21 -0
  102. data/lib/cucumber/hooks.rb +30 -20
  103. data/lib/cucumber/load_path.rb +1 -0
  104. data/lib/cucumber/multiline_argument.rb +9 -19
  105. data/lib/cucumber/multiline_argument/data_table.rb +143 -250
  106. data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +154 -0
  107. data/lib/cucumber/multiline_argument/doc_string.rb +2 -1
  108. data/lib/cucumber/platform.rb +5 -6
  109. data/lib/cucumber/project_initializer.rb +2 -2
  110. data/lib/cucumber/rake/task.rb +34 -27
  111. data/lib/cucumber/rspec/disable_option_parser.rb +10 -8
  112. data/lib/cucumber/rspec/doubles.rb +2 -1
  113. data/lib/cucumber/running_test_case.rb +4 -54
  114. data/lib/cucumber/runtime.rb +54 -72
  115. data/lib/cucumber/runtime/after_hooks.rb +10 -5
  116. data/lib/cucumber/runtime/before_hooks.rb +9 -4
  117. data/lib/cucumber/runtime/for_programming_languages.rb +12 -44
  118. data/lib/cucumber/runtime/step_hooks.rb +5 -2
  119. data/lib/cucumber/runtime/support_code.rb +30 -32
  120. data/lib/cucumber/runtime/user_interface.rb +16 -34
  121. data/lib/cucumber/step_definition_light.rb +7 -4
  122. data/lib/cucumber/step_definitions.rb +3 -2
  123. data/lib/cucumber/step_match.rb +42 -26
  124. data/lib/cucumber/step_match_search.rb +11 -12
  125. data/lib/cucumber/term/ansicolor.rb +39 -39
  126. data/lib/cucumber/unit.rb +1 -0
  127. data/lib/cucumber/version +1 -1
  128. data/lib/simplecov_setup.rb +2 -1
  129. metadata +238 -623
  130. data/.coveralls.yml +0 -1
  131. data/.github/ISSUE_TEMPLATE.md +0 -48
  132. data/.github/PULL_REQUEST_TEMPLATE.md +0 -39
  133. data/.rspec +0 -1
  134. data/.ruby-gemset +0 -1
  135. data/.travis.yml +0 -35
  136. data/.yardopts +0 -1
  137. data/Gemfile +0 -22
  138. data/Rakefile +0 -22
  139. data/cucumber.gemspec +0 -47
  140. data/cucumber.yml +0 -20
  141. data/examples/i18n/README.textile +0 -3
  142. data/examples/i18n/Rakefile +0 -33
  143. data/examples/i18n/ar/Rakefile +0 -6
  144. data/examples/i18n/ar/features/addition.feature +0 -17
  145. data/examples/i18n/ar/features/step_definitions/calculator_steps.rb +0 -24
  146. data/examples/i18n/ar/lib/calculator.rb +0 -11
  147. data/examples/i18n/bg/Rakefile +0 -6
  148. data/examples/i18n/bg/features/addition.feature +0 -12
  149. data/examples/i18n/bg/features/consecutive_calculations.feature +0 -19
  150. data/examples/i18n/bg/features/division.feature +0 -17
  151. data/examples/i18n/bg/features/step_definitions/calculator_steps.rb +0 -24
  152. data/examples/i18n/bg/features/support/env.rb +0 -5
  153. data/examples/i18n/bg/features/support/world.rb +0 -8
  154. data/examples/i18n/bg/lib/calculator.rb +0 -24
  155. data/examples/i18n/ca/Rakefile +0 -6
  156. data/examples/i18n/ca/features/step_definitions/calculator_steps.rb +0 -21
  157. data/examples/i18n/ca/features/suma.feature +0 -17
  158. data/examples/i18n/ca/lib/calculadora.rb +0 -16
  159. data/examples/i18n/cs/Rakefile +0 -6
  160. data/examples/i18n/cs/features/addition.feature +0 -17
  161. data/examples/i18n/cs/features/division.feature +0 -11
  162. data/examples/i18n/cs/features/step_definitions/calculator_steps.rb +0 -24
  163. data/examples/i18n/cs/lib/calculator.rb +0 -14
  164. data/examples/i18n/da/Rakefile +0 -6
  165. data/examples/i18n/da/features/sammenlaegning.feature +0 -18
  166. data/examples/i18n/da/features/step_definitions/lommeregner_steps.rb +0 -24
  167. data/examples/i18n/da/lib/lommeregner.rb +0 -11
  168. data/examples/i18n/de/Rakefile +0 -6
  169. data/examples/i18n/de/features/addition.feature +0 -17
  170. data/examples/i18n/de/features/division.feature +0 -10
  171. data/examples/i18n/de/features/step_definitions/calculator_steps.rb +0 -24
  172. data/examples/i18n/de/lib/calculator.rb +0 -14
  173. data/examples/i18n/el/Rakefile +0 -6
  174. data/examples/i18n/el/features/addition.feature +0 -17
  175. data/examples/i18n/el/features/division.feature +0 -10
  176. data/examples/i18n/el/features/step_definitions/calculator_steps.rb +0 -24
  177. data/examples/i18n/el/lib/calculator.rb +0 -14
  178. data/examples/i18n/en-lol/Rakefile +0 -4
  179. data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +0 -16
  180. data/examples/i18n/en-lol/features/stuffing.feature +0 -8
  181. data/examples/i18n/en-lol/features/support/env.rb +0 -7
  182. data/examples/i18n/en-lol/lib/basket.rb +0 -12
  183. data/examples/i18n/en-lol/lib/belly.rb +0 -11
  184. data/examples/i18n/en/Rakefile +0 -6
  185. data/examples/i18n/en/features/addition.feature +0 -17
  186. data/examples/i18n/en/features/division.feature +0 -10
  187. data/examples/i18n/en/features/step_definitions/calculator_steps.rb +0 -24
  188. data/examples/i18n/en/lib/calculator.rb +0 -14
  189. data/examples/i18n/eo/Rakefile +0 -6
  190. data/examples/i18n/eo/features/adicio.feature +0 -17
  191. data/examples/i18n/eo/features/divido.feature +0 -10
  192. data/examples/i18n/eo/features/step_definitions/calculator_steps.rb +0 -24
  193. data/examples/i18n/eo/lib/calculator.rb +0 -14
  194. data/examples/i18n/es/Rakefile +0 -6
  195. data/examples/i18n/es/features/adicion.feature +0 -17
  196. data/examples/i18n/es/features/step_definitions/calculador_steps.rb +0 -21
  197. data/examples/i18n/es/lib/calculador.rb +0 -14
  198. data/examples/i18n/et/Rakefile +0 -6
  199. data/examples/i18n/et/features/jagamine.feature +0 -10
  200. data/examples/i18n/et/features/liitmine.feature +0 -17
  201. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +0 -24
  202. data/examples/i18n/et/lib/kalkulaator.rb +0 -14
  203. data/examples/i18n/fi/Rakefile +0 -6
  204. data/examples/i18n/fi/features/jakolasku.feature +0 -10
  205. data/examples/i18n/fi/features/step_definitions/laskin_steps.rb +0 -24
  206. data/examples/i18n/fi/features/yhteenlasku.feature +0 -17
  207. data/examples/i18n/fi/lib/laskin.rb +0 -14
  208. data/examples/i18n/fr/Rakefile +0 -8
  209. data/examples/i18n/fr/features/addition.feature +0 -18
  210. data/examples/i18n/fr/features/addition2.feature +0 -17
  211. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +0 -32
  212. data/examples/i18n/fr/features/support/env.rb +0 -5
  213. data/examples/i18n/fr/lib/calculatrice.rb +0 -10
  214. data/examples/i18n/he/Rakefile +0 -6
  215. data/examples/i18n/he/features/addition.feature +0 -17
  216. data/examples/i18n/he/features/division.feature +0 -10
  217. data/examples/i18n/he/features/step_definitions/calculator_steps.rb +0 -24
  218. data/examples/i18n/he/lib/calculator.rb +0 -15
  219. data/examples/i18n/hi/Rakefile +0 -6
  220. data/examples/i18n/hi/features/addition.feature +0 -16
  221. data/examples/i18n/hi/features/division.feature +0 -10
  222. data/examples/i18n/hi/features/step_definitions/calculator_steps.rb +0 -24
  223. data/examples/i18n/hi/lib/calculator.rb +0 -15
  224. data/examples/i18n/ht/Rakefile +0 -6
  225. data/examples/i18n/ht/features/adisyon.feature +0 -17
  226. data/examples/i18n/ht/features/divizyon.feature +0 -10
  227. data/examples/i18n/ht/features/step_definitions/kalkilatris_steps.rb +0 -25
  228. data/examples/i18n/ht/lib/kalkilatris.rb +0 -14
  229. data/examples/i18n/hu/Rakefile +0 -6
  230. data/examples/i18n/hu/features/osszeadas.feature +0 -17
  231. data/examples/i18n/hu/features/osztas.feature +0 -10
  232. data/examples/i18n/hu/features/step_definitions/calculator_steps.rb +0 -25
  233. data/examples/i18n/hu/lib/calculator.rb +0 -14
  234. data/examples/i18n/id/Rakefile +0 -6
  235. data/examples/i18n/id/features/addition.feature +0 -17
  236. data/examples/i18n/id/features/division.feature +0 -10
  237. data/examples/i18n/id/features/step_definitions/calculator_steps.rb +0 -24
  238. data/examples/i18n/id/lib/calculator.rb +0 -14
  239. data/examples/i18n/it/Rakefile +0 -6
  240. data/examples/i18n/it/features/somma.feature +0 -11
  241. data/examples/i18n/it/features/step_definitions/calcolatrice_steps.rb +0 -24
  242. data/examples/i18n/it/lib/calcolatrice.rb +0 -11
  243. data/examples/i18n/ja/Rakefile +0 -6
  244. data/examples/i18n/ja/features/addition.feature +0 -17
  245. data/examples/i18n/ja/features/division.feature +0 -10
  246. data/examples/i18n/ja/features/step_definitions/calculator_steps.rb +0 -19
  247. data/examples/i18n/ja/features/support/env.rb +0 -5
  248. data/examples/i18n/ja/lib/calculator.rb +0 -14
  249. data/examples/i18n/ko/Rakefile +0 -6
  250. data/examples/i18n/ko/features/addition.feature +0 -17
  251. data/examples/i18n/ko/features/division.feature +0 -11
  252. data/examples/i18n/ko/features/step_definitions/calculator_steps.rb +0 -24
  253. data/examples/i18n/ko/lib/calculator.rb +0 -14
  254. data/examples/i18n/lt/Rakefile +0 -6
  255. data/examples/i18n/lt/features/addition.feature +0 -17
  256. data/examples/i18n/lt/features/division.feature +0 -10
  257. data/examples/i18n/lt/features/step_definitions/calculator_steps.rb +0 -24
  258. data/examples/i18n/lt/lib/calculator.rb +0 -14
  259. data/examples/i18n/lv/Rakefile +0 -6
  260. data/examples/i18n/lv/features/addition.feature +0 -17
  261. data/examples/i18n/lv/features/division.feature +0 -10
  262. data/examples/i18n/lv/features/step_definitions/calculator_steps.rb +0 -24
  263. data/examples/i18n/lv/lib/calculator.rb +0 -14
  264. data/examples/i18n/no/Rakefile +0 -6
  265. data/examples/i18n/no/features/step_definitions/kalkulator_steps.rb +0 -17
  266. data/examples/i18n/no/features/summering.feature +0 -19
  267. data/examples/i18n/no/features/support/env.rb +0 -6
  268. data/examples/i18n/no/lib/kalkulator.rb +0 -11
  269. data/examples/i18n/pl/Rakefile +0 -6
  270. data/examples/i18n/pl/features/addition.feature +0 -17
  271. data/examples/i18n/pl/features/division.feature +0 -10
  272. data/examples/i18n/pl/features/step_definitions/calculator_steps.rb +0 -24
  273. data/examples/i18n/pl/features/support/env.rb +0 -5
  274. data/examples/i18n/pl/lib/calculator.rb +0 -14
  275. data/examples/i18n/pt/Rakefile +0 -6
  276. data/examples/i18n/pt/features/adicao.feature +0 -11
  277. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +0 -20
  278. data/examples/i18n/pt/features/support/env.rb +0 -5
  279. data/examples/i18n/pt/lib/calculadora.rb +0 -10
  280. data/examples/i18n/ro/Rakefile +0 -6
  281. data/examples/i18n/ro/features/adunare.feature +0 -12
  282. data/examples/i18n/ro/features/step_definitions/calculator_steps.rb +0 -21
  283. data/examples/i18n/ro/lib/calculator.rb +0 -11
  284. data/examples/i18n/ru/Rakefile +0 -6
  285. data/examples/i18n/ru/features/addition.feature +0 -11
  286. data/examples/i18n/ru/features/consecutive_calculations.feature +0 -17
  287. data/examples/i18n/ru/features/division.feature +0 -16
  288. data/examples/i18n/ru/features/step_definitions/calculator_steps.rb +0 -19
  289. data/examples/i18n/ru/features/support/env.rb +0 -5
  290. data/examples/i18n/ru/features/support/world.rb +0 -8
  291. data/examples/i18n/ru/lib/calculator.rb +0 -24
  292. data/examples/i18n/sk/Rakefile +0 -6
  293. data/examples/i18n/sk/features/addition.feature +0 -17
  294. data/examples/i18n/sk/features/division.feature +0 -10
  295. data/examples/i18n/sk/features/step_definitions/calculator_steps.rb +0 -24
  296. data/examples/i18n/sk/lib/calculator.rb +0 -14
  297. data/examples/i18n/sr-Cyrl/Rakefile +0 -6
  298. data/examples/i18n/sr-Cyrl/features/sabiranje.feature +0 -18
  299. data/examples/i18n/sr-Cyrl/features/step_definitions/calculator_steps.rb +0 -20
  300. data/examples/i18n/sr-Cyrl/features/support/env.rb +0 -5
  301. data/examples/i18n/sr-Cyrl/lib/calculator.rb +0 -12
  302. data/examples/i18n/sr-Latn/Rakefile +0 -6
  303. data/examples/i18n/sr-Latn/features/sabiranje.feature +0 -18
  304. data/examples/i18n/sr-Latn/features/step_definitions/calculator_steps.rb +0 -24
  305. data/examples/i18n/sr-Latn/lib/calculator.rb +0 -12
  306. data/examples/i18n/sv/Rakefile +0 -6
  307. data/examples/i18n/sv/features/step_definitions/kalkulator_steps.rb +0 -24
  308. data/examples/i18n/sv/features/summering.feature +0 -18
  309. data/examples/i18n/sv/lib/kalkulator.rb +0 -11
  310. data/examples/i18n/tr/Rakefile +0 -6
  311. data/examples/i18n/tr/features/bolme.feature +0 -10
  312. data/examples/i18n/tr/features/step_definitions/hesap_makinesi_adimlari.rb +0 -24
  313. data/examples/i18n/tr/features/toplama.feature +0 -18
  314. data/examples/i18n/tr/lib/hesap_makinesi.rb +0 -15
  315. data/examples/i18n/uk/Rakefile +0 -6
  316. data/examples/i18n/uk/features/addition.feature +0 -11
  317. data/examples/i18n/uk/features/consecutive_calculations.feature +0 -17
  318. data/examples/i18n/uk/features/division.feature +0 -16
  319. data/examples/i18n/uk/features/step_definitions/calculator_steps.rb +0 -19
  320. data/examples/i18n/uk/features/support/env.rb +0 -5
  321. data/examples/i18n/uk/features/support/world.rb +0 -8
  322. data/examples/i18n/uk/lib/calculator.rb +0 -24
  323. data/examples/i18n/uz/Rakefile +0 -6
  324. data/examples/i18n/uz/features/addition.feature +0 -10
  325. data/examples/i18n/uz/features/consecutive_calculations.feature +0 -17
  326. data/examples/i18n/uz/features/division.feature +0 -17
  327. data/examples/i18n/uz/features/step_definitions/calculator_steps.rb +0 -19
  328. data/examples/i18n/uz/features/support/env.rb +0 -5
  329. data/examples/i18n/uz/features/support/world.rb +0 -8
  330. data/examples/i18n/uz/lib/calculator.rb +0 -24
  331. data/examples/i18n/zh-CN/Rakefile +0 -4
  332. data/examples/i18n/zh-CN/features/addition.feature +0 -18
  333. data/examples/i18n/zh-CN/features/step_definitions/calculator_steps.rb +0 -26
  334. data/examples/i18n/zh-CN/lib/calculator.rb +0 -10
  335. data/examples/i18n/zh-TW/Rakefile +0 -4
  336. data/examples/i18n/zh-TW/features/addition.feature +0 -17
  337. data/examples/i18n/zh-TW/features/division.feature +0 -11
  338. data/examples/i18n/zh-TW/features/step_definitions/calculator_steps.rb +0 -24
  339. data/examples/i18n/zh-TW/lib/calculator.rb +0 -14
  340. data/examples/rspec_doubles/Rakefile +0 -4
  341. data/examples/rspec_doubles/features/mocking.feature +0 -9
  342. data/examples/rspec_doubles/features/step_definitions/calvin_steps.rb +0 -19
  343. data/examples/rspec_doubles/features/support/env.rb +0 -12
  344. data/examples/sinatra/README.textile +0 -13
  345. data/examples/sinatra/Rakefile +0 -6
  346. data/examples/sinatra/app.rb +0 -14
  347. data/examples/sinatra/features/add.feature +0 -11
  348. data/examples/sinatra/features/step_definitions/add_steps.rb +0 -15
  349. data/examples/sinatra/features/support/env.rb +0 -10
  350. data/examples/sinatra/views/add.erb +0 -7
  351. data/examples/sinatra/views/layout.erb +0 -8
  352. data/examples/tcl/README.textile +0 -11
  353. data/examples/tcl/Rakefile +0 -6
  354. data/examples/tcl/features/fibonnacci.feature +0 -17
  355. data/examples/tcl/features/step_definitions/fib_steps.rb +0 -7
  356. data/examples/tcl/features/support/env.rb +0 -6
  357. data/examples/tcl/src/fib.tcl +0 -3
  358. data/examples/test_unit/Gemfile +0 -4
  359. data/examples/test_unit/Rakefile +0 -6
  360. data/examples/test_unit/features/step_definitions/test_unit_steps.rb +0 -20
  361. data/examples/test_unit/features/test_unit.feature +0 -9
  362. data/examples/watir/README.textile +0 -16
  363. data/examples/watir/Rakefile +0 -12
  364. data/examples/watir/cucumber.yml +0 -1
  365. data/examples/watir/features/search.feature +0 -12
  366. data/examples/watir/features/step_definitions/search_steps.rb +0 -26
  367. data/examples/watir/features/support/env.rb +0 -35
  368. data/examples/watir/features/support/screenshots.rb +0 -47
  369. data/features/docs/api/list_step_defs_as_json.feature +0 -50
  370. data/features/docs/api/listen_for_events.feature +0 -59
  371. data/features/docs/api/run_cli_main_with_existing_runtime.feature +0 -26
  372. data/features/docs/cli/backtraces.feature +0 -36
  373. data/features/docs/cli/dry_run.feature +0 -70
  374. data/features/docs/cli/exclude_files.feature +0 -18
  375. data/features/docs/cli/execute_with_tag_filter.feature +0 -117
  376. data/features/docs/cli/fail_fast.feature +0 -46
  377. data/features/docs/cli/finding_steps.feature +0 -28
  378. data/features/docs/cli/help.feature +0 -8
  379. data/features/docs/cli/randomize.feature +0 -140
  380. data/features/docs/cli/require.feature +0 -27
  381. data/features/docs/cli/retry_failing_tests.feature +0 -67
  382. data/features/docs/cli/run_scenarios_matching_name.feature +0 -104
  383. data/features/docs/cli/run_specific_scenarios.feature +0 -77
  384. data/features/docs/cli/showing_differences.feature +0 -43
  385. data/features/docs/cli/specifying_multiple_formatters.feature +0 -65
  386. data/features/docs/cli/strict_mode.feature +0 -64
  387. data/features/docs/defining_steps/nested_steps.feature +0 -177
  388. data/features/docs/defining_steps/nested_steps_i18n.feature +0 -36
  389. data/features/docs/defining_steps/nested_steps_with_second_arg.feature +0 -54
  390. data/features/docs/defining_steps/one_line_step_definitions.feature +0 -65
  391. data/features/docs/defining_steps/printing_messages.feature +0 -147
  392. data/features/docs/defining_steps/skip_scenario.feature +0 -30
  393. data/features/docs/defining_steps/snippets.feature +0 -56
  394. data/features/docs/defining_steps/table_diffing.feature +0 -50
  395. data/features/docs/exception_in_after_hook.feature +0 -126
  396. data/features/docs/exception_in_after_step_hook.feature +0 -102
  397. data/features/docs/exception_in_around_hook.feature +0 -78
  398. data/features/docs/exception_in_before_hook.feature +0 -96
  399. data/features/docs/extending_cucumber/custom_filter.feature +0 -29
  400. data/features/docs/extending_cucumber/custom_formatter.feature +0 -102
  401. data/features/docs/formatters/api_methods.feature +0 -37
  402. data/features/docs/formatters/debug_formatter.feature +0 -47
  403. data/features/docs/formatters/formatter_step_file_colon_line.feature +0 -44
  404. data/features/docs/formatters/html_formatter.feature +0 -91
  405. data/features/docs/formatters/json_formatter.feature +0 -767
  406. data/features/docs/formatters/junit_formatter.feature +0 -454
  407. data/features/docs/formatters/pretty_formatter.feature +0 -73
  408. data/features/docs/formatters/progress_formatter.feature +0 -31
  409. data/features/docs/formatters/rerun_formatter.feature +0 -188
  410. data/features/docs/formatters/summary_formatter.feature +0 -34
  411. data/features/docs/formatters/usage_formatter.feature +0 -98
  412. data/features/docs/getting_started.feature +0 -27
  413. data/features/docs/gherkin/background.feature +0 -548
  414. data/features/docs/gherkin/doc_strings.feature +0 -74
  415. data/features/docs/gherkin/expand_option_for_outlines.feature +0 -46
  416. data/features/docs/gherkin/language_from_header.feature +0 -32
  417. data/features/docs/gherkin/language_help.feature +0 -42
  418. data/features/docs/gherkin/outlines.feature +0 -156
  419. data/features/docs/gherkin/unicode_table.feature +0 -32
  420. data/features/docs/gherkin/using_descriptions.feature +0 -82
  421. data/features/docs/gherkin/using_star_notation.feature +0 -37
  422. data/features/docs/iso-8859-1.feature +0 -6
  423. data/features/docs/post_configuration_hook.feature +0 -33
  424. data/features/docs/profiles.feature +0 -120
  425. data/features/docs/rake_task.feature +0 -141
  426. data/features/docs/raketask.feature +0 -44
  427. data/features/docs/work_in_progress.feature +0 -154
  428. data/features/docs/writing_support_code/after_hooks.feature +0 -102
  429. data/features/docs/writing_support_code/after_step_hooks.feature +0 -53
  430. data/features/docs/writing_support_code/around_hooks.feature +0 -260
  431. data/features/docs/writing_support_code/before_hook.feature +0 -65
  432. data/features/docs/writing_support_code/hook_order.feature +0 -61
  433. data/features/docs/writing_support_code/load_path.feature +0 -17
  434. data/features/docs/writing_support_code/state.feature +0 -32
  435. data/features/docs/writing_support_code/tagged_hooks.feature +0 -95
  436. data/features/docs/writing_support_code/transforms.feature +0 -98
  437. data/features/docs/writing_support_code/world.feature +0 -129
  438. data/features/lib/step_definitions/aruba_steps.rb +0 -27
  439. data/features/lib/step_definitions/cli_steps.rb +0 -4
  440. data/features/lib/step_definitions/cucumber_steps.rb +0 -79
  441. data/features/lib/step_definitions/iso-8859-1_steps.rb +0 -13
  442. data/features/lib/step_definitions/json_steps.rb +0 -8
  443. data/features/lib/step_definitions/junit_steps.rb +0 -14
  444. data/features/lib/step_definitions/language_steps.rb +0 -9
  445. data/features/lib/step_definitions/profile_steps.rb +0 -16
  446. data/features/lib/step_definitions/retry_steps.rb +0 -55
  447. data/features/lib/step_definitions/ruby_steps.rb +0 -4
  448. data/features/lib/step_definitions/wire_steps.rb +0 -59
  449. data/features/lib/support/env.rb +0 -22
  450. data/features/lib/support/fake_wire_server.rb +0 -81
  451. data/features/lib/support/feature_factory.rb +0 -68
  452. data/features/lib/support/normalise_output.rb +0 -51
  453. data/gem_tasks/contributors.rake +0 -16
  454. data/gem_tasks/cov.rake +0 -6
  455. data/gem_tasks/cucumber.rake +0 -26
  456. data/gem_tasks/downloads.rb +0 -8
  457. data/gem_tasks/environment.rake +0 -8
  458. data/gem_tasks/examples.rake +0 -12
  459. data/gem_tasks/fix_cr_lf.rake +0 -11
  460. data/gem_tasks/flog.rake +0 -5
  461. data/gem_tasks/rspec.rake +0 -7
  462. data/gem_tasks/sass.rake +0 -5
  463. data/gem_tasks/stats +0 -16
  464. data/gem_tasks/versions.txt +0 -74
  465. data/lib/cucumber/core_ext/instance_exec.rb +0 -71
  466. data/lib/cucumber/formatter/cucumber.css +0 -286
  467. data/lib/cucumber/formatter/cucumber.sass +0 -247
  468. data/lib/cucumber/formatter/debug.rb +0 -36
  469. data/lib/cucumber/formatter/hook_query_visitor.rb +0 -41
  470. data/lib/cucumber/formatter/html.rb +0 -690
  471. data/lib/cucumber/formatter/jquery-min.js +0 -154
  472. data/lib/cucumber/formatter/json_pretty.rb +0 -11
  473. data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1012
  474. data/lib/cucumber/formatter/legacy_api/ast.rb +0 -390
  475. data/lib/cucumber/formatter/legacy_api/results.rb +0 -52
  476. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
  477. data/lib/cucumber/rb_support/rb_hook.rb +0 -20
  478. data/lib/cucumber/rb_support/rb_language.rb +0 -227
  479. data/lib/cucumber/rb_support/rb_step_definition.rb +0 -132
  480. data/lib/cucumber/rb_support/rb_transform.rb +0 -60
  481. data/lib/cucumber/rb_support/rb_world.rb +0 -171
  482. data/lib/cucumber/rb_support/snippet.rb +0 -171
  483. data/lib/cucumber/step_argument.rb +0 -26
  484. data/spec/cucumber/cli/configuration_spec.rb +0 -436
  485. data/spec/cucumber/cli/main_spec.rb +0 -84
  486. data/spec/cucumber/cli/options_spec.rb +0 -411
  487. data/spec/cucumber/cli/profile_loader_spec.rb +0 -47
  488. data/spec/cucumber/cli/rerun_spec.rb +0 -86
  489. data/spec/cucumber/configuration_spec.rb +0 -148
  490. data/spec/cucumber/constantize_spec.rb +0 -20
  491. data/spec/cucumber/core_ext/instance_exec_spec.rb +0 -5
  492. data/spec/cucumber/file_specs_spec.rb +0 -61
  493. data/spec/cucumber/filters/activate_steps_spec.rb +0 -152
  494. data/spec/cucumber/filters/gated_receiver_spec.rb +0 -48
  495. data/spec/cucumber/filters/retry_spec.rb +0 -85
  496. data/spec/cucumber/filters/tag_limits/test_case_index_spec.rb +0 -39
  497. data/spec/cucumber/filters/tag_limits/verifier_spec.rb +0 -58
  498. data/spec/cucumber/filters/tag_limits_spec.rb +0 -60
  499. data/spec/cucumber/formatter/ansicolor_spec.rb +0 -33
  500. data/spec/cucumber/formatter/console_counts_spec.rb +0 -14
  501. data/spec/cucumber/formatter/debug_spec.rb +0 -65
  502. data/spec/cucumber/formatter/duration_spec.rb +0 -23
  503. data/spec/cucumber/formatter/fail_fast_spec.rb +0 -88
  504. data/spec/cucumber/formatter/html_spec.rb +0 -543
  505. data/spec/cucumber/formatter/interceptor_spec.rb +0 -137
  506. data/spec/cucumber/formatter/json_spec.rb +0 -842
  507. data/spec/cucumber/formatter/junit_spec.rb +0 -253
  508. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +0 -2187
  509. data/spec/cucumber/formatter/pretty_spec.rb +0 -920
  510. data/spec/cucumber/formatter/progress_spec.rb +0 -170
  511. data/spec/cucumber/formatter/rerun_spec.rb +0 -97
  512. data/spec/cucumber/formatter/spec_helper.rb +0 -83
  513. data/spec/cucumber/hooks_spec.rb +0 -31
  514. data/spec/cucumber/multiline_argument/data_table_spec.rb +0 -604
  515. data/spec/cucumber/project_initializer_spec.rb +0 -88
  516. data/spec/cucumber/rake/forked_spec.rb +0 -54
  517. data/spec/cucumber/rake/task_spec.rb +0 -86
  518. data/spec/cucumber/rb_support/rb_language_spec.rb +0 -321
  519. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +0 -200
  520. data/spec/cucumber/rb_support/rb_transform_spec.rb +0 -47
  521. data/spec/cucumber/rb_support/rb_world_spec.rb +0 -48
  522. data/spec/cucumber/rb_support/snippet_spec.rb +0 -138
  523. data/spec/cucumber/running_test_case_spec.rb +0 -140
  524. data/spec/cucumber/runtime/for_programming_languages_spec.rb +0 -37
  525. data/spec/cucumber/runtime/support_code_spec.rb +0 -17
  526. data/spec/cucumber/runtime_spec.rb +0 -21
  527. data/spec/cucumber/sell_cucumbers.feature +0 -19
  528. data/spec/cucumber/step_argument_spec.rb +0 -19
  529. data/spec/cucumber/step_match_search_spec.rb +0 -123
  530. data/spec/cucumber/step_match_spec.rb +0 -86
  531. data/spec/cucumber/world/pending_spec.rb +0 -48
  532. data/spec/spec_helper.rb +0 -30
  533. data/spec/support/standard_step_actions.rb +0 -19
@@ -1,252 +1,452 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'fileutils'
4
+ require 'gherkin/dialect'
3
5
  require 'cucumber/formatter/console'
4
6
  require 'cucumber/formatter/io'
5
7
  require 'cucumber/gherkin/formatter/escaping'
6
8
  require 'cucumber/formatter/console_counts'
7
9
  require 'cucumber/formatter/console_issues'
10
+ require 'cucumber/formatter/duration_extractor'
11
+ require 'cucumber/formatter/backtrace_filter'
12
+ require 'cucumber/formatter/ast_lookup'
8
13
 
9
14
  module Cucumber
10
15
  module Formatter
11
16
  # The formatter used for <tt>--format pretty</tt> (the default formatter).
12
17
  #
13
- # This formatter prints features to plain text - exactly how they were parsed,
14
- # just prettier. That means with proper indentation and alignment of table columns.
18
+ # This formatter prints the result of the feature executions to plain text - exactly how they were parsed.
15
19
  #
16
20
  # If the output is STDOUT (and not a file), there are bright colours to watch too.
17
21
  #
18
- class Pretty
22
+ class Pretty # rubocop:disable Metrics/ClassLength
19
23
  include FileUtils
20
24
  include Console
21
25
  include Io
22
26
  include Cucumber::Gherkin::Formatter::Escaping
23
- attr_writer :indent
24
- attr_reader :runtime
25
-
26
- def initialize(runtime, path_or_io, options)
27
- @runtime, @io, @options = runtime, ensure_io(path_or_io), options
28
- @config = runtime.configuration
29
- @exceptions = []
30
- @indent = 0
31
- @prefixes = options[:prefixes] || {}
32
- @delayed_messages = []
33
- @previous_step_keyword = nil
27
+ attr_reader :config, :options
28
+ private :config, :options
29
+ attr_reader :current_feature_uri, :current_scenario_outline, :current_examples, :current_test_case
30
+ private :current_feature_uri, :current_scenario_outline, :current_examples, :current_test_case
31
+ attr_reader :in_scenario_outline, :print_background_steps
32
+ private :in_scenario_outline, :print_background_steps
33
+
34
+ def initialize(config)
35
+ @io = ensure_io(config.out_stream)
36
+ @config = config
37
+ @options = config.to_hash
34
38
  @snippets_input = []
35
- @counts = ConsoleCounts.new(runtime.configuration)
36
- @issues = ConsoleIssues.new(runtime.configuration)
39
+ @total_duration = 0
40
+ @exceptions = []
41
+ @gherkin_sources = {}
42
+ @step_matches = {}
43
+ @ast_lookup = AstLookup.new(config)
44
+ @counts = ConsoleCounts.new(config)
45
+ @issues = ConsoleIssues.new(config, @ast_lookup)
46
+ @first_feature = true
47
+ @current_feature_uri = ''
48
+ @current_scenario_outline = nil
49
+ @current_examples = nil
50
+ @current_test_case = nil
51
+ @in_scenario_outline = false
52
+ @print_background_steps = false
53
+ @test_step_output = []
54
+ @passed_test_cases = []
55
+ @source_indent = 0
56
+ @next_comment_to_be_printed = 0
57
+ config.on_event :gherkin_source_read, &method(:on_gherkin_source_read)
58
+ config.on_event :step_activated, &method(:on_step_activated)
59
+ config.on_event :test_case_started, &method(:on_test_case_started)
60
+ config.on_event :test_step_started, &method(:on_test_step_started)
61
+ config.on_event :test_step_finished, &method(:on_test_step_finished)
62
+ config.on_event :test_case_finished, &method(:on_test_case_finished)
63
+ config.on_event :test_run_finished, &method(:on_test_run_finished)
64
+ end
65
+
66
+ def on_gherkin_source_read(event)
67
+ @gherkin_sources[event.path] = event.body
68
+ end
69
+
70
+ def on_step_activated(event)
71
+ test_step, step_match = *event.attributes
72
+ @step_matches[test_step.to_s] = step_match
73
+ end
74
+
75
+ def on_test_case_started(event)
76
+ if !same_feature_as_previous_test_case?(event.test_case.location)
77
+ if first_feature?
78
+ @first_feature = false
79
+ print_profile_information
80
+ else
81
+ print_comments(gherkin_source.split("\n").length, 0)
82
+ @io.puts
83
+ end
84
+ @current_feature_uri = event.test_case.location.file
85
+ @exceptions = []
86
+ print_feature_data
87
+ if feature_has_background?
88
+ print_background_data
89
+ @print_background_steps = true
90
+ @in_scenario_outline = false
91
+ end
92
+ else
93
+ @print_background_steps = false
94
+ end
95
+ @current_test_case = event.test_case
96
+ print_step_header(current_test_case) unless print_background_steps
97
+ end
98
+
99
+ def on_test_step_started(event)
100
+ return if event.test_step.hook?
101
+ print_step_header(current_test_case) if first_step_after_printing_background_steps?(event.test_step)
102
+ end
103
+
104
+ def on_test_step_finished(event)
105
+ collect_snippet_data(event.test_step, @ast_lookup) if event.result.undefined?
106
+ return if in_scenario_outline && !options[:expand]
107
+ exception_to_be_printed = find_exception_to_be_printed(event.result)
108
+ print_step_data(event.test_step, event.result) if print_step_data?(event, exception_to_be_printed)
109
+ print_step_output
110
+ return unless exception_to_be_printed
111
+ print_exception(exception_to_be_printed, event.result.to_sym, 6)
112
+ @exceptions << exception_to_be_printed
113
+ end
114
+
115
+ def on_test_case_finished(event)
116
+ @total_duration += DurationExtractor.new(event.result).result_duration
117
+ @passed_test_cases << event.test_case if config.wip? && event.result.passed?
118
+ if in_scenario_outline && !options[:expand]
119
+ print_row_data(event.test_case, event.result)
120
+ else
121
+ exception_to_be_printed = find_exception_to_be_printed(event.result)
122
+ return unless exception_to_be_printed
123
+ print_exception(exception_to_be_printed, event.result.to_sym, 6)
124
+ @exceptions << exception_to_be_printed
125
+ end
37
126
  end
38
127
 
39
- def before_features(features)
40
- print_profile_information
128
+ def on_test_run_finished(_event)
129
+ print_comments(gherkin_source.split("\n").length, 0) unless current_feature_uri.empty?
130
+ @io.puts
131
+ print_summary
41
132
  end
42
133
 
43
- def after_features(features)
44
- print_summary(features)
134
+ def attach(src, media_type)
135
+ return unless media_type == 'text/x.cucumber.log+plain'
136
+ @test_step_output.push src
45
137
  end
46
138
 
47
- def before_feature(feature)
48
- @exceptions = []
49
- @indent = 0
139
+ private
140
+
141
+ def find_exception_to_be_printed(result)
142
+ return nil if result.ok?(options[:strict])
143
+ result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
144
+ exception = result.failed? ? result.exception : result
145
+ return nil if @exceptions.include?(exception)
146
+ exception
50
147
  end
51
148
 
52
- def comment_line(comment_line)
53
- @io.puts(comment_line.indent(@indent))
54
- @io.flush
149
+ def calculate_source_indent(test_case)
150
+ scenario = scenario_source(test_case).scenario
151
+ @source_indent = calculate_source_indent_for_ast_node(scenario)
55
152
  end
56
153
 
57
- def after_tags(tags)
58
- if @indent == 1
59
- @io.puts
60
- @io.flush
154
+ def calculate_source_indent_for_ast_node(ast_node)
155
+ indent = 4 + ast_node.keyword.length
156
+ indent += 1 + ast_node.name.length
157
+ ast_node.steps.each do |step|
158
+ step_indent = 5 + step.keyword.length + step.text.length
159
+ indent = step_indent if step_indent > indent
61
160
  end
161
+ indent
62
162
  end
63
163
 
64
- def tag_name(tag_name)
65
- tag = format_string(tag_name, :tag).indent(@indent)
66
- @io.print(tag)
67
- @io.flush
68
- @indent = 1
164
+ def calculate_source_indent_for_expanded_test_case(test_case, scenario_keyword, expanded_name)
165
+ indent = 7 + scenario_keyword.length
166
+ indent += 2 + expanded_name.length
167
+ test_case.test_steps.each do |step|
168
+ if !step.hook? && step.location.lines.max >= test_case.location.lines.max
169
+ step_indent = 9 + test_step_keyword(step).length + step.text.length
170
+ indent = step_indent if step_indent > indent
171
+ end
172
+ end
173
+ indent
69
174
  end
70
175
 
71
- def feature_name(keyword, name)
72
- @io.puts("#{keyword}: #{name}")
73
- @io.puts
74
- @io.flush
176
+ def print_step_output
177
+ @test_step_output.each { |message| @io.puts(format_string(message, :tag).indent(6)) }
178
+ @test_step_output = []
75
179
  end
76
180
 
77
- def before_feature_element(feature_element)
78
- @indent = 2
79
- @scenario_indent = 2
181
+ def first_feature?
182
+ @first_feature
80
183
  end
81
184
 
82
- def after_feature_element(feature_element)
83
- print_messages
84
- @io.puts
85
- @io.flush
185
+ def same_feature_as_previous_test_case?(location)
186
+ location.file == current_feature_uri
86
187
  end
87
188
 
88
- def before_background(background)
89
- @indent = 2
90
- @scenario_indent = 2
91
- @in_background = true
189
+ def feature_has_background?
190
+ feature_children = gherkin_document.feature.children
191
+ return false if feature_children.empty?
192
+ !feature_children.first.background.nil?
92
193
  end
93
194
 
94
- def after_background(background)
95
- print_messages
96
- @in_background = nil
97
- @io.puts
98
- @io.flush
195
+ def print_step_header(test_case)
196
+ if from_scenario_outline?(test_case)
197
+ @in_scenario_outline = true
198
+ unless same_outline_as_previous_test_case?(test_case)
199
+ @current_scenario_outline = scenario_source(test_case).scenario_outline
200
+ @io.puts
201
+ print_outline_data(current_scenario_outline)
202
+ end
203
+ unless same_examples_as_previous_test_case?(test_case)
204
+ @current_examples = scenario_source(test_case).examples
205
+ @io.puts
206
+ print_examples_data(current_examples)
207
+ end
208
+ print_expanded_row_data(current_test_case) if options[:expand]
209
+ else
210
+ @in_scenario_outline = false
211
+ @current_scenario_outline = nil
212
+ @current_examples = nil
213
+ @io.puts
214
+ @source_indent = calculate_source_indent(current_test_case)
215
+ print_scenario_data(test_case)
216
+ end
99
217
  end
100
218
 
101
- def background_name(keyword, name, file_colon_line, source_indent)
102
- print_feature_element_name(keyword, name, file_colon_line, source_indent)
219
+ def same_outline_as_previous_test_case?(test_case)
220
+ scenario_source(test_case).scenario_outline == current_scenario_outline
103
221
  end
104
222
 
105
- def before_examples_array(examples_array)
106
- @indent = 4
107
- @io.puts
108
- @visiting_first_example_name = true
223
+ def same_examples_as_previous_test_case?(test_case)
224
+ scenario_source(test_case).examples == current_examples
225
+ end
226
+
227
+ def from_scenario_outline?(test_case)
228
+ scenario = scenario_source(test_case)
229
+ scenario.type != :Scenario
230
+ end
231
+
232
+ def first_step_after_printing_background_steps?(test_step)
233
+ return false unless print_background_steps
234
+ return false unless test_step.location.lines.max >= current_test_case.location.lines.max
235
+ @print_background_steps = false
236
+ true
109
237
  end
110
238
 
111
- def examples_name(keyword, name)
112
- @io.puts unless @visiting_first_example_name
113
- @visiting_first_example_name = false
114
- @io.puts(" #{keyword}: #{name}")
239
+ def print_feature_data
240
+ feature = gherkin_document.feature
241
+ print_language_comment(feature.location.line)
242
+ print_comments(feature.location.line, 0)
243
+ print_tags(feature.tags, 0)
244
+ print_feature_line(feature)
245
+ print_description(feature.description)
115
246
  @io.flush
116
- @indent = 6
117
- @scenario_indent = 6
118
247
  end
119
248
 
120
- def before_outline_table(outline_table)
121
- @table = outline_table
249
+ def print_language_comment(feature_line)
250
+ gherkin_source.split("\n")[0..feature_line].each do |line|
251
+ @io.puts(format_string(line, :comment)) if /# *language *:/ =~ line
252
+ end
122
253
  end
123
254
 
124
- def after_outline_table(outline_table)
125
- @table = nil
126
- @indent = 4
255
+ def print_comments(up_to_line, indent)
256
+ comments = gherkin_document.comments
257
+ return if comments.empty? || comments.length <= @next_comment_to_be_printed
258
+ comments[@next_comment_to_be_printed..-1].each do |comment|
259
+ if comment.location.line <= up_to_line
260
+ @io.puts(format_string(comment.text.strip, :comment).indent(indent))
261
+ @next_comment_to_be_printed += 1
262
+ end
263
+ break if @next_comment_to_be_printed >= comments.length
264
+ end
127
265
  end
128
266
 
129
- def scenario_name(keyword, name, file_colon_line, source_indent)
130
- print_feature_element_name(keyword, name, file_colon_line, source_indent)
267
+ def print_tags(tags, indent)
268
+ return if !tags || tags.empty?
269
+ @io.puts(tags.map { |tag| format_string(tag.name, :tag) }.join(' ').indent(indent))
131
270
  end
132
271
 
133
- def before_step(step)
134
- @current_step = step
135
- @indent = 6
136
- print_messages
272
+ def print_feature_line(feature)
273
+ print_keyword_name(feature.keyword, feature.name, 0)
137
274
  end
138
275
 
139
- def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
140
- @hide_this_step = false
141
- if exception
142
- if @exceptions.include?(exception)
143
- @hide_this_step = true
144
- return
145
- end
146
- @exceptions << exception
276
+ def print_keyword_name(keyword, name, indent, location = nil)
277
+ line = "#{keyword}:"
278
+ line += " #{name}"
279
+ @io.print(line.indent(indent))
280
+ if location && options[:source]
281
+ line_comment = format_string("# #{location}", :comment).indent(@source_indent - line.length - indent)
282
+ @io.print(line_comment)
147
283
  end
148
- if status != :failed && @in_background ^ background
149
- @hide_this_step = true
150
- return
284
+ @io.puts
285
+ end
286
+
287
+ def print_description(description)
288
+ return unless description
289
+ description.split("\n").each do |line|
290
+ @io.puts(line)
151
291
  end
152
- @status = status
153
292
  end
154
293
 
155
- def step_name(keyword, step_match, status, source_indent, background, file_colon_line)
156
- return if @hide_this_step
157
- source_indent = nil unless @options[:source]
158
- name_to_report = format_step(keyword, step_match, status, source_indent)
159
- @io.puts(name_to_report.indent(@scenario_indent + 2))
160
- print_messages
294
+ def print_background_data
295
+ @io.puts
296
+ background = gherkin_document.feature.children.first.background
297
+ @source_indent = calculate_source_indent_for_ast_node(background) if options[:source]
298
+ print_comments(background.location.line, 2)
299
+ print_background_line(background)
300
+ print_description(background.description)
301
+ @io.flush
302
+ end
303
+
304
+ def print_background_line(background)
305
+ print_keyword_name(background.keyword, background.name, 2, "#{current_feature_uri}:#{background.location.line}")
161
306
  end
162
307
 
163
- def doc_string(string)
164
- return if @options[:no_multiline] || @hide_this_step
165
- s = %{"""\n#{string}\n"""}.indent(@indent)
166
- s = s.split("\n").map{|l| l =~ /^\s+$/ ? '' : l}.join("\n")
167
- @io.puts(format_string(s, @current_step.status))
308
+ def print_scenario_data(test_case)
309
+ scenario = scenario_source(test_case).scenario
310
+ print_comments(scenario.location.line, 2)
311
+ print_tags(scenario.tags, 2)
312
+ print_scenario_line(scenario, test_case.location)
313
+ print_description(scenario.description)
168
314
  @io.flush
169
315
  end
170
316
 
171
- def exception(exception, status)
172
- return if @hide_this_step
173
- print_messages
174
- print_exception(exception, status, @indent)
317
+ def print_scenario_line(scenario, location = nil)
318
+ print_keyword_name(scenario.keyword, scenario.name, 2, location)
319
+ end
320
+
321
+ def print_step_data?(event, exception_to_be_printed)
322
+ !event.test_step.hook? && (
323
+ print_background_steps ||
324
+ event.test_step.location.lines.max >= current_test_case.location.lines.max ||
325
+ exception_to_be_printed
326
+ )
327
+ end
328
+
329
+ def print_step_data(test_step, result)
330
+ base_indent = options[:expand] && in_scenario_outline ? 8 : 4
331
+ step_keyword = test_step_keyword(test_step)
332
+ indent = options[:source] ? @source_indent - step_keyword.length - test_step.text.length - base_indent : nil
333
+ print_comments(test_step.location.lines.max, base_indent)
334
+ name_to_report = format_step(step_keyword, @step_matches.fetch(test_step.to_s) { NoStepMatch.new(test_step, test_step.text) }, result.to_sym, indent)
335
+ @io.puts(name_to_report.indent(base_indent))
336
+ print_multiline_argument(test_step, result, base_indent + 2) unless options[:no_multiline]
175
337
  @io.flush
176
338
  end
177
339
 
178
- def before_multiline_arg(multiline_arg)
179
- return if @options[:no_multiline] || @hide_this_step
180
- @table = multiline_arg
340
+ def test_step_keyword(test_step)
341
+ step = step_source(test_step).step
342
+ step.keyword
181
343
  end
182
344
 
183
- def after_multiline_arg(multiline_arg)
184
- @table = nil
345
+ def step_source(test_step)
346
+ @ast_lookup.step_source(test_step)
185
347
  end
186
348
 
187
- def before_table_row(table_row)
188
- return if !@table || @hide_this_step
189
- @col_index = 0
190
- @io.print ' |'.indent(@indent-2)
349
+ def scenario_source(test_case)
350
+ @ast_lookup.scenario_source(test_case)
191
351
  end
192
352
 
193
- def after_table_row(table_row)
194
- return if !@table || @hide_this_step
195
- print_table_row_messages
196
- @io.puts
197
- if table_row.exception && !@exceptions.include?(table_row.exception)
198
- print_exception(table_row.exception, table_row.status, @indent)
199
- end
353
+ def gherkin_source
354
+ @gherkin_sources[current_feature_uri]
200
355
  end
201
356
 
202
- def after_table_cell(cell)
203
- return unless @table
204
- @col_index += 1
357
+ def gherkin_document
358
+ @ast_lookup.gherkin_document(current_feature_uri)
205
359
  end
206
360
 
207
- def table_cell_value(value, status)
208
- return if !@table || @hide_this_step
209
- status ||= @status || :passed
210
- width = @table.col_width(@col_index)
211
- cell_text = escape_cell(value.to_s || '')
212
- padded = cell_text + (' ' * (width - cell_text.unpack('U*').length))
213
- prefix = cell_prefix(status)
214
- @io.print(' ' + format_string("#{prefix}#{padded}", status) + ::Cucumber::Term::ANSIColor.reset(" |"))
215
- @io.flush
361
+ def print_multiline_argument(test_step, result, indent)
362
+ step = step_source(test_step).step
363
+ if !step.doc_string.nil?
364
+ print_doc_string(step.doc_string.content, result.to_sym, indent)
365
+ elsif !step.data_table.nil?
366
+ print_data_table(step.data_table, result.to_sym, indent)
367
+ end
216
368
  end
217
369
 
218
- def before_test_case(test_case)
219
- @previous_step_keyword = nil
370
+ def print_data_table(data_table, status, indent)
371
+ data_table.rows.each do |row|
372
+ print_comments(row.location.line, indent)
373
+ @io.puts format_string(gherkin_source.split("\n")[row.location.line - 1].strip, status).indent(indent)
374
+ end
220
375
  end
221
376
 
222
- def after_test_step(test_step, result)
223
- collect_snippet_data(test_step, result)
377
+ def print_outline_data(scenario_outline) # rubocop:disable Metrics/AbcSize
378
+ print_comments(scenario_outline.location.line, 2)
379
+ print_tags(scenario_outline.tags, 2)
380
+ @source_indent = calculate_source_indent_for_ast_node(scenario_outline) if options[:source]
381
+ print_scenario_line(scenario_outline, "#{current_feature_uri}:#{scenario_outline.location.line}")
382
+ print_description(scenario_outline.description)
383
+ scenario_outline.steps.each do |step|
384
+ print_comments(step.location.line, 4)
385
+ step_line = " #{step.keyword}#{step.text}"
386
+ @io.print(format_string(step_line, :skipped))
387
+ if options[:source]
388
+ comment_line = format_string("# #{current_feature_uri}:#{step.location.line}", :comment)
389
+ @io.print(comment_line.indent(@source_indent - step_line.length))
390
+ end
391
+ @io.puts
392
+ next if options[:no_multiline]
393
+ print_doc_string(step.doc_string.content, :skipped, 6) unless step.doc_string.nil?
394
+ print_data_table(step.data_table, :skipped, 6) unless step.data_table.nil?
395
+ end
396
+ @io.flush
224
397
  end
225
398
 
226
- private
399
+ def print_doc_string(content, status, indent)
400
+ s = %("""\n#{content}\n""").indent(indent)
401
+ s = s.split("\n").map { |l| l =~ /^\s+$/ ? '' : l }.join("\n")
402
+ @io.puts(format_string(s, status))
403
+ end
227
404
 
228
- def print_feature_element_name(keyword, name, file_colon_line, source_indent)
229
- @io.puts if @scenario_indent == 6
230
- names = name.empty? ? [name] : name.split("\n")
231
- line = "#{keyword}: #{names[0]}".indent(@scenario_indent)
232
- @io.print(line)
233
- if @options[:source]
234
- line_comment = "# #{file_colon_line}".indent(source_indent)
235
- @io.print(format_string(line_comment, :comment))
405
+ def print_examples_data(examples)
406
+ print_comments(examples.location.line, 4)
407
+ print_tags(examples.tags, 4)
408
+ print_keyword_name(examples.keyword, examples.name, 4)
409
+ print_description(examples.description)
410
+ unless options[:expand]
411
+ print_comments(examples.table_header.location.line, 6)
412
+ @io.puts(gherkin_source.split("\n")[examples.table_header.location.line - 1].strip.indent(6))
236
413
  end
414
+ @io.flush
415
+ end
416
+
417
+ def print_row_data(test_case, result)
418
+ print_comments(test_case.location.lines.max, 6)
419
+ @io.print(format_string(gherkin_source.split("\n")[test_case.location.lines.max - 1].strip, result.to_sym).indent(6))
420
+ @io.print(format_string(@test_step_output.join(', '), :tag).indent(2)) unless @test_step_output.empty?
421
+ @test_step_output = []
237
422
  @io.puts
238
- names[1..-1].each {|s| @io.puts "#{s}"}
423
+ if result.failed? || result.pending?
424
+ result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
425
+ exception = result.failed? ? result.exception : result
426
+ unless @exceptions.include?(exception)
427
+ print_exception(exception, result.to_sym, 6)
428
+ @exceptions << exception
429
+ end
430
+ end
239
431
  @io.flush
240
432
  end
241
433
 
242
- def cell_prefix(status)
243
- @prefixes[status]
434
+ def print_expanded_row_data(test_case)
435
+ feature = gherkin_document.feature
436
+ language_code = feature.language || 'en'
437
+ language = ::Gherkin::Dialect.for(language_code)
438
+ scenario_keyword = language.scenario_keywords[0]
439
+ row = scenario_source(test_case).row
440
+ expanded_name = '| ' + row.cells.map(&:value).join(' | ') + ' |'
441
+ @source_indent = calculate_source_indent_for_expanded_test_case(test_case, scenario_keyword, expanded_name)
442
+ @io.puts
443
+ print_keyword_name(scenario_keyword, expanded_name, 6, test_case.location)
244
444
  end
245
445
 
246
- def print_summary(features)
247
- print_statistics(features.duration, @config, @counts, @issues)
248
- print_snippets(@options)
249
- print_passing_wip(@options)
446
+ def print_summary
447
+ print_statistics(@total_duration, config, @counts, @issues)
448
+ print_snippets(options)
449
+ print_passing_wip(config, @passed_test_cases, @ast_lookup)
250
450
  end
251
451
  end
252
452
  end