kbaum-cucumber 0.4.5.pre

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 (511) hide show
  1. data/.gitattributes +1 -0
  2. data/.gitignore +18 -0
  3. data/Caliper.yml +5 -0
  4. data/History.txt +1292 -0
  5. data/LICENSE +22 -0
  6. data/README.rdoc +26 -0
  7. data/Rakefile +63 -0
  8. data/VERSION.yml +5 -0
  9. data/bin/cucumber +16 -0
  10. data/cucumber.gemspec +741 -0
  11. data/cucumber.yml +10 -0
  12. data/examples/dos_line_endings/Rakefile +6 -0
  13. data/examples/dos_line_endings/features/dos_line_endings.feature +9 -0
  14. data/examples/i18n/README.textile +18 -0
  15. data/examples/i18n/Rakefile +32 -0
  16. data/examples/i18n/ar/Rakefile +6 -0
  17. data/examples/i18n/ar/features/addition.feature +17 -0
  18. data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +24 -0
  19. data/examples/i18n/ar/lib/calculator.rb +11 -0
  20. data/examples/i18n/bg/Rakefile +6 -0
  21. data/examples/i18n/bg/features/addition.feature +12 -0
  22. data/examples/i18n/bg/features/consecutive_calculations.feature +19 -0
  23. data/examples/i18n/bg/features/division.feature +17 -0
  24. data/examples/i18n/bg/features/step_definitons/calculator_steps.rb +24 -0
  25. data/examples/i18n/bg/features/support/env.rb +6 -0
  26. data/examples/i18n/bg/features/support/world.rb +8 -0
  27. data/examples/i18n/bg/lib/calculator.rb +24 -0
  28. data/examples/i18n/cat/Rakefile +6 -0
  29. data/examples/i18n/cat/features/step_definitons/calculator_steps.rb +21 -0
  30. data/examples/i18n/cat/features/suma.feature +17 -0
  31. data/examples/i18n/cat/lib/calculadora.rb +16 -0
  32. data/examples/i18n/da/Rakefile +6 -0
  33. data/examples/i18n/da/features/sammenlaegning.feature +18 -0
  34. data/examples/i18n/da/features/step_definitons/lommeregner_steps.rb +24 -0
  35. data/examples/i18n/da/lib/lommeregner.rb +11 -0
  36. data/examples/i18n/de/.gitignore +1 -0
  37. data/examples/i18n/de/Rakefile +6 -0
  38. data/examples/i18n/de/features/addition.feature +17 -0
  39. data/examples/i18n/de/features/division.feature +10 -0
  40. data/examples/i18n/de/features/step_definitons/calculator_steps.rb +24 -0
  41. data/examples/i18n/de/lib/calculator.rb +14 -0
  42. data/examples/i18n/en-lol/Rakefile +4 -0
  43. data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +16 -0
  44. data/examples/i18n/en-lol/features/stuffing.feature +8 -0
  45. data/examples/i18n/en-lol/features/support/env.rb +8 -0
  46. data/examples/i18n/en-lol/lib/basket.rb +12 -0
  47. data/examples/i18n/en-lol/lib/belly.rb +11 -0
  48. data/examples/i18n/en/.gitignore +1 -0
  49. data/examples/i18n/en/Rakefile +6 -0
  50. data/examples/i18n/en/features/addition.feature +17 -0
  51. data/examples/i18n/en/features/division.feature +10 -0
  52. data/examples/i18n/en/features/step_definitons/calculator_steps.rb +24 -0
  53. data/examples/i18n/en/lib/calculator.rb +14 -0
  54. data/examples/i18n/es/Rakefile +6 -0
  55. data/examples/i18n/es/features/adicion.feature +17 -0
  56. data/examples/i18n/es/features/step_definitons/calculador_steps.rb +21 -0
  57. data/examples/i18n/es/lib/calculador.rb +14 -0
  58. data/examples/i18n/et/Rakefile +6 -0
  59. data/examples/i18n/et/features/jagamine.feature +10 -0
  60. data/examples/i18n/et/features/liitmine.feature +17 -0
  61. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +24 -0
  62. data/examples/i18n/et/lib/kalkulaator.rb +14 -0
  63. data/examples/i18n/fi/.gitignore +1 -0
  64. data/examples/i18n/fi/Rakefile +6 -0
  65. data/examples/i18n/fi/features/jakolasku.feature +10 -0
  66. data/examples/i18n/fi/features/step_definitons/laskin_steps.rb +24 -0
  67. data/examples/i18n/fi/features/yhteenlasku.feature +17 -0
  68. data/examples/i18n/fi/lib/laskin.rb +14 -0
  69. data/examples/i18n/fr/Rakefile +6 -0
  70. data/examples/i18n/fr/features/addition.feature +18 -0
  71. data/examples/i18n/fr/features/addition2.feature +17 -0
  72. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +38 -0
  73. data/examples/i18n/fr/lib/calculatrice.rb +10 -0
  74. data/examples/i18n/he/Rakefile +6 -0
  75. data/examples/i18n/he/features/addition.feature +17 -0
  76. data/examples/i18n/he/features/division.feature +10 -0
  77. data/examples/i18n/he/features/step_definitons/calculator_steps.rb +24 -0
  78. data/examples/i18n/he/lib/calculator.rb +14 -0
  79. data/examples/i18n/hu/.gitignore +1 -0
  80. data/examples/i18n/hu/Rakefile +6 -0
  81. data/examples/i18n/hu/features/addition.feature +17 -0
  82. data/examples/i18n/hu/features/division.feature +10 -0
  83. data/examples/i18n/hu/features/step_definitons/calculator_steps.rb +25 -0
  84. data/examples/i18n/hu/lib/calculator.rb +14 -0
  85. data/examples/i18n/id/.gitignore +1 -0
  86. data/examples/i18n/id/Rakefile +6 -0
  87. data/examples/i18n/id/features/addition.feature +17 -0
  88. data/examples/i18n/id/features/division.feature +10 -0
  89. data/examples/i18n/id/features/step_definitons/calculator_steps.rb +24 -0
  90. data/examples/i18n/id/lib/calculator.rb +14 -0
  91. data/examples/i18n/it/Rakefile +6 -0
  92. data/examples/i18n/it/features/somma.feature +11 -0
  93. data/examples/i18n/it/features/step_definitons/calcolatrice_steps.rb +24 -0
  94. data/examples/i18n/it/lib/calcolatrice.rb +11 -0
  95. data/examples/i18n/ja/.gitignore +1 -0
  96. data/examples/i18n/ja/Rakefile +6 -0
  97. data/examples/i18n/ja/features/addition.feature +17 -0
  98. data/examples/i18n/ja/features/division.feature +10 -0
  99. data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +24 -0
  100. data/examples/i18n/ja/lib/calculator.rb +14 -0
  101. data/examples/i18n/ko/.gitignore +1 -0
  102. data/examples/i18n/ko/Rakefile +6 -0
  103. data/examples/i18n/ko/features/addition.feature +17 -0
  104. data/examples/i18n/ko/features/division.feature +11 -0
  105. data/examples/i18n/ko/features/step_definitons/calculator_steps.rb +24 -0
  106. data/examples/i18n/ko/lib/calculator.rb +14 -0
  107. data/examples/i18n/lt/.gitignore +1 -0
  108. data/examples/i18n/lt/Rakefile +6 -0
  109. data/examples/i18n/lt/features/addition.feature +17 -0
  110. data/examples/i18n/lt/features/division.feature +10 -0
  111. data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +24 -0
  112. data/examples/i18n/lt/lib/calculator.rb +14 -0
  113. data/examples/i18n/lv/Rakefile +6 -0
  114. data/examples/i18n/lv/features/addition.feature +17 -0
  115. data/examples/i18n/lv/features/division.feature +10 -0
  116. data/examples/i18n/lv/features/step_definitons/calculator_steps.rb +24 -0
  117. data/examples/i18n/lv/lib/calculator.rb +14 -0
  118. data/examples/i18n/no/Rakefile +6 -0
  119. data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +17 -0
  120. data/examples/i18n/no/features/summering.feature +19 -0
  121. data/examples/i18n/no/features/support/env.rb +6 -0
  122. data/examples/i18n/no/lib/kalkulator.rb +11 -0
  123. data/examples/i18n/pl/.gitignore +1 -0
  124. data/examples/i18n/pl/Rakefile +6 -0
  125. data/examples/i18n/pl/features/addition.feature +17 -0
  126. data/examples/i18n/pl/features/division.feature +10 -0
  127. data/examples/i18n/pl/features/step_definitons/calculator_steps.rb +24 -0
  128. data/examples/i18n/pl/features/support/env.rb +6 -0
  129. data/examples/i18n/pl/lib/calculator.rb +14 -0
  130. data/examples/i18n/pt/Rakefile +6 -0
  131. data/examples/i18n/pt/features/adicao.feature +11 -0
  132. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +20 -0
  133. data/examples/i18n/pt/features/support/env.rb +6 -0
  134. data/examples/i18n/pt/lib/calculadora.rb +10 -0
  135. data/examples/i18n/ro/Rakefile +6 -0
  136. data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +24 -0
  137. data/examples/i18n/ro/features/suma.feature +11 -0
  138. data/examples/i18n/ro/lib/calculator.rb +11 -0
  139. data/examples/i18n/ru/Rakefile +6 -0
  140. data/examples/i18n/ru/features/addition.feature +11 -0
  141. data/examples/i18n/ru/features/consecutive_calculations.feature +17 -0
  142. data/examples/i18n/ru/features/division.feature +16 -0
  143. data/examples/i18n/ru/features/step_definitons/calculator_steps.rb +19 -0
  144. data/examples/i18n/ru/features/support/env.rb +6 -0
  145. data/examples/i18n/ru/features/support/world.rb +8 -0
  146. data/examples/i18n/ru/lib/calculator.rb +24 -0
  147. data/examples/i18n/se/Rakefile +6 -0
  148. data/examples/i18n/se/features/step_definitons/kalkulator_steps.rb +24 -0
  149. data/examples/i18n/se/features/summering.feature +18 -0
  150. data/examples/i18n/se/lib/kalkulator.rb +11 -0
  151. data/examples/i18n/sk/.gitignore +1 -0
  152. data/examples/i18n/sk/Rakefile +6 -0
  153. data/examples/i18n/sk/features/addition.feature +17 -0
  154. data/examples/i18n/sk/features/division.feature +10 -0
  155. data/examples/i18n/sk/features/step_definitons/calculator_steps.rb +24 -0
  156. data/examples/i18n/sk/lib/calculator.rb +14 -0
  157. data/examples/i18n/sr-latn/Rakefile +6 -0
  158. data/examples/i18n/sr-latn/features/sabiranje.feature +18 -0
  159. data/examples/i18n/sr-latn/features/step_definitons/calculator_steps.rb +24 -0
  160. data/examples/i18n/sr-latn/lib/calculator.rb +12 -0
  161. data/examples/i18n/sr/Rakefile +6 -0
  162. data/examples/i18n/sr/features/sabiranje.feature +18 -0
  163. data/examples/i18n/sr/features/step_definitons/calculator_steps.rb +24 -0
  164. data/examples/i18n/sr/lib/calculator.rb +12 -0
  165. data/examples/i18n/tr/.gitignore +1 -0
  166. data/examples/i18n/tr/Rakefile +6 -0
  167. data/examples/i18n/tr/features/bolme.feature +10 -0
  168. data/examples/i18n/tr/features/step_definitons/hesap_makinesi_adimlari.rb +24 -0
  169. data/examples/i18n/tr/features/toplama.feature +18 -0
  170. data/examples/i18n/tr/lib/hesap_makinesi.rb +15 -0
  171. data/examples/i18n/uz/Rakefile +6 -0
  172. data/examples/i18n/uz/features/addition.feature +10 -0
  173. data/examples/i18n/uz/features/consecutive_calculations.feature +17 -0
  174. data/examples/i18n/uz/features/division.feature +17 -0
  175. data/examples/i18n/uz/features/step_definitons/calculator_steps.rb +19 -0
  176. data/examples/i18n/uz/features/support/env.rb +6 -0
  177. data/examples/i18n/uz/features/support/world.rb +8 -0
  178. data/examples/i18n/uz/lib/calculator.rb +24 -0
  179. data/examples/i18n/zh-CN/Rakefile +4 -0
  180. data/examples/i18n/zh-CN/features/addition.feature +18 -0
  181. data/examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb +26 -0
  182. data/examples/i18n/zh-CN/lib/calculator.rb +10 -0
  183. data/examples/i18n/zh-TW/.gitignore +1 -0
  184. data/examples/i18n/zh-TW/Rakefile +4 -0
  185. data/examples/i18n/zh-TW/features/addition.feature +17 -0
  186. data/examples/i18n/zh-TW/features/division.feature +11 -0
  187. data/examples/i18n/zh-TW/features/step_definitons/calculator_steps.rb +24 -0
  188. data/examples/i18n/zh-TW/lib/calculator.rb +14 -0
  189. data/examples/junit/features/one_passing_one_failing.feature +8 -0
  190. data/examples/junit/features/pending.feature +5 -0
  191. data/examples/junit/features/step_definitions/steps.rb +11 -0
  192. data/examples/python/features/fibonacci.feature +19 -0
  193. data/examples/python/features/step_definitions/fib_steps.py +11 -0
  194. data/examples/python/lib/.gitignore +1 -0
  195. data/examples/python/lib/fib.py +7 -0
  196. data/examples/ramaze/README.textile +7 -0
  197. data/examples/ramaze/Rakefile +6 -0
  198. data/examples/ramaze/app.rb +21 -0
  199. data/examples/ramaze/features/add.feature +11 -0
  200. data/examples/ramaze/features/step_definitions/add_steps.rb +15 -0
  201. data/examples/ramaze/features/support/env.rb +32 -0
  202. data/examples/ramaze/layout/default.html.erb +8 -0
  203. data/examples/ramaze/view/index.html.erb +5 -0
  204. data/examples/ruby2python/features/fibonacci.feature +19 -0
  205. data/examples/ruby2python/features/step_definitions/fib_steps.rb +7 -0
  206. data/examples/ruby2python/features/support/env.rb +21 -0
  207. data/examples/ruby2python/lib/.gitignore +1 -0
  208. data/examples/ruby2python/lib/fib.py +7 -0
  209. data/examples/selenium/Rakefile +6 -0
  210. data/examples/selenium/features/search.feature +9 -0
  211. data/examples/selenium/features/step_definitons/search_steps.rb +13 -0
  212. data/examples/selenium/features/support/env.rb +19 -0
  213. data/examples/selenium_webrat/Rakefile +6 -0
  214. data/examples/selenium_webrat/config.ru +0 -0
  215. data/examples/selenium_webrat/features/search.feature +9 -0
  216. data/examples/selenium_webrat/features/step_definitons/search_steps.rb +13 -0
  217. data/examples/selenium_webrat/features/support/env.rb +45 -0
  218. data/examples/self_test/.gitignore +1 -0
  219. data/examples/self_test/README.textile +6 -0
  220. data/examples/self_test/Rakefile +6 -0
  221. data/examples/self_test/features/background/background_tagged_before_on_outline.feature +12 -0
  222. data/examples/self_test/features/background/background_with_name.feature +7 -0
  223. data/examples/self_test/features/background/failing_background.feature +12 -0
  224. data/examples/self_test/features/background/failing_background_after_success.feature +11 -0
  225. data/examples/self_test/features/background/multiline_args_background.feature +32 -0
  226. data/examples/self_test/features/background/passing_background.feature +10 -0
  227. data/examples/self_test/features/background/pending_background.feature +10 -0
  228. data/examples/self_test/features/background/scenario_outline_failing_background.feature +16 -0
  229. data/examples/self_test/features/background/scenario_outline_passing_background.feature +16 -0
  230. data/examples/self_test/features/call_undefined_step_from_step_def.feature +7 -0
  231. data/examples/self_test/features/failing_expectation.feature +4 -0
  232. data/examples/self_test/features/lots_of_undefined.feature +8 -0
  233. data/examples/self_test/features/multiline_name.feature +27 -0
  234. data/examples/self_test/features/outline_sample.feature +15 -0
  235. data/examples/self_test/features/sample.feature +21 -0
  236. data/examples/self_test/features/search_sample.feature +32 -0
  237. data/examples/self_test/features/step_definitions/sample_steps.rb +81 -0
  238. data/examples/self_test/features/support/env.rb +18 -0
  239. data/examples/self_test/features/tags_sample.feature +17 -0
  240. data/examples/self_test/features/tons_of_cukes.feature +52 -0
  241. data/examples/self_test/features/undefined_multiline_args.feature +12 -0
  242. data/examples/self_test/list-of-features.txt +1 -0
  243. data/examples/sinatra/README.textile +13 -0
  244. data/examples/sinatra/Rakefile +6 -0
  245. data/examples/sinatra/app.rb +14 -0
  246. data/examples/sinatra/features/add.feature +11 -0
  247. data/examples/sinatra/features/step_definitions/add_steps.rb +15 -0
  248. data/examples/sinatra/features/support/env.rb +30 -0
  249. data/examples/sinatra/views/add.erb +5 -0
  250. data/examples/sinatra/views/layout.erb +8 -0
  251. data/examples/steps_library/features/step_definitions/steps_lib1.rb +8 -0
  252. data/examples/steps_library/features/step_definitions/steps_lib2.rb +8 -0
  253. data/examples/tcl/README.textile +11 -0
  254. data/examples/tcl/Rakefile +6 -0
  255. data/examples/tcl/features/fibonnacci.feature +17 -0
  256. data/examples/tcl/features/step_definitions/fib_steps.rb +7 -0
  257. data/examples/tcl/features/support/env.rb +6 -0
  258. data/examples/tcl/src/fib.tcl +3 -0
  259. data/examples/test_unit/Rakefile +6 -0
  260. data/examples/test_unit/features/step_definitions/test_unit_steps.rb +23 -0
  261. data/examples/test_unit/features/test_unit.feature +9 -0
  262. data/examples/tickets/Rakefile +20 -0
  263. data/examples/tickets/features.html +138 -0
  264. data/examples/tickets/features/172.feature +28 -0
  265. data/examples/tickets/features/177/1.feature +28 -0
  266. data/examples/tickets/features/177/2.feature +20 -0
  267. data/examples/tickets/features/177/3.feature +18 -0
  268. data/examples/tickets/features/180.feature +7 -0
  269. data/examples/tickets/features/229/tagged_hooks.feature +8 -0
  270. data/examples/tickets/features/229/tagged_hooks.rb +14 -0
  271. data/examples/tickets/features/236.feature +13 -0
  272. data/examples/tickets/features/241.feature +12 -0
  273. data/examples/tickets/features/246.feature +4 -0
  274. data/examples/tickets/features/248.feature +11 -0
  275. data/examples/tickets/features/270/back.feature +14 -0
  276. data/examples/tickets/features/270/back.steps.rb +14 -0
  277. data/examples/tickets/features/272/hooks.feature +26 -0
  278. data/examples/tickets/features/272/hooks_steps.rb +53 -0
  279. data/examples/tickets/features/279/py_string_indent.feature +25 -0
  280. data/examples/tickets/features/279/py_string_indent.steps.rb +12 -0
  281. data/examples/tickets/features/279/wrong.feature_ +11 -0
  282. data/examples/tickets/features/301/filter_background_tagged_hooks.feature +6 -0
  283. data/examples/tickets/features/301/filter_background_tagged_hooks_steps.rb +12 -0
  284. data/examples/tickets/features/306/only_background.feature +4 -0
  285. data/examples/tickets/features/lib/eatting_machine.rb +18 -0
  286. data/examples/tickets/features/lib/pantry.rb +20 -0
  287. data/examples/tickets/features/scenario_outline.feature +95 -0
  288. data/examples/tickets/features/step_definitons/246_steps.rb +3 -0
  289. data/examples/tickets/features/step_definitons/248_steps.rb +15 -0
  290. data/examples/tickets/features/step_definitons/scenario_outline_steps.rb +42 -0
  291. data/examples/tickets/features/step_definitons/tickets_steps.rb +81 -0
  292. data/examples/tickets/features/table_diffing.feature +13 -0
  293. data/examples/tickets/features/tickets.feature +28 -0
  294. data/examples/watir/README.textile +16 -0
  295. data/examples/watir/Rakefile +10 -0
  296. data/examples/watir/features/search.feature +12 -0
  297. data/examples/watir/features/step_definitions/search_steps.rb +26 -0
  298. data/examples/watir/features/support/env.rb +32 -0
  299. data/examples/watir/features/support/screenshots.rb +44 -0
  300. data/examples/webrat/features/search.feature +12 -0
  301. data/examples/webrat/features/step_definitions/kvasir_steps.rb +14 -0
  302. data/examples/webrat/features/support/env.rb +17 -0
  303. data/features/announce.feature +122 -0
  304. data/features/background.feature +308 -0
  305. data/features/bug_371.feature +32 -0
  306. data/features/bug_464.feature +16 -0
  307. data/features/bug_475.feature +43 -0
  308. data/features/call_many_steps.feature +124 -0
  309. data/features/cucumber_cli.feature +654 -0
  310. data/features/cucumber_cli_diff_disabled.feature +52 -0
  311. data/features/cucumber_cli_outlines.feature +105 -0
  312. data/features/custom_formatter.feature +47 -0
  313. data/features/default_snippets.feature +42 -0
  314. data/features/drb_server_integration.feature +174 -0
  315. data/features/exception_in_after_block.feature +100 -0
  316. data/features/exception_in_after_step_block.feature +102 -0
  317. data/features/exception_in_before_block.feature +78 -0
  318. data/features/exclude_files.feature +20 -0
  319. data/features/expand.feature +60 -0
  320. data/features/html_formatter.feature +7 -0
  321. data/features/html_formatter/a.html +400 -0
  322. data/features/junit_formatter.feature +88 -0
  323. data/features/language_from_header.feature +30 -0
  324. data/features/language_help.feature +68 -0
  325. data/features/listener_debugger_formatter.feature +41 -0
  326. data/features/multiline_names.feature +43 -0
  327. data/features/negative_tagged_hooks.feature +61 -0
  328. data/features/post_configuration_hook.feature +37 -0
  329. data/features/profiles.feature +112 -0
  330. data/features/rake_task.feature +152 -0
  331. data/features/report_called_undefined_steps.feature +34 -0
  332. data/features/simplest.feature +11 -0
  333. data/features/snippet.feature +22 -0
  334. data/features/step_definitions/cucumber_steps.rb +154 -0
  335. data/features/step_definitions/extra_steps.rb +2 -0
  336. data/features/step_definitions/simplest_steps.rb +3 -0
  337. data/features/step_definitions/wire_steps.rb +14 -0
  338. data/features/support/env.rb +141 -0
  339. data/features/support/env.rb.simplest +7 -0
  340. data/features/support/fake_wire_server.rb +63 -0
  341. data/features/table_diffing.feature +45 -0
  342. data/features/table_mapping.feature +35 -0
  343. data/features/tag_logic.feature +258 -0
  344. data/features/transform.feature +245 -0
  345. data/features/unicode_table.feature +35 -0
  346. data/features/usage_and_stepdefs_formatter.feature +169 -0
  347. data/features/wire_protocol.feature +177 -0
  348. data/features/work_in_progress.feature +156 -0
  349. data/gem_tasks/contributors.rake +13 -0
  350. data/gem_tasks/environment.rake +7 -0
  351. data/gem_tasks/features.rake +18 -0
  352. data/gem_tasks/fix_cr_lf.rake +10 -0
  353. data/gem_tasks/flog.rake +4 -0
  354. data/gem_tasks/rspec.rake +15 -0
  355. data/gem_tasks/sass.rake +4 -0
  356. data/gem_tasks/sdoc.rake +12 -0
  357. data/lib/README.rdoc +12 -0
  358. data/lib/autotest/cucumber.rb +6 -0
  359. data/lib/autotest/cucumber_mixin.rb +131 -0
  360. data/lib/autotest/cucumber_rails.rb +6 -0
  361. data/lib/autotest/cucumber_rails_rspec.rb +6 -0
  362. data/lib/autotest/cucumber_rspec.rb +6 -0
  363. data/lib/autotest/discover.rb +9 -0
  364. data/lib/cucumber.rb +15 -0
  365. data/lib/cucumber/ast.rb +30 -0
  366. data/lib/cucumber/ast/background.rb +75 -0
  367. data/lib/cucumber/ast/comment.rb +31 -0
  368. data/lib/cucumber/ast/examples.rb +36 -0
  369. data/lib/cucumber/ast/feature.rb +85 -0
  370. data/lib/cucumber/ast/feature_element.rb +68 -0
  371. data/lib/cucumber/ast/features.rb +40 -0
  372. data/lib/cucumber/ast/outline_table.rb +166 -0
  373. data/lib/cucumber/ast/py_string.rb +59 -0
  374. data/lib/cucumber/ast/scenario.rb +111 -0
  375. data/lib/cucumber/ast/scenario_outline.rb +100 -0
  376. data/lib/cucumber/ast/step.rb +121 -0
  377. data/lib/cucumber/ast/step_collection.rb +76 -0
  378. data/lib/cucumber/ast/step_invocation.rb +190 -0
  379. data/lib/cucumber/ast/table.rb +655 -0
  380. data/lib/cucumber/ast/tags.rb +122 -0
  381. data/lib/cucumber/ast/tree_walker.rb +201 -0
  382. data/lib/cucumber/ast/visitor.rb +11 -0
  383. data/lib/cucumber/broadcaster.rb +13 -0
  384. data/lib/cucumber/cli/configuration.rb +180 -0
  385. data/lib/cucumber/cli/drb_client.rb +32 -0
  386. data/lib/cucumber/cli/language_help_formatter.rb +72 -0
  387. data/lib/cucumber/cli/main.rb +121 -0
  388. data/lib/cucumber/cli/options.rb +404 -0
  389. data/lib/cucumber/cli/profile_loader.rb +82 -0
  390. data/lib/cucumber/constantize.rb +34 -0
  391. data/lib/cucumber/core_ext/instance_exec.rb +98 -0
  392. data/lib/cucumber/core_ext/proc.rb +30 -0
  393. data/lib/cucumber/core_ext/string.rb +16 -0
  394. data/lib/cucumber/feature_file.rb +54 -0
  395. data/lib/cucumber/filter.rb +41 -0
  396. data/lib/cucumber/formatter/ansicolor.rb +157 -0
  397. data/lib/cucumber/formatter/color_io.rb +23 -0
  398. data/lib/cucumber/formatter/console.rb +205 -0
  399. data/lib/cucumber/formatter/cucumber.css +248 -0
  400. data/lib/cucumber/formatter/cucumber.sass +241 -0
  401. data/lib/cucumber/formatter/debug.rb +33 -0
  402. data/lib/cucumber/formatter/duration.rb +13 -0
  403. data/lib/cucumber/formatter/html.rb +545 -0
  404. data/lib/cucumber/formatter/io.rb +33 -0
  405. data/lib/cucumber/formatter/junit.rb +149 -0
  406. data/lib/cucumber/formatter/ordered_xml_markup.rb +24 -0
  407. data/lib/cucumber/formatter/pdf.rb +234 -0
  408. data/lib/cucumber/formatter/pretty.rb +237 -0
  409. data/lib/cucumber/formatter/progress.rb +75 -0
  410. data/lib/cucumber/formatter/rerun.rb +50 -0
  411. data/lib/cucumber/formatter/stepdefs.rb +14 -0
  412. data/lib/cucumber/formatter/steps.rb +49 -0
  413. data/lib/cucumber/formatter/summary.rb +35 -0
  414. data/lib/cucumber/formatter/tag_cloud.rb +34 -0
  415. data/lib/cucumber/formatter/unicode.rb +35 -0
  416. data/lib/cucumber/formatter/usage.rb +127 -0
  417. data/lib/cucumber/language_support.rb +30 -0
  418. data/lib/cucumber/language_support/language_methods.rb +110 -0
  419. data/lib/cucumber/languages.yml +535 -0
  420. data/lib/cucumber/parser.rb +8 -0
  421. data/lib/cucumber/parser/common.rb +170 -0
  422. data/lib/cucumber/parser/common.tt +21 -0
  423. data/lib/cucumber/parser/feature.rb +1783 -0
  424. data/lib/cucumber/parser/feature.tt +317 -0
  425. data/lib/cucumber/parser/i18n.tt +34 -0
  426. data/lib/cucumber/parser/natural_language.rb +108 -0
  427. data/lib/cucumber/parser/py_string.rb +276 -0
  428. data/lib/cucumber/parser/py_string.tt +45 -0
  429. data/lib/cucumber/parser/table.rb +305 -0
  430. data/lib/cucumber/parser/table.tt +60 -0
  431. data/lib/cucumber/parser/treetop_ext.rb +53 -0
  432. data/lib/cucumber/platform.rb +31 -0
  433. data/lib/cucumber/py_support/py_dsl.py +10 -0
  434. data/lib/cucumber/py_support/py_language.py +10 -0
  435. data/lib/cucumber/py_support/py_language.rb +81 -0
  436. data/lib/cucumber/rake/task.rb +166 -0
  437. data/lib/cucumber/rb_support/rb_dsl.rb +102 -0
  438. data/lib/cucumber/rb_support/rb_hook.rb +19 -0
  439. data/lib/cucumber/rb_support/rb_language.rb +179 -0
  440. data/lib/cucumber/rb_support/rb_step_definition.rb +75 -0
  441. data/lib/cucumber/rb_support/rb_transform.rb +37 -0
  442. data/lib/cucumber/rb_support/rb_world.rb +81 -0
  443. data/lib/cucumber/rb_support/regexp_argument_matcher.rb +21 -0
  444. data/lib/cucumber/rspec_neuter.rb +23 -0
  445. data/lib/cucumber/step_argument.rb +9 -0
  446. data/lib/cucumber/step_definition_light.rb +20 -0
  447. data/lib/cucumber/step_match.rb +107 -0
  448. data/lib/cucumber/step_mother.rb +350 -0
  449. data/lib/cucumber/webrat/element_locator.rb +93 -0
  450. data/lib/cucumber/webrat/table_locator.rb +1 -0
  451. data/lib/cucumber/wire_support/connection.rb +42 -0
  452. data/lib/cucumber/wire_support/request_handler.rb +19 -0
  453. data/lib/cucumber/wire_support/wire_exception.rb +10 -0
  454. data/lib/cucumber/wire_support/wire_language.rb +52 -0
  455. data/lib/cucumber/wire_support/wire_packet.rb +34 -0
  456. data/lib/cucumber/wire_support/wire_protocol.rb +64 -0
  457. data/lib/cucumber/wire_support/wire_step_definition.rb +21 -0
  458. data/spec/cucumber/ast/background_spec.rb +54 -0
  459. data/spec/cucumber/ast/feature_element_spec.rb +41 -0
  460. data/spec/cucumber/ast/feature_factory.rb +62 -0
  461. data/spec/cucumber/ast/feature_spec.rb +44 -0
  462. data/spec/cucumber/ast/outline_table_spec.rb +21 -0
  463. data/spec/cucumber/ast/py_string_spec.rb +51 -0
  464. data/spec/cucumber/ast/scenario_outline_spec.rb +73 -0
  465. data/spec/cucumber/ast/scenario_spec.rb +45 -0
  466. data/spec/cucumber/ast/step_collection_spec.rb +17 -0
  467. data/spec/cucumber/ast/step_spec.rb +66 -0
  468. data/spec/cucumber/ast/table_spec.rb +422 -0
  469. data/spec/cucumber/ast/tags_spec.rb +29 -0
  470. data/spec/cucumber/ast/tree_walker_spec.rb +11 -0
  471. data/spec/cucumber/broadcaster_spec.rb +15 -0
  472. data/spec/cucumber/cli/configuration_spec.rb +396 -0
  473. data/spec/cucumber/cli/drb_client_spec.rb +77 -0
  474. data/spec/cucumber/cli/main_spec.rb +172 -0
  475. data/spec/cucumber/cli/options_spec.rb +335 -0
  476. data/spec/cucumber/cli/profile_loader_spec.rb +10 -0
  477. data/spec/cucumber/core_ext/proc_spec.rb +68 -0
  478. data/spec/cucumber/formatter/ansicolor_spec.rb +31 -0
  479. data/spec/cucumber/formatter/color_io_spec.rb +27 -0
  480. data/spec/cucumber/formatter/console_spec.rb +20 -0
  481. data/spec/cucumber/formatter/duration_spec.rb +22 -0
  482. data/spec/cucumber/formatter/html_spec.rb +213 -0
  483. data/spec/cucumber/formatter/junit_spec.rb +110 -0
  484. data/spec/cucumber/formatter/progress_spec.rb +38 -0
  485. data/spec/cucumber/formatter/spec_helper.rb +50 -0
  486. data/spec/cucumber/parser/feature_parser_spec.rb +400 -0
  487. data/spec/cucumber/parser/table_parser_spec.rb +52 -0
  488. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +132 -0
  489. data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +18 -0
  490. data/spec/cucumber/sell_cucumbers.feature +19 -0
  491. data/spec/cucumber/step_match_spec.rb +56 -0
  492. data/spec/cucumber/step_mother_spec.rb +270 -0
  493. data/spec/cucumber/treetop_parser/empty_feature.feature +4 -0
  494. data/spec/cucumber/treetop_parser/empty_scenario.feature +9 -0
  495. data/spec/cucumber/treetop_parser/empty_scenario_outline.feature +3 -0
  496. data/spec/cucumber/treetop_parser/fit_scenario.feature +8 -0
  497. data/spec/cucumber/treetop_parser/given_scenario.feature +9 -0
  498. data/spec/cucumber/treetop_parser/invalid_scenario_outlines.feature +7 -0
  499. data/spec/cucumber/treetop_parser/multiline_steps.feature +17 -0
  500. data/spec/cucumber/treetop_parser/multiple_tables.feature +27 -0
  501. data/spec/cucumber/treetop_parser/scenario_outline.feature +16 -0
  502. data/spec/cucumber/treetop_parser/spaces.feature +12 -0
  503. data/spec/cucumber/treetop_parser/test_dos.feature +25 -0
  504. data/spec/cucumber/treetop_parser/with_comments.feature +23 -0
  505. data/spec/cucumber/treetop_parser/with_tags.feature +18 -0
  506. data/spec/cucumber/wire_support/wire_language_spec.rb +47 -0
  507. data/spec/cucumber/wire_support/wire_packet_spec.rb +26 -0
  508. data/spec/cucumber/world/pending_spec.rb +46 -0
  509. data/spec/spec.opts +4 -0
  510. data/spec/spec_helper.rb +18 -0
  511. metadata +813 -0
@@ -0,0 +1,655 @@
1
+ module Cucumber
2
+ module Ast
3
+ # Step Definitions that match a plain text Step with a multiline argument table
4
+ # will receive it as an instance of Table. A Table object holds the data of a
5
+ # table parsed from a feature file and lets you access and manipulate the data
6
+ # in different ways.
7
+ #
8
+ # For example:
9
+ #
10
+ # Given I have:
11
+ # | a | b |
12
+ # | c | d |
13
+ #
14
+ # And a matching StepDefinition:
15
+ #
16
+ # Given /I have:/ do |table|
17
+ # data = table.raw
18
+ # end
19
+ #
20
+ # This will store <tt>[['a', 'b'], ['c', 'd']]</tt> in the <tt>data</tt> variable.
21
+ #
22
+ class Table
23
+ class Different < StandardError
24
+ attr_reader :table
25
+
26
+ def initialize(table)
27
+ super('Tables were not identical')
28
+ @table = table
29
+ end
30
+ end
31
+
32
+ include Enumerable
33
+
34
+ NULL_CONVERSIONS = Hash.new(lambda{ |cell_value| cell_value }).freeze
35
+
36
+ attr_accessor :file
37
+
38
+ def self.default_arg_name #:nodoc:
39
+ "table"
40
+ end
41
+
42
+ # Creates a new instance. +raw+ should be an Array of Array of String
43
+ # or an Array of Hash (similar to what #hashes returns).
44
+ # You don't typically create your own Table objects - Cucumber will do
45
+ # it internally and pass them to your Step Definitions.
46
+ #
47
+ def initialize(raw, conversion_procs = NULL_CONVERSIONS.dup)
48
+ @cells_class = Cells
49
+ @cell_class = Cell
50
+
51
+ raw = ensure_array_of_array(raw)
52
+ # Verify that it's square
53
+ transposed = raw.transpose
54
+ create_cell_matrix(raw)
55
+ @conversion_procs = conversion_procs
56
+ end
57
+
58
+ # JSON representation
59
+ def to_json
60
+ raw.to_json
61
+ end
62
+
63
+ # Creates a copy of this table, inheriting any column mappings.
64
+ # registered with #map_headers!
65
+ #
66
+ def dup
67
+ self.class.new(raw.dup, @conversion_procs.dup)
68
+ end
69
+
70
+ # Returns a new, transposed table. Example:
71
+ #
72
+ # | a | 7 | 4 |
73
+ # | b | 9 | 2 |
74
+ #
75
+ # Gets converted into the following:
76
+ #
77
+ # | a | b |
78
+ # | 7 | 9 |
79
+ # | 4 | 2 |
80
+ #
81
+ def transpose
82
+ self.class.new(raw.transpose, @conversion_procs.dup)
83
+ end
84
+
85
+ # Converts this table into an Array of Hash where the keys of each
86
+ # Hash are the headers in the table. For example, a Table built from
87
+ # the following plain text:
88
+ #
89
+ # | a | b | sum |
90
+ # | 2 | 3 | 5 |
91
+ # | 7 | 9 | 16 |
92
+ #
93
+ # Gets converted into the following:
94
+ #
95
+ # [{'a' => '2', 'b' => '3', 'sum' => '5'}, {'a' => '7', 'b' => '9', 'sum' => '16'}]
96
+ #
97
+ # Use #map_column! to specify how values in a column are converted.
98
+ #
99
+ def hashes
100
+ @hashes ||= cells_rows[1..-1].map do |row|
101
+ row.to_hash
102
+ end
103
+ end
104
+
105
+ # Converts this table into a Hash where the first column is
106
+ # used as keys and the second column is used as values
107
+ #
108
+ # | a | 2 |
109
+ # | b | 3 |
110
+ #
111
+ # Gets converted into the following:
112
+ #
113
+ # {'a' => '2', 'b' => '3'}
114
+ #
115
+ # The table must be exactly two columns wide
116
+ #
117
+ def rows_hash
118
+ return @rows_hash if @rows_hash
119
+ verify_table_width(2)
120
+ @rows_hash = self.transpose.hashes[0]
121
+ end
122
+
123
+ # Gets the raw data of this table. For example, a Table built from
124
+ # the following plain text:
125
+ #
126
+ # | a | b |
127
+ # | c | d |
128
+ #
129
+ # gets converted into the following:
130
+ #
131
+ # [['a', 'b], ['c', 'd']]
132
+ #
133
+ def raw
134
+ cell_matrix.map do |row|
135
+ row.map do |cell|
136
+ cell.value
137
+ end
138
+ end
139
+ end
140
+
141
+ # Same as #raw, but skips the first (header) row
142
+ def rows
143
+ raw[1..-1]
144
+ end
145
+
146
+ def each_cells_row(&proc) #:nodoc:
147
+ cells_rows.each(&proc)
148
+ end
149
+
150
+ def accept(visitor) #:nodoc:
151
+ return if Cucumber.wants_to_quit
152
+ cells_rows.each do |row|
153
+ visitor.visit_table_row(row)
154
+ end
155
+ nil
156
+ end
157
+
158
+ # Matches +pattern+ against the header row of the table.
159
+ # This is used especially for argument transforms.
160
+ #
161
+ # Example:
162
+ # | column_1_name | column_2_name |
163
+ # | x | y |
164
+ #
165
+ # table.match(/table:column_1_name,column_2_name/) #=> non-nil
166
+ #
167
+ # Note: must use 'table:' prefix on match
168
+ def match(pattern)
169
+ header_to_match = "table:#{headers.join(',')}"
170
+ pattern.match(header_to_match)
171
+ end
172
+
173
+ # For testing only
174
+ def to_sexp #:nodoc:
175
+ [:table, *cells_rows.map{|row| row.to_sexp}]
176
+ end
177
+
178
+ # Redefines the table headers. This makes it possible to use
179
+ # prettier and more flexible header names in the features. The
180
+ # keys of +mappings+ are Strings or regular expressions
181
+ # (anything that responds to #=== will work) that may match
182
+ # column headings in the table. The values of +mappings+ are
183
+ # desired names for the columns.
184
+ #
185
+ # Example:
186
+ #
187
+ # | Phone Number | Address |
188
+ # | 123456 | xyz |
189
+ # | 345678 | abc |
190
+ #
191
+ # A StepDefinition receiving this table can then map the columns
192
+ # with both Regexp and String:
193
+ #
194
+ # table.map_headers!(/phone( number)?/i => :phone, 'Address' => :address)
195
+ # table.hashes
196
+ # # => [{:phone => '123456', :address => 'xyz'}, {:phone => '345678', :address => 'abc'}]
197
+ #
198
+ # You may also pass in a block if you wish to convert all of the headers:
199
+ #
200
+ # table.map_headers! { |header| header.downcase }
201
+ # table.hashes.keys
202
+ # # => ['phone number', 'address']
203
+ #
204
+ # When a block is passed in along with a hash then the mappings in the hash take precendence:
205
+ #
206
+ # table.map_headers!('Address' => 'ADDRESS') { |header| header.downcase }
207
+ # table.hashes.keys
208
+ # # => ['phone number', 'ADDRESS']
209
+ #
210
+ def map_headers!(mappings={}, &block)
211
+ header_cells = cell_matrix[0]
212
+
213
+ if block_given?
214
+ header_values = header_cells.map { |cell| cell.value } - mappings.keys
215
+ mappings = mappings.merge(Hash[*header_values.zip(header_values.map(&block)).flatten])
216
+ end
217
+
218
+ mappings.each_pair do |pre, post|
219
+ mapped_cells = header_cells.select{|cell| pre === cell.value}
220
+ raise "No headers matched #{pre.inspect}" if mapped_cells.empty?
221
+ raise "#{mapped_cells.length} headers matched #{pre.inspect}: #{mapped_cells.map{|c| c.value}.inspect}" if mapped_cells.length > 1
222
+ mapped_cells[0].value = post
223
+ if @conversion_procs.has_key?(pre)
224
+ @conversion_procs[post] = @conversion_procs.delete(pre)
225
+ end
226
+ end
227
+ end
228
+
229
+ # Returns a new Table where the headers are redefined. See #map_headers!
230
+ def map_headers(mappings={})
231
+ table = self.dup
232
+ table.map_headers!(mappings)
233
+ table
234
+ end
235
+
236
+ # Change how #hashes converts column values. The +column_name+ argument identifies the column
237
+ # and +conversion_proc+ performs the conversion for each cell in that column. If +strict+ is
238
+ # true, an error will be raised if the column named +column_name+ is not found. If +strict+
239
+ # is false, no error will be raised. Example:
240
+ #
241
+ # Given /^an expense report for (.*) with the following posts:$/ do |table|
242
+ # posts_table.map_column!('amount') { |a| a.to_i }
243
+ # posts_table.hashes.each do |post|
244
+ # # post['amount'] is a Fixnum, rather than a String
245
+ # end
246
+ # end
247
+ #
248
+ def map_column!(column_name, strict=true, &conversion_proc)
249
+ verify_column(column_name) if strict
250
+ @conversion_procs[column_name] = conversion_proc
251
+ end
252
+
253
+ # Compares +other_table+ to self. If +other_table+ contains columns
254
+ # and/or rows that are not in self, new columns/rows are added at the
255
+ # relevant positions, marking the cells in those rows/columns as
256
+ # <tt>surplus</tt>. Likewise, if +other_table+ lacks columns and/or
257
+ # rows that are present in self, these are marked as <tt>missing</tt>.
258
+ #
259
+ # <tt>surplus</tt> and <tt>missing</tt> cells are recognised by formatters
260
+ # and displayed so that it's easy to read the differences.
261
+ #
262
+ # Cells that are different, but <em>look</em> identical (for example the
263
+ # boolean true and the string "true") are converted to their Object#inspect
264
+ # representation and preceded with (i) - to make it easier to identify
265
+ # where the difference actually is.
266
+ #
267
+ # Since all tables that are passed to StepDefinitions always have String
268
+ # objects in their cells, you may want to use #map_column! before calling
269
+ # #diff!. You can use #map_column! on either of the tables.
270
+ #
271
+ # A Different error is raised if there are missing rows or columns, or
272
+ # surplus rows. An error is <em>not</em> raised for surplus columns.
273
+ # Whether to raise or not raise can be changed by setting values in
274
+ # +options+ to true or false:
275
+ #
276
+ # * <tt>missing_row</tt> : Raise on missing rows (defaults to true)
277
+ # * <tt>surplus_row</tt> : Raise on surplus rows (defaults to true)
278
+ # * <tt>missing_col</tt> : Raise on missing columns (defaults to true)
279
+ # * <tt>surplus_col</tt> : Raise on surplus columns (defaults to false)
280
+ #
281
+ # The +other_table+ argument can be another Table, an Array of Array or
282
+ # an Array of Hash (similar to the structure returned by #hashes).
283
+ #
284
+ # Calling this method is particularly useful in <tt>Then</tt> steps that take
285
+ # a Table argument, if you want to compare that table to some actual values.
286
+ #
287
+ def diff!(other_table, options={})
288
+ options = {:missing_row => true, :surplus_row => true, :missing_col => true, :surplus_col => false}.merge(options)
289
+
290
+ other_table = ensure_table(other_table)
291
+ other_table.convert_columns!
292
+ ensure_green!
293
+
294
+ original_width = cell_matrix[0].length
295
+ other_table_cell_matrix = pad!(other_table.cell_matrix)
296
+ padded_width = cell_matrix[0].length
297
+
298
+ missing_col = cell_matrix[0].detect{|cell| cell.status == :undefined}
299
+ surplus_col = padded_width > original_width
300
+
301
+ require_diff_lcs
302
+ cell_matrix.extend(Diff::LCS)
303
+ convert_columns!
304
+ changes = cell_matrix.diff(other_table_cell_matrix).flatten
305
+
306
+ inserted = 0
307
+ missing = 0
308
+
309
+ row_indices = Array.new(other_table_cell_matrix.length) {|n| n}
310
+
311
+ last_change = nil
312
+ missing_row_pos = nil
313
+ insert_row_pos = nil
314
+
315
+ changes.each do |change|
316
+ if(change.action == '-')
317
+ missing_row_pos = change.position + inserted
318
+ cell_matrix[missing_row_pos].each{|cell| cell.status = :undefined}
319
+ row_indices.insert(missing_row_pos, nil)
320
+ missing += 1
321
+ else # '+'
322
+ insert_row_pos = change.position + missing
323
+ inserted_row = change.element
324
+ inserted_row.each{|cell| cell.status = :comment}
325
+ cell_matrix.insert(insert_row_pos, inserted_row)
326
+ row_indices[insert_row_pos] = nil
327
+ inspect_rows(cell_matrix[missing_row_pos], inserted_row) if last_change && last_change.action == '-'
328
+ inserted += 1
329
+ end
330
+ last_change = change
331
+ end
332
+
333
+ other_table_cell_matrix.each_with_index do |other_row, i|
334
+ row_index = row_indices.index(i)
335
+ row = cell_matrix[row_index] if row_index
336
+ if row
337
+ (original_width..padded_width).each do |col_index|
338
+ surplus_cell = other_row[col_index]
339
+ row[col_index].value = surplus_cell.value if row[col_index]
340
+ end
341
+ end
342
+ end
343
+
344
+ clear_cache!
345
+ should_raise =
346
+ missing_row_pos && options[:missing_row] ||
347
+ insert_row_pos && options[:surplus_row] ||
348
+ missing_col && options[:missing_col] ||
349
+ surplus_col && options[:surplus_col]
350
+ raise Different.new(self) if should_raise
351
+ end
352
+
353
+ def to_hash(cells) #:nodoc:
354
+ hash = Hash.new do |hash, key|
355
+ hash[key.to_s] if key.is_a?(Symbol)
356
+ end
357
+ raw[0].each_with_index do |column_name, column_index|
358
+ value = @conversion_procs[column_name].call(cells.value(column_index))
359
+ hash[column_name] = value
360
+ end
361
+ hash
362
+ end
363
+
364
+ def index(cells) #:nodoc:
365
+ cells_rows.index(cells)
366
+ end
367
+
368
+ def verify_column(column_name) #:nodoc:
369
+ raise %{The column named "#{column_name}" does not exist} unless raw[0].include?(column_name)
370
+ end
371
+
372
+ def verify_table_width(width) #:nodoc:
373
+ raise %{The table must have exactly #{width} columns} unless raw[0].size == width
374
+ end
375
+
376
+ def arguments_replaced(arguments) #:nodoc:
377
+ raw_with_replaced_args = raw.map do |row|
378
+ row.map do |cell|
379
+ cell_with_replaced_args = cell
380
+ arguments.each do |name, value|
381
+ if cell_with_replaced_args && cell_with_replaced_args.include?(name)
382
+ cell_with_replaced_args = value ? cell_with_replaced_args.gsub(name, value) : nil
383
+ end
384
+ end
385
+ cell_with_replaced_args
386
+ end
387
+ end
388
+ Table.new(raw_with_replaced_args)
389
+ end
390
+
391
+ def has_text?(text) #:nodoc:
392
+ raw.flatten.compact.detect{|cell_value| cell_value.index(text)}
393
+ end
394
+
395
+ def cells_rows #:nodoc:
396
+ @rows ||= cell_matrix.map do |cell_row|
397
+ @cells_class.new(self, cell_row)
398
+ end
399
+ end
400
+
401
+ def headers #:nodoc:
402
+ raw.first
403
+ end
404
+
405
+ def header_cell(col) #:nodoc:
406
+ cells_rows[0][col]
407
+ end
408
+
409
+ def cell_matrix #:nodoc:
410
+ @cell_matrix
411
+ end
412
+
413
+ def col_width(col) #:nodoc:
414
+ columns[col].__send__(:width)
415
+ end
416
+
417
+ def to_s(options = {}) #:nodoc:
418
+ options = {:color => true, :indent => 2, :prefixes => TO_S_PREFIXES}.merge(options)
419
+ io = StringIO.new
420
+
421
+ c = Term::ANSIColor.coloring?
422
+ Term::ANSIColor.coloring = options[:color]
423
+ formatter = Formatter::Pretty.new(nil, io, options)
424
+ formatter.instance_variable_set('@indent', options[:indent])
425
+ TreeWalker.new(nil, [formatter]).visit_multiline_arg(self)
426
+
427
+ Term::ANSIColor.coloring = c
428
+ io.rewind
429
+ s = "\n" + io.read + (" " * (options[:indent] - 2))
430
+ s
431
+ end
432
+
433
+ private
434
+
435
+ TO_S_PREFIXES = Hash.new(' ')
436
+ TO_S_PREFIXES[:comment] = ['(+) ']
437
+ TO_S_PREFIXES[:undefined] = ['(-) ']
438
+
439
+ protected
440
+
441
+ def inspect_rows(missing_row, inserted_row) #:nodoc:
442
+ missing_row.each_with_index do |missing_cell, col|
443
+ inserted_cell = inserted_row[col]
444
+ if(missing_cell.value != inserted_cell.value && (missing_cell.value.to_s == inserted_cell.value.to_s))
445
+ missing_cell.inspect!
446
+ inserted_cell.inspect!
447
+ end
448
+ end
449
+ end
450
+
451
+ def create_cell_matrix(raw) #:nodoc:
452
+ @cell_matrix = raw.map do |raw_row|
453
+ line = raw_row.line rescue -1
454
+ raw_row.map do |raw_cell|
455
+ new_cell(raw_cell, line)
456
+ end
457
+ end
458
+ end
459
+
460
+ def convert_columns! #:nodoc:
461
+ cell_matrix.transpose.each do |col|
462
+ conversion_proc = @conversion_procs[col[0].value]
463
+ col[1..-1].each do |cell|
464
+ cell.value = conversion_proc.call(cell.value)
465
+ end
466
+ end
467
+ end
468
+
469
+ def require_diff_lcs #:nodoc:
470
+ begin
471
+ require 'diff/lcs'
472
+ rescue LoadError => e
473
+ e.message << "\n Please gem install diff-lcs\n"
474
+ raise e
475
+ end
476
+ end
477
+
478
+ def clear_cache! #:nodoc:
479
+ @hashes = @rows_hash = @rows = @columns = nil
480
+ end
481
+
482
+ def columns #:nodoc:
483
+ @columns ||= cell_matrix.transpose.map do |cell_row|
484
+ @cells_class.new(self, cell_row)
485
+ end
486
+ end
487
+
488
+ def new_cell(raw_cell, line) #:nodoc:
489
+ @cell_class.new(raw_cell, self, line)
490
+ end
491
+
492
+ # Pads our own cell_matrix and returns a cell matrix of same
493
+ # column width that can be used for diffing
494
+ def pad!(other_cell_matrix) #:nodoc:
495
+ clear_cache!
496
+ cols = cell_matrix.transpose
497
+ unmapped_cols = other_cell_matrix.transpose
498
+
499
+ mapped_cols = []
500
+
501
+ cols.each_with_index do |col, col_index|
502
+ header = col[0]
503
+ candidate_cols, unmapped_cols = unmapped_cols.partition do |other_col|
504
+ other_col[0] == header
505
+ end
506
+ raise "More than one column has the header #{header}" if candidate_cols.size > 2
507
+
508
+ other_padded_col = if candidate_cols.size == 1
509
+ # Found a matching column
510
+ candidate_cols[0]
511
+ else
512
+ mark_as_missing(cols[col_index])
513
+ (0...other_cell_matrix.length).map do |row|
514
+ val = row == 0 ? header.value : nil
515
+ SurplusCell.new(val, self, -1)
516
+ end
517
+ end
518
+ mapped_cols.insert(col_index, other_padded_col)
519
+ end
520
+
521
+ unmapped_cols.each_with_index do |col, col_index|
522
+ empty_col = (0...cell_matrix.length).map do |row|
523
+ SurplusCell.new(nil, self, -1)
524
+ end
525
+ cols << empty_col
526
+ end
527
+
528
+ @cell_matrix = cols.transpose
529
+ (mapped_cols + unmapped_cols).transpose
530
+ end
531
+
532
+ def ensure_table(table_or_array) #:nodoc:
533
+ return table_or_array if Table === table_or_array
534
+ Table.new(table_or_array)
535
+ end
536
+
537
+ def ensure_array_of_array(array)
538
+ Hash === array[0] ? hashes_to_array(array) : array
539
+ end
540
+
541
+ def hashes_to_array(hashes) #:nodoc:
542
+ header = hashes[0].keys
543
+ [header] + hashes.map{|hash| header.map{|key| hash[key]}}
544
+ end
545
+
546
+ def ensure_green! #:nodoc:
547
+ each_cell{|cell| cell.status = :passed}
548
+ end
549
+
550
+ def each_cell(&proc) #:nodoc:
551
+ cell_matrix.each{|row| row.each(&proc)}
552
+ end
553
+
554
+ def mark_as_missing(col) #:nodoc:
555
+ col.each do |cell|
556
+ cell.status = :undefined
557
+ end
558
+ end
559
+
560
+ # Represents a row of cells or columns of cells
561
+ class Cells #:nodoc:
562
+ include Enumerable
563
+ attr_reader :exception
564
+
565
+ def initialize(table, cells)
566
+ @table, @cells = table, cells
567
+ end
568
+
569
+ def accept(visitor)
570
+ return if Cucumber.wants_to_quit
571
+ each do |cell|
572
+ visitor.visit_table_cell(cell)
573
+ end
574
+ nil
575
+ end
576
+
577
+ # For testing only
578
+ def to_sexp #:nodoc:
579
+ [:row, line, *@cells.map{|cell| cell.to_sexp}]
580
+ end
581
+
582
+ def to_hash #:nodoc:
583
+ @to_hash ||= @table.to_hash(self)
584
+ end
585
+
586
+ def value(n) #:nodoc:
587
+ self[n].value
588
+ end
589
+
590
+ def [](n)
591
+ @cells[n]
592
+ end
593
+
594
+ def line
595
+ @cells[0].line
596
+ end
597
+
598
+ def dom_id
599
+ "row_#{line}"
600
+ end
601
+
602
+ private
603
+
604
+ def index
605
+ @table.index(self)
606
+ end
607
+
608
+ def width
609
+ map{|cell| cell.value ? cell.value.to_s.jlength : 0}.max
610
+ end
611
+
612
+ def each(&proc)
613
+ @cells.each(&proc)
614
+ end
615
+ end
616
+
617
+ class Cell #:nodoc:
618
+ attr_reader :line, :table
619
+ attr_accessor :status, :value
620
+
621
+ def initialize(value, table, line)
622
+ @value, @table, @line = value, table, line
623
+ end
624
+
625
+ def accept(visitor)
626
+ return if Cucumber.wants_to_quit
627
+ visitor.visit_table_cell_value(value, status)
628
+ end
629
+
630
+ def inspect!
631
+ @value = "(i) #{value.inspect}"
632
+ end
633
+
634
+ def ==(o)
635
+ SurplusCell === o || value == o.value
636
+ end
637
+
638
+ # For testing only
639
+ def to_sexp #:nodoc:
640
+ [:cell, @value]
641
+ end
642
+ end
643
+
644
+ class SurplusCell < Cell #:nodoc:
645
+ def status
646
+ :comment
647
+ end
648
+
649
+ def ==(o)
650
+ true
651
+ end
652
+ end
653
+ end
654
+ end
655
+ end