mobiusloop 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (516) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.travis.yml +22 -0
  6. data/.yardopts +1 -0
  7. data/CONTRIBUTING.md +68 -0
  8. data/Gemfile +5 -0
  9. data/History.md +2280 -0
  10. data/LICENSE +22 -0
  11. data/README.md +373 -0
  12. data/Rakefile +22 -0
  13. data/bin/mobiusloop +8 -0
  14. data/cucumber.gemspec +47 -0
  15. data/cucumber.yml +20 -0
  16. data/examples/i18n/README.textile +3 -0
  17. data/examples/i18n/Rakefile +33 -0
  18. data/examples/i18n/ar/Rakefile +6 -0
  19. data/examples/i18n/ar/features/addition.feature +17 -0
  20. data/examples/i18n/ar/features/step_definitions/calculator_steps.rb +24 -0
  21. data/examples/i18n/ar/lib/calculator.rb +11 -0
  22. data/examples/i18n/bg/Rakefile +6 -0
  23. data/examples/i18n/bg/features/addition.feature +12 -0
  24. data/examples/i18n/bg/features/consecutive_calculations.feature +19 -0
  25. data/examples/i18n/bg/features/division.feature +17 -0
  26. data/examples/i18n/bg/features/step_definitions/calculator_steps.rb +24 -0
  27. data/examples/i18n/bg/features/support/env.rb +5 -0
  28. data/examples/i18n/bg/features/support/world.rb +8 -0
  29. data/examples/i18n/bg/lib/calculator.rb +24 -0
  30. data/examples/i18n/ca/Rakefile +6 -0
  31. data/examples/i18n/ca/features/step_definitions/calculator_steps.rb +21 -0
  32. data/examples/i18n/ca/features/suma.feature +17 -0
  33. data/examples/i18n/ca/lib/calculadora.rb +16 -0
  34. data/examples/i18n/cs/Rakefile +6 -0
  35. data/examples/i18n/cs/features/addition.feature +17 -0
  36. data/examples/i18n/cs/features/division.feature +11 -0
  37. data/examples/i18n/cs/features/step_definitions/calculator_steps.rb +24 -0
  38. data/examples/i18n/cs/lib/calculator.rb +14 -0
  39. data/examples/i18n/da/Rakefile +6 -0
  40. data/examples/i18n/da/features/sammenlaegning.feature +18 -0
  41. data/examples/i18n/da/features/step_definitions/lommeregner_steps.rb +24 -0
  42. data/examples/i18n/da/lib/lommeregner.rb +11 -0
  43. data/examples/i18n/de/Rakefile +6 -0
  44. data/examples/i18n/de/features/addition.feature +17 -0
  45. data/examples/i18n/de/features/division.feature +10 -0
  46. data/examples/i18n/de/features/step_definitions/calculator_steps.rb +24 -0
  47. data/examples/i18n/de/lib/calculator.rb +14 -0
  48. data/examples/i18n/el/Rakefile +6 -0
  49. data/examples/i18n/el/features/addition.feature +17 -0
  50. data/examples/i18n/el/features/division.feature +10 -0
  51. data/examples/i18n/el/features/step_definitions/calculator_steps.rb +24 -0
  52. data/examples/i18n/el/lib/calculator.rb +14 -0
  53. data/examples/i18n/en-lol/Rakefile +4 -0
  54. data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +16 -0
  55. data/examples/i18n/en-lol/features/stuffing.feature +8 -0
  56. data/examples/i18n/en-lol/features/support/env.rb +7 -0
  57. data/examples/i18n/en-lol/lib/basket.rb +12 -0
  58. data/examples/i18n/en-lol/lib/belly.rb +11 -0
  59. data/examples/i18n/en/Rakefile +6 -0
  60. data/examples/i18n/en/features/addition.feature +17 -0
  61. data/examples/i18n/en/features/division.feature +10 -0
  62. data/examples/i18n/en/features/step_definitions/calculator_steps.rb +24 -0
  63. data/examples/i18n/en/lib/calculator.rb +14 -0
  64. data/examples/i18n/eo/Rakefile +6 -0
  65. data/examples/i18n/eo/features/adicio.feature +17 -0
  66. data/examples/i18n/eo/features/divido.feature +10 -0
  67. data/examples/i18n/eo/features/step_definitions/calculator_steps.rb +24 -0
  68. data/examples/i18n/eo/lib/calculator.rb +14 -0
  69. data/examples/i18n/es/Rakefile +6 -0
  70. data/examples/i18n/es/features/adicion.feature +17 -0
  71. data/examples/i18n/es/features/step_definitions/calculador_steps.rb +21 -0
  72. data/examples/i18n/es/lib/calculador.rb +14 -0
  73. data/examples/i18n/et/Rakefile +6 -0
  74. data/examples/i18n/et/features/jagamine.feature +10 -0
  75. data/examples/i18n/et/features/liitmine.feature +17 -0
  76. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +24 -0
  77. data/examples/i18n/et/lib/kalkulaator.rb +14 -0
  78. data/examples/i18n/fi/Rakefile +6 -0
  79. data/examples/i18n/fi/features/jakolasku.feature +10 -0
  80. data/examples/i18n/fi/features/step_definitions/laskin_steps.rb +24 -0
  81. data/examples/i18n/fi/features/yhteenlasku.feature +17 -0
  82. data/examples/i18n/fi/lib/laskin.rb +14 -0
  83. data/examples/i18n/fr/Rakefile +8 -0
  84. data/examples/i18n/fr/features/addition.feature +18 -0
  85. data/examples/i18n/fr/features/addition2.feature +17 -0
  86. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +32 -0
  87. data/examples/i18n/fr/features/support/env.rb +5 -0
  88. data/examples/i18n/fr/lib/calculatrice.rb +10 -0
  89. data/examples/i18n/he/Rakefile +6 -0
  90. data/examples/i18n/he/features/addition.feature +17 -0
  91. data/examples/i18n/he/features/division.feature +10 -0
  92. data/examples/i18n/he/features/step_definitions/calculator_steps.rb +24 -0
  93. data/examples/i18n/he/lib/calculator.rb +15 -0
  94. data/examples/i18n/hi/Rakefile +6 -0
  95. data/examples/i18n/hi/features/addition.feature +16 -0
  96. data/examples/i18n/hi/features/division.feature +10 -0
  97. data/examples/i18n/hi/features/step_definitions/calculator_steps.rb +24 -0
  98. data/examples/i18n/hi/lib/calculator.rb +15 -0
  99. data/examples/i18n/ht/Rakefile +6 -0
  100. data/examples/i18n/ht/features/adisyon.feature +17 -0
  101. data/examples/i18n/ht/features/divizyon.feature +10 -0
  102. data/examples/i18n/ht/features/step_definitions/kalkilatris_steps.rb +25 -0
  103. data/examples/i18n/ht/lib/kalkilatris.rb +14 -0
  104. data/examples/i18n/hu/Rakefile +6 -0
  105. data/examples/i18n/hu/features/osszeadas.feature +17 -0
  106. data/examples/i18n/hu/features/osztas.feature +10 -0
  107. data/examples/i18n/hu/features/step_definitions/calculator_steps.rb +25 -0
  108. data/examples/i18n/hu/lib/calculator.rb +14 -0
  109. data/examples/i18n/id/Rakefile +6 -0
  110. data/examples/i18n/id/features/addition.feature +17 -0
  111. data/examples/i18n/id/features/division.feature +10 -0
  112. data/examples/i18n/id/features/step_definitions/calculator_steps.rb +24 -0
  113. data/examples/i18n/id/lib/calculator.rb +14 -0
  114. data/examples/i18n/it/Rakefile +6 -0
  115. data/examples/i18n/it/features/somma.feature +11 -0
  116. data/examples/i18n/it/features/step_definitions/calcolatrice_steps.rb +24 -0
  117. data/examples/i18n/it/lib/calcolatrice.rb +11 -0
  118. data/examples/i18n/ja/Rakefile +6 -0
  119. data/examples/i18n/ja/features/addition.feature +17 -0
  120. data/examples/i18n/ja/features/division.feature +10 -0
  121. data/examples/i18n/ja/features/step_definitions/calculator_steps.rb +19 -0
  122. data/examples/i18n/ja/features/support/env.rb +5 -0
  123. data/examples/i18n/ja/lib/calculator.rb +14 -0
  124. data/examples/i18n/ko/Rakefile +6 -0
  125. data/examples/i18n/ko/features/addition.feature +17 -0
  126. data/examples/i18n/ko/features/division.feature +11 -0
  127. data/examples/i18n/ko/features/step_definitions/calculator_steps.rb +24 -0
  128. data/examples/i18n/ko/lib/calculator.rb +14 -0
  129. data/examples/i18n/lt/Rakefile +6 -0
  130. data/examples/i18n/lt/features/addition.feature +17 -0
  131. data/examples/i18n/lt/features/division.feature +10 -0
  132. data/examples/i18n/lt/features/step_definitions/calculator_steps.rb +24 -0
  133. data/examples/i18n/lt/lib/calculator.rb +14 -0
  134. data/examples/i18n/lv/Rakefile +6 -0
  135. data/examples/i18n/lv/features/addition.feature +17 -0
  136. data/examples/i18n/lv/features/division.feature +10 -0
  137. data/examples/i18n/lv/features/step_definitions/calculator_steps.rb +24 -0
  138. data/examples/i18n/lv/lib/calculator.rb +14 -0
  139. data/examples/i18n/no/Rakefile +6 -0
  140. data/examples/i18n/no/features/step_definitions/kalkulator_steps.rb +17 -0
  141. data/examples/i18n/no/features/summering.feature +19 -0
  142. data/examples/i18n/no/features/support/env.rb +6 -0
  143. data/examples/i18n/no/lib/kalkulator.rb +11 -0
  144. data/examples/i18n/pl/Rakefile +6 -0
  145. data/examples/i18n/pl/features/addition.feature +17 -0
  146. data/examples/i18n/pl/features/division.feature +10 -0
  147. data/examples/i18n/pl/features/step_definitions/calculator_steps.rb +24 -0
  148. data/examples/i18n/pl/features/support/env.rb +5 -0
  149. data/examples/i18n/pl/lib/calculator.rb +14 -0
  150. data/examples/i18n/pt/Rakefile +6 -0
  151. data/examples/i18n/pt/features/adicao.feature +11 -0
  152. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +20 -0
  153. data/examples/i18n/pt/features/support/env.rb +5 -0
  154. data/examples/i18n/pt/lib/calculadora.rb +10 -0
  155. data/examples/i18n/ro/Rakefile +6 -0
  156. data/examples/i18n/ro/features/adunare.feature +12 -0
  157. data/examples/i18n/ro/features/step_definitions/calculator_steps.rb +21 -0
  158. data/examples/i18n/ro/lib/calculator.rb +11 -0
  159. data/examples/i18n/ru/Rakefile +6 -0
  160. data/examples/i18n/ru/features/addition.feature +11 -0
  161. data/examples/i18n/ru/features/consecutive_calculations.feature +17 -0
  162. data/examples/i18n/ru/features/division.feature +16 -0
  163. data/examples/i18n/ru/features/step_definitions/calculator_steps.rb +19 -0
  164. data/examples/i18n/ru/features/support/env.rb +5 -0
  165. data/examples/i18n/ru/features/support/world.rb +8 -0
  166. data/examples/i18n/ru/lib/calculator.rb +24 -0
  167. data/examples/i18n/sk/Rakefile +6 -0
  168. data/examples/i18n/sk/features/addition.feature +17 -0
  169. data/examples/i18n/sk/features/division.feature +10 -0
  170. data/examples/i18n/sk/features/step_definitions/calculator_steps.rb +24 -0
  171. data/examples/i18n/sk/lib/calculator.rb +14 -0
  172. data/examples/i18n/sr-Cyrl/Rakefile +6 -0
  173. data/examples/i18n/sr-Cyrl/features/sabiranje.feature +18 -0
  174. data/examples/i18n/sr-Cyrl/features/step_definitions/calculator_steps.rb +20 -0
  175. data/examples/i18n/sr-Cyrl/features/support/env.rb +5 -0
  176. data/examples/i18n/sr-Cyrl/lib/calculator.rb +12 -0
  177. data/examples/i18n/sr-Latn/Rakefile +6 -0
  178. data/examples/i18n/sr-Latn/features/sabiranje.feature +18 -0
  179. data/examples/i18n/sr-Latn/features/step_definitions/calculator_steps.rb +24 -0
  180. data/examples/i18n/sr-Latn/lib/calculator.rb +12 -0
  181. data/examples/i18n/sv/Rakefile +6 -0
  182. data/examples/i18n/sv/features/step_definitions/kalkulator_steps.rb +24 -0
  183. data/examples/i18n/sv/features/summering.feature +18 -0
  184. data/examples/i18n/sv/lib/kalkulator.rb +11 -0
  185. data/examples/i18n/tr/Rakefile +6 -0
  186. data/examples/i18n/tr/features/bolme.feature +10 -0
  187. data/examples/i18n/tr/features/step_definitions/hesap_makinesi_adimlari.rb +24 -0
  188. data/examples/i18n/tr/features/toplama.feature +18 -0
  189. data/examples/i18n/tr/lib/hesap_makinesi.rb +15 -0
  190. data/examples/i18n/uk/Rakefile +6 -0
  191. data/examples/i18n/uk/features/addition.feature +11 -0
  192. data/examples/i18n/uk/features/consecutive_calculations.feature +17 -0
  193. data/examples/i18n/uk/features/division.feature +16 -0
  194. data/examples/i18n/uk/features/step_definitions/calculator_steps.rb +19 -0
  195. data/examples/i18n/uk/features/support/env.rb +5 -0
  196. data/examples/i18n/uk/features/support/world.rb +8 -0
  197. data/examples/i18n/uk/lib/calculator.rb +24 -0
  198. data/examples/i18n/uz/Rakefile +6 -0
  199. data/examples/i18n/uz/features/addition.feature +10 -0
  200. data/examples/i18n/uz/features/consecutive_calculations.feature +17 -0
  201. data/examples/i18n/uz/features/division.feature +17 -0
  202. data/examples/i18n/uz/features/step_definitions/calculator_steps.rb +19 -0
  203. data/examples/i18n/uz/features/support/env.rb +5 -0
  204. data/examples/i18n/uz/features/support/world.rb +8 -0
  205. data/examples/i18n/uz/lib/calculator.rb +24 -0
  206. data/examples/i18n/zh-CN/Rakefile +4 -0
  207. data/examples/i18n/zh-CN/features/addition.feature +18 -0
  208. data/examples/i18n/zh-CN/features/step_definitions/calculator_steps.rb +26 -0
  209. data/examples/i18n/zh-CN/lib/calculator.rb +10 -0
  210. data/examples/i18n/zh-TW/Rakefile +4 -0
  211. data/examples/i18n/zh-TW/features/addition.feature +17 -0
  212. data/examples/i18n/zh-TW/features/division.feature +11 -0
  213. data/examples/i18n/zh-TW/features/step_definitions/calculator_steps.rb +24 -0
  214. data/examples/i18n/zh-TW/lib/calculator.rb +14 -0
  215. data/examples/mobiusloop/increase_readers.goal +13 -0
  216. data/examples/mobiusloop/scale_page_response.rb +20 -0
  217. data/examples/mobiusloop/total_articles_scale.rb +10 -0
  218. data/examples/mobiusloop/total_readers_scale.rb +10 -0
  219. data/examples/rspec_doubles/Rakefile +4 -0
  220. data/examples/rspec_doubles/features/mocking.feature +9 -0
  221. data/examples/rspec_doubles/features/step_definitions/calvin_steps.rb +19 -0
  222. data/examples/rspec_doubles/features/support/env.rb +12 -0
  223. data/examples/sinatra/README.textile +13 -0
  224. data/examples/sinatra/Rakefile +6 -0
  225. data/examples/sinatra/app.rb +14 -0
  226. data/examples/sinatra/features/add.feature +11 -0
  227. data/examples/sinatra/features/step_definitions/add_steps.rb +15 -0
  228. data/examples/sinatra/features/support/env.rb +10 -0
  229. data/examples/sinatra/views/add.erb +7 -0
  230. data/examples/sinatra/views/layout.erb +8 -0
  231. data/examples/tcl/README.textile +11 -0
  232. data/examples/tcl/Rakefile +6 -0
  233. data/examples/tcl/features/fibonnacci.feature +17 -0
  234. data/examples/tcl/features/step_definitions/fib_steps.rb +7 -0
  235. data/examples/tcl/features/support/env.rb +6 -0
  236. data/examples/tcl/src/fib.tcl +3 -0
  237. data/examples/test_unit/Gemfile +4 -0
  238. data/examples/test_unit/Rakefile +6 -0
  239. data/examples/test_unit/features/step_definitions/test_unit_steps.rb +20 -0
  240. data/examples/test_unit/features/test_unit.feature +9 -0
  241. data/examples/watir/README.textile +16 -0
  242. data/examples/watir/Rakefile +12 -0
  243. data/examples/watir/cucumber.yml +1 -0
  244. data/examples/watir/features/search.feature +12 -0
  245. data/examples/watir/features/step_definitions/search_steps.rb +26 -0
  246. data/examples/watir/features/support/env.rb +35 -0
  247. data/examples/watir/features/support/screenshots.rb +47 -0
  248. data/features/docs/api/list_step_defs_as_json.feature +50 -0
  249. data/features/docs/api/listen_for_events.feature +58 -0
  250. data/features/docs/api/run_cli_main_with_existing_runtime.feature +26 -0
  251. data/features/docs/cli/backtraces.feature +36 -0
  252. data/features/docs/cli/dry_run.feature +70 -0
  253. data/features/docs/cli/exclude_files.feature +18 -0
  254. data/features/docs/cli/execute_with_tag_filter.feature +117 -0
  255. data/features/docs/cli/fail_fast.feature +46 -0
  256. data/features/docs/cli/finding_steps.feature +28 -0
  257. data/features/docs/cli/randomize.feature +140 -0
  258. data/features/docs/cli/require.feature +27 -0
  259. data/features/docs/cli/retry_failing_tests.feature +32 -0
  260. data/features/docs/cli/run_scenarios_matching_name.feature +104 -0
  261. data/features/docs/cli/run_specific_scenarios.feature +77 -0
  262. data/features/docs/cli/showing_differences.feature +43 -0
  263. data/features/docs/cli/specifying_multiple_formatters.feature +65 -0
  264. data/features/docs/cli/strict_mode.feature +64 -0
  265. data/features/docs/defining_steps/nested_steps.feature +177 -0
  266. data/features/docs/defining_steps/nested_steps_i18n.feature +34 -0
  267. data/features/docs/defining_steps/nested_steps_with_second_arg.feature +54 -0
  268. data/features/docs/defining_steps/one_line_step_definitions.feature +65 -0
  269. data/features/docs/defining_steps/printing_messages.feature +148 -0
  270. data/features/docs/defining_steps/skip_scenario.feature +64 -0
  271. data/features/docs/defining_steps/snippets.feature +56 -0
  272. data/features/docs/defining_steps/table_diffing.feature +50 -0
  273. data/features/docs/exception_in_after_hook.feature +126 -0
  274. data/features/docs/exception_in_after_step_hook.feature +102 -0
  275. data/features/docs/exception_in_around_hook.feature +78 -0
  276. data/features/docs/exception_in_before_hook.feature +96 -0
  277. data/features/docs/extending_cucumber/custom_filter.feature +29 -0
  278. data/features/docs/extending_cucumber/custom_formatter.feature +130 -0
  279. data/features/docs/formatters/api_methods.feature +37 -0
  280. data/features/docs/formatters/debug_formatter.feature +47 -0
  281. data/features/docs/formatters/formatter_step_file_colon_line.feature +44 -0
  282. data/features/docs/formatters/html_formatter.feature +91 -0
  283. data/features/docs/formatters/json_formatter.feature +767 -0
  284. data/features/docs/formatters/junit_formatter.feature +454 -0
  285. data/features/docs/formatters/pretty_formatter.feature +73 -0
  286. data/features/docs/formatters/progress_formatter.feature +31 -0
  287. data/features/docs/formatters/rerun_formatter.feature +188 -0
  288. data/features/docs/formatters/usage_formatter.feature +98 -0
  289. data/features/docs/getting_started.feature +27 -0
  290. data/features/docs/gherkin/background.feature +548 -0
  291. data/features/docs/gherkin/doc_strings.feature +74 -0
  292. data/features/docs/gherkin/expand_option_for_outlines.feature +46 -0
  293. data/features/docs/gherkin/language_from_header.feature +32 -0
  294. data/features/docs/gherkin/language_help.feature +42 -0
  295. data/features/docs/gherkin/outlines.feature +156 -0
  296. data/features/docs/gherkin/unicode_table.feature +32 -0
  297. data/features/docs/gherkin/using_descriptions.feature +82 -0
  298. data/features/docs/gherkin/using_star_notation.feature +37 -0
  299. data/features/docs/iso-8859-1.feature +6 -0
  300. data/features/docs/post_configuration_hook.feature +49 -0
  301. data/features/docs/profiles.feature +120 -0
  302. data/features/docs/rake_task.feature +141 -0
  303. data/features/docs/raketask.feature +44 -0
  304. data/features/docs/work_in_progress.feature +154 -0
  305. data/features/docs/writing_support_code/after_hooks.feature +102 -0
  306. data/features/docs/writing_support_code/after_step_hooks.feature +53 -0
  307. data/features/docs/writing_support_code/around_hooks.feature +260 -0
  308. data/features/docs/writing_support_code/before_hook.feature +65 -0
  309. data/features/docs/writing_support_code/hook_order.feature +61 -0
  310. data/features/docs/writing_support_code/load_path.feature +17 -0
  311. data/features/docs/writing_support_code/state.feature +32 -0
  312. data/features/docs/writing_support_code/tagged_hooks.feature +95 -0
  313. data/features/docs/writing_support_code/transforms.feature +98 -0
  314. data/features/lib/step_definitions/aruba_steps.rb +26 -0
  315. data/features/lib/step_definitions/cucumber_steps.rb +78 -0
  316. data/features/lib/step_definitions/iso-8859-1_steps.rb +12 -0
  317. data/features/lib/step_definitions/json_steps.rb +7 -0
  318. data/features/lib/step_definitions/junit_steps.rb +13 -0
  319. data/features/lib/step_definitions/language_steps.rb +8 -0
  320. data/features/lib/step_definitions/profile_steps.rb +15 -0
  321. data/features/lib/step_definitions/retry_steps.rb +35 -0
  322. data/features/lib/step_definitions/ruby_steps.rb +3 -0
  323. data/features/lib/step_definitions/wire_steps.rb +58 -0
  324. data/features/lib/support/env.rb +21 -0
  325. data/features/lib/support/fake_wire_server.rb +80 -0
  326. data/features/lib/support/feature_factory.rb +67 -0
  327. data/features/lib/support/normalise_output.rb +50 -0
  328. data/gem_tasks/contributors.rake +15 -0
  329. data/gem_tasks/cov.rake +5 -0
  330. data/gem_tasks/cucumber.rake +25 -0
  331. data/gem_tasks/downloads.rb +7 -0
  332. data/gem_tasks/environment.rake +7 -0
  333. data/gem_tasks/examples.rake +11 -0
  334. data/gem_tasks/fix_cr_lf.rake +10 -0
  335. data/gem_tasks/flog.rake +4 -0
  336. data/gem_tasks/rspec.rake +6 -0
  337. data/gem_tasks/sass.rake +4 -0
  338. data/gem_tasks/stats +16 -0
  339. data/gem_tasks/versions.txt +74 -0
  340. data/gherkin-languages.json +2972 -0
  341. data/lib/autotest/cucumber.rb +6 -0
  342. data/lib/autotest/cucumber_mixin.rb +135 -0
  343. data/lib/autotest/cucumber_rails.rb +6 -0
  344. data/lib/autotest/cucumber_rails_rspec.rb +6 -0
  345. data/lib/autotest/cucumber_rails_rspec2.rb +6 -0
  346. data/lib/autotest/cucumber_rspec.rb +6 -0
  347. data/lib/autotest/cucumber_rspec2.rb +6 -0
  348. data/lib/autotest/discover.rb +11 -0
  349. data/lib/cucumber.rb +37 -0
  350. data/lib/cucumber/ast.rb +13 -0
  351. data/lib/cucumber/cli/configuration.rb +146 -0
  352. data/lib/cucumber/cli/main.rb +99 -0
  353. data/lib/cucumber/cli/options.rb +465 -0
  354. data/lib/cucumber/cli/profile_loader.rb +91 -0
  355. data/lib/cucumber/cli/rerun_file.rb +29 -0
  356. data/lib/cucumber/configuration.rb +268 -0
  357. data/lib/cucumber/constantize.rb +45 -0
  358. data/lib/cucumber/core_ext/instance_exec.rb +70 -0
  359. data/lib/cucumber/core_ext/string.rb +9 -0
  360. data/lib/cucumber/deprecate.rb +29 -0
  361. data/lib/cucumber/encoding.rb +5 -0
  362. data/lib/cucumber/errors.rb +51 -0
  363. data/lib/cucumber/events.rb +20 -0
  364. data/lib/cucumber/events/after_test_case.rb +25 -0
  365. data/lib/cucumber/events/after_test_step.rb +30 -0
  366. data/lib/cucumber/events/before_test_case.rb +18 -0
  367. data/lib/cucumber/events/before_test_step.rb +23 -0
  368. data/lib/cucumber/events/bus.rb +86 -0
  369. data/lib/cucumber/events/finished_testing.rb +9 -0
  370. data/lib/cucumber/events/step_match.rb +23 -0
  371. data/lib/cucumber/file_specs.rb +37 -0
  372. data/lib/cucumber/filters.rb +9 -0
  373. data/lib/cucumber/filters/activate_steps.rb +67 -0
  374. data/lib/cucumber/filters/apply_after_hooks.rb +9 -0
  375. data/lib/cucumber/filters/apply_after_step_hooks.rb +12 -0
  376. data/lib/cucumber/filters/apply_around_hooks.rb +12 -0
  377. data/lib/cucumber/filters/apply_before_hooks.rb +9 -0
  378. data/lib/cucumber/filters/gated_receiver.rb +25 -0
  379. data/lib/cucumber/filters/prepare_world.rb +45 -0
  380. data/lib/cucumber/filters/quit.rb +28 -0
  381. data/lib/cucumber/filters/randomizer.rb +45 -0
  382. data/lib/cucumber/filters/retry.rb +32 -0
  383. data/lib/cucumber/filters/tag_limits.rb +45 -0
  384. data/lib/cucumber/filters/tag_limits/test_case_index.rb +31 -0
  385. data/lib/cucumber/filters/tag_limits/verifier.rb +59 -0
  386. data/lib/cucumber/formatter/ansicolor.rb +160 -0
  387. data/lib/cucumber/formatter/backtrace_filter.rb +41 -0
  388. data/lib/cucumber/formatter/console.rb +252 -0
  389. data/lib/cucumber/formatter/cucumber.css +286 -0
  390. data/lib/cucumber/formatter/cucumber.sass +247 -0
  391. data/lib/cucumber/formatter/debug.rb +35 -0
  392. data/lib/cucumber/formatter/duration.rb +13 -0
  393. data/lib/cucumber/formatter/duration_extractor.rb +28 -0
  394. data/lib/cucumber/formatter/event_bus_report.rb +38 -0
  395. data/lib/cucumber/formatter/fail_fast.rb +18 -0
  396. data/lib/cucumber/formatter/fanout.rb +27 -0
  397. data/lib/cucumber/formatter/hook_query_visitor.rb +40 -0
  398. data/lib/cucumber/formatter/html.rb +689 -0
  399. data/lib/cucumber/formatter/ignore_missing_messages.rb +20 -0
  400. data/lib/cucumber/formatter/interceptor.rb +80 -0
  401. data/lib/cucumber/formatter/io.rb +34 -0
  402. data/lib/cucumber/formatter/jquery-min.js +154 -0
  403. data/lib/cucumber/formatter/json.rb +334 -0
  404. data/lib/cucumber/formatter/json_pretty.rb +10 -0
  405. data/lib/cucumber/formatter/junit.rb +238 -0
  406. data/lib/cucumber/formatter/legacy_api/adapter.rb +1016 -0
  407. data/lib/cucumber/formatter/legacy_api/ast.rb +389 -0
  408. data/lib/cucumber/formatter/legacy_api/results.rb +51 -0
  409. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +31 -0
  410. data/lib/cucumber/formatter/pretty.rb +247 -0
  411. data/lib/cucumber/formatter/progress.rb +73 -0
  412. data/lib/cucumber/formatter/rerun.rb +35 -0
  413. data/lib/cucumber/formatter/stepdefs.rb +14 -0
  414. data/lib/cucumber/formatter/steps.rb +49 -0
  415. data/lib/cucumber/formatter/summary.rb +35 -0
  416. data/lib/cucumber/formatter/unicode.rb +53 -0
  417. data/lib/cucumber/formatter/usage.rb +136 -0
  418. data/lib/cucumber/gherkin/data_table_parser.rb +31 -0
  419. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +99 -0
  420. data/lib/cucumber/gherkin/formatter/escaping.rb +17 -0
  421. data/lib/cucumber/gherkin/i18n.rb +15 -0
  422. data/lib/cucumber/gherkin/steps_parser.rb +31 -0
  423. data/lib/cucumber/hooks.rb +99 -0
  424. data/lib/cucumber/load_path.rb +13 -0
  425. data/lib/cucumber/multiline_argument.rb +71 -0
  426. data/lib/cucumber/multiline_argument/data_table.rb +744 -0
  427. data/lib/cucumber/multiline_argument/doc_string.rb +9 -0
  428. data/lib/cucumber/platform.rb +27 -0
  429. data/lib/cucumber/project_initializer.rb +82 -0
  430. data/lib/cucumber/rake/task.rb +168 -0
  431. data/lib/cucumber/rb_support/rb_dsl.rb +119 -0
  432. data/lib/cucumber/rb_support/rb_hook.rb +19 -0
  433. data/lib/cucumber/rb_support/rb_language.rb +216 -0
  434. data/lib/cucumber/rb_support/rb_step_definition.rb +131 -0
  435. data/lib/cucumber/rb_support/rb_transform.rb +59 -0
  436. data/lib/cucumber/rb_support/rb_world.rb +149 -0
  437. data/lib/cucumber/rb_support/snippet.rb +170 -0
  438. data/lib/cucumber/rspec/disable_option_parser.rb +23 -0
  439. data/lib/cucumber/rspec/doubles.rb +19 -0
  440. data/lib/cucumber/running_test_case.rb +134 -0
  441. data/lib/cucumber/runtime.rb +266 -0
  442. data/lib/cucumber/runtime/after_hooks.rb +25 -0
  443. data/lib/cucumber/runtime/before_hooks.rb +27 -0
  444. data/lib/cucumber/runtime/for_programming_languages.rb +66 -0
  445. data/lib/cucumber/runtime/step_hooks.rb +23 -0
  446. data/lib/cucumber/runtime/support_code.rb +151 -0
  447. data/lib/cucumber/runtime/user_interface.rb +85 -0
  448. data/lib/cucumber/step_argument.rb +25 -0
  449. data/lib/cucumber/step_definition_light.rb +20 -0
  450. data/lib/cucumber/step_definitions.rb +13 -0
  451. data/lib/cucumber/step_match.rb +141 -0
  452. data/lib/cucumber/step_match_search.rb +67 -0
  453. data/lib/cucumber/term/ansicolor.rb +110 -0
  454. data/lib/cucumber/unit.rb +11 -0
  455. data/lib/cucumber/version +1 -0
  456. data/lib/mobiusloop/measure.rb +19 -0
  457. data/lib/mobiusloop/mobius_steps.rb +36 -0
  458. data/lib/mobiusloop/objective.rb +10 -0
  459. data/lib/mobiusloop/outcome.rb +99 -0
  460. data/lib/mobiusloop/scale.rb +32 -0
  461. data/lib/simplecov_setup.rb +18 -0
  462. data/major_changes_to_cucumber.md +45 -0
  463. data/mobiusloop.gemspec +47 -0
  464. data/spec/cucumber/cli/configuration_spec.rb +435 -0
  465. data/spec/cucumber/cli/main_spec.rb +83 -0
  466. data/spec/cucumber/cli/options_spec.rb +410 -0
  467. data/spec/cucumber/cli/profile_loader_spec.rb +46 -0
  468. data/spec/cucumber/cli/rerun_spec.rb +85 -0
  469. data/spec/cucumber/configuration_spec.rb +147 -0
  470. data/spec/cucumber/constantize_spec.rb +19 -0
  471. data/spec/cucumber/core_ext/instance_exec_spec.rb +4 -0
  472. data/spec/cucumber/events/bus_spec.rb +94 -0
  473. data/spec/cucumber/file_specs_spec.rb +60 -0
  474. data/spec/cucumber/filters/activate_steps_spec.rb +149 -0
  475. data/spec/cucumber/filters/gated_receiver_spec.rb +47 -0
  476. data/spec/cucumber/filters/retry_spec.rb +79 -0
  477. data/spec/cucumber/filters/tag_limits/test_case_index_spec.rb +38 -0
  478. data/spec/cucumber/filters/tag_limits/verifier_spec.rb +57 -0
  479. data/spec/cucumber/filters/tag_limits_spec.rb +59 -0
  480. data/spec/cucumber/formatter/ansicolor_spec.rb +32 -0
  481. data/spec/cucumber/formatter/debug_spec.rb +64 -0
  482. data/spec/cucumber/formatter/duration_spec.rb +22 -0
  483. data/spec/cucumber/formatter/event_bus_report_spec.rb +88 -0
  484. data/spec/cucumber/formatter/fail_fast_spec.rb +88 -0
  485. data/spec/cucumber/formatter/html_spec.rb +538 -0
  486. data/spec/cucumber/formatter/interceptor_spec.rb +136 -0
  487. data/spec/cucumber/formatter/json_spec.rb +841 -0
  488. data/spec/cucumber/formatter/junit_spec.rb +252 -0
  489. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +2182 -0
  490. data/spec/cucumber/formatter/pretty_spec.rb +919 -0
  491. data/spec/cucumber/formatter/progress_spec.rb +169 -0
  492. data/spec/cucumber/formatter/rerun_spec.rb +91 -0
  493. data/spec/cucumber/formatter/spec_helper.rb +82 -0
  494. data/spec/cucumber/hooks_spec.rb +30 -0
  495. data/spec/cucumber/multiline_argument/data_table_spec.rb +603 -0
  496. data/spec/cucumber/project_initializer_spec.rb +87 -0
  497. data/spec/cucumber/rake/forked_spec.rb +53 -0
  498. data/spec/cucumber/rake/task_spec.rb +85 -0
  499. data/spec/cucumber/rb_support/rb_language_spec.rb +243 -0
  500. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +199 -0
  501. data/spec/cucumber/rb_support/rb_transform_spec.rb +46 -0
  502. data/spec/cucumber/rb_support/rb_world_spec.rb +47 -0
  503. data/spec/cucumber/rb_support/snippet_spec.rb +137 -0
  504. data/spec/cucumber/running_test_case_spec.rb +139 -0
  505. data/spec/cucumber/runtime/for_programming_languages_spec.rb +36 -0
  506. data/spec/cucumber/runtime/support_code_spec.rb +16 -0
  507. data/spec/cucumber/runtime_spec.rb +20 -0
  508. data/spec/cucumber/sell_cucumbers.feature +19 -0
  509. data/spec/cucumber/step_argument_spec.rb +18 -0
  510. data/spec/cucumber/step_match_search_spec.rb +122 -0
  511. data/spec/cucumber/step_match_spec.rb +85 -0
  512. data/spec/cucumber/world/pending_spec.rb +47 -0
  513. data/spec/cucumber_spec.rb +39 -0
  514. data/spec/spec_helper.rb +29 -0
  515. data/spec/support/standard_step_actions.rb +18 -0
  516. metadata +1007 -0
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+ require 'cucumber/formatter/interceptor'
3
+
4
+ module Cucumber::Formatter
5
+ describe Interceptor::Pipe do
6
+ let(:pipe) do
7
+ pipe = double('original pipe')
8
+
9
+ allow(pipe).to receive(:instance_of?) { true }
10
+
11
+ pipe
12
+ end
13
+
14
+ describe '#wrap!' do
15
+ it 'raises an ArgumentError if its not passed :stderr/:stdout' do
16
+ expect {
17
+ Interceptor::Pipe.wrap(:nonsense)
18
+ }.to raise_error(ArgumentError)
19
+ end
20
+
21
+ context 'when passed :stderr' do
22
+ before :each do
23
+ @stderr = $stdout
24
+ end
25
+
26
+ it 'wraps $stderr' do
27
+ wrapped = Interceptor::Pipe.wrap(:stderr)
28
+
29
+ expect($stderr).to be_instance_of Interceptor::Pipe
30
+ expect($stderr).to be wrapped
31
+ end
32
+
33
+ after :each do
34
+ $stderr = @stderr
35
+ end
36
+ end
37
+
38
+ context 'when passed :stdout' do
39
+ before :each do
40
+ @stdout = $stdout
41
+ end
42
+
43
+ it 'wraps $stdout' do
44
+ wrapped = Interceptor::Pipe.wrap(:stdout)
45
+
46
+ expect($stdout).to be_instance_of Interceptor::Pipe
47
+ expect($stdout).to be wrapped
48
+ end
49
+
50
+ after :each do
51
+ $stdout = @stdout
52
+ end
53
+ end
54
+ end
55
+
56
+ describe '#unwrap!' do
57
+ before :each do
58
+ @stdout = $stdout
59
+ @wrapped = Interceptor::Pipe.wrap(:stdout)
60
+ end
61
+
62
+ it 'raises an ArgumentError if it wasn\'t passed :stderr/:stdout' do
63
+ expect {
64
+ Interceptor::Pipe.unwrap!(:nonsense)
65
+ }.to raise_error(ArgumentError)
66
+ end
67
+
68
+ it 'resets $stdout when #unwrap! is called' do
69
+ interceptor = Interceptor::Pipe.unwrap! :stdout
70
+
71
+ expect(interceptor).to be_instance_of Interceptor::Pipe
72
+ expect($stdout).not_to be interceptor
73
+ end
74
+
75
+ it 'noops if $stdout or $stderr has been overwritten' do
76
+ $stdout = StringIO.new
77
+ pipe = Interceptor::Pipe.unwrap! :stdout
78
+ expect(pipe).to eq $stdout
79
+
80
+ $stderr = StringIO.new
81
+ pipe = Interceptor::Pipe.unwrap! :stderr
82
+ expect(pipe).to eq $stderr
83
+ end
84
+
85
+ it 'disables the pipe bypass' do
86
+ buffer = '(::)'
87
+ Interceptor::Pipe.unwrap! :stdout
88
+
89
+ expect(@wrapped).to receive(:write).with(buffer)
90
+ expect(@wrapped.buffer).not_to receive(:<<)
91
+
92
+ @wrapped.write(buffer)
93
+ end
94
+
95
+ after :each do
96
+ $stdout = @stdout
97
+ end
98
+ end
99
+
100
+ describe '#write' do
101
+ let(:buffer) { 'Some stupid buffer' }
102
+ let(:pi) { Interceptor::Pipe.new(pipe) }
103
+
104
+ it 'writes arguments to the original pipe' do
105
+ expect(pipe).to receive(:write).with(buffer) { buffer.size }
106
+ expect(pi.write(buffer)).to eq buffer.size
107
+ end
108
+
109
+ it 'adds the buffer to its stored output' do
110
+ allow(pipe).to receive(:write)
111
+
112
+ pi.write(buffer)
113
+
114
+ expect(pi.buffer).not_to be_empty
115
+ expect(pi.buffer.first).to eq buffer
116
+ end
117
+ end
118
+
119
+ describe '#method_missing' do
120
+ let(:pi) { Interceptor::Pipe.new(pipe) }
121
+
122
+ it 'passes #tty? to the original pipe' do
123
+ expect(pipe).to receive(:tty?) { true }
124
+ expect(pi.tty?).to be true
125
+ end
126
+ end
127
+
128
+ describe '#respond_to' do
129
+ let(:pi) { Interceptor::Pipe.wrap(:stderr) }
130
+
131
+ it 'responds to all methods $stderr has' do
132
+ $stderr.methods.each { |m| expect(pi.respond_to?(m)).to be true }
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,841 @@
1
+ require 'spec_helper'
2
+ require 'cucumber/formatter/spec_helper'
3
+ require 'cucumber/formatter/json'
4
+ require 'cucumber/cli/options'
5
+ require 'multi_json'
6
+
7
+ module Cucumber
8
+ module Formatter
9
+ describe Json do
10
+ extend SpecHelperDsl
11
+ include SpecHelper
12
+
13
+ context "Given a single feature" do
14
+ before(:each) do
15
+ @out = StringIO.new
16
+ @formatter = Json.new(actual_runtime.configuration.with_options(out_stream: @out))
17
+ run_defined_feature
18
+ end
19
+
20
+ describe "with a scenario with no steps" do
21
+ define_feature <<-FEATURE
22
+ Feature: Banana party
23
+
24
+ Scenario: Monkey eats bananas
25
+ FEATURE
26
+
27
+ it "outputs the json data" do
28
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
29
+ [{"id": "banana-party",
30
+ "uri": "spec.feature",
31
+ "keyword": "Feature",
32
+ "name": "Banana party",
33
+ "line": 1,
34
+ "description": "",
35
+ "elements":
36
+ [{"id": "banana-party;monkey-eats-bananas",
37
+ "keyword": "Scenario",
38
+ "name": "Monkey eats bananas",
39
+ "line": 3,
40
+ "description": "",
41
+ "type": "scenario"}]}]})
42
+ end
43
+ end
44
+
45
+ describe "with a scenario with an undefined step" do
46
+ define_feature <<-FEATURE
47
+ Feature: Banana party
48
+
49
+ Scenario: Monkey eats bananas
50
+ Given there are bananas
51
+ FEATURE
52
+
53
+ it "outputs the json data" do
54
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
55
+ [{"id": "banana-party",
56
+ "uri": "spec.feature",
57
+ "keyword": "Feature",
58
+ "name": "Banana party",
59
+ "line": 1,
60
+ "description": "",
61
+ "elements":
62
+ [{"id": "banana-party;monkey-eats-bananas",
63
+ "keyword": "Scenario",
64
+ "name": "Monkey eats bananas",
65
+ "line": 3,
66
+ "description": "",
67
+ "type": "scenario",
68
+ "steps":
69
+ [{"keyword": "Given ",
70
+ "name": "there are bananas",
71
+ "line": 4,
72
+ "match": {"location": "spec.feature:4"},
73
+ "result": {"status": "undefined"}}]}]}]})
74
+ end
75
+ end
76
+
77
+ describe "with a scenario with a passed step" do
78
+ define_feature <<-FEATURE
79
+ Feature: Banana party
80
+
81
+ Scenario: Monkey eats bananas
82
+ Given there are bananas
83
+ FEATURE
84
+
85
+ define_steps do
86
+ Given(/^there are bananas$/) {}
87
+ end
88
+
89
+ it "outputs the json data" do
90
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
91
+ [{"id": "banana-party",
92
+ "uri": "spec.feature",
93
+ "keyword": "Feature",
94
+ "name": "Banana party",
95
+ "line": 1,
96
+ "description": "",
97
+ "elements":
98
+ [{"id": "banana-party;monkey-eats-bananas",
99
+ "keyword": "Scenario",
100
+ "name": "Monkey eats bananas",
101
+ "line": 3,
102
+ "description": "",
103
+ "type": "scenario",
104
+ "steps":
105
+ [{"keyword": "Given ",
106
+ "name": "there are bananas",
107
+ "line": 4,
108
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:86"},
109
+ "result": {"status": "passed",
110
+ "duration": 1}}]}]}]})
111
+ end
112
+ end
113
+
114
+ describe "with a scenario with a failed step" do
115
+ define_feature <<-FEATURE
116
+ Feature: Banana party
117
+
118
+ Scenario: Monkey eats bananas
119
+ Given there are bananas
120
+ FEATURE
121
+
122
+ define_steps do
123
+ Given(/^there are bananas$/) { raise "no bananas" }
124
+ end
125
+
126
+ it "outputs the json data" do
127
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
128
+ [{"id": "banana-party",
129
+ "uri": "spec.feature",
130
+ "keyword": "Feature",
131
+ "name": "Banana party",
132
+ "line": 1,
133
+ "description": "",
134
+ "elements":
135
+ [{"id": "banana-party;monkey-eats-bananas",
136
+ "keyword": "Scenario",
137
+ "name": "Monkey eats bananas",
138
+ "line": 3,
139
+ "description": "",
140
+ "type": "scenario",
141
+ "steps":
142
+ [{"keyword": "Given ",
143
+ "name": "there are bananas",
144
+ "line": 4,
145
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:123"},
146
+ "result": {"status": "failed",
147
+ "error_message": "no bananas (RuntimeError)\\n./spec/cucumber/formatter/json_spec.rb:123:in `/^there are bananas$/'\\nspec.feature:4:in `Given there are bananas'",
148
+ "duration": 1}}]}]}]})
149
+ end
150
+ end
151
+
152
+ describe "with a scenario with a pending step" do
153
+ define_feature <<-FEATURE
154
+ Feature: Banana party
155
+
156
+ Scenario: Monkey eats bananas
157
+ Given there are bananas
158
+ FEATURE
159
+
160
+ define_steps do
161
+ Given(/^there are bananas$/) { pending }
162
+ end
163
+
164
+ it "outputs the json data" do
165
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
166
+ [{"id": "banana-party",
167
+ "uri": "spec.feature",
168
+ "keyword": "Feature",
169
+ "name": "Banana party",
170
+ "line": 1,
171
+ "description": "",
172
+ "elements":
173
+ [{"id": "banana-party;monkey-eats-bananas",
174
+ "keyword": "Scenario",
175
+ "name": "Monkey eats bananas",
176
+ "line": 3,
177
+ "description": "",
178
+ "type": "scenario",
179
+ "steps":
180
+ [{"keyword": "Given ",
181
+ "name": "there are bananas",
182
+ "line": 4,
183
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:161"},
184
+ "result": {"status": "pending",
185
+ "error_message": "TODO (Cucumber::Pending)\\n./spec/cucumber/formatter/json_spec.rb:161:in `/^there are bananas$/'\\nspec.feature:4:in `Given there are bananas'",
186
+ "duration": 1}}]}]}]})
187
+ end
188
+ end
189
+
190
+ describe "with a scenario outline with one example" do
191
+ define_feature <<-FEATURE
192
+ Feature: Banana party
193
+
194
+ Scenario Outline: Monkey eats bananas
195
+ Given there are <fruit>
196
+
197
+ Examples: Fruit Table
198
+ | fruit |
199
+ | bananas |
200
+ FEATURE
201
+
202
+ define_steps do
203
+ Given(/^there are bananas$/) {}
204
+ end
205
+
206
+ it "outputs the json data" do
207
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
208
+ [{"id": "banana-party",
209
+ "uri": "spec.feature",
210
+ "keyword": "Feature",
211
+ "name": "Banana party",
212
+ "line": 1,
213
+ "description": "",
214
+ "elements":
215
+ [{"id": "banana-party;monkey-eats-bananas;fruit-table;2",
216
+ "keyword": "Scenario Outline",
217
+ "name": "Monkey eats bananas",
218
+ "line": 8,
219
+ "description": "",
220
+ "type": "scenario",
221
+ "steps":
222
+ [{"keyword": "Given ",
223
+ "name": "there are bananas",
224
+ "line": 8,
225
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:203"},
226
+ "result": {"status": "passed",
227
+ "duration": 1}}]}]}]})
228
+ end
229
+ end
230
+
231
+ describe "with tags in the feature file" do
232
+ define_feature <<-FEATURE
233
+ @f
234
+ Feature: Banana party
235
+
236
+ @s
237
+ Scenario: Monkey eats bananas
238
+ Given there are bananas
239
+
240
+ @so
241
+ Scenario Outline: Monkey eats bananas
242
+ Given there are <fruit>
243
+
244
+ @ex
245
+ Examples: Fruit Table
246
+ | fruit |
247
+ | bananas |
248
+ FEATURE
249
+
250
+ define_steps do
251
+ Given(/^there are bananas$/) {}
252
+ end
253
+
254
+ it "the tags are included in the json data" do
255
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
256
+ [{"id": "banana-party",
257
+ "uri": "spec.feature",
258
+ "keyword": "Feature",
259
+ "name": "Banana party",
260
+ "line": 2,
261
+ "description": "",
262
+ "tags": [{"name": "@f",
263
+ "line": 1}],
264
+ "elements":
265
+ [{"id": "banana-party;monkey-eats-bananas",
266
+ "keyword": "Scenario",
267
+ "name": "Monkey eats bananas",
268
+ "line": 5,
269
+ "description": "",
270
+ "tags": [{"name": "@f",
271
+ "line": 1},
272
+ {"name": "@s",
273
+ "line": 4}],
274
+ "type": "scenario",
275
+ "steps":
276
+ [{"keyword": "Given ",
277
+ "name": "there are bananas",
278
+ "line": 6,
279
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:251"},
280
+ "result": {"status": "passed",
281
+ "duration": 1}}]},
282
+ {"id": "banana-party;monkey-eats-bananas;fruit-table;2",
283
+ "keyword": "Scenario Outline",
284
+ "name": "Monkey eats bananas",
285
+ "line": 15,
286
+ "description": "",
287
+ "tags": [{"name": "@f",
288
+ "line": 1},
289
+ {"name": "@so",
290
+ "line": 8},
291
+ {"name": "@ex",
292
+ "line": 12}],
293
+ "type": "scenario",
294
+ "steps":
295
+ [{"keyword": "Given ",
296
+ "name": "there are bananas",
297
+ "line": 15,
298
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:251"},
299
+ "result": {"status": "passed",
300
+ "duration": 1}}]}]}]})
301
+ end
302
+ end
303
+
304
+ describe "with comments in the feature file" do
305
+ define_feature <<-FEATURE
306
+ #feature comment
307
+ Feature: Banana party
308
+
309
+ #background comment
310
+ Background: There are bananas
311
+ Given there are bananas
312
+
313
+ #scenario comment
314
+ Scenario: Monkey eats bananas
315
+ #step comment1
316
+ Then the monkey eats bananas
317
+
318
+ #scenario outline comment
319
+ Scenario Outline: Monkey eats bananas
320
+ #step comment2
321
+ Then the monkey eats <fruit>
322
+
323
+ #examples table comment
324
+ Examples: Fruit Table
325
+ | fruit |
326
+ #examples table row comment
327
+ | bananas |
328
+ FEATURE
329
+
330
+ define_steps do
331
+ Given(/^there are bananas$/) {}
332
+ Then(/^the monkey eats bananas$/) {}
333
+ end
334
+
335
+ it "the comments are included in the json data" do
336
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
337
+ [{"id": "banana-party",
338
+ "uri": "spec.feature",
339
+ "keyword": "Feature",
340
+ "name": "Banana party",
341
+ "line": 2,
342
+ "description": "",
343
+ "comments": [{"value": "#feature comment",
344
+ "line": 1}],
345
+ "elements":
346
+ [{"keyword": "Background",
347
+ "name": "There are bananas",
348
+ "line": 5,
349
+ "description": "",
350
+ "comments": [{"value": "#background comment",
351
+ "line": 4}],
352
+ "type": "background",
353
+ "steps":
354
+ [{"keyword": "Given ",
355
+ "name": "there are bananas",
356
+ "line": 6,
357
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:331"},
358
+ "result": {"status": "passed",
359
+ "duration": 1}}]},
360
+ {"id": "banana-party;monkey-eats-bananas",
361
+ "keyword": "Scenario",
362
+ "name": "Monkey eats bananas",
363
+ "line": 9,
364
+ "description": "",
365
+ "comments": [{"value": "#scenario comment",
366
+ "line": 8}],
367
+ "type": "scenario",
368
+ "steps":
369
+ [{"keyword": "Then ",
370
+ "name": "the monkey eats bananas",
371
+ "line": 11,
372
+ "comments": [{"value": "#step comment1",
373
+ "line": 10}],
374
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:332"},
375
+ "result": {"status": "passed",
376
+ "duration": 1}}]},
377
+ {"keyword": "Background",
378
+ "name": "There are bananas",
379
+ "line": 5,
380
+ "description": "",
381
+ "comments": [{"value": "#background comment",
382
+ "line": 4}],
383
+ "type": "background",
384
+ "steps":
385
+ [{"keyword": "Given ",
386
+ "name": "there are bananas",
387
+ "line": 6,
388
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:331"},
389
+ "result": {"status": "passed",
390
+ "duration": 1}}]},
391
+ {"id": "banana-party;monkey-eats-bananas;fruit-table;2",
392
+ "keyword": "Scenario Outline",
393
+ "name": "Monkey eats bananas",
394
+ "line": 22,
395
+ "description": "",
396
+ "comments": [{"value": "#scenario outline comment",
397
+ "line": 13},
398
+ {"value": "#examples table comment",
399
+ "line": 18},
400
+ {"value": "#examples table row comment",
401
+ "line": 21}],
402
+ "type": "scenario",
403
+ "steps":
404
+ [{"keyword": "Then ",
405
+ "name": "the monkey eats bananas",
406
+ "line": 22,
407
+ "comments": [{"value": "#step comment2",
408
+ "line": 15}],
409
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:332"},
410
+ "result": {"status": "passed",
411
+ "duration": 1}}]}]}]})
412
+ end
413
+ end
414
+
415
+ describe "with a scenario with a step with a doc string" do
416
+ define_feature <<-FEATURE
417
+ Feature: Banana party
418
+
419
+ Scenario: Monkey eats bananas
420
+ Given there are bananas
421
+ """
422
+ the doc string
423
+ """
424
+ FEATURE
425
+
426
+ define_steps do
427
+ Given(/^there are bananas$/) { |s| s }
428
+ end
429
+
430
+ it "includes the doc string in the json data" do
431
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
432
+ [{"id": "banana-party",
433
+ "uri": "spec.feature",
434
+ "keyword": "Feature",
435
+ "name": "Banana party",
436
+ "line": 1,
437
+ "description": "",
438
+ "elements":
439
+ [{"id": "banana-party;monkey-eats-bananas",
440
+ "keyword": "Scenario",
441
+ "name": "Monkey eats bananas",
442
+ "line": 3,
443
+ "description": "",
444
+ "type": "scenario",
445
+ "steps":
446
+ [{"keyword": "Given ",
447
+ "name": "there are bananas",
448
+ "line": 4,
449
+ "doc_string": {"value": "the doc string",
450
+ "content_type": "",
451
+ "line": 5},
452
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:427"},
453
+ "result": {"status": "passed",
454
+ "duration": 1}}]}]}]})
455
+ end
456
+ end
457
+
458
+ describe "with a scenario with a step that use puts" do
459
+ define_feature <<-FEATURE
460
+ Feature: Banana party
461
+
462
+ Scenario: Monkey eats bananas
463
+ Given there are bananas
464
+ FEATURE
465
+
466
+ define_steps do
467
+ Given(/^there are bananas$/) { puts "from step" }
468
+ end
469
+
470
+ it "includes the output from the step in the json data" do
471
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
472
+ [{"id": "banana-party",
473
+ "uri": "spec.feature",
474
+ "keyword": "Feature",
475
+ "name": "Banana party",
476
+ "line": 1,
477
+ "description": "",
478
+ "elements":
479
+ [{"id": "banana-party;monkey-eats-bananas",
480
+ "keyword": "Scenario",
481
+ "name": "Monkey eats bananas",
482
+ "line": 3,
483
+ "description": "",
484
+ "type": "scenario",
485
+ "steps":
486
+ [{"keyword": "Given ",
487
+ "name": "there are bananas",
488
+ "line": 4,
489
+ "output": ["from step"],
490
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:467"},
491
+ "result": {"status": "passed",
492
+ "duration": 1}}]}]}]})
493
+ end
494
+ end
495
+
496
+ describe "with a background" do
497
+ define_feature <<-FEATURE
498
+ Feature: Banana party
499
+
500
+ Background: There are bananas
501
+ Given there are bananas
502
+
503
+ Scenario: Monkey eats bananas
504
+ Then the monkey eats bananas
505
+
506
+ Scenario: Monkey eats more bananas
507
+ Then the monkey eats more bananas
508
+ FEATURE
509
+
510
+ it "includes the background in the json data each time it is executed" do
511
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
512
+ [{"id": "banana-party",
513
+ "uri": "spec.feature",
514
+ "keyword": "Feature",
515
+ "name": "Banana party",
516
+ "line": 1,
517
+ "description": "",
518
+ "elements":
519
+ [{"keyword": "Background",
520
+ "name": "There are bananas",
521
+ "line": 3,
522
+ "description": "",
523
+ "type": "background",
524
+ "steps":
525
+ [{"keyword": "Given ",
526
+ "name": "there are bananas",
527
+ "line": 4,
528
+ "match": {"location": "spec.feature:4"},
529
+ "result": {"status": "undefined"}}]},
530
+ {"id": "banana-party;monkey-eats-bananas",
531
+ "keyword": "Scenario",
532
+ "name": "Monkey eats bananas",
533
+ "line": 6,
534
+ "description": "",
535
+ "type": "scenario",
536
+ "steps":
537
+ [{"keyword": "Then ",
538
+ "name": "the monkey eats bananas",
539
+ "line": 7,
540
+ "match": {"location": "spec.feature:7"},
541
+ "result": {"status": "undefined"}}]},
542
+ {"keyword": "Background",
543
+ "name": "There are bananas",
544
+ "line": 3,
545
+ "description": "",
546
+ "type": "background",
547
+ "steps":
548
+ [{"keyword": "Given ",
549
+ "name": "there are bananas",
550
+ "line": 4,
551
+ "match": {"location": "spec.feature:4"},
552
+ "result": {"status": "undefined"}}]},
553
+ {"id": "banana-party;monkey-eats-more-bananas",
554
+ "keyword": "Scenario",
555
+ "name": "Monkey eats more bananas",
556
+ "line": 9,
557
+ "description": "",
558
+ "type": "scenario",
559
+ "steps":
560
+ [{"keyword": "Then ",
561
+ "name": "the monkey eats more bananas",
562
+ "line": 10,
563
+ "match": {"location": "spec.feature:10"},
564
+ "result": {"status": "undefined"}}]}]}]})
565
+ end
566
+ end
567
+
568
+ describe "with a scenario with a step that embeds data directly" do
569
+ define_feature <<-FEATURE
570
+ Feature: Banana party
571
+
572
+ Scenario: Monkey eats bananas
573
+ Given there are bananas
574
+ FEATURE
575
+
576
+ define_steps do
577
+ Given(/^there are bananas$/) { data = "YWJj"
578
+ embed data, "mime-type;base64" }
579
+ end
580
+
581
+ it "includes the data from the step in the json data" do
582
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
583
+ [{"id": "banana-party",
584
+ "uri": "spec.feature",
585
+ "keyword": "Feature",
586
+ "name": "Banana party",
587
+ "line": 1,
588
+ "description": "",
589
+ "elements":
590
+ [{"id": "banana-party;monkey-eats-bananas",
591
+ "keyword": "Scenario",
592
+ "name": "Monkey eats bananas",
593
+ "line": 3,
594
+ "description": "",
595
+ "type": "scenario",
596
+ "steps":
597
+ [{"keyword": "Given ",
598
+ "name": "there are bananas",
599
+ "line": 4,
600
+ "embeddings": [{"mime_type": "mime-type",
601
+ "data": "YWJj"}],
602
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:577"},
603
+ "result": {"status": "passed",
604
+ "duration": 1}}]}]}]})
605
+ end
606
+ end
607
+
608
+ describe "with a scenario with a step that embeds a file" do
609
+ define_feature <<-FEATURE
610
+ Feature: Banana party
611
+
612
+ Scenario: Monkey eats bananas
613
+ Given there are bananas
614
+ FEATURE
615
+
616
+ define_steps do
617
+ Given(/^there are bananas$/) {
618
+ RSpec::Mocks.allow_message(File, :file?) { true }
619
+ f1 = RSpec::Mocks::Double.new
620
+ RSpec::Mocks.allow_message(File, :open) { |&block| block.call(f1) }
621
+ RSpec::Mocks.allow_message(f1, :read) { "foo" }
622
+ embed('out/snapshot.jpeg', 'image/png')
623
+ }
624
+ end
625
+
626
+ it "includes the file content in the json data" do
627
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
628
+ [{"id": "banana-party",
629
+ "uri": "spec.feature",
630
+ "keyword": "Feature",
631
+ "name": "Banana party",
632
+ "line": 1,
633
+ "description": "",
634
+ "elements":
635
+ [{"id": "banana-party;monkey-eats-bananas",
636
+ "keyword": "Scenario",
637
+ "name": "Monkey eats bananas",
638
+ "line": 3,
639
+ "description": "",
640
+ "type": "scenario",
641
+ "steps":
642
+ [{"keyword": "Given ",
643
+ "name": "there are bananas",
644
+ "line": 4,
645
+ "embeddings": [{"mime_type": "image/png",
646
+ "data": "Zm9v"}],
647
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:617"},
648
+ "result": {"status": "passed",
649
+ "duration": 1}}]}]}]})
650
+ end
651
+ end
652
+
653
+ describe "with a scenario with hooks" do
654
+ define_feature <<-FEATURE
655
+ Feature: Banana party
656
+
657
+ Scenario: Monkey eats bananas
658
+ Given there are bananas
659
+ FEATURE
660
+
661
+ define_steps do
662
+ Before() {}
663
+ Before() {}
664
+ After() {}
665
+ After() {}
666
+ AfterStep() {}
667
+ AfterStep() {}
668
+ Around() { |scenario, block| block.call }
669
+ Given(/^there are bananas$/) {}
670
+ end
671
+
672
+ it "includes all hooks except the around hook in the json data" do
673
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
674
+ [{"id": "banana-party",
675
+ "uri": "spec.feature",
676
+ "keyword": "Feature",
677
+ "name": "Banana party",
678
+ "line": 1,
679
+ "description": "",
680
+ "elements":
681
+ [{"id": "banana-party;monkey-eats-bananas",
682
+ "keyword": "Scenario",
683
+ "name": "Monkey eats bananas",
684
+ "line": 3,
685
+ "description": "",
686
+ "type": "scenario",
687
+ "before":
688
+ [{"match": {"location": "spec/cucumber/formatter/json_spec.rb:662"},
689
+ "result": {"status": "passed",
690
+ "duration": 1}},
691
+ {"match": {"location": "spec/cucumber/formatter/json_spec.rb:663"},
692
+ "result": {"status": "passed",
693
+ "duration": 1}}],
694
+ "steps":
695
+ [{"keyword": "Given ",
696
+ "name": "there are bananas",
697
+ "line": 4,
698
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:669"},
699
+ "result": {"status": "passed",
700
+ "duration": 1},
701
+ "after":
702
+ [{"match": {"location": "spec/cucumber/formatter/json_spec.rb:666"},
703
+ "result": {"status": "passed",
704
+ "duration": 1}},
705
+ {"match": {"location": "spec/cucumber/formatter/json_spec.rb:667"},
706
+ "result": {"status": "passed",
707
+ "duration": 1}}]}],
708
+ "after":
709
+ [{"match": {"location": "spec/cucumber/formatter/json_spec.rb:665"},
710
+ "result": {"status": "passed",
711
+ "duration": 1}},
712
+ {"match": {"location": "spec/cucumber/formatter/json_spec.rb:664"},
713
+ "result": {"status": "passed",
714
+ "duration": 1}}]}]}]})
715
+ end
716
+ end
717
+
718
+ describe "with a scenario when only an around hook is failing" do
719
+ define_feature <<-FEATURE
720
+ Feature: Banana party
721
+
722
+ Scenario: Monkey eats bananas
723
+ Given there are bananas
724
+ FEATURE
725
+
726
+ define_steps do
727
+ Around() { |scenario, block| block.call; raise RuntimeError, "error" }
728
+ Given(/^there are bananas$/) {}
729
+ end
730
+
731
+ it "includes the around hook result in the json data" do
732
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
733
+ [{"id": "banana-party",
734
+ "uri": "spec.feature",
735
+ "keyword": "Feature",
736
+ "name": "Banana party",
737
+ "line": 1,
738
+ "description": "",
739
+ "elements":
740
+ [{"id": "banana-party;monkey-eats-bananas",
741
+ "keyword": "Scenario",
742
+ "name": "Monkey eats bananas",
743
+ "line": 3,
744
+ "description": "",
745
+ "type": "scenario",
746
+ "steps":
747
+ [{"keyword": "Given ",
748
+ "name": "there are bananas",
749
+ "line": 4,
750
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:728"},
751
+ "result": {"status": "passed",
752
+ "duration": 1}}],
753
+ "around":
754
+ [{"match": {"location": "unknown_hook_location:1"},
755
+ "result": {"status": "failed",
756
+ "error_message": "error (RuntimeError)\\n./spec/cucumber/formatter/json_spec.rb:727:in `Around'",
757
+ "duration": 1}}]}]}]})
758
+ end
759
+ end
760
+
761
+ describe "with a scenario with a step with a data table" do
762
+ define_feature <<-FEATURE
763
+ Feature: Banana party
764
+
765
+ Scenario: Monkey eats bananas
766
+ Given there are bananas
767
+ | aa | bb |
768
+ | cc | dd |
769
+ FEATURE
770
+
771
+ define_steps do
772
+ Given(/^there are bananas$/) { |s| s }
773
+ end
774
+
775
+ it "includes the doc string in the json data" do
776
+ expect(load_normalised_json(@out)).to eq MultiJson.load(%{
777
+ [{"id": "banana-party",
778
+ "uri": "spec.feature",
779
+ "keyword": "Feature",
780
+ "name": "Banana party",
781
+ "line": 1,
782
+ "description": "",
783
+ "elements":
784
+ [{"id": "banana-party;monkey-eats-bananas",
785
+ "keyword": "Scenario",
786
+ "name": "Monkey eats bananas",
787
+ "line": 3,
788
+ "description": "",
789
+ "type": "scenario",
790
+ "steps":
791
+ [{"keyword": "Given ",
792
+ "name": "there are bananas",
793
+ "line": 4,
794
+ "rows":
795
+ [{"cells": ["aa", "bb"]},
796
+ {"cells": ["cc", "dd"]}],
797
+ "match": {"location": "spec/cucumber/formatter/json_spec.rb:772"},
798
+ "result": {"status": "passed",
799
+ "duration": 1}}]}]}]})
800
+ end
801
+ end
802
+ end
803
+
804
+ def load_normalised_json(out)
805
+ normalise_json(MultiJson.load(out.string))
806
+ end
807
+
808
+ def normalise_json(json)
809
+ #make sure duration was captured (should be >= 0)
810
+ #then set it to what is "expected" since duration is dynamic
811
+ json.each do |feature|
812
+ elements = feature.fetch('elements') { [] }
813
+ elements.each do |scenario|
814
+ ['steps', 'before', 'after', 'around'].each do |type|
815
+ if scenario[type]
816
+ scenario[type].each do |step_or_hook|
817
+ normalise_json_step_or_hook(step_or_hook)
818
+ if step_or_hook['after']
819
+ step_or_hook['after'].each do |hook|
820
+ normalise_json_step_or_hook(hook)
821
+ end
822
+ end
823
+ end
824
+ end
825
+ end
826
+ end
827
+ end
828
+ end
829
+
830
+ def normalise_json_step_or_hook(step_or_hook)
831
+ if step_or_hook['result']
832
+ if step_or_hook['result']['duration']
833
+ expect(step_or_hook['result']['duration']).to be >= 0
834
+ step_or_hook['result']['duration'] = 1
835
+ end
836
+ end
837
+ end
838
+
839
+ end
840
+ end
841
+ end