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,131 @@
1
+ require 'cucumber/step_match'
2
+ require 'cucumber/step_argument'
3
+ require 'cucumber/core_ext/string'
4
+
5
+ module Cucumber
6
+ module RbSupport
7
+ # A Ruby Step Definition holds a Regexp and a Proc, and is created
8
+ # by calling <tt>Given</tt>, <tt>When</tt> or <tt>Then</tt>
9
+ # in the <tt>step_definitions</tt> ruby files. See also RbDsl.
10
+ #
11
+ # Example:
12
+ #
13
+ # Given /I have (\d+) cucumbers in my belly/ do
14
+ # # some code here
15
+ # end
16
+ #
17
+ class RbStepDefinition
18
+
19
+ class MissingProc < StandardError
20
+ def message
21
+ "Step definitions must always have a proc or symbol"
22
+ end
23
+ end
24
+
25
+ class << self
26
+ def new(rb_language, pattern, proc_or_sym, options)
27
+ raise MissingProc if proc_or_sym.nil?
28
+ super rb_language, parse_pattern(pattern), create_proc(proc_or_sym, options)
29
+ end
30
+
31
+ private
32
+
33
+ def parse_pattern(pattern)
34
+ return pattern if pattern.is_a?(Regexp)
35
+ raise ArgumentError unless pattern.is_a?(String)
36
+ p = Regexp.escape(pattern)
37
+ p = p.gsub(/\\\$\w+/, '(.*)') # Replace $var with (.*)
38
+ Regexp.new("^#{p}$")
39
+ end
40
+
41
+ def create_proc(proc_or_sym, options)
42
+ return proc_or_sym if proc_or_sym.is_a?(Proc)
43
+ raise ArgumentError unless proc_or_sym.is_a?(Symbol)
44
+ message = proc_or_sym
45
+ target_proc = parse_target_proc_from(options)
46
+ patch_location_onto lambda { |*args|
47
+ target = instance_exec(&target_proc)
48
+ target.send(message, *args)
49
+ }
50
+ end
51
+
52
+ def patch_location_onto(block)
53
+ location = Core::Ast::Location.of_caller(5)
54
+ block.define_singleton_method(:source_location) { [location.file, location.line] }
55
+ block
56
+ end
57
+
58
+ def parse_target_proc_from(options)
59
+ return lambda { self } unless options.key?(:on)
60
+ target = options[:on]
61
+ case target
62
+ when Proc
63
+ target
64
+ when Symbol
65
+ lambda { self.send(target) }
66
+ else
67
+ lambda { raise ArgumentError, "Target must be a symbol or a proc" }
68
+ end
69
+ end
70
+ end
71
+
72
+ def initialize(rb_language, regexp, proc)
73
+ @rb_language, @regexp, @proc = rb_language, regexp, proc
74
+ @rb_language.available_step_definition(regexp_source, location)
75
+ end
76
+
77
+ def regexp_source
78
+ @regexp.inspect
79
+ end
80
+
81
+ def to_hash
82
+ flags = ''
83
+ flags += 'm' if (@regexp.options & Regexp::MULTILINE) != 0
84
+ flags += 'i' if (@regexp.options & Regexp::IGNORECASE) != 0
85
+ flags += 'x' if (@regexp.options & Regexp::EXTENDED) != 0
86
+ {'source' => @regexp.source, 'flags' => flags}
87
+ end
88
+
89
+ def ==(step_definition)
90
+ regexp_source == step_definition.regexp_source
91
+ end
92
+
93
+ def arguments_from(step_name)
94
+ args = StepArgument.arguments_from(@regexp, step_name)
95
+ @rb_language.invoked_step_definition(regexp_source, location) if args
96
+ args
97
+ end
98
+
99
+ def invoke(args)
100
+ begin
101
+ args = @rb_language.execute_transforms(args)
102
+ @rb_language.current_world.cucumber_instance_exec(true, regexp_source, *args, &@proc)
103
+ rescue Cucumber::ArityMismatchError => e
104
+ e.backtrace.unshift(self.backtrace_line)
105
+ raise e
106
+ end
107
+ end
108
+
109
+ def backtrace_line
110
+ "#{location.to_s}:in `#{regexp_source}'"
111
+ end
112
+
113
+ def file_colon_line
114
+ case @proc
115
+ when Proc
116
+ location.to_s
117
+ when Symbol
118
+ ":#{@proc}"
119
+ end
120
+ end
121
+
122
+ def location
123
+ @location ||= Cucumber::Core::Ast::Location.from_source_location(*@proc.source_location)
124
+ end
125
+
126
+ def file
127
+ @file ||= location.file
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,59 @@
1
+ module Cucumber
2
+ module RbSupport
3
+ # A Ruby Transform holds a Regexp and a Proc, and is created
4
+ # by calling <tt>Transform in the <tt>support</tt> ruby files.
5
+ # See also RbDsl.
6
+ #
7
+ # Example:
8
+ #
9
+ # Transform /^(\d+) cucumbers$/ do |cucumbers_string|
10
+ # cucumbers_string.to_i
11
+ # end
12
+ #
13
+ class RbTransform
14
+ class MissingProc < StandardError
15
+ def message
16
+ "Transforms must always have a proc with at least one argument"
17
+ end
18
+ end
19
+
20
+ def initialize(rb_language, pattern, proc)
21
+ raise MissingProc if proc.nil? || proc.arity < 1
22
+ @rb_language, @regexp, @proc = rb_language, Regexp.new(pattern), proc
23
+ end
24
+
25
+ def match(arg)
26
+ arg ? arg.match(@regexp) : nil
27
+ end
28
+
29
+ def invoke(arg)
30
+ if matched = match(arg)
31
+ args = matched.captures.empty? ? [arg] : matched.captures
32
+ @rb_language.current_world.cucumber_instance_exec(true, @regexp.inspect, *args, &@proc)
33
+ end
34
+ end
35
+
36
+ def to_s
37
+ convert_captures(strip_anchors(@regexp.source))
38
+ end
39
+
40
+ private
41
+ def convert_captures(regexp_source)
42
+ regexp_source
43
+ .gsub(/(\()(?!\?[<:=!])/,'(?:')
44
+ .gsub(/(\(\?<)(?![=!])/,'(?:<')
45
+ end
46
+
47
+ def strip_captures(regexp_source)
48
+ regexp_source.
49
+ gsub(/(\()/, '').
50
+ gsub(/(\))/, '')
51
+ end
52
+
53
+ def strip_anchors(regexp_source)
54
+ regexp_source.
55
+ gsub(/(^\^|\$$)/, '')
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,149 @@
1
+ require 'cucumber/gherkin/formatter/ansi_escapes'
2
+
3
+ module Cucumber
4
+ module RbSupport
5
+ # Defines the basic DSL methods availlable in all Cucumber step definitions.
6
+ #
7
+ # You can, and probably should, extend this DSL with your own methods that
8
+ # make sense in your domain. For more on that, see {Cucumber::RbSupport::RbDsl#World}
9
+ module RbWorld
10
+
11
+ # @private
12
+ AnsiEscapes = Cucumber::Gherkin::Formatter::AnsiEscapes
13
+
14
+ # Call a Transform with a string from another Transform definition
15
+ def Transform(arg)
16
+ rb = @__cucumber_runtime.support_code.ruby
17
+ rb.execute_transforms([arg]).first
18
+ end
19
+
20
+ # @private
21
+ attr_writer :__cucumber_runtime, :__natural_language
22
+
23
+ # Run a single Gherkin step
24
+ # @example Call another step
25
+ # step "I am logged in"
26
+ # @example Call a step with quotes in the name
27
+ # step %{the user "Dave" is logged in}
28
+ # @example Passing a table
29
+ # step "the following users exist:", table(%{
30
+ # | name | email |
31
+ # | Matt | matt@matt.com |
32
+ # | Aslak | aslak@aslak.com |
33
+ # })
34
+ # @example Passing a multiline string
35
+ # step "the email should contain:", "Dear sir,\nYou've won a prize!\n"
36
+ # @param [String] name The name of the step
37
+ # @param [String,Cucumber::Ast::DocString,Cucumber::Ast::Table] multiline_argument
38
+ def step(name, raw_multiline_arg=nil)
39
+ location = Core::Ast::Location.of_caller
40
+ @__cucumber_runtime.invoke_dynamic_step(name, MultilineArgument.from(raw_multiline_arg, location))
41
+ end
42
+
43
+ # Run a snippet of Gherkin
44
+ # @example
45
+ # steps %{
46
+ # Given the user "Susan" exists
47
+ # And I am logged in as "Susan"
48
+ # }
49
+ # @param [String] steps_text The Gherkin snippet to run
50
+ def steps(steps_text)
51
+ location = Core::Ast::Location.of_caller
52
+ @__cucumber_runtime.invoke_dynamic_steps(steps_text, @__natural_language, location)
53
+ end
54
+
55
+ # Parse Gherkin into a {Cucumber::Ast::Table} object.
56
+ #
57
+ # Useful in conjunction with the #step method.
58
+ # @example Create a table
59
+ # users = table(%{
60
+ # | name | email |
61
+ # | Matt | matt@matt.com |
62
+ # | Aslak | aslak@aslak.com |
63
+ # })
64
+ # @param [String] text_or_table The Gherkin string that represents the table
65
+ def table(text_or_table, file=nil, line_offset=0)
66
+ @__cucumber_runtime.table(text_or_table, file, line_offset)
67
+ end
68
+
69
+ # Create an {Cucumber::Ast::DocString} object
70
+ #
71
+ # Useful in conjunction with the #step method, when
72
+ # want to specify a content type.
73
+ # @example Create a multiline string
74
+ # code = multiline_string(%{
75
+ # puts "this is ruby code"
76
+ # %}, 'ruby')
77
+ def doc_string(string_without_triple_quotes, content_type='', line_offset=0)
78
+ STDERR.puts AnsiEscapes.failed + "WARNING: #doc_string is deprecated. Just pass a regular String instead:" + caller[0] + AnsiEscapes.reset
79
+ # TODO: rename this method to multiline_string
80
+ @__cucumber_runtime.doc_string(string_without_triple_quotes, content_type, line_offset)
81
+ end
82
+
83
+ # @deprecated Use {#puts} instead.
84
+ def announce(*messages)
85
+ STDERR.puts AnsiEscapes.failed + "WARNING: #announce is deprecated. Use #puts instead:" + caller[0] + AnsiEscapes.reset
86
+ puts(*messages)
87
+ end
88
+
89
+ # Print a message to the output.
90
+ #
91
+ # @note Cucumber might surprise you with the behaviour of this method. Instead
92
+ # of sending the output directly to STDOUT, Cucumber will intercept and cache
93
+ # the message until the current step has finished, and then display it.
94
+ #
95
+ # If you'd prefer to see the message immediately, call {Kernel.puts} instead.
96
+ def puts(*messages)
97
+ # Even though they won't be output until later, converting the messages to
98
+ # strings right away will protect them from modifications to their original
99
+ # objects in the mean time
100
+ messages.collect! { |message| "#{message}" }
101
+
102
+ @__cucumber_runtime.puts(*messages)
103
+ end
104
+
105
+ # Pause the tests and ask the operator for input
106
+ def ask(question, timeout_seconds=60)
107
+ @__cucumber_runtime.ask(question, timeout_seconds)
108
+ end
109
+
110
+ # Embed an image in the output
111
+ def embed(file, mime_type, label='Screenshot')
112
+ @__cucumber_runtime.embed(file, mime_type, label)
113
+ end
114
+
115
+ # Mark the matched step as pending.
116
+ def pending(message = "TODO")
117
+ if block_given?
118
+ begin
119
+ yield
120
+ rescue Exception
121
+ raise Pending, message
122
+ end
123
+ raise Pending, "Expected pending '#{message}' to fail. No Error was raised. No longer pending?"
124
+ else
125
+ raise Pending, message
126
+ end
127
+ end
128
+
129
+ # Skips this step and the remaining steps in the scenario
130
+ def skip_this_scenario(message = "Scenario skipped")
131
+ raise Core::Test::Result::Skipped, message
132
+ end
133
+
134
+ # Prints the list of modules that are included in the World
135
+ def inspect
136
+ modules = [self.class]
137
+ (class << self; self; end).instance_eval do
138
+ modules += included_modules
139
+ end
140
+ sprintf("#<%s:0x%x>", modules.join('+'), self.object_id)
141
+ end
142
+
143
+ # see {#inspect}
144
+ def to_s
145
+ inspect
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,170 @@
1
+ module Cucumber
2
+ module RbSupport
3
+ module Snippet
4
+
5
+ ARGUMENT_PATTERNS = ['"([^"]*)"', '(\d+)']
6
+
7
+ class Generator
8
+ def self.register_on(configuration)
9
+ configuration.snippet_generators << new
10
+ end
11
+
12
+ def call(code_keyword, step_name, multiline_arg, snippet_type = :regexp)
13
+ snippet_class = typed_snippet_class(snippet_type)
14
+ snippet_class.new(code_keyword, step_name, multiline_arg).to_s
15
+ end
16
+
17
+ def typed_snippet_class(type)
18
+ SNIPPET_TYPES.fetch(type || :regexp)
19
+ end
20
+ end
21
+
22
+ class BaseSnippet
23
+
24
+ def initialize(code_keyword, pattern, multiline_argument)
25
+ @number_of_arguments = 0
26
+ @code_keyword = code_keyword
27
+ @pattern = replace_and_count_capturing_groups(pattern)
28
+ @multiline_argument = MultilineArgumentSnippet.new(multiline_argument)
29
+ end
30
+
31
+ def to_s
32
+ "#{step} #{do_block}"
33
+ end
34
+
35
+ def step
36
+ "#{code_keyword}#{typed_pattern}"
37
+ end
38
+
39
+ def self.cli_option_string(type)
40
+ "%-7s: %-28s e.g. %s" % [type, description, example]
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :code_keyword, :pattern, :multiline_argument, :number_of_arguments
46
+
47
+ def replace_and_count_capturing_groups(pattern)
48
+ modified_pattern = ::Regexp.escape(pattern).gsub('\ ', ' ').gsub('/', '\/')
49
+
50
+ ARGUMENT_PATTERNS.each do |argument_pattern|
51
+ modified_pattern.gsub!(::Regexp.new(argument_pattern), argument_pattern)
52
+ @number_of_arguments += modified_pattern.scan(argument_pattern).length
53
+ end
54
+
55
+ modified_pattern
56
+ end
57
+
58
+ def do_block
59
+ do_block = ""
60
+ do_block << "do#{arguments}\n"
61
+ multiline_argument.append_comment_to(do_block)
62
+ do_block << " pending # Write code here that turns the phrase above into concrete actions\n"
63
+ do_block << "end"
64
+ do_block
65
+ end
66
+
67
+ def arguments
68
+ block_args = (0...number_of_arguments).map { |n| "arg#{n+1}" }
69
+ multiline_argument.append_block_argument_to(block_args)
70
+ block_args.empty? ? "" : " |#{block_args.join(", ")}|"
71
+ end
72
+
73
+ def self.example
74
+ new("Given", "missing step", MultilineArgument::None.new).step
75
+ end
76
+
77
+ end
78
+
79
+ class Regexp < BaseSnippet
80
+ def typed_pattern
81
+ "(/^#{pattern}$/)"
82
+ end
83
+
84
+ def self.description
85
+ "Snippets with parentheses"
86
+ end
87
+ end
88
+
89
+ class Classic < BaseSnippet
90
+ def typed_pattern
91
+ " /^#{pattern}$/"
92
+ end
93
+
94
+ def self.description
95
+ "Snippets without parentheses. Note that these cause a warning from modern versions of Ruby."
96
+ end
97
+ end
98
+
99
+ class Percent < BaseSnippet
100
+ def typed_pattern
101
+ " %r{^#{pattern}$}"
102
+ end
103
+
104
+ def self.description
105
+ "Snippets with percent regexp"
106
+ end
107
+ end
108
+
109
+ SNIPPET_TYPES = {
110
+ :regexp => Regexp,
111
+ :classic => Classic,
112
+ :percent => Percent
113
+ }
114
+
115
+ module MultilineArgumentSnippet
116
+
117
+ def self.new(multiline_argument)
118
+ builder = Builder.new
119
+ multiline_argument.describe_to(builder)
120
+ builder.result
121
+ end
122
+
123
+ class Builder
124
+ def doc_string(*args)
125
+ @result = DocString.new
126
+ end
127
+
128
+ def data_table(table, *args)
129
+ @result = DataTable.new(table)
130
+ end
131
+
132
+ def result
133
+ @result || None.new
134
+ end
135
+ end
136
+
137
+ class DocString
138
+ def append_block_argument_to(array)
139
+ array << 'string'
140
+ end
141
+
142
+ def append_comment_to(string)
143
+ end
144
+ end
145
+
146
+ class DataTable
147
+ def initialize(table)
148
+ @table = table
149
+ end
150
+
151
+ def append_block_argument_to(array)
152
+ array << 'table'
153
+ end
154
+
155
+ def append_comment_to(string)
156
+ string << " # table is a #{Cucumber::MultilineArgument::DataTable.to_s}\n"
157
+ end
158
+ end
159
+
160
+ class None
161
+ def append_block_argument_to(array)
162
+ end
163
+
164
+ def append_comment_to(string)
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end