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,169 @@
1
+ require 'spec_helper'
2
+ require 'cucumber/formatter/spec_helper'
3
+ require 'cucumber/formatter/progress'
4
+ require 'cucumber/cli/options'
5
+
6
+ module Cucumber
7
+ module Formatter
8
+ describe Progress do
9
+ extend SpecHelperDsl
10
+ include SpecHelper
11
+
12
+ before(:each) do
13
+ Cucumber::Term::ANSIColor.coloring = false
14
+ @out = StringIO.new
15
+ @formatter = Progress.new(runtime, @out, Cucumber::Cli::Options.new)
16
+ end
17
+
18
+ describe "given a single feature" do
19
+ before(:each) do
20
+ run_defined_feature
21
+ end
22
+
23
+ describe "with a scenario" do
24
+ define_feature <<-FEATURE
25
+ Feature: Banana party
26
+
27
+ Scenario: Monkey eats banana
28
+ Given there are bananas
29
+ FEATURE
30
+
31
+ it "outputs the undefined step" do
32
+ expect(@out.string).to include "U\n"
33
+ end
34
+ end
35
+
36
+ describe "with a background" do
37
+ define_feature <<-FEATURE
38
+ Feature: Banana party
39
+
40
+ Background:
41
+ Given a tree
42
+
43
+ Scenario: Monkey eats banana
44
+ Given there are bananas
45
+ FEATURE
46
+
47
+ it "outputs the two undefined steps" do
48
+ expect(@out.string).to include "UU\n"
49
+ end
50
+ end
51
+
52
+ describe "with a scenario outline" do
53
+ define_feature <<-FEATURE
54
+ Feature: Fud Pyramid
55
+
56
+ Scenario Outline: Monkey eats a balanced diet
57
+ Given there are <Things>
58
+
59
+ Examples: Fruit
60
+ | Things |
61
+ | apples |
62
+ | bananas |
63
+ Examples: Vegetables
64
+ | Things |
65
+ | broccoli |
66
+ | carrots |
67
+ FEATURE
68
+
69
+ it "outputs each undefined step" do
70
+ expect(@out.string).to include "UUUU\n"
71
+ end
72
+
73
+ it "has 4 undefined scenarios" do
74
+ expect(@out.string).to include "4 scenarios (4 undefined)"
75
+ end
76
+
77
+ it "has 4 undefined steps" do
78
+ expect(@out.string).to include "4 steps (4 undefined)"
79
+ end
80
+
81
+ end
82
+
83
+ describe "with hooks" do
84
+
85
+ describe "all hook passes" do
86
+ define_feature <<-FEATURE
87
+ Feature:
88
+ Scenario:
89
+ Given this step passes
90
+ FEATURE
91
+
92
+ define_steps do
93
+ Before do
94
+ end
95
+ AfterStep do
96
+ end
97
+ After do
98
+ end
99
+ Given(/^this step passes$/) {}
100
+ end
101
+
102
+ it "only steps generate output" do
103
+ lines = <<-OUTPUT
104
+ .
105
+ 1 scenario (1 passed)
106
+ 1 step (1 passed)
107
+ OUTPUT
108
+ lines.split("\n").each do |line|
109
+ expect(@out.string).to include line.strip
110
+ end
111
+ end
112
+ end
113
+
114
+ describe "with a failing before hook" do
115
+ define_feature <<-FEATURE
116
+ Feature:
117
+ Scenario:
118
+ Given this step passes
119
+ FEATURE
120
+
121
+ define_steps do
122
+ Before do
123
+ fail "hook failed"
124
+ end
125
+ Given(/^this step passes$/) {}
126
+ end
127
+
128
+ it "the failing hook generate output" do
129
+ lines = <<-OUTPUT
130
+ F-
131
+ 1 scenario (1 failed)
132
+ 1 step (1 skipped)
133
+ OUTPUT
134
+ lines.split("\n").each do |line|
135
+ expect(@out.string).to include line.strip
136
+ end
137
+ end
138
+ end
139
+
140
+ describe "with a failing after hook" do
141
+ define_feature <<-FEATURE
142
+ Feature:
143
+ Scenario:
144
+ Given this step passes
145
+ FEATURE
146
+
147
+ define_steps do
148
+ After do
149
+ fail "hook failed"
150
+ end
151
+ Given(/^this step passes$/) {}
152
+ end
153
+
154
+ it "the failing hook generate output" do
155
+ lines = <<-OUTPUT
156
+ .F
157
+ 1 scenario (1 failed)
158
+ 1 step (1 passed)
159
+ OUTPUT
160
+ lines.split("\n").each do |line|
161
+ expect(@out.string).to include line.strip
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,91 @@
1
+ require 'cucumber/formatter/rerun'
2
+ require 'cucumber/core'
3
+ require 'cucumber/core/gherkin/writer'
4
+ require 'cucumber/core/filter'
5
+ require 'support/standard_step_actions'
6
+
7
+ module Cucumber::Formatter
8
+ describe Rerun do
9
+ include Cucumber::Core::Gherkin::Writer
10
+ include Cucumber::Core
11
+
12
+ # after_test_case
13
+ context 'when 2 scenarios fail in the same file' do
14
+ it 'Prints the locations of the failed scenarios' do
15
+ gherkin = gherkin('foo.feature') do
16
+ feature do
17
+ scenario do
18
+ step 'failing'
19
+ end
20
+
21
+ scenario do
22
+ step 'failing'
23
+ end
24
+
25
+ scenario do
26
+ step 'passing'
27
+ end
28
+ end
29
+ end
30
+ io = StringIO.new
31
+ report = Rerun.new(double, io, {})
32
+
33
+ execute [gherkin], report, [StandardStepActions.new]
34
+
35
+ expect( io.string ).to eq 'foo.feature:3:6'
36
+ end
37
+ end
38
+
39
+ context 'with failures in multiple files' do
40
+ it 'prints the location of the failed scenarios in each file' do
41
+ foo = gherkin('foo.feature') do
42
+ feature do
43
+ scenario do
44
+ step 'failing'
45
+ end
46
+
47
+ scenario do
48
+ step 'failing'
49
+ end
50
+
51
+ scenario do
52
+ step 'passing'
53
+ end
54
+ end
55
+ end
56
+
57
+ bar = gherkin('bar.feature') do
58
+ feature do
59
+ scenario do
60
+ step 'failing'
61
+ end
62
+ end
63
+ end
64
+
65
+ io = StringIO.new
66
+ report = Rerun.new(double, io, {})
67
+
68
+ execute [foo, bar], report, [StandardStepActions.new]
69
+
70
+ expect(io.string).to eq 'foo.feature:3:6 bar.feature:3'
71
+ end
72
+ end
73
+
74
+ context 'when there are no failing scenarios' do
75
+ it 'prints nothing' do
76
+ gherkin = gherkin('foo.feature') do
77
+ feature do
78
+ scenario do
79
+ step 'passing'
80
+ end
81
+ end
82
+ end
83
+
84
+ io = StringIO.new
85
+ report = Rerun.new(double, io, {})
86
+
87
+ execute [gherkin], report, [StandardStepActions.new]
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,82 @@
1
+ module Cucumber
2
+ module Formatter
3
+ module SpecHelperDsl
4
+ attr_reader :feature_content, :step_defs, :feature_filename
5
+
6
+ def define_feature(string, feature_file = 'spec.feature')
7
+ @feature_content = string
8
+ @feature_filename = feature_file
9
+ end
10
+
11
+ def define_steps(&block)
12
+ @step_defs = block
13
+ end
14
+ end
15
+
16
+ require 'cucumber/core'
17
+ module SpecHelper
18
+ include Core
19
+
20
+ def run_defined_feature
21
+ define_steps
22
+ actual_runtime.visitor = report
23
+
24
+ receiver = Test::Runner.new(report)
25
+ filters = [
26
+ Filters::ActivateSteps.new(
27
+ StepMatchSearch.new(actual_runtime.support_code.ruby.method(:step_matches), actual_runtime.configuration),
28
+ actual_runtime.configuration
29
+ ),
30
+ Filters::ApplyAfterStepHooks.new(actual_runtime.support_code),
31
+ Filters::ApplyBeforeHooks.new(actual_runtime.support_code),
32
+ Filters::ApplyAfterHooks.new(actual_runtime.support_code),
33
+ Filters::ApplyAroundHooks.new(actual_runtime.support_code),
34
+ Filters::PrepareWorld.new(actual_runtime)
35
+ ]
36
+ compile [gherkin_doc], receiver, filters
37
+ end
38
+
39
+ require 'cucumber/formatter/event_bus_report'
40
+ def event_bus_report
41
+ @event_bus_report ||= Formatter::EventBusReport.new(actual_runtime.configuration)
42
+ end
43
+
44
+ require 'cucumber/formatter/legacy_api/adapter'
45
+ def report
46
+ @report ||= LegacyApi::Adapter.new(
47
+ Fanout.new([@formatter, event_bus_report]),
48
+ actual_runtime.results,
49
+ actual_runtime.configuration)
50
+ end
51
+
52
+ require 'cucumber/core/gherkin/document'
53
+ def gherkin_doc
54
+ Core::Gherkin::Document.new(self.class.feature_filename, gherkin)
55
+ end
56
+
57
+ def gherkin
58
+ self.class.feature_content || raise("No feature content defined!")
59
+ end
60
+
61
+ def runtime
62
+ @runtime_facade ||= LegacyApi::RuntimeFacade.new(actual_runtime.results, actual_runtime.support_code, actual_runtime.configuration)
63
+ end
64
+
65
+ def actual_runtime
66
+ @runtime ||= Runtime.new(options)
67
+ end
68
+
69
+ def define_steps
70
+ return unless step_defs = self.class.step_defs
71
+ rb = runtime.support_code.ruby
72
+ dsl = Object.new
73
+ dsl.extend RbSupport::RbDsl
74
+ dsl.instance_exec &step_defs
75
+ end
76
+
77
+ def options
78
+ {}
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,30 @@
1
+ require 'cucumber/hooks'
2
+ module Cucumber::Hooks
3
+ shared_examples_for 'a source node' do
4
+ it "responds to name" do
5
+ expect( subject.name ).to be_a(String)
6
+ end
7
+
8
+ it "responds to location" do
9
+ expect( subject.location ).to eq(location)
10
+ end
11
+
12
+ it "responds to match_locations?" do
13
+ expect( subject.match_locations? [location] ).to be_truthy
14
+ expect( subject.match_locations? [] ).to be_falsey
15
+ end
16
+ end
17
+
18
+ require 'cucumber/core/ast/location'
19
+ describe BeforeHook do
20
+ subject { BeforeHook.new(location) }
21
+ let(:location) { Cucumber::Core::Ast::Location.new('hooks.rb', 1) }
22
+ it_behaves_like 'a source node'
23
+ end
24
+
25
+ describe AfterHook do
26
+ subject { AfterHook.new(location) }
27
+ let(:location) { Cucumber::Core::Ast::Location.new('hooks.rb', 1) }
28
+ it_behaves_like 'a source node'
29
+ end
30
+ end
@@ -0,0 +1,603 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'cucumber/multiline_argument/data_table'
4
+
5
+ module Cucumber
6
+ module MultilineArgument
7
+ describe DataTable do
8
+ before do
9
+ @table = DataTable.from([
10
+ %w{one four seven},
11
+ %w{4444 55555 666666}
12
+ ])
13
+ end
14
+
15
+ it "should have rows" do
16
+ expect( @table.cells_rows[0].map{|cell| cell.value} ).to eq %w{one four seven}
17
+ end
18
+
19
+ it "should have columns" do
20
+ expect( @table.columns[1].map{|cell| cell.value} ).to eq %w{four 55555}
21
+ end
22
+
23
+ it "should have same cell objects in rows and columns" do
24
+ # 666666
25
+ expect( @table.cells_rows[1][2] ).to equal(@table.columns[2][1])
26
+ end
27
+
28
+ it "should be convertible to an array of hashes" do
29
+ expect( @table.hashes ).to eq [
30
+ {'one' => '4444', 'four' => '55555', 'seven' => '666666'}
31
+ ]
32
+ end
33
+
34
+ it "should accept symbols as keys for the hashes" do
35
+ expect( @table.hashes.first[:one] ).to eq '4444'
36
+ end
37
+
38
+ it "should return the row values in order" do
39
+ expect( @table.rows.first ).to eq %w{4444 55555 666666}
40
+ end
41
+
42
+ describe '#symbolic_hashes' do
43
+
44
+ it 'should covert data table to an array of hashes with symbols as keys' do
45
+ ast_table = Cucumber::Core::Ast::DataTable.new([['foo', 'Bar', 'Foo Bar'], %w{1 22 333}], nil)
46
+ data_table = DataTable.new(ast_table)
47
+ expect(data_table.symbolic_hashes).to eq([{:foo => '1', :bar => '22', :foo_bar => '333'}])
48
+ end
49
+
50
+ it 'should be able to be accessed multiple times' do
51
+ @table.symbolic_hashes
52
+ expect{@table.symbolic_hashes}.to_not raise_error
53
+ end
54
+
55
+ end
56
+
57
+ describe '#map_column!' do
58
+ it "should allow mapping columns" do
59
+ @table.map_column!('one') { |v| v.to_i }
60
+ expect( @table.hashes.first['one'] ).to eq 4444
61
+ end
62
+
63
+ it "applies the block once to each value" do
64
+ headers = ['header']
65
+ rows = ['value']
66
+ table = DataTable.from [headers, rows]
67
+ count = 0
68
+ table.map_column!('header') { |value| count +=1 }
69
+ table.rows
70
+ expect( count ).to eq rows.size
71
+ end
72
+
73
+ it "should allow mapping columns and take a symbol as the column name" do
74
+ @table.map_column!(:one) { |v| v.to_i }
75
+ expect( @table.hashes.first['one'] ).to eq 4444
76
+ end
77
+
78
+ it "should allow mapping columns and modify the rows as well" do
79
+ @table.map_column!(:one) { |v| v.to_i }
80
+ expect( @table.rows.first ).to include(4444)
81
+ expect( @table.rows.first ).to_not include('4444')
82
+ end
83
+
84
+ it "should pass silently if a mapped column does not exist in non-strict mode" do
85
+ expect {
86
+ @table.map_column!('two', false) { |v| v.to_i }
87
+ @table.hashes
88
+ }.not_to raise_error
89
+ end
90
+
91
+ it "should fail if a mapped column does not exist in strict mode" do
92
+ expect {
93
+ @table.map_column!('two', true) { |v| v.to_i }
94
+ @table.hashes
95
+ }.to raise_error('The column named "two" does not exist')
96
+ end
97
+
98
+ it "should return the table" do
99
+ expect( (@table.map_column!(:one) { |v| v.to_i }) ).to eq @table
100
+ end
101
+ end
102
+
103
+ describe '#map_column' do
104
+ it "should allow mapping columns" do
105
+ new_table = @table.map_column('one') { |v| v.to_i }
106
+ expect( new_table.hashes.first['one'] ).to eq 4444
107
+ end
108
+
109
+ it "applies the block once to each value" do
110
+ headers = ['header']
111
+ rows = ['value']
112
+ table = DataTable.from [headers, rows]
113
+ count = 0
114
+ new_table = table.map_column('header') { |value| count +=1 }
115
+ new_table.rows
116
+ expect( count ).to eq rows.size
117
+ end
118
+
119
+ it "should allow mapping columns and take a symbol as the column name" do
120
+ new_table = @table.map_column(:one) { |v| v.to_i }
121
+ expect( new_table.hashes.first['one'] ).to eq 4444
122
+ end
123
+
124
+ it "should allow mapping columns and modify the rows as well" do
125
+ new_table = @table.map_column(:one) { |v| v.to_i }
126
+ expect( new_table.rows.first ).to include(4444)
127
+ expect( new_table.rows.first ).to_not include('4444')
128
+ end
129
+
130
+ it "should pass silently if a mapped column does not exist in non-strict mode" do
131
+ expect {
132
+ new_table = @table.map_column('two', false) { |v| v.to_i }
133
+ new_table.hashes
134
+ }.not_to raise_error
135
+ end
136
+
137
+ it "should fail if a mapped column does not exist in strict mode" do
138
+ expect {
139
+ new_table = @table.map_column('two', true) { |v| v.to_i }
140
+ new_table.hashes
141
+ }.to raise_error('The column named "two" does not exist')
142
+ end
143
+
144
+ it "should return a new table" do
145
+ expect( (@table.map_column(:one) { |v| v.to_i }) ).to_not eq @table
146
+ end
147
+ end
148
+
149
+ describe "#match" do
150
+ before(:each) do
151
+ @table = DataTable.from([
152
+ %w{one four seven},
153
+ %w{4444 55555 666666}
154
+ ])
155
+ end
156
+
157
+ it "returns nil if headers do not match" do
158
+ expect( @table.match('does,not,match') ).to be_nil
159
+ end
160
+ it "requires a table: prefix on match" do
161
+ expect( @table.match('table:one,four,seven') ).to_not be_nil
162
+ end
163
+ it "does not match if no table: prefix on match" do
164
+ expect( @table.match('one,four,seven') ).to be_nil
165
+ end
166
+ end
167
+
168
+ describe "#transpose" do
169
+ before(:each) do
170
+ @table = DataTable.from([
171
+ %w{one 1111},
172
+ %w{two 22222}
173
+ ])
174
+ end
175
+
176
+ it "should be convertible in to an array where each row is a hash" do
177
+ expect( @table.transpose.hashes[0] ).to eq('one' => '1111', 'two' => '22222')
178
+ end
179
+ end
180
+
181
+ describe "#rows_hash" do
182
+
183
+ it "should return a hash of the rows" do
184
+ table = DataTable.from([
185
+ %w{one 1111},
186
+ %w{two 22222}
187
+ ])
188
+ expect( table.rows_hash ).to eq( 'one' => '1111', 'two' => '22222' )
189
+ end
190
+
191
+ it "should fail if the table doesn't have two columns" do
192
+ faulty_table = DataTable.from([
193
+ %w{one 1111 abc},
194
+ %w{two 22222 def}
195
+ ])
196
+ expect {
197
+ faulty_table.rows_hash
198
+ }.to raise_error('The table must have exactly 2 columns')
199
+ end
200
+
201
+ it "should support header and column mapping" do
202
+ table = DataTable.from([
203
+ %w{one 1111},
204
+ %w{two 22222}
205
+ ])
206
+ t2 = table.map_headers({ 'two' => 'Two' }) { |header| header.upcase }.
207
+ map_column('two', false) { |val| val.to_i }
208
+ expect( t2.rows_hash ).to eq( 'ONE' => '1111', 'Two' => 22222 )
209
+ end
210
+ end
211
+
212
+ describe '#map_headers!' do
213
+ let(:table) do
214
+ DataTable.from([
215
+ %w{HELLO WORLD},
216
+ %w{4444 55555}
217
+ ])
218
+ end
219
+
220
+ it "renames the columns to the specified values in the provided hash" do
221
+ @table.map_headers!('one' => :three)
222
+ expect( @table.hashes.first[:three] ).to eq '4444'
223
+ end
224
+
225
+ it "allows renaming columns using regexp" do
226
+ @table.map_headers!(/one|uno/ => :three)
227
+ expect( @table.hashes.first[:three] ).to eq '4444'
228
+ end
229
+
230
+ it "copies column mappings" do
231
+ @table.map_column!('one') { |v| v.to_i }
232
+ @table.map_headers!('one' => 'three')
233
+ expect( @table.hashes.first['three'] ).to eq 4444
234
+ end
235
+
236
+ it "takes a block and operates on all the headers with it" do
237
+ table.map_headers! do |header|
238
+ header.downcase
239
+ end
240
+ expect( table.hashes.first.keys ).to match %w[hello world]
241
+ end
242
+
243
+ it "treats the mappings in the provided hash as overrides when used with a block" do
244
+ table.map_headers!('WORLD' => 'foo') do |header|
245
+ header.downcase
246
+ end
247
+
248
+ expect( table.hashes.first.keys ).to match %w[hello foo]
249
+ end
250
+ end
251
+
252
+ describe '#map_headers' do
253
+ let(:table) do
254
+ DataTable.from([
255
+ %w{HELLO WORLD},
256
+ %w{4444 55555}
257
+ ])
258
+ end
259
+
260
+ it "renames the columns to the specified values in the provided hash" do
261
+ table2 = @table.map_headers('one' => :three)
262
+ expect( table2.hashes.first[:three] ).to eq '4444'
263
+ end
264
+
265
+ it "allows renaming columns using regexp" do
266
+ table2 = @table.map_headers(/one|uno/ => :three)
267
+ expect( table2.hashes.first[:three] ).to eq '4444'
268
+ end
269
+
270
+ it "copies column mappings" do
271
+ @table.map_column!('one') { |v| v.to_i }
272
+ table2 = @table.map_headers('one' => 'three')
273
+ expect( table2.hashes.first['three'] ).to eq 4444
274
+ end
275
+
276
+ it "takes a block and operates on all the headers with it" do
277
+ table2 = table.map_headers do |header|
278
+ header.downcase
279
+ end
280
+
281
+ expect( table2.hashes.first.keys ).to match %w[hello world]
282
+ end
283
+
284
+ it "treats the mappings in the provided hash as overrides when used with a block" do
285
+ table2 = table.map_headers('WORLD' => 'foo') do |header|
286
+ header.downcase
287
+ end
288
+
289
+ expect( table2.hashes.first.keys ).to match %w[hello foo]
290
+ end
291
+ end
292
+
293
+ describe "diff!" do
294
+ it "should detect a complex diff" do
295
+ t1 = DataTable.from(%{
296
+ | 1 | 22 | 333 | 4444 |
297
+ | 55555 | 666666 | 7777777 | 88888888 |
298
+ | 999999999 | 0000000000 | 01010101010 | 121212121212 |
299
+ | 4000 | ABC | DEF | 50000 |
300
+ })
301
+
302
+ t2 = DataTable.from(%{
303
+ | a | 4444 | 1 |
304
+ | bb | 88888888 | 55555 |
305
+ | ccc | xxxxxxxx | 999999999 |
306
+ | dddd | 4000 | 300 |
307
+ | e | 50000 | 4000 |
308
+ })
309
+ expect { t1.diff!(t2) }.to raise_error
310
+ expect( t1.to_s(:indent => 12, :color => false) ).to eq %{
311
+ | 1 | (-) 22 | (-) 333 | 4444 | (+) a |
312
+ | 55555 | (-) 666666 | (-) 7777777 | 88888888 | (+) bb |
313
+ | (-) 999999999 | (-) 0000000000 | (-) 01010101010 | (-) 121212121212 | (+) |
314
+ | (+) 999999999 | (+) | (+) | (+) xxxxxxxx | (+) ccc |
315
+ | (+) 300 | (+) | (+) | (+) 4000 | (+) dddd |
316
+ | 4000 | (-) ABC | (-) DEF | 50000 | (+) e |
317
+ }
318
+ end
319
+
320
+ it "should not change table when diffed with identical" do
321
+ t = DataTable.from(%{
322
+ |a|b|c|
323
+ |d|e|f|
324
+ |g|h|i|
325
+ })
326
+ t.diff!(t.dup)
327
+ expect( t.to_s(:indent => 12, :color => false) ).to eq %{
328
+ | a | b | c |
329
+ | d | e | f |
330
+ | g | h | i |
331
+ }
332
+ end
333
+
334
+ context "in case of duplicate header values" do
335
+ it "raises no error for two identical tables" do
336
+ t = DataTable.from(%{
337
+ |a|a|c|
338
+ |d|e|f|
339
+ |g|h|i|
340
+ })
341
+ t.diff!(t.dup)
342
+ expect( t.to_s(:indent => 12, :color => false) ).to eq %{
343
+ | a | a | c |
344
+ | d | e | f |
345
+ | g | h | i |
346
+ }
347
+ end
348
+
349
+ it "detects a diff in one cell" do
350
+ t1 = DataTable.from(%{
351
+ |a|a|c|
352
+ |d|e|f|
353
+ |g|h|i|
354
+ })
355
+ t2 = DataTable.from(%{
356
+ |a|a|c|
357
+ |d|oops|f|
358
+ |g|h|i|
359
+ })
360
+ expect{ t1.diff!(t2) }.to raise_error
361
+ expect( t1.to_s(:indent => 12, :color => false) ).to eq %{
362
+ | a | a | c |
363
+ | (-) d | (-) e | (-) f |
364
+ | (+) d | (+) oops | (+) f |
365
+ | g | h | i |
366
+ }
367
+ end
368
+
369
+ it "detects missing columns" do
370
+ t1 = DataTable.from(%{
371
+ |a|a|b|c|
372
+ |d|d|e|f|
373
+ |g|g|h|i|
374
+ })
375
+ t2 = DataTable.from(%{
376
+ |a|b|c|
377
+ |d|e|f|
378
+ |g|h|i|
379
+ })
380
+ expect{ t1.diff!(t2) }.to raise_error
381
+ expect( t1.to_s(:indent => 12, :color => false) ).to eq %{
382
+ | a | (-) a | b | c |
383
+ | d | (-) d | e | f |
384
+ | g | (-) g | h | i |
385
+ }
386
+ end
387
+
388
+ it "detects surplus columns" do
389
+ t1 = DataTable.from(%{
390
+ |a|b|c|
391
+ |d|e|f|
392
+ |g|h|i|
393
+ })
394
+ t2 = DataTable.from(%{
395
+ |a|b|a|c|
396
+ |d|e|d|f|
397
+ |g|h|g|i|
398
+ })
399
+ expect{ t1.diff!(t2, :surplus_col => true) }.to raise_error
400
+ expect( t1.to_s(:indent => 12, :color => false) ).to eq %{
401
+ | a | b | c | (+) a |
402
+ | d | e | f | (+) d |
403
+ | g | h | i | (+) g |
404
+ }
405
+ end
406
+ end
407
+
408
+ it "should inspect missing and surplus cells" do
409
+ t1 = DataTable.from([
410
+ ['name', 'male', 'lastname', 'swedish'],
411
+ ['aslak', 'true', 'hellesøy', 'false']
412
+ ])
413
+ t2 = DataTable.from([
414
+ ['name', 'male', 'lastname', 'swedish'],
415
+ ['aslak', true, 'hellesøy', false]
416
+ ])
417
+ expect { t1.diff!(t2) }.to raise_error
418
+
419
+ expect( t1.to_s(:indent => 12, :color => false) ).to eq %{
420
+ | name | male | lastname | swedish |
421
+ | (-) aslak | (-) (i) "true" | (-) hellesøy | (-) (i) "false" |
422
+ | (+) aslak | (+) (i) true | (+) hellesøy | (+) (i) false |
423
+ }
424
+ end
425
+
426
+ it "should allow column mapping of target before diffing" do
427
+ t1 = DataTable.from([
428
+ ['name', 'male'],
429
+ ['aslak', 'true']
430
+ ])
431
+ t1.map_column!('male') { |m| m == 'true' }
432
+ t2 = DataTable.from([
433
+ ['name', 'male'],
434
+ ['aslak', true]
435
+ ])
436
+ t1.diff!(t2)
437
+ expect( t1.to_s(:indent => 12, :color => false) ).to eq %{
438
+ | name | male |
439
+ | aslak | true |
440
+ }
441
+ end
442
+
443
+ it "should allow column mapping of argument before diffing" do
444
+ t1 = DataTable.from([
445
+ ['name', 'male'],
446
+ ['aslak', true]
447
+ ])
448
+ t1.map_column!('male') {
449
+ 'true'
450
+ }
451
+ t2 = DataTable.from([
452
+ ['name', 'male'],
453
+ ['aslak', 'true']
454
+ ])
455
+ t2.diff!(t1)
456
+ expect( t1.to_s(:indent => 12, :color => false) ).to eq %{
457
+ | name | male |
458
+ | aslak | true |
459
+ }
460
+ end
461
+
462
+ it "should allow header mapping before diffing" do
463
+ t1 = DataTable.from([
464
+ ['Name', 'Male'],
465
+ ['aslak', 'true']
466
+ ])
467
+ t1.map_headers!('Name' => 'name', 'Male' => 'male')
468
+ t1.map_column!('male') { |m| m == 'true' }
469
+ t2 = DataTable.from([
470
+ ['name', 'male'],
471
+ ['aslak', true]
472
+ ])
473
+ t1.diff!(t2)
474
+ expect( t1.to_s(:indent => 12, :color => false) ).to eq %{
475
+ | name | male |
476
+ | aslak | true |
477
+ }
478
+ end
479
+
480
+ it "should detect seemingly identical tables as different" do
481
+ t1 = DataTable.from([
482
+ ['X', 'Y'],
483
+ ['2', '1']
484
+ ])
485
+ t2 = DataTable.from([
486
+ ['X', 'Y'],
487
+ [2, 1]
488
+ ])
489
+ expect { t1.diff!(t2) }.to raise_error
490
+ expect( t1.to_s(:indent => 12, :color => false) ).to eq %{
491
+ | X | Y |
492
+ | (-) (i) "2" | (-) (i) "1" |
493
+ | (+) (i) 2 | (+) (i) 1 |
494
+ }
495
+ end
496
+
497
+ it "should not allow mappings that match more than 1 column" do
498
+ t1 = DataTable.from([
499
+ ['Cuke', 'Duke'],
500
+ ['Foo', 'Bar']
501
+ ])
502
+ expect do
503
+ t1.map_headers!(/uk/ => 'u')
504
+ t1.hashes
505
+ end.to raise_error(%{2 headers matched /uk/: ["Cuke", "Duke"]})
506
+ end
507
+
508
+ describe "raising" do
509
+ before do
510
+ @t = DataTable.from(%{
511
+ | a | b |
512
+ | c | d |
513
+ })
514
+ expect( @t ).not_to eq nil
515
+ end
516
+
517
+ it "should raise on missing rows" do
518
+ t = DataTable.from(%{
519
+ | a | b |
520
+ })
521
+ expect( lambda { @t.dup.diff!(t) } ).to raise_error
522
+ expect { @t.dup.diff!(t, :missing_row => false) }.not_to raise_error
523
+ end
524
+
525
+ it "should not raise on surplus rows when surplus is at the end" do
526
+ t = DataTable.from(%{
527
+ | a | b |
528
+ | c | d |
529
+ | e | f |
530
+ })
531
+ expect { @t.dup.diff!(t) }.to raise_error
532
+ expect { @t.dup.diff!(t, :surplus_row => false) }.not_to raise_error
533
+ end
534
+
535
+ it "should not raise on surplus rows when surplus is interleaved" do
536
+ t1 = DataTable.from(%{
537
+ | row_1 | row_2 |
538
+ | four | 4 |
539
+ })
540
+ t2 = DataTable.from(%{
541
+ | row_1 | row_2 |
542
+ | one | 1 |
543
+ | two | 2 |
544
+ | three | 3 |
545
+ | four | 4 |
546
+ | five | 5 |
547
+ })
548
+ expect { t1.dup.diff!(t2) }.to raise_error
549
+
550
+ expect { t1.dup.diff!(t2, :surplus_row => false) }.not_to raise_error
551
+ end
552
+
553
+ it "should raise on missing columns" do
554
+ t = DataTable.from(%{
555
+ | a |
556
+ | c |
557
+ })
558
+ expect { @t.dup.diff!(t) }.to raise_error
559
+ expect { @t.dup.diff!(t, :missing_col => false) }.not_to raise_error
560
+ end
561
+
562
+ it "should not raise on surplus columns" do
563
+ t = DataTable.from(%{
564
+ | a | b | x |
565
+ | c | d | y |
566
+ })
567
+ expect { @t.dup.diff!(t) }.not_to raise_error
568
+ expect { @t.dup.diff!(t, :surplus_col => true) }.to raise_error
569
+ end
570
+
571
+ it "should not raise on misplaced columns" do
572
+ t = DataTable.from(%{
573
+ | b | a |
574
+ | d | c |
575
+ })
576
+ expect { @t.dup.diff!(t) }.not_to raise_error
577
+ expect { @t.dup.diff!(t, :misplaced_col => true) }.to raise_error
578
+ end
579
+ end
580
+
581
+ it "can compare to an Array" do
582
+ t = DataTable.from(%{
583
+ | b | a |
584
+ | d | c |
585
+ })
586
+ other = [ %w{b a}, %w{d c} ]
587
+
588
+ expect { t.diff!(other) }.not_to raise_error
589
+ end
590
+ end
591
+
592
+ describe "#from" do
593
+ it "should allow Array of Hash" do
594
+ t1 = DataTable.from([{'name' => 'aslak', 'male' => 'true'}])
595
+ expect( t1.to_s(:indent => 12, :color => false) ).to eq %{
596
+ | male | name |
597
+ | true | aslak |
598
+ }
599
+ end
600
+ end
601
+ end
602
+ end
603
+ end