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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. checksums.yaml +5 -5
  2. data/{History.md → CHANGELOG.md} +267 -14
  3. data/CONTRIBUTING.md +4 -21
  4. data/README.md +14 -15
  5. data/bin/cucumber +2 -1
  6. data/lib/autotest/cucumber.rb +1 -0
  7. data/lib/autotest/cucumber_mixin.rb +36 -40
  8. data/lib/autotest/cucumber_rails.rb +1 -0
  9. data/lib/autotest/cucumber_rails_rspec.rb +1 -0
  10. data/lib/autotest/cucumber_rails_rspec2.rb +1 -0
  11. data/lib/autotest/cucumber_rspec.rb +1 -0
  12. data/lib/autotest/cucumber_rspec2.rb +1 -0
  13. data/lib/autotest/discover.rb +1 -0
  14. data/lib/cucumber.rb +2 -1
  15. data/lib/cucumber/cli/configuration.rb +8 -7
  16. data/lib/cucumber/cli/main.rb +14 -14
  17. data/lib/cucumber/cli/options.rb +141 -120
  18. data/lib/cucumber/cli/profile_loader.rb +50 -29
  19. data/lib/cucumber/cli/rerun_file.rb +1 -0
  20. data/lib/cucumber/configuration.rb +40 -30
  21. data/lib/cucumber/constantize.rb +8 -10
  22. data/lib/cucumber/core_ext/string.rb +1 -0
  23. data/lib/cucumber/deprecate.rb +33 -9
  24. data/lib/cucumber/encoding.rb +2 -1
  25. data/lib/cucumber/errors.rb +10 -8
  26. data/lib/cucumber/events.rb +14 -9
  27. data/lib/cucumber/events/envelope.rb +9 -0
  28. data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
  29. data/lib/cucumber/events/gherkin_source_read.rb +1 -4
  30. data/lib/cucumber/events/hook_test_step_created.rb +13 -0
  31. data/lib/cucumber/events/step_activated.rb +6 -6
  32. data/lib/cucumber/events/step_definition_registered.rb +4 -8
  33. data/lib/cucumber/events/test_case_created.rb +13 -0
  34. data/lib/cucumber/events/test_case_finished.rb +1 -5
  35. data/lib/cucumber/events/test_case_ready.rb +12 -0
  36. data/lib/cucumber/events/{test_case_starting.rb → test_case_started.rb} +1 -5
  37. data/lib/cucumber/events/test_run_finished.rb +2 -3
  38. data/lib/cucumber/events/{test_run_starting.rb → test_run_started.rb} +3 -5
  39. data/lib/cucumber/events/test_step_created.rb +13 -0
  40. data/lib/cucumber/events/test_step_finished.rb +0 -6
  41. data/lib/cucumber/events/{test_step_starting.rb → test_step_started.rb} +2 -8
  42. data/lib/cucumber/file_specs.rb +7 -6
  43. data/lib/cucumber/filters.rb +3 -1
  44. data/lib/cucumber/filters/activate_steps.rb +11 -5
  45. data/lib/cucumber/filters/apply_after_hooks.rb +1 -0
  46. data/lib/cucumber/filters/apply_after_step_hooks.rb +1 -0
  47. data/lib/cucumber/filters/apply_around_hooks.rb +1 -0
  48. data/lib/cucumber/filters/apply_before_hooks.rb +1 -0
  49. data/lib/cucumber/filters/broadcast_test_case_ready_event.rb +12 -0
  50. data/lib/cucumber/filters/{broadcast_test_run_starting_event.rb → broadcast_test_run_started_event.rb} +4 -3
  51. data/lib/cucumber/filters/gated_receiver.rb +1 -2
  52. data/lib/cucumber/filters/prepare_world.rb +6 -13
  53. data/lib/cucumber/filters/quit.rb +3 -7
  54. data/lib/cucumber/filters/randomizer.rb +6 -7
  55. data/lib/cucumber/filters/retry.rb +2 -2
  56. data/lib/cucumber/filters/tag_limits.rb +2 -2
  57. data/lib/cucumber/filters/tag_limits/test_case_index.rb +1 -2
  58. data/lib/cucumber/filters/tag_limits/verifier.rb +3 -6
  59. data/lib/cucumber/formatter/ansicolor.rb +33 -37
  60. data/lib/cucumber/formatter/ast_lookup.rb +165 -0
  61. data/lib/cucumber/formatter/backtrace_filter.rb +10 -10
  62. data/lib/cucumber/formatter/console.rb +37 -74
  63. data/lib/cucumber/formatter/console_counts.rb +4 -9
  64. data/lib/cucumber/formatter/console_issues.rb +10 -7
  65. data/lib/cucumber/formatter/duration.rb +2 -1
  66. data/lib/cucumber/formatter/duration_extractor.rb +4 -2
  67. data/lib/cucumber/formatter/errors.rb +6 -0
  68. data/lib/cucumber/formatter/fail_fast.rb +9 -6
  69. data/lib/cucumber/formatter/fanout.rb +3 -3
  70. data/lib/cucumber/formatter/html.rb +11 -603
  71. data/lib/cucumber/formatter/http_io.rb +93 -0
  72. data/lib/cucumber/formatter/ignore_missing_messages.rb +2 -4
  73. data/lib/cucumber/formatter/interceptor.rb +10 -12
  74. data/lib/cucumber/formatter/io.rb +19 -12
  75. data/lib/cucumber/formatter/json.rb +106 -112
  76. data/lib/cucumber/formatter/junit.rb +81 -76
  77. data/lib/cucumber/formatter/message.rb +22 -0
  78. data/lib/cucumber/formatter/message_builder.rb +241 -0
  79. data/lib/cucumber/formatter/pretty.rb +353 -153
  80. data/lib/cucumber/formatter/progress.rb +30 -33
  81. data/lib/cucumber/formatter/query/hook_by_test_step.rb +31 -0
  82. data/lib/cucumber/formatter/query/pickle_by_test.rb +26 -0
  83. data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +26 -0
  84. data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +40 -0
  85. data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +40 -0
  86. data/lib/cucumber/formatter/rerun.rb +24 -5
  87. data/lib/cucumber/formatter/stepdefs.rb +2 -2
  88. data/lib/cucumber/formatter/steps.rb +4 -5
  89. data/lib/cucumber/formatter/summary.rb +18 -11
  90. data/lib/cucumber/formatter/unicode.rb +16 -18
  91. data/lib/cucumber/formatter/usage.rb +30 -26
  92. data/lib/cucumber/gherkin/data_table_parser.rb +18 -6
  93. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +83 -86
  94. data/lib/cucumber/gherkin/formatter/escaping.rb +13 -12
  95. data/lib/cucumber/gherkin/i18n.rb +1 -0
  96. data/lib/cucumber/gherkin/steps_parser.rb +18 -8
  97. data/lib/cucumber/glue/dsl.rb +13 -26
  98. data/lib/cucumber/glue/hook.rb +35 -11
  99. data/lib/cucumber/glue/invoke_in_world.rb +15 -20
  100. data/lib/cucumber/glue/proto_world.rb +48 -42
  101. data/lib/cucumber/glue/registry_and_more.rb +58 -23
  102. data/lib/cucumber/glue/snippet.rb +23 -26
  103. data/lib/cucumber/glue/step_definition.rb +51 -28
  104. data/lib/cucumber/glue/world_factory.rb +2 -4
  105. data/lib/cucumber/hooks.rb +27 -17
  106. data/lib/cucumber/load_path.rb +1 -0
  107. data/lib/cucumber/multiline_argument.rb +7 -17
  108. data/lib/cucumber/multiline_argument/data_table.rb +113 -82
  109. data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +8 -12
  110. data/lib/cucumber/multiline_argument/doc_string.rb +2 -1
  111. data/lib/cucumber/platform.rb +4 -3
  112. data/lib/cucumber/project_initializer.rb +2 -2
  113. data/lib/cucumber/rake/task.rb +28 -21
  114. data/lib/cucumber/rspec/disable_option_parser.rb +10 -8
  115. data/lib/cucumber/rspec/doubles.rb +1 -0
  116. data/lib/cucumber/running_test_case.rb +4 -54
  117. data/lib/cucumber/runtime.rb +32 -63
  118. data/lib/cucumber/runtime/after_hooks.rb +9 -4
  119. data/lib/cucumber/runtime/before_hooks.rb +9 -4
  120. data/lib/cucumber/runtime/for_programming_languages.rb +12 -9
  121. data/lib/cucumber/runtime/step_hooks.rb +5 -2
  122. data/lib/cucumber/runtime/support_code.rb +16 -22
  123. data/lib/cucumber/runtime/user_interface.rb +12 -23
  124. data/lib/cucumber/step_definition_light.rb +6 -4
  125. data/lib/cucumber/step_definitions.rb +3 -2
  126. data/lib/cucumber/step_match.rb +29 -14
  127. data/lib/cucumber/step_match_search.rb +10 -10
  128. data/lib/cucumber/term/ansicolor.rb +39 -39
  129. data/lib/cucumber/unit.rb +1 -0
  130. data/lib/cucumber/version +1 -1
  131. data/lib/simplecov_setup.rb +1 -0
  132. metadata +206 -678
  133. data/.coveralls.yml +0 -1
  134. data/.cucumberproignore +0 -6
  135. data/.github/ISSUE_TEMPLATE.md +0 -48
  136. data/.github/PULL_REQUEST_TEMPLATE.md +0 -39
  137. data/.rspec +0 -1
  138. data/.rubocop.yml +0 -13
  139. data/.rubocop_todo.yml +0 -1075
  140. data/.ruby-gemset +0 -1
  141. data/.travis.yml +0 -69
  142. data/.yardopts +0 -1
  143. data/Gemfile +0 -28
  144. data/Rakefile +0 -32
  145. data/appveyor.yml +0 -26
  146. data/cucumber.gemspec +0 -52
  147. data/cucumber.yml +0 -19
  148. data/examples/i18n/README.textile +0 -3
  149. data/examples/i18n/Rakefile +0 -33
  150. data/examples/i18n/ar/Rakefile +0 -6
  151. data/examples/i18n/ar/features/addition.feature +0 -17
  152. data/examples/i18n/ar/features/step_definitions/calculator_steps.rb +0 -24
  153. data/examples/i18n/ar/lib/calculator.rb +0 -11
  154. data/examples/i18n/bg/Rakefile +0 -6
  155. data/examples/i18n/bg/features/addition.feature +0 -12
  156. data/examples/i18n/bg/features/consecutive_calculations.feature +0 -19
  157. data/examples/i18n/bg/features/division.feature +0 -17
  158. data/examples/i18n/bg/features/step_definitions/calculator_steps.rb +0 -24
  159. data/examples/i18n/bg/features/support/env.rb +0 -5
  160. data/examples/i18n/bg/features/support/world.rb +0 -8
  161. data/examples/i18n/bg/lib/calculator.rb +0 -24
  162. data/examples/i18n/ca/Rakefile +0 -6
  163. data/examples/i18n/ca/features/step_definitions/calculator_steps.rb +0 -21
  164. data/examples/i18n/ca/features/suma.feature +0 -17
  165. data/examples/i18n/ca/lib/calculadora.rb +0 -16
  166. data/examples/i18n/cs/Rakefile +0 -6
  167. data/examples/i18n/cs/features/addition.feature +0 -17
  168. data/examples/i18n/cs/features/division.feature +0 -11
  169. data/examples/i18n/cs/features/step_definitions/calculator_steps.rb +0 -24
  170. data/examples/i18n/cs/lib/calculator.rb +0 -14
  171. data/examples/i18n/da/Rakefile +0 -6
  172. data/examples/i18n/da/features/sammenlaegning.feature +0 -18
  173. data/examples/i18n/da/features/step_definitions/lommeregner_steps.rb +0 -24
  174. data/examples/i18n/da/lib/lommeregner.rb +0 -11
  175. data/examples/i18n/de/Rakefile +0 -6
  176. data/examples/i18n/de/features/addition.feature +0 -17
  177. data/examples/i18n/de/features/division.feature +0 -10
  178. data/examples/i18n/de/features/step_definitions/calculator_steps.rb +0 -24
  179. data/examples/i18n/de/lib/calculator.rb +0 -14
  180. data/examples/i18n/el/Rakefile +0 -6
  181. data/examples/i18n/el/features/addition.feature +0 -17
  182. data/examples/i18n/el/features/division.feature +0 -10
  183. data/examples/i18n/el/features/step_definitions/calculator_steps.rb +0 -24
  184. data/examples/i18n/el/lib/calculator.rb +0 -14
  185. data/examples/i18n/en-lol/Rakefile +0 -4
  186. data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +0 -16
  187. data/examples/i18n/en-lol/features/stuffing.feature +0 -8
  188. data/examples/i18n/en-lol/features/support/env.rb +0 -7
  189. data/examples/i18n/en-lol/lib/basket.rb +0 -12
  190. data/examples/i18n/en-lol/lib/belly.rb +0 -11
  191. data/examples/i18n/en/Rakefile +0 -6
  192. data/examples/i18n/en/features/addition.feature +0 -17
  193. data/examples/i18n/en/features/division.feature +0 -10
  194. data/examples/i18n/en/features/step_definitions/calculator_steps.rb +0 -24
  195. data/examples/i18n/en/lib/calculator.rb +0 -14
  196. data/examples/i18n/eo/Rakefile +0 -6
  197. data/examples/i18n/eo/features/adicio.feature +0 -17
  198. data/examples/i18n/eo/features/divido.feature +0 -10
  199. data/examples/i18n/eo/features/step_definitions/calculator_steps.rb +0 -24
  200. data/examples/i18n/eo/lib/calculator.rb +0 -14
  201. data/examples/i18n/es/Rakefile +0 -6
  202. data/examples/i18n/es/features/adicion.feature +0 -17
  203. data/examples/i18n/es/features/step_definitions/calculador_steps.rb +0 -21
  204. data/examples/i18n/es/lib/calculador.rb +0 -14
  205. data/examples/i18n/et/Rakefile +0 -6
  206. data/examples/i18n/et/features/jagamine.feature +0 -10
  207. data/examples/i18n/et/features/liitmine.feature +0 -17
  208. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +0 -24
  209. data/examples/i18n/et/lib/kalkulaator.rb +0 -14
  210. data/examples/i18n/fi/Rakefile +0 -6
  211. data/examples/i18n/fi/features/jakolasku.feature +0 -10
  212. data/examples/i18n/fi/features/step_definitions/laskin_steps.rb +0 -24
  213. data/examples/i18n/fi/features/yhteenlasku.feature +0 -17
  214. data/examples/i18n/fi/lib/laskin.rb +0 -14
  215. data/examples/i18n/fr/Rakefile +0 -8
  216. data/examples/i18n/fr/features/addition.feature +0 -18
  217. data/examples/i18n/fr/features/addition2.feature +0 -17
  218. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +0 -32
  219. data/examples/i18n/fr/features/support/env.rb +0 -5
  220. data/examples/i18n/fr/lib/calculatrice.rb +0 -10
  221. data/examples/i18n/he/Rakefile +0 -6
  222. data/examples/i18n/he/features/addition.feature +0 -17
  223. data/examples/i18n/he/features/division.feature +0 -10
  224. data/examples/i18n/he/features/step_definitions/calculator_steps.rb +0 -24
  225. data/examples/i18n/he/lib/calculator.rb +0 -15
  226. data/examples/i18n/hi/Rakefile +0 -6
  227. data/examples/i18n/hi/features/addition.feature +0 -16
  228. data/examples/i18n/hi/features/division.feature +0 -10
  229. data/examples/i18n/hi/features/step_definitions/calculator_steps.rb +0 -24
  230. data/examples/i18n/hi/lib/calculator.rb +0 -15
  231. data/examples/i18n/ht/Rakefile +0 -6
  232. data/examples/i18n/ht/features/adisyon.feature +0 -17
  233. data/examples/i18n/ht/features/divizyon.feature +0 -10
  234. data/examples/i18n/ht/features/step_definitions/kalkilatris_steps.rb +0 -25
  235. data/examples/i18n/ht/lib/kalkilatris.rb +0 -14
  236. data/examples/i18n/hu/Rakefile +0 -6
  237. data/examples/i18n/hu/features/osszeadas.feature +0 -17
  238. data/examples/i18n/hu/features/osztas.feature +0 -10
  239. data/examples/i18n/hu/features/step_definitions/calculator_steps.rb +0 -25
  240. data/examples/i18n/hu/lib/calculator.rb +0 -14
  241. data/examples/i18n/id/Rakefile +0 -6
  242. data/examples/i18n/id/features/addition.feature +0 -17
  243. data/examples/i18n/id/features/division.feature +0 -10
  244. data/examples/i18n/id/features/step_definitions/calculator_steps.rb +0 -24
  245. data/examples/i18n/id/lib/calculator.rb +0 -14
  246. data/examples/i18n/it/Rakefile +0 -6
  247. data/examples/i18n/it/features/somma.feature +0 -11
  248. data/examples/i18n/it/features/step_definitions/calcolatrice_steps.rb +0 -24
  249. data/examples/i18n/it/lib/calcolatrice.rb +0 -11
  250. data/examples/i18n/ja/Rakefile +0 -6
  251. data/examples/i18n/ja/features/addition.feature +0 -17
  252. data/examples/i18n/ja/features/division.feature +0 -10
  253. data/examples/i18n/ja/features/step_definitions/calculator_steps.rb +0 -19
  254. data/examples/i18n/ja/features/support/env.rb +0 -5
  255. data/examples/i18n/ja/lib/calculator.rb +0 -14
  256. data/examples/i18n/ko/Rakefile +0 -6
  257. data/examples/i18n/ko/features/addition.feature +0 -17
  258. data/examples/i18n/ko/features/division.feature +0 -11
  259. data/examples/i18n/ko/features/step_definitions/calculator_steps.rb +0 -24
  260. data/examples/i18n/ko/lib/calculator.rb +0 -14
  261. data/examples/i18n/lt/Rakefile +0 -6
  262. data/examples/i18n/lt/features/addition.feature +0 -17
  263. data/examples/i18n/lt/features/division.feature +0 -10
  264. data/examples/i18n/lt/features/step_definitions/calculator_steps.rb +0 -24
  265. data/examples/i18n/lt/lib/calculator.rb +0 -14
  266. data/examples/i18n/lv/Rakefile +0 -6
  267. data/examples/i18n/lv/features/addition.feature +0 -17
  268. data/examples/i18n/lv/features/division.feature +0 -10
  269. data/examples/i18n/lv/features/step_definitions/calculator_steps.rb +0 -24
  270. data/examples/i18n/lv/lib/calculator.rb +0 -14
  271. data/examples/i18n/no/Rakefile +0 -6
  272. data/examples/i18n/no/features/step_definitions/kalkulator_steps.rb +0 -17
  273. data/examples/i18n/no/features/summering.feature +0 -19
  274. data/examples/i18n/no/features/support/env.rb +0 -6
  275. data/examples/i18n/no/lib/kalkulator.rb +0 -11
  276. data/examples/i18n/pl/Rakefile +0 -6
  277. data/examples/i18n/pl/features/addition.feature +0 -17
  278. data/examples/i18n/pl/features/division.feature +0 -10
  279. data/examples/i18n/pl/features/step_definitions/calculator_steps.rb +0 -24
  280. data/examples/i18n/pl/features/support/env.rb +0 -5
  281. data/examples/i18n/pl/lib/calculator.rb +0 -14
  282. data/examples/i18n/pt/Rakefile +0 -6
  283. data/examples/i18n/pt/features/adicao.feature +0 -11
  284. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +0 -20
  285. data/examples/i18n/pt/features/support/env.rb +0 -5
  286. data/examples/i18n/pt/lib/calculadora.rb +0 -10
  287. data/examples/i18n/ro/Rakefile +0 -6
  288. data/examples/i18n/ro/features/adunare.feature +0 -12
  289. data/examples/i18n/ro/features/step_definitions/calculator_steps.rb +0 -21
  290. data/examples/i18n/ro/lib/calculator.rb +0 -11
  291. data/examples/i18n/ru/Rakefile +0 -6
  292. data/examples/i18n/ru/features/addition.feature +0 -11
  293. data/examples/i18n/ru/features/consecutive_calculations.feature +0 -17
  294. data/examples/i18n/ru/features/division.feature +0 -16
  295. data/examples/i18n/ru/features/step_definitions/calculator_steps.rb +0 -19
  296. data/examples/i18n/ru/features/support/env.rb +0 -5
  297. data/examples/i18n/ru/features/support/world.rb +0 -8
  298. data/examples/i18n/ru/lib/calculator.rb +0 -24
  299. data/examples/i18n/sk/Rakefile +0 -6
  300. data/examples/i18n/sk/features/addition.feature +0 -17
  301. data/examples/i18n/sk/features/division.feature +0 -10
  302. data/examples/i18n/sk/features/step_definitions/calculator_steps.rb +0 -24
  303. data/examples/i18n/sk/lib/calculator.rb +0 -14
  304. data/examples/i18n/sr-Cyrl/Rakefile +0 -6
  305. data/examples/i18n/sr-Cyrl/features/sabiranje.feature +0 -18
  306. data/examples/i18n/sr-Cyrl/features/step_definitions/calculator_steps.rb +0 -20
  307. data/examples/i18n/sr-Cyrl/features/support/env.rb +0 -5
  308. data/examples/i18n/sr-Cyrl/lib/calculator.rb +0 -12
  309. data/examples/i18n/sr-Latn/Rakefile +0 -6
  310. data/examples/i18n/sr-Latn/features/sabiranje.feature +0 -18
  311. data/examples/i18n/sr-Latn/features/step_definitions/calculator_steps.rb +0 -24
  312. data/examples/i18n/sr-Latn/lib/calculator.rb +0 -12
  313. data/examples/i18n/sv/Rakefile +0 -6
  314. data/examples/i18n/sv/features/step_definitions/kalkulator_steps.rb +0 -24
  315. data/examples/i18n/sv/features/summering.feature +0 -18
  316. data/examples/i18n/sv/lib/kalkulator.rb +0 -11
  317. data/examples/i18n/tr/Rakefile +0 -6
  318. data/examples/i18n/tr/features/bolme.feature +0 -10
  319. data/examples/i18n/tr/features/step_definitions/hesap_makinesi_adimlari.rb +0 -24
  320. data/examples/i18n/tr/features/toplama.feature +0 -18
  321. data/examples/i18n/tr/lib/hesap_makinesi.rb +0 -15
  322. data/examples/i18n/uk/Rakefile +0 -6
  323. data/examples/i18n/uk/features/addition.feature +0 -11
  324. data/examples/i18n/uk/features/consecutive_calculations.feature +0 -17
  325. data/examples/i18n/uk/features/division.feature +0 -16
  326. data/examples/i18n/uk/features/step_definitions/calculator_steps.rb +0 -19
  327. data/examples/i18n/uk/features/support/env.rb +0 -5
  328. data/examples/i18n/uk/features/support/world.rb +0 -8
  329. data/examples/i18n/uk/lib/calculator.rb +0 -24
  330. data/examples/i18n/uz/Rakefile +0 -6
  331. data/examples/i18n/uz/features/addition.feature +0 -10
  332. data/examples/i18n/uz/features/consecutive_calculations.feature +0 -17
  333. data/examples/i18n/uz/features/division.feature +0 -17
  334. data/examples/i18n/uz/features/step_definitions/calculator_steps.rb +0 -19
  335. data/examples/i18n/uz/features/support/env.rb +0 -5
  336. data/examples/i18n/uz/features/support/world.rb +0 -8
  337. data/examples/i18n/uz/lib/calculator.rb +0 -24
  338. data/examples/i18n/zh-CN/Rakefile +0 -4
  339. data/examples/i18n/zh-CN/features/addition.feature +0 -18
  340. data/examples/i18n/zh-CN/features/step_definitions/calculator_steps.rb +0 -26
  341. data/examples/i18n/zh-CN/lib/calculator.rb +0 -10
  342. data/examples/i18n/zh-TW/Rakefile +0 -4
  343. data/examples/i18n/zh-TW/features/addition.feature +0 -17
  344. data/examples/i18n/zh-TW/features/division.feature +0 -11
  345. data/examples/i18n/zh-TW/features/step_definitions/calculator_steps.rb +0 -24
  346. data/examples/i18n/zh-TW/lib/calculator.rb +0 -14
  347. data/examples/rspec_doubles/Rakefile +0 -4
  348. data/examples/rspec_doubles/features/mocking.feature +0 -9
  349. data/examples/rspec_doubles/features/step_definitions/calvin_steps.rb +0 -19
  350. data/examples/rspec_doubles/features/support/env.rb +0 -12
  351. data/examples/sinatra/README.textile +0 -13
  352. data/examples/sinatra/Rakefile +0 -6
  353. data/examples/sinatra/app.rb +0 -14
  354. data/examples/sinatra/features/add.feature +0 -11
  355. data/examples/sinatra/features/step_definitions/add_steps.rb +0 -15
  356. data/examples/sinatra/features/support/env.rb +0 -10
  357. data/examples/sinatra/views/add.erb +0 -7
  358. data/examples/sinatra/views/layout.erb +0 -8
  359. data/examples/tcl/README.textile +0 -11
  360. data/examples/tcl/Rakefile +0 -6
  361. data/examples/tcl/features/fibonnacci.feature +0 -17
  362. data/examples/tcl/features/step_definitions/fib_steps.rb +0 -7
  363. data/examples/tcl/features/support/env.rb +0 -6
  364. data/examples/tcl/src/fib.tcl +0 -3
  365. data/examples/test_unit/Gemfile +0 -4
  366. data/examples/test_unit/Rakefile +0 -6
  367. data/examples/test_unit/features/step_definitions/test_unit_steps.rb +0 -20
  368. data/examples/test_unit/features/test_unit.feature +0 -9
  369. data/examples/watir/README.textile +0 -16
  370. data/examples/watir/Rakefile +0 -12
  371. data/examples/watir/cucumber.yml +0 -1
  372. data/examples/watir/features/search.feature +0 -12
  373. data/examples/watir/features/step_definitions/search_steps.rb +0 -26
  374. data/examples/watir/features/support/env.rb +0 -35
  375. data/examples/watir/features/support/screenshots.rb +0 -47
  376. data/features/docs/api/list_step_defs_as_json.feature +0 -64
  377. data/features/docs/api/listen_for_events.feature +0 -59
  378. data/features/docs/api/run_cli_main_with_existing_runtime.feature +0 -27
  379. data/features/docs/cli/backtraces.feature +0 -36
  380. data/features/docs/cli/dry_run.feature +0 -73
  381. data/features/docs/cli/exclude_files.feature +0 -18
  382. data/features/docs/cli/execute_with_tag_filter.feature +0 -117
  383. data/features/docs/cli/fail_fast.feature +0 -48
  384. data/features/docs/cli/finding_steps.feature +0 -28
  385. data/features/docs/cli/help.feature +0 -8
  386. data/features/docs/cli/i18n.feature +0 -42
  387. data/features/docs/cli/randomize.feature +0 -140
  388. data/features/docs/cli/require.feature +0 -27
  389. data/features/docs/cli/retry_failing_tests.feature +0 -92
  390. data/features/docs/cli/run_scenarios_matching_name.feature +0 -105
  391. data/features/docs/cli/run_specific_scenarios.feature +0 -77
  392. data/features/docs/cli/showing_differences.feature +0 -43
  393. data/features/docs/cli/specifying_multiple_formatters.feature +0 -68
  394. data/features/docs/cli/strict_mode.feature +0 -70
  395. data/features/docs/defining_steps/nested_steps.feature +0 -181
  396. data/features/docs/defining_steps/nested_steps_i18n.feature +0 -37
  397. data/features/docs/defining_steps/nested_steps_with_second_arg.feature +0 -56
  398. data/features/docs/defining_steps/one_line_step_definitions.feature +0 -65
  399. data/features/docs/defining_steps/printing_messages.feature +0 -147
  400. data/features/docs/defining_steps/skip_scenario.feature +0 -31
  401. data/features/docs/defining_steps/snippets.feature +0 -56
  402. data/features/docs/defining_steps/table_diffing.feature +0 -50
  403. data/features/docs/events/gherkin_source_read_event.feature +0 -43
  404. data/features/docs/events/step_activated_event.feature +0 -36
  405. data/features/docs/events/step_definition_registered_event.feature +0 -29
  406. data/features/docs/events/test_case_finished_event.feature +0 -35
  407. data/features/docs/events/test_case_starting_event.feature +0 -54
  408. data/features/docs/events/test_run_finished_event.feature +0 -40
  409. data/features/docs/events/test_run_starting_event.feature +0 -41
  410. data/features/docs/events/test_step_finished_event.feature +0 -47
  411. data/features/docs/events/test_step_starting_event.feature +0 -43
  412. data/features/docs/exception_in_after_hook.feature +0 -127
  413. data/features/docs/exception_in_after_step_hook.feature +0 -104
  414. data/features/docs/exception_in_around_hook.feature +0 -80
  415. data/features/docs/exception_in_before_hook.feature +0 -98
  416. data/features/docs/extending_cucumber/custom_filter.feature +0 -29
  417. data/features/docs/extending_cucumber/custom_formatter.feature +0 -122
  418. data/features/docs/formatters/api_methods.feature +0 -37
  419. data/features/docs/formatters/formatter_step_file_colon_line.feature +0 -44
  420. data/features/docs/formatters/html_formatter.feature +0 -91
  421. data/features/docs/formatters/json_formatter.feature +0 -767
  422. data/features/docs/formatters/junit_formatter.feature +0 -455
  423. data/features/docs/formatters/pretty_formatter.feature +0 -74
  424. data/features/docs/formatters/progress_formatter.feature +0 -32
  425. data/features/docs/formatters/rerun_formatter.feature +0 -190
  426. data/features/docs/formatters/summary_formatter.feature +0 -35
  427. data/features/docs/formatters/usage_formatter.feature +0 -101
  428. data/features/docs/getting_started.feature +0 -28
  429. data/features/docs/gherkin/background.feature +0 -548
  430. data/features/docs/gherkin/doc_strings.feature +0 -76
  431. data/features/docs/gherkin/expand_option_for_outlines.feature +0 -47
  432. data/features/docs/gherkin/language_from_header.feature +0 -32
  433. data/features/docs/gherkin/outlines.feature +0 -160
  434. data/features/docs/gherkin/unicode_table.feature +0 -33
  435. data/features/docs/gherkin/using_descriptions.feature +0 -83
  436. data/features/docs/gherkin/using_star_notation.feature +0 -37
  437. data/features/docs/iso-8859-1.feature +0 -6
  438. data/features/docs/post_configuration_hook.feature +0 -33
  439. data/features/docs/profiles.feature +0 -120
  440. data/features/docs/rake_task.feature +0 -146
  441. data/features/docs/raketask.feature +0 -46
  442. data/features/docs/work_in_progress.feature +0 -157
  443. data/features/docs/writing_support_code/after_hooks.feature +0 -102
  444. data/features/docs/writing_support_code/after_step_hooks.feature +0 -55
  445. data/features/docs/writing_support_code/around_hooks.feature +0 -266
  446. data/features/docs/writing_support_code/before_hook.feature +0 -66
  447. data/features/docs/writing_support_code/hook_order.feature +0 -63
  448. data/features/docs/writing_support_code/load_path.feature +0 -17
  449. data/features/docs/writing_support_code/parameter_types.feature +0 -75
  450. data/features/docs/writing_support_code/state.feature +0 -32
  451. data/features/docs/writing_support_code/tagged_hooks.feature +0 -95
  452. data/features/docs/writing_support_code/world.feature +0 -129
  453. data/features/lib/step_definitions/aruba_steps.rb +0 -21
  454. data/features/lib/step_definitions/cli_steps.rb +0 -4
  455. data/features/lib/step_definitions/cucumber_steps.rb +0 -75
  456. data/features/lib/step_definitions/iso-8859-1_steps.rb +0 -13
  457. data/features/lib/step_definitions/json_steps.rb +0 -8
  458. data/features/lib/step_definitions/junit_steps.rb +0 -14
  459. data/features/lib/step_definitions/language_steps.rb +0 -9
  460. data/features/lib/step_definitions/profile_steps.rb +0 -16
  461. data/features/lib/step_definitions/retry_steps.rb +0 -55
  462. data/features/lib/step_definitions/ruby_steps.rb +0 -4
  463. data/features/lib/support/env.rb +0 -22
  464. data/features/lib/support/fake_wire_server.rb +0 -86
  465. data/features/lib/support/feature_factory.rb +0 -68
  466. data/features/lib/support/normalise_output.rb +0 -52
  467. data/features/lib/support/parameter_types.rb +0 -8
  468. data/gem_tasks/contributors.rake +0 -19
  469. data/gem_tasks/cov.rake +0 -6
  470. data/gem_tasks/downloads.rb +0 -8
  471. data/gem_tasks/environment.rake +0 -4
  472. data/gem_tasks/examples.rake +0 -12
  473. data/gem_tasks/fix_cr_lf.rake +0 -11
  474. data/gem_tasks/flog.rake +0 -5
  475. data/gem_tasks/rspec.rake +0 -7
  476. data/gem_tasks/sass.rake +0 -5
  477. data/gem_tasks/stats +0 -16
  478. data/gem_tasks/versions.txt +0 -74
  479. data/lib/cucumber/formatter/cucumber.css +0 -286
  480. data/lib/cucumber/formatter/cucumber.sass +0 -247
  481. data/lib/cucumber/formatter/hook_query_visitor.rb +0 -41
  482. data/lib/cucumber/formatter/html_builder.rb +0 -110
  483. data/lib/cucumber/formatter/inline-js.js +0 -30
  484. data/lib/cucumber/formatter/jquery-min.js +0 -154
  485. data/lib/cucumber/formatter/json_pretty.rb +0 -11
  486. data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1012
  487. data/lib/cucumber/formatter/legacy_api/ast.rb +0 -386
  488. data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
  489. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
  490. data/lib/cucumber/step_argument.rb +0 -24
  491. data/scripts/invite-collaborator +0 -40
  492. data/scripts/update-history +0 -83
  493. data/spec/cucumber/cli/configuration_spec.rb +0 -434
  494. data/spec/cucumber/cli/main_spec.rb +0 -84
  495. data/spec/cucumber/cli/options_spec.rb +0 -445
  496. data/spec/cucumber/cli/profile_loader_spec.rb +0 -66
  497. data/spec/cucumber/cli/rerun_spec.rb +0 -86
  498. data/spec/cucumber/configuration_spec.rb +0 -148
  499. data/spec/cucumber/constantize_spec.rb +0 -20
  500. data/spec/cucumber/events_spec.rb +0 -9
  501. data/spec/cucumber/file_specs_spec.rb +0 -61
  502. data/spec/cucumber/filters/activate_steps_spec.rb +0 -152
  503. data/spec/cucumber/filters/gated_receiver_spec.rb +0 -48
  504. data/spec/cucumber/filters/retry_spec.rb +0 -98
  505. data/spec/cucumber/filters/tag_limits/test_case_index_spec.rb +0 -39
  506. data/spec/cucumber/filters/tag_limits/verifier_spec.rb +0 -58
  507. data/spec/cucumber/filters/tag_limits_spec.rb +0 -60
  508. data/spec/cucumber/formatter/ansicolor_spec.rb +0 -33
  509. data/spec/cucumber/formatter/backtrace_filter_spec.rb +0 -32
  510. data/spec/cucumber/formatter/console_counts_spec.rb +0 -14
  511. data/spec/cucumber/formatter/duration_spec.rb +0 -23
  512. data/spec/cucumber/formatter/fail_fast_spec.rb +0 -88
  513. data/spec/cucumber/formatter/html_spec.rb +0 -543
  514. data/spec/cucumber/formatter/interceptor_spec.rb +0 -137
  515. data/spec/cucumber/formatter/json_spec.rb +0 -840
  516. data/spec/cucumber/formatter/junit_spec.rb +0 -251
  517. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +0 -2187
  518. data/spec/cucumber/formatter/pretty_spec.rb +0 -920
  519. data/spec/cucumber/formatter/progress_spec.rb +0 -170
  520. data/spec/cucumber/formatter/rerun_spec.rb +0 -97
  521. data/spec/cucumber/formatter/spec_helper.rb +0 -84
  522. data/spec/cucumber/glue/proto_world_spec.rb +0 -63
  523. data/spec/cucumber/glue/registry_and_more_spec.rb +0 -213
  524. data/spec/cucumber/glue/snippet_spec.rb +0 -174
  525. data/spec/cucumber/glue/step_definition_spec.rb +0 -207
  526. data/spec/cucumber/hooks_spec.rb +0 -31
  527. data/spec/cucumber/multiline_argument/data_table_spec.rb +0 -648
  528. data/spec/cucumber/project_initializer_spec.rb +0 -88
  529. data/spec/cucumber/rake/forked_spec.rb +0 -54
  530. data/spec/cucumber/rake/task_spec.rb +0 -86
  531. data/spec/cucumber/running_test_case_spec.rb +0 -140
  532. data/spec/cucumber/runtime/for_programming_languages_spec.rb +0 -8
  533. data/spec/cucumber/runtime/support_code_spec.rb +0 -17
  534. data/spec/cucumber/runtime_spec.rb +0 -21
  535. data/spec/cucumber/sell_cucumbers.feature +0 -19
  536. data/spec/cucumber/step_argument_spec.rb +0 -19
  537. data/spec/cucumber/step_match_search_spec.rb +0 -113
  538. data/spec/cucumber/step_match_spec.rb +0 -86
  539. data/spec/cucumber/world/pending_spec.rb +0 -48
  540. data/spec/spec_helper.rb +0 -30
  541. data/spec/support/standard_step_actions.rb +0 -19
@@ -1,25 +1,26 @@
1
1
  # frozen_string_literal: true
2
- require 'cucumber/platform'
3
2
 
3
+ require 'cucumber/platform'
4
4
 
5
5
  module Cucumber
6
6
  module Formatter
7
- @backtrace_filters = %w(
7
+ @backtrace_filters = %w[
8
8
  /vendor/rails
9
9
  lib/cucumber
10
10
  bin/cucumber:
11
11
  lib/rspec
12
12
  gems/
13
+ site_ruby/
13
14
  minitest
14
15
  test/unit
15
16
  .gem/ruby
16
- lib/ruby/
17
17
  bin/bundle
18
- )
18
+ ]
19
19
 
20
- if ::Cucumber::JRUBY
21
- @backtrace_filters << 'org/jruby/'
22
- end
20
+ @backtrace_filters << RbConfig::CONFIG['rubyarchdir'] if RbConfig::CONFIG['rubyarchdir']
21
+ @backtrace_filters << RbConfig::CONFIG['rubylibdir'] if RbConfig::CONFIG['rubylibdir']
22
+
23
+ @backtrace_filters << 'org/jruby/' if ::Cucumber::JRUBY
23
24
 
24
25
  BACKTRACE_FILTER_PATTERNS = Regexp.new(@backtrace_filters.join('|'))
25
26
 
@@ -31,7 +32,7 @@ module Cucumber
31
32
  def exception
32
33
  return @exception if ::Cucumber.use_full_backtrace
33
34
 
34
- pwd_pattern = /#{::Regexp.escape(::Dir.pwd)}\//m
35
+ pwd_pattern = /#{::Regexp.escape(::Dir.pwd)}\//m # rubocop:disable Style/RegexpLiteral
35
36
  backtrace = @exception.backtrace.map { |line| line.gsub(pwd_pattern, './') }
36
37
 
37
38
  filtered = (backtrace || []).reject do |line|
@@ -41,7 +42,7 @@ module Cucumber
41
42
  if ::ENV['CUCUMBER_TRUNCATE_OUTPUT']
42
43
  # Strip off file locations
43
44
  filtered = filtered.map do |line|
44
- line =~ /(.*):in `/ ? $1 : line
45
+ line =~ /(.*):in `/ ? Regexp.last_match(1) : line
45
46
  end
46
47
  end
47
48
 
@@ -49,6 +50,5 @@ module Cucumber
49
50
  @exception
50
51
  end
51
52
  end
52
-
53
53
  end
54
54
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'cucumber/formatter/ansicolor'
3
4
  require 'cucumber/formatter/duration'
4
5
  require 'cucumber/gherkin/i18n'
5
6
 
6
7
  module Cucumber
7
8
  module Formatter
8
-
9
9
  # This module contains helper methods that are used by formatters that
10
10
  # print output to the terminal.
11
11
  #
@@ -46,7 +46,7 @@ module Cucumber
46
46
  def format_string(o, status)
47
47
  fmt = format_for(status)
48
48
  o.to_s.split("\n").map do |line|
49
- if Proc === fmt
49
+ if Proc == fmt.class
50
50
  fmt.call(line)
51
51
  else
52
52
  fmt % line
@@ -54,10 +54,6 @@ module Cucumber
54
54
  end.join("\n")
55
55
  end
56
56
 
57
- def print_steps(status)
58
- print_elements(runtime.steps(status), status, 'steps')
59
- end
60
-
61
57
  def print_elements(elements, status, kind)
62
58
  return if elements.empty?
63
59
 
@@ -109,33 +105,30 @@ module Cucumber
109
105
  end
110
106
 
111
107
  # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/10655
112
- def linebreaks(s, max)
113
- return s unless max && max > 0
114
- s.gsub(/.{1,#{max}}(?:\s|\Z)/){($& + 5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n")}.rstrip
108
+ def linebreaks(msg, max)
109
+ return msg unless max && max > 0
110
+ msg.gsub(/.{1,#{max}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") }.rstrip
115
111
  end
116
112
 
117
- def collect_snippet_data(test_step, result)
113
+ def collect_snippet_data(test_step, ast_lookup)
118
114
  # collect snippet data for undefined steps
119
- return if hook?(test_step)
120
- keyword = test_step.source.last.actual_keyword(@previous_step_keyword)
121
- @previous_step_keyword = keyword
122
- return unless result.undefined?
123
- @snippets_input << Console::SnippetData.new(keyword, test_step.source.last)
115
+ keyword = ast_lookup.snippet_step_keyword(test_step)
116
+ @snippets_input << Console::SnippetData.new(keyword, test_step)
124
117
  end
125
118
 
126
119
  def print_snippets(options)
127
120
  return unless options[:snippets]
128
- return if runtime.steps(:undefined).empty?
121
+ return if @snippets_input.empty?
129
122
 
130
- snippet_text_proc = lambda { |step_keyword, step_name, multiline_arg|
131
- runtime.snippet_text(step_keyword, step_name, multiline_arg)
132
- }
123
+ snippet_text_proc = lambda do |step_keyword, step_name, multiline_arg|
124
+ snippet_text(step_keyword, step_name, multiline_arg)
125
+ end
133
126
  do_print_snippets(snippet_text_proc)
134
127
  end
135
128
 
136
129
  def do_print_snippets(snippet_text_proc)
137
130
  snippets = @snippets_input.map do |data|
138
- snippet_text_proc.call(data.actual_keyword, data.step.name, data.step.multiline_arg)
131
+ snippet_text_proc.call(data.actual_keyword, data.step.text, data.step.multiline_arg)
139
132
  end.uniq
140
133
 
141
134
  text = "\nYou can implement step definitions for undefined steps with these snippets:\n\n"
@@ -146,10 +139,14 @@ module Cucumber
146
139
  @io.flush
147
140
  end
148
141
 
149
- def print_passing_wip(options)
150
- return unless options[:wip]
151
- passed_messages = element_messages(runtime.scenarios(:passed), :passed)
152
- do_print_passing_wip(passed_messages)
142
+ def print_passing_wip(config, passed_test_cases, ast_lookup)
143
+ return unless config.wip?
144
+ messages = passed_test_cases.map do |test_case|
145
+ scenario_source = ast_lookup.scenario_source(test_case)
146
+ keyword = scenario_source.type == :Scenario ? scenario_source.scenario.keyword : scenario_source.scenario_outline.keyword
147
+ linebreaks("#{test_case.location.on_line(test_case.location.lines.max)}:in `#{keyword}: #{test_case.name}'", ENV['CUCUMBER_TRUNCATE_OUTPUT'].to_i)
148
+ end
149
+ do_print_passing_wip(messages)
153
150
  end
154
151
 
155
152
  def do_print_passing_wip(passed_messages)
@@ -161,62 +158,32 @@ module Cucumber
161
158
  end
162
159
  end
163
160
 
164
- def embed(file, mime_type, label)
165
- # no-op
166
- end
167
-
168
- #define @delayed_messages = [] in your Formatter if you want to
169
- #activate this feature
170
- def puts(*messages)
171
- if @delayed_messages
172
- @delayed_messages += messages
173
- else
174
- if @io
175
- @io.puts
176
- messages.each do |message|
177
- @io.puts(format_string(message, :tag))
178
- end
179
- @io.flush
180
- end
181
- end
182
- end
183
-
184
- def print_messages
185
- @delayed_messages.each {|message| print_message(message)}
186
- empty_messages
187
- end
188
-
189
- def print_table_row_messages
190
- return if @delayed_messages.empty?
191
- @io.print(format_string(@delayed_messages.join(', '), :tag).indent(2))
192
- @io.flush
193
- empty_messages
194
- end
195
-
196
- def print_message(message)
197
- @io.puts(format_string(message, :tag).indent(@indent))
161
+ def attach(src, media_type)
162
+ return unless media_type == 'text/x.cucumber.log+plain'
163
+ return unless @io
164
+ @io.puts
165
+ @io.puts(format_string(src, :tag))
198
166
  @io.flush
199
167
  end
200
168
 
201
- def empty_messages
202
- @delayed_messages = []
203
- end
204
-
205
169
  def print_profile_information
206
170
  return if @options[:skip_profile_information] || @options[:profiles].nil? || @options[:profiles].empty?
207
171
  do_print_profile_information(@options[:profiles])
208
172
  end
209
173
 
210
174
  def do_print_profile_information(profiles)
211
- profiles_sentence = profiles.size == 1 ? profiles.first :
212
- "#{profiles[0...-1].join(', ')} and #{profiles.last}"
175
+ profiles_sentence = if profiles.size == 1
176
+ profiles.first
177
+ else
178
+ "#{profiles[0...-1].join(', ')} and #{profiles.last}"
179
+ end
213
180
 
214
- @io.puts "Using the #{profiles_sentence} profile#{'s' if profiles.size> 1}..."
181
+ @io.puts "Using the #{profiles_sentence} profile#{'s' if profiles.size > 1}..."
215
182
  end
216
183
 
217
184
  private
218
185
 
219
- FORMATS = Hash.new{ |hash, format| hash[format] = method(format).to_proc }
186
+ FORMATS = Hash.new { |hash, format| hash[format] = method(format).to_proc }
220
187
 
221
188
  def format_for(*keys)
222
189
  key = keys.join('_').to_sym
@@ -225,10 +192,6 @@ module Cucumber
225
192
  fmt
226
193
  end
227
194
 
228
- def hook?(test_step)
229
- not test_step.source.last.respond_to?(:actual_keyword)
230
- end
231
-
232
195
  def element_messages(elements, status)
233
196
  elements.map do |element|
234
197
  if status == :failed
@@ -241,18 +204,18 @@ module Cucumber
241
204
 
242
205
  def snippet_text(step_keyword, step_name, multiline_arg)
243
206
  keyword = Cucumber::Gherkin::I18n.code_keyword_for(step_keyword).strip
244
- config.snippet_generators.map { |generator|
207
+ config.snippet_generators.map do |generator|
245
208
  generator.call(keyword, step_name, multiline_arg, config.snippet_type)
246
- }.join("\n")
209
+ end.join("\n")
247
210
  end
248
211
 
249
212
  class SnippetData
250
213
  attr_reader :actual_keyword, :step
251
214
  def initialize(actual_keyword, step)
252
- @actual_keyword, @step = actual_keyword, step
215
+ @actual_keyword = actual_keyword
216
+ @step = step
253
217
  end
254
218
  end
255
-
256
219
  end
257
220
  end
258
221
  end
@@ -29,15 +29,10 @@ module Cucumber
29
29
  end
30
30
 
31
31
  def status_counts(summary)
32
- counts = Core::Test::Result::TYPES.map { |status|
33
- count = summary.total(status)
34
- [status, count]
35
- }.select { |status, count|
36
- count > 0
37
- }.map { |status, count|
38
- format_string("#{count} #{status}", status)
39
- }
40
- "(#{counts.join(", ")})" if counts.any?
32
+ counts = Core::Test::Result::TYPES.map { |status| [status, summary.total(status)] }
33
+ counts = counts.select { |_status, count| count > 0 }
34
+ counts = counts.map { |status, count| format_string("#{count} #{status}", status) }
35
+ "(#{counts.join(', ')})" if counts.any?
41
36
  end
42
37
  end
43
38
  end
@@ -5,19 +5,20 @@ module Cucumber
5
5
  class ConsoleIssues
6
6
  include Console
7
7
 
8
- def initialize(config)
8
+ def initialize(config, ast_lookup = AstLookup.new(config))
9
9
  @previous_test_case = nil
10
10
  @issues = Hash.new { |h, k| h[k] = [] }
11
11
  @config = config
12
12
  @config.on_event(:test_case_finished) do |event|
13
13
  if event.test_case != @previous_test_case
14
14
  @previous_test_case = event.test_case
15
- @issues[event.result.to_sym] << event.test_case unless event.result.ok?(@config.strict?)
15
+ @issues[event.result.to_sym] << event.test_case unless event.result.ok?(@config.strict)
16
16
  elsif event.result.passed?
17
- @issues[:flaky] << event.test_case unless Core::Test::Result::Flaky.ok?(@config.strict?)
17
+ @issues[:flaky] << event.test_case unless Core::Test::Result::Flaky.ok?(@config.strict.strict?(:flaky))
18
18
  @issues[:failed].delete(event.test_case)
19
19
  end
20
20
  end
21
+ @ast_lookup = ast_lookup
21
22
  end
22
23
 
23
24
  def to_s
@@ -34,10 +35,12 @@ module Cucumber
34
35
 
35
36
  def scenario_listing(type, test_cases)
36
37
  return [] if test_cases.empty?
37
- [ format_string("#{type_heading(type)} Scenarios:", type) ] + test_cases.map { |test_case|
38
- source = @config.source? ? format_string(" # #{test_case.keyword}: #{test_case.name}", :comment) : ''
39
- format_string("cucumber #{profiles_string}" + test_case.location, type) + source
40
- }
38
+ [format_string("#{type_heading(type)} Scenarios:", type)] + test_cases.map do |test_case|
39
+ scenario_source = @ast_lookup.scenario_source(test_case)
40
+ keyword = scenario_source.type == :Scenario ? scenario_source.scenario.keyword : scenario_source.scenario_outline.keyword
41
+ source = @config.source? ? format_string(" # #{keyword}: #{test_case.name}", :comment) : ''
42
+ format_string("cucumber #{profiles_string}#{test_case.location.file}:#{test_case.location.lines.max}", type) + source
43
+ end
41
44
  end
42
45
 
43
46
  def type_heading(type)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Cucumber
3
4
  module Formatter
4
5
  module Duration
@@ -7,7 +8,7 @@ module Cucumber
7
8
  # <tt>time</tt> format.
8
9
  def format_duration(seconds)
9
10
  m, s = seconds.divmod(60)
10
- "#{m}m#{format('%.3f', s)}s"
11
+ "#{m}m#{format('%<seconds>.3f', seconds: s)}s"
11
12
  end
12
13
  end
13
14
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Cucumber
3
4
  module Formatter
4
-
5
5
  class DurationExtractor
6
6
  attr_reader :result_duration
7
7
  def initialize(result)
@@ -22,8 +22,10 @@ module Cucumber
22
22
  def exception(*) end
23
23
 
24
24
  def duration(duration, *)
25
- duration.tap { |duration| @result_duration = duration.nanoseconds / 10**9.0 }
25
+ duration.tap { |dur| @result_duration = dur.nanoseconds / 10**9.0 }
26
26
  end
27
+
28
+ def attach(*) end
27
29
  end
28
30
  end
29
31
  end
@@ -0,0 +1,6 @@
1
+ module Cucumber
2
+ module Formatter
3
+ class TestCaseUnknownError < StandardError; end
4
+ class TestStepUnknownError < StandardError; end
5
+ end
6
+ end
@@ -1,20 +1,23 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'cucumber/formatter/io'
3
4
  require 'cucumber/formatter/console'
4
5
 
5
6
  module Cucumber
6
7
  module Formatter
7
-
8
8
  class FailFast
9
-
10
9
  def initialize(configuration)
10
+ @previous_test_case = nil
11
11
  configuration.on_event :test_case_finished do |event|
12
- _test_case, result = *event.attributes
13
- Cucumber.wants_to_quit = true unless result.ok?(configuration.strict?)
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
14
19
  end
15
20
  end
16
-
17
21
  end
18
-
19
22
  end
20
23
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Cucumber
3
4
  module Formatter
4
-
5
5
  # Forwards any messages sent to this object to all recipients
6
6
  # that respond to that message.
7
7
  class Fanout < BasicObject
@@ -13,6 +13,8 @@ module Cucumber
13
13
  end
14
14
 
15
15
  def method_missing(message, *args)
16
+ super unless recipients
17
+
16
18
  recipients.each do |recipient|
17
19
  recipient.send(message, *args) if recipient.respond_to?(message)
18
20
  end
@@ -21,8 +23,6 @@ module Cucumber
21
23
  def respond_to_missing?(name, include_private = false)
22
24
  recipients.any? { |recipient| recipient.respond_to?(name, include_private) }
23
25
  end
24
-
25
26
  end
26
-
27
27
  end
28
28
  end
@@ -1,615 +1,23 @@
1
- # frozen_string_literal: true
2
- require 'erb'
3
- require 'cucumber/formatter/duration'
4
1
  require 'cucumber/formatter/io'
5
- require 'cucumber/formatter/html_builder'
6
- require 'pathname'
2
+ require 'cucumber/html_formatter'
3
+ require 'cucumber/formatter/message_builder'
7
4
 
8
5
  module Cucumber
9
6
  module Formatter
10
- class Html
11
-
12
- # TODO: remove coupling to types
13
- AST_CLASSES = {
14
- Cucumber::Core::Ast::Scenario => 'scenario',
15
- Cucumber::Core::Ast::ScenarioOutline => 'scenario outline'
16
- }
17
-
18
- AST_DATA_TABLE = LegacyApi::Ast::MultilineArg::DataTable
19
-
20
- include ERB::Util # for the #h method
21
- include Duration
7
+ class HTML < MessageBuilder
22
8
  include Io
23
9
 
24
- attr_reader :builder
25
- private :builder
26
-
27
- def initialize(runtime, path_or_io, options)
28
- @io = ensure_io(path_or_io)
29
- @runtime = runtime
30
- @options = options
31
- @buffer = {}
32
- @builder = HtmlBuilder.new(target: @io, indent: 0)
33
- @feature_number = 0
34
- @scenario_number = 0
35
- @step_number = 0
36
- @header_red = nil
37
- @delayed_messages = []
38
- @inside_outline = false
39
- @previous_step_keyword = nil
40
- end
41
-
42
- def embed(src, mime_type, label)
43
- if image?(mime_type)
44
- src = src_is_file_or_data?(src) ? src : "data:#{standardize_mime_type(mime_type)},#{src}"
45
-
46
- builder.embed_image(src: set_path(src), label: label, id: next_id(:img))
47
- else
48
- builder.embed_text(src: src, label: label, id: next_id(:text))
49
- end
50
- end
51
-
52
- def set_path(src)
53
- if @io.respond_to?(:path) and File.file?(src)
54
- out_dir = Pathname.new(File.dirname(File.absolute_path(@io.path)))
55
- src = Pathname.new(File.absolute_path(src)).relative_path_from(out_dir)
56
- end
57
-
58
- src
59
- end
60
-
61
- def standardize_mime_type(mime_type)
62
- mime_type =~ /;base[0-9]+$/ ? mime_type : mime_type + ';base64'
63
- end
64
-
65
- def src_is_file_or_data?(src)
66
- File.file?(src) or src =~ /^data:image\/(png|gif|jpg|jpeg);base64,/
67
- end
68
-
69
- def image?(mime_type)
70
- mime_type =~ /^image\/(png|gif|jpg|jpeg)/
71
- end
72
-
73
- def before_features(features)
74
- @step_count = features && features.step_count || 0 #TODO: Make this work with core!
75
-
76
- builder.build_document!
77
- builder.format_features! features
78
- end
79
-
80
- def after_features(features)
81
- print_stats(features)
82
- builder << '</div>'
83
- builder << '</body>'
84
- builder << '</html>'
85
- end
86
-
87
- def before_feature(_feature)
88
- @exceptions = []
89
- builder << '<div class="feature">'
90
- end
91
-
92
- def after_feature(_feature)
93
- builder << '</div>'
94
- end
95
-
96
- def before_comment(_comment)
97
- builder << '<pre class="comment">'
98
- end
99
-
100
- def after_comment(_comment)
101
- builder << '</pre>'
102
- end
103
-
104
- def comment_line(comment_line)
105
- builder.text!(comment_line)
106
- builder.br
107
- end
108
-
109
- def after_tags(_tags)
110
- @tag_spacer = nil
111
- end
112
-
113
- def tag_name(tag_name)
114
- builder.text!(@tag_spacer) if @tag_spacer
115
- @tag_spacer = ' '
116
- builder.span(tag_name, :class => 'tag')
117
- end
118
-
119
- def feature_name(keyword, name)
120
- lines = name.split(/\r?\n/)
121
- return if lines.empty?
122
- builder.h2 do |h2|
123
- builder.span(keyword + ': ' + lines[0], :class => 'val')
124
- end
125
- builder.p(:class => 'narrative') do
126
- lines[1..-1].each do |line|
127
- builder.text!(line.strip)
128
- builder.br
129
- end
130
- end
131
- end
132
-
133
- def before_test_case(_test_case)
134
- @previous_step_keyword = nil
135
- end
136
-
137
- def before_background(_background)
138
- @in_background = true
139
- builder << '<div class="background">'
140
- end
141
-
142
- def after_background(_background)
143
- @in_background = nil
144
- builder << '</div>'
145
- end
146
-
147
- def background_name(keyword, name, _file_colon_line, _source_indent)
148
- @listing_background = true
149
- builder.h3(:id => "background_#{@scenario_number}") do |h3|
150
- builder.span(keyword, :class => 'keyword')
151
- builder.text!(' ')
152
- builder.span(name, :class => 'val')
153
- end
154
- end
155
-
156
- def before_feature_element(feature_element)
157
- @scenario_number+=1
158
- @scenario_red = false
159
- css_class = AST_CLASSES[feature_element.class]
160
- builder << "<div class='#{css_class}'>"
161
- @in_scenario_outline = feature_element.class == Cucumber::Core::Ast::ScenarioOutline
162
- end
163
-
164
- def after_feature_element(_feature_element)
165
- unless @in_scenario_outline
166
- print_messages
167
- builder << '</ol>'
168
- end
169
- builder << '</div>'
170
- @in_scenario_outline = nil
171
- end
172
-
173
- def scenario_name(keyword, name, file_colon_line, _source_indent)
174
- builder.span(:class => 'scenario_file') do
175
- builder << file_colon_line
176
- end
177
- @listing_background = false
178
- scenario_id = "scenario_#{@scenario_number}"
179
- if @inside_outline
180
- @outline_row += 1
181
- scenario_id += "_#{@outline_row}"
182
- @scenario_red = false
183
- end
184
- builder.h3(:id => scenario_id) do
185
- builder.span(keyword + ':', :class => 'keyword')
186
- builder.text!(' ')
187
- builder.span(name, :class => 'val')
188
- end
189
- end
190
-
191
- def before_outline_table(_outline_table)
192
- @inside_outline = true
193
- @outline_row = 0
194
- builder << '<table>'
195
- end
196
-
197
- def after_outline_table(_outline_table)
198
- builder << '</table>'
199
- @outline_row = nil
200
- @inside_outline = false
201
- end
202
-
203
- def before_examples(_examples)
204
- builder << '<div class="examples">'
205
- end
206
-
207
- def after_examples(_examples)
208
- builder << '</div>'
209
- end
210
-
211
- def examples_name(keyword, name)
212
- builder.h4 do
213
- builder.span(keyword, :class => 'keyword')
214
- builder.text!(' ')
215
- builder.span(name, :class => 'val')
216
- end
217
- end
10
+ def initialize(config)
11
+ @io = ensure_io(config.out_stream)
12
+ @html_formatter = Cucumber::HTMLFormatter::Formatter.new(@io)
13
+ @html_formatter.write_pre_message
218
14
 
219
- def before_steps(_steps)
220
- builder << '<ol>'
15
+ super(config)
221
16
  end
222
17
 
223
- def after_steps(_steps)
224
- print_messages
225
- builder << '</ol>' if @in_background or @in_scenario_outline
226
- end
227
-
228
- def before_step(step)
229
- print_messages
230
- @step_id = step.dom_id
231
- @step_number += 1
232
- @step = step
233
- end
234
-
235
- def after_step(_step)
236
- move_progress
237
- end
238
-
239
- def before_step_result(_keyword, step_match, _multiline_arg, status, exception, _source_indent, background, _file_colon_line)
240
- @step_match = step_match
241
- @hide_this_step = false
242
- if exception
243
- if @exceptions.include?(exception)
244
- @hide_this_step = true
245
- return
246
- end
247
- @exceptions << exception
248
- end
249
- if status != :failed && @in_background ^ background
250
- @hide_this_step = true
251
- return
252
- end
253
- @status = status
254
- return if @hide_this_step
255
- set_scenario_color(status)
256
- builder << "<li id='#{@step_id}' class='step #{status}'>"
257
- end
258
-
259
- def after_step_result(keyword, step_match, _multiline_arg, status, _exception, _source_indent, _background, _file_colon_line)
260
- return if @hide_this_step
261
- # print snippet for undefined steps
262
- unless outline_step?(@step)
263
- keyword = @step.actual_keyword(@previous_step_keyword)
264
- @previous_step_keyword = keyword
265
- end
266
- if status == :undefined
267
- builder.pre do |pre|
268
- # TODO: snippet text should be an event sent to the formatter so we don't
269
- # have this couping to the runtime.
270
- pre << @runtime.snippet_text(keyword,step_match.instance_variable_get('@name') || '', @step.multiline_arg)
271
- end
272
- end
273
- builder << '</li>'
274
- print_messages
275
- end
276
-
277
- def step_name(keyword, step_match, status, _source_indent, background, _file_colon_line)
278
- background_in_scenario = background && !@listing_background
279
- @skip_step = background_in_scenario
280
-
281
- unless @skip_step
282
- build_step(keyword, step_match, status)
283
- end
284
- end
285
-
286
- def exception(exception, _status)
287
- return if @hide_this_step
288
- print_messages
289
- build_exception_detail(exception)
290
- end
291
-
292
- def extra_failure_content(file_colon_line)
293
- @snippet_extractor ||= SnippetExtractor.new
294
- "<pre class=\"ruby\"><code>#{@snippet_extractor.snippet(file_colon_line)}</code></pre>"
295
- end
296
-
297
- def before_multiline_arg(multiline_arg)
298
- return if @hide_this_step || @skip_step
299
- if AST_DATA_TABLE === multiline_arg
300
- builder << '<table>'
301
- end
302
- end
303
-
304
- def after_multiline_arg(multiline_arg)
305
- return if @hide_this_step || @skip_step
306
- if AST_DATA_TABLE === multiline_arg
307
- builder << '</table>'
308
- end
309
- end
310
-
311
- def doc_string(string)
312
- return if @hide_this_step
313
- builder.pre(:class => 'val') do |pre|
314
- builder << h(string).gsub("\n", '&#x000A;')
315
- end
316
- end
317
-
318
- def before_table_row(table_row)
319
- @row_id = table_row.dom_id
320
- @col_index = 0
321
- return if @hide_this_step
322
- builder << "<tr class='step' id='#{@row_id}'>"
323
- end
324
-
325
- def after_table_row(table_row)
326
- return if @hide_this_step
327
- print_table_row_messages
328
- builder << '</tr>'
329
- if table_row.exception
330
- builder.tr do
331
- builder.td(:colspan => @col_index.to_s, :class => 'failed') do
332
- builder.pre do |pre|
333
- pre << h(format_exception(table_row.exception))
334
- end
335
- end
336
- end
337
- if table_row.exception.is_a? ::Cucumber::Pending
338
- set_scenario_color_pending
339
- else
340
- set_scenario_color_failed
341
- end
342
- end
343
- if @outline_row
344
- @outline_row += 1
345
- end
346
- @step_number += 1
347
- move_progress
348
- end
349
-
350
- def table_cell_value(value, status)
351
- return if @hide_this_step
352
-
353
- @cell_type = @outline_row == 0 ? :th : :td
354
- attributes = {:id => "#{@row_id}_#{@col_index}", :class => 'step'}
355
- attributes[:class] += " #{status}" if status
356
- build_cell(@cell_type, value, attributes)
357
- set_scenario_color(status) if @inside_outline
358
- @col_index += 1
359
- end
360
-
361
- def puts(message)
362
- @delayed_messages << message
363
- #builder.pre(message, :class => 'message')
364
- end
365
-
366
- def print_messages
367
- return if @delayed_messages.empty?
368
-
369
- #builder.ol do
370
- @delayed_messages.each do |ann|
371
- builder.li(:class => 'step message') do
372
- builder << ann
373
- end
374
- end
375
- #end
376
- empty_messages
377
- end
378
-
379
- def print_table_row_messages
380
- return if @delayed_messages.empty?
381
-
382
- builder.td(:class => 'message') do
383
- builder << @delayed_messages.join(', ')
384
- end
385
- empty_messages
386
- end
387
-
388
- def empty_messages
389
- @delayed_messages = []
390
- end
391
-
392
- def after_test_case(_test_case, result)
393
- if result.failed? and not @scenario_red
394
- set_scenario_color_failed
395
- end
396
- end
397
-
398
- protected
399
-
400
- def next_id(type)
401
- @indices ||= Hash.new { 0 }
402
- @indices[type] += 1
403
- "#{type}_#{@indices[:type]}"
404
- end
405
-
406
- def build_exception_detail(exception)
407
- backtrace = Array.new
408
-
409
- builder.div(:class => 'message') do
410
- message = exception.message
411
-
412
- if defined?(RAILS_ROOT) && message.include?('Exception caught')
413
- matches = message.match(/Showing <i>(.+)<\/i>(?:.+) #(\d+)/)
414
- backtrace += ["#{RAILS_ROOT}/#{matches[1]}:#{matches[2]}"] if matches
415
- matches = message.match(/<code>([^(\/)]+)<\//m)
416
- message = matches ? matches[1] : ''
417
- end
418
-
419
- unless exception.instance_of?(RuntimeError)
420
- message = "#{message} (#{exception.class})"
421
- end
422
-
423
- builder.pre do
424
- builder.text!(message)
425
- end
426
- end
427
-
428
- builder.div(:class => 'backtrace') do
429
- builder.pre do
430
- backtrace = exception.backtrace
431
- backtrace.delete_if { |x| x =~ /\/gems\/(cucumber|rspec)/ }
432
- builder << backtrace_line(backtrace.join("\n"))
433
- end
434
- end
435
-
436
- extra = extra_failure_content(backtrace)
437
- builder << extra unless extra == ''
438
- end
439
-
440
- def set_scenario_color(status)
441
- if status.nil? or status == :undefined or status == :pending
442
- set_scenario_color_pending
443
- end
444
- if status == :failed
445
- set_scenario_color_failed
446
- end
447
- end
448
-
449
- def set_scenario_color_failed
450
- builder.script do
451
- builder.text!("makeRed('cucumber-header');") unless @header_red
452
- @header_red = true
453
- scenario_or_background = @in_background ? 'background' : 'scenario'
454
- builder.text!("makeRed('#{scenario_or_background}_#{@scenario_number}');") unless @scenario_red
455
- @scenario_red = true
456
- if @options[:expand] and @inside_outline
457
- builder.text!("makeRed('#{scenario_or_background}_#{@scenario_number}_#{@outline_row}');")
458
- end
459
- end
460
- end
461
-
462
- def set_scenario_color_pending
463
- builder.script do
464
- builder.text!("makeYellow('cucumber-header');") unless @header_red
465
- scenario_or_background = @in_background ? 'background' : 'scenario'
466
- builder.text!("makeYellow('#{scenario_or_background}_#{@scenario_number}');") unless @scenario_red
467
- end
468
- end
469
-
470
- def build_step(keyword, step_match, _status)
471
- step_name = step_match.format_args(lambda{|param| %{<span class="param">#{param}</span>}})
472
- builder.div(:class => 'step_name') do |div|
473
- builder.span(keyword, :class => 'keyword')
474
- builder.span(:class => 'step val') do |name|
475
- name << h(step_name).gsub(/&lt;span class=&quot;(.*?)&quot;&gt;/, '<span class="\1">').gsub(/&lt;\/span&gt;/, '</span>')
476
- end
477
- end
478
-
479
- step_file = step_match.file_colon_line
480
- step_file.gsub(/^([^:]*\.rb):(\d*)/) do
481
- if ENV['TM_PROJECT_DIRECTORY']
482
- step_file = "<a href=\"txmt://open?url=file://#{File.expand_path($1)}&line=#{$2}\">#{$1}:#{$2}</a> "
483
- end
484
- end
485
-
486
- builder.div(:class => 'step_file') do |div|
487
- builder.span do
488
- builder << step_file
489
- end
490
- end
491
- end
492
-
493
- def build_cell(cell_type, value, attributes)
494
- builder.__send__(cell_type, attributes) do
495
- builder.div do
496
- builder.span(value,:class => 'step param')
497
- end
498
- end
499
- end
500
-
501
- def move_progress
502
- builder << " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>"
503
- end
504
-
505
- def percent_done
506
- result = 100.0
507
- if @step_count != 0
508
- result = ((@step_number).to_f / @step_count.to_f * 1000).to_i / 10.0
509
- end
510
- result
511
- end
512
-
513
- def format_exception(exception)
514
- ([exception.message.to_s] + exception.backtrace).join("\n")
515
- end
516
-
517
- def backtrace_line(line)
518
- if ENV['TM_PROJECT_DIRECTORY']
519
- line.gsub(/^([^:]*\.(?:rb|feature|haml)):(\d*).*$/) do
520
- "<a href=\"txmt://open?url=file://#{File.expand_path($1)}&line=#{$2}\">#{$1}:#{$2}</a> "
521
- end
522
- else
523
- line
524
- end
525
- end
526
-
527
- def print_stats(features)
528
- builder << "<script type=\"text/javascript\">document.getElementById('duration').innerHTML = \"Finished in <strong>#{format_duration(features.duration)} seconds</strong>\";</script>"
529
- builder << "<script type=\"text/javascript\">document.getElementById('totals').innerHTML = \"#{print_stat_string(features)}\";</script>"
530
- end
531
-
532
- def print_stat_string(_features)
533
- string = String.new
534
- string << dump_count(@runtime.scenarios.length, 'scenario')
535
- scenario_count = print_status_counts{|status| @runtime.scenarios(status)}
536
- string << scenario_count if scenario_count
537
- string << '<br />'
538
- string << dump_count(@runtime.steps.length, 'step')
539
- step_count = print_status_counts{|status| @runtime.steps(status)}
540
- string << step_count if step_count
541
- end
542
-
543
- def print_status_counts
544
- counts = [:failed, :skipped, :undefined, :pending, :passed].map do |status|
545
- elements = yield status
546
- elements.any? ? "#{elements.length} #{status}" : nil
547
- end.compact
548
- return " (#{counts.join(', ')})" if counts.any?
549
- end
550
-
551
- def dump_count(count, what, state=nil)
552
- [count, state, "#{what}#{count == 1 ? '' : 's'}"].compact.join(' ')
553
- end
554
-
555
- def outline_step?(_step)
556
- not @step.step.respond_to?(:actual_keyword)
557
- end
558
-
559
- class SnippetExtractor #:nodoc:
560
- class NullConverter; def convert(code, _pre); code; end; end #:nodoc:
561
-
562
- begin
563
- require 'syntax/convertors/html'
564
- @@converter = Syntax::Convertors::HTML.for_syntax 'ruby'
565
- rescue LoadError
566
- @@converter = NullConverter.new
567
- end
568
-
569
- def snippet(error)
570
- raw_code, line = snippet_for(error[0])
571
- highlighted = @@converter.convert(raw_code, false)
572
- highlighted << "\n<span class=\"comment\"># gem install syntax to get syntax highlighting</span>" if @@converter.is_a?(NullConverter)
573
- post_process(highlighted, line)
574
- end
575
-
576
- def snippet_for(error_line)
577
- if error_line =~ /(.*):(\d+)/
578
- file = $1
579
- line = $2.to_i
580
- [lines_around(file, line), line]
581
- else
582
- ["# Couldn't get snippet for #{error_line}", 1]
583
- end
584
- end
585
-
586
- def lines_around(file, line)
587
- if File.file?(file)
588
- begin
589
- lines = File.open(file).read.split("\n")
590
- rescue ArgumentError
591
- return "# Couldn't get snippet for #{file}"
592
- end
593
- min = [0, line-3].max
594
- max = [line+1, lines.length-1].min
595
- selected_lines = []
596
- selected_lines.join("\n")
597
- lines[min..max].join("\n")
598
- else
599
- "# Couldn't get snippet for #{file}"
600
- end
601
- end
602
-
603
- def post_process(highlighted, offending_line)
604
- new_lines = []
605
- highlighted.split("\n").each_with_index do |line, i|
606
- new_line = "<span class=\"linenum\">#{offending_line+i-2}</span>#{line}"
607
- new_line = "<span class=\"offending\">#{new_line}</span>" if i == 2
608
- new_lines << new_line
609
- end
610
- new_lines.join("\n")
611
- end
612
-
18
+ def output_envelope(envelope)
19
+ @html_formatter.write_message(envelope)
20
+ @html_formatter.write_post_message if envelope.test_run_finished
613
21
  end
614
22
  end
615
23
  end