cucumber 0.1.10 → 0.2.0

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 (348) hide show
  1. data/History.txt +223 -5
  2. data/License.txt +1 -1
  3. data/Manifest.txt +174 -85
  4. data/README.txt +2 -39
  5. data/Rakefile +1 -2
  6. data/bin/cucumber +2 -2
  7. data/config/hoe.rb +9 -3
  8. data/examples/cs/README.textile +1 -22
  9. data/examples/cs/Rakefile +1 -1
  10. data/examples/cs/compile.bat +1 -0
  11. data/examples/cs/features/addition.feature +16 -0
  12. data/examples/cs/features/step_definitons/calculator_steps.rb +19 -0
  13. data/examples/cs/src/demo/Calculator.cs +20 -0
  14. data/examples/i18n/README.textile +1 -1
  15. data/examples/i18n/Rakefile +20 -4
  16. data/examples/i18n/ar/features/addition.feature +10 -11
  17. data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +4 -12
  18. data/examples/i18n/da/features/step_definitons/kalkulator_steps.rb +4 -2
  19. data/examples/i18n/de/features/addition.feature +10 -11
  20. data/examples/i18n/de/features/division.feature +0 -1
  21. data/examples/i18n/de/features/step_definitons/calculator_steps.rb +5 -11
  22. data/examples/i18n/en/features/addition.feature +10 -11
  23. data/examples/i18n/en/features/division.feature +0 -1
  24. data/examples/i18n/en/features/step_definitons/calculator_steps.rb +5 -12
  25. data/examples/i18n/en-lol/Rakefile +6 -0
  26. data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +16 -0
  27. data/examples/i18n/en-lol/features/stuffing.feature +8 -0
  28. data/examples/i18n/en-lol/features/support/env.rb +8 -0
  29. data/examples/i18n/en-lol/lib/basket.rb +12 -0
  30. data/examples/i18n/en-lol/lib/belly.rb +11 -0
  31. data/examples/i18n/es/features/adicion.feature +11 -12
  32. data/examples/i18n/es/features/step_definitons/calculador_steps.rb +10 -11
  33. data/examples/i18n/es/lib/calculador.rb +4 -1
  34. data/examples/i18n/et/features/jagamine.feature +9 -0
  35. data/examples/i18n/et/features/liitmine.feature +10 -11
  36. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +7 -9
  37. data/examples/i18n/et/lib/kalkulaator.rb +5 -1
  38. data/examples/i18n/fi/Rakefile +6 -0
  39. data/examples/i18n/fi/features/jakolasku.feature +9 -0
  40. data/examples/i18n/fi/features/step_definitons/laskin_steps.rb +24 -0
  41. data/examples/i18n/fi/features/yhteenlasku.feature +16 -0
  42. data/examples/i18n/fi/lib/laskin.rb +14 -0
  43. data/examples/i18n/fr/features/addition.feature +16 -12
  44. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +14 -11
  45. data/examples/i18n/fr/lib/calculatrice.rb +1 -1
  46. data/examples/i18n/id/features/addition.feature +10 -11
  47. data/examples/i18n/id/features/division.feature +0 -1
  48. data/examples/i18n/id/features/step_definitons/calculator_steps.rb +5 -12
  49. data/examples/i18n/it/features/step_definitons/calcolatrice_steps.rb +4 -2
  50. data/examples/i18n/ja/features/addition.feature +10 -11
  51. data/examples/i18n/ja/features/division.feature +2 -3
  52. data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +6 -12
  53. data/examples/i18n/ko/Rakefile +6 -0
  54. data/examples/i18n/ko/features/addition.feature +16 -0
  55. data/examples/i18n/ko/features/division.feature +10 -0
  56. data/examples/i18n/ko/features/step_definitons/calculator_steps.rb +24 -0
  57. data/examples/i18n/ko/lib/calculator.rb +14 -0
  58. data/examples/i18n/lt/features/addition.feature +11 -11
  59. data/examples/i18n/lt/features/division.feature +0 -1
  60. data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +5 -12
  61. data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +4 -9
  62. data/examples/i18n/no/features/summering.feature +1 -0
  63. data/examples/i18n/no/features/support/env.rb +6 -0
  64. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +4 -2
  65. data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +4 -2
  66. data/examples/i18n/ru/Rakefile +6 -0
  67. data/examples/i18n/ru/features/addition.feature +10 -0
  68. data/examples/i18n/ru/features/consecutive_calculations.feature +16 -0
  69. data/examples/i18n/ru/features/division.feature +15 -0
  70. data/examples/i18n/ru/features/step_definitons/calculator_steps.rb +19 -0
  71. data/examples/i18n/ru/features/support/env.rb +6 -0
  72. data/examples/i18n/ru/features/support/world.rb +7 -0
  73. data/examples/i18n/ru/lib/calculator.rb +24 -0
  74. data/examples/i18n/se/features/step_definitons/kalkulator_steps.rb +4 -2
  75. data/examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb +5 -3
  76. data/examples/i18n/zh-TW/Rakefile +6 -0
  77. data/examples/i18n/zh-TW/features/addition.feature +16 -0
  78. data/examples/i18n/zh-TW/features/division.feature +10 -0
  79. data/examples/i18n/zh-TW/features/step_definitons/calculator_steps.rb +24 -0
  80. data/examples/i18n/zh-TW/lib/calculator.rb +14 -0
  81. data/examples/java/features/step_definitons/hello_steps.rb +1 -1
  82. data/examples/java/features/step_definitons/tree_steps.rb +1 -1
  83. data/examples/jbehave/README.textile +20 -0
  84. data/examples/jbehave/features/support/env.rb +7 -0
  85. data/examples/jbehave/features/trading.feature +28 -0
  86. data/examples/jbehave/pom.xml +53 -0
  87. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/converters/TraderConverter.java +32 -0
  88. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Stock.java +42 -0
  89. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Trader.java +29 -0
  90. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/persistence/TraderPersister.java +22 -0
  91. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/scenarios/TraderSteps.java +70 -0
  92. data/examples/selenium/features/search.feature +1 -1
  93. data/examples/selenium/features/step_definitons/search_steps.rb +13 -0
  94. data/examples/selenium/features/support/env.rb +19 -0
  95. data/examples/selenium_webrat/features/search.feature +9 -0
  96. data/examples/selenium_webrat/features/step_definitons/search_steps.rb +13 -0
  97. data/examples/selenium_webrat/features/support/env.rb +41 -0
  98. data/examples/self_test/README.textile +6 -0
  99. data/examples/self_test/Rakefile +6 -0
  100. data/examples/self_test/features/background/failing_background.feature +11 -0
  101. data/examples/self_test/features/background/failing_background_after_success.feature +11 -0
  102. data/examples/self_test/features/background/multiline_args_background.feature +32 -0
  103. data/examples/self_test/features/background/passing_background.feature +10 -0
  104. data/examples/self_test/features/background/pending_background.feature +10 -0
  105. data/examples/self_test/features/background/scenario_outline_failing_background.feature +16 -0
  106. data/examples/self_test/features/background/scenario_outline_passing_background.feature +16 -0
  107. data/examples/self_test/features/call_undefined_step_from_step_def.feature +7 -0
  108. data/examples/self_test/features/failing_expectation.feature +4 -0
  109. data/examples/self_test/features/lots_of_undefined.feature +8 -0
  110. data/examples/self_test/features/outline_sample.feature +15 -0
  111. data/examples/self_test/features/sample.feature +19 -0
  112. data/examples/self_test/features/step_definitions/sample_steps.rb +64 -0
  113. data/examples/self_test/features/support/env.rb +1 -0
  114. data/examples/self_test/features/support/tag_count_formatter.rb +25 -0
  115. data/examples/sinatra/Rakefile +6 -0
  116. data/examples/sinatra/app.rb +14 -0
  117. data/examples/sinatra/features/add.feature +11 -0
  118. data/examples/sinatra/features/step_definitions/add_steps.rb +15 -0
  119. data/examples/sinatra/features/support/env.rb +20 -0
  120. data/examples/sinatra/views/add.erb +5 -0
  121. data/examples/sinatra/views/layout.erb +8 -0
  122. data/examples/tickets/Rakefile +13 -8
  123. data/examples/tickets/cucumber.yml +2 -1
  124. data/examples/tickets/features/172.feature +28 -0
  125. data/examples/tickets/features/177/1.feature +29 -0
  126. data/examples/tickets/features/177/2.feature +21 -0
  127. data/examples/tickets/features/177/3.feature +18 -0
  128. data/examples/tickets/features/180.feature +7 -0
  129. data/examples/tickets/features/236.feature +13 -0
  130. data/examples/tickets/features/241.feature +13 -0
  131. data/examples/tickets/features/lib/eatting_machine.rb +18 -0
  132. data/examples/tickets/features/lib/pantry.rb +20 -0
  133. data/examples/tickets/features/scenario_outline.feature +95 -0
  134. data/examples/tickets/features/step_definitons/scenario_outline_steps.rb +42 -0
  135. data/examples/tickets/features/step_definitons/tickets_steps.rb +46 -5
  136. data/examples/tickets/features/tickets.feature +5 -1
  137. data/examples/watir/README.textile +16 -0
  138. data/examples/watir/features/step_definitons/search_steps.rb +24 -0
  139. data/examples/watir/features/support/env.rb +32 -0
  140. data/features/background.feature +221 -0
  141. data/features/cucumber_cli.feature +389 -0
  142. data/features/cucumber_cli_diff_disabled.feature +45 -0
  143. data/features/cucumber_cli_outlines.feature +81 -0
  144. data/features/custom_formatter.feature +11 -0
  145. data/features/report_called_undefined_steps.feature +34 -0
  146. data/features/step_definitions/cucumber_steps.rb +30 -0
  147. data/features/step_definitions/extra_steps.rb +2 -0
  148. data/features/support/env.rb +8 -0
  149. data/gem_tasks/deployment.rake +0 -23
  150. data/gem_tasks/features.rake +1 -1
  151. data/gem_tasks/fix_cr_lf.rake +1 -1
  152. data/gem_tasks/flog.rake +1 -1
  153. data/gem_tasks/gemspec.rake +4 -0
  154. data/gem_tasks/jar.rake +67 -0
  155. data/gem_tasks/rspec.rake +31 -15
  156. data/gem_tasks/yard.rake +8 -0
  157. data/lib/autotest/cucumber_mixin.rb +41 -25
  158. data/lib/cucumber/ast/background.rb +50 -0
  159. data/lib/cucumber/ast/comment.rb +26 -0
  160. data/lib/cucumber/ast/examples.rb +38 -0
  161. data/lib/cucumber/ast/feature.rb +62 -0
  162. data/lib/cucumber/ast/feature_element.rb +46 -0
  163. data/lib/cucumber/ast/features.rb +20 -0
  164. data/lib/cucumber/ast/outline_table.rb +81 -0
  165. data/lib/cucumber/ast/py_string.rb +58 -0
  166. data/lib/cucumber/ast/scenario.rb +64 -0
  167. data/lib/cucumber/ast/scenario_outline.rb +90 -0
  168. data/lib/cucumber/ast/step.rb +122 -0
  169. data/lib/cucumber/ast/step_collection.rb +66 -0
  170. data/lib/cucumber/ast/step_invocation.rb +110 -0
  171. data/lib/cucumber/ast/table.rb +318 -0
  172. data/lib/cucumber/ast/tags.rb +33 -0
  173. data/lib/cucumber/ast/visitor.rb +125 -0
  174. data/lib/cucumber/ast.rb +29 -0
  175. data/lib/cucumber/broadcaster.rb +2 -9
  176. data/lib/cucumber/cli/configuration.rb +364 -0
  177. data/lib/cucumber/cli/language_help_formatter.rb +59 -0
  178. data/lib/cucumber/cli/main.rb +109 -0
  179. data/lib/cucumber/core_ext/exception.rb +53 -0
  180. data/lib/cucumber/core_ext/instance_exec.rb +54 -0
  181. data/lib/cucumber/core_ext/proc.rb +29 -65
  182. data/lib/cucumber/core_ext/string.rb +26 -0
  183. data/lib/cucumber/formatter/ansicolor.rb +102 -0
  184. data/lib/cucumber/formatter/color_io.rb +23 -0
  185. data/lib/cucumber/formatter/console.rb +109 -0
  186. data/lib/cucumber/formatter/cucumber.css +55 -0
  187. data/lib/cucumber/formatter/cucumber.sass +49 -0
  188. data/lib/cucumber/formatter/html.rb +133 -0
  189. data/lib/cucumber/formatter/pretty.rb +179 -0
  190. data/lib/cucumber/formatter/profile.rb +77 -0
  191. data/lib/cucumber/formatter/progress.rb +60 -0
  192. data/lib/cucumber/formatter/rerun.rb +35 -0
  193. data/lib/cucumber/formatter/unicode.rb +35 -0
  194. data/lib/cucumber/formatter.rb +1 -0
  195. data/lib/cucumber/formatters/unicode.rb +2 -0
  196. data/lib/cucumber/jbehave.rb +97 -0
  197. data/lib/cucumber/languages.yml +214 -72
  198. data/lib/cucumber/parser/basic.rb +0 -0
  199. data/lib/cucumber/parser/feature.rb +1487 -0
  200. data/lib/cucumber/parser/feature.tt +193 -0
  201. data/lib/cucumber/parser/i18n.tt +31 -0
  202. data/lib/cucumber/parser/table.rb +402 -0
  203. data/lib/cucumber/parser/table.tt +59 -0
  204. data/lib/cucumber/parser/treetop_ext.rb +75 -0
  205. data/lib/cucumber/parser.rb +43 -0
  206. data/lib/cucumber/platform.rb +13 -8
  207. data/lib/cucumber/rails/rspec.rb +6 -10
  208. data/lib/cucumber/rails/world.rb +8 -8
  209. data/lib/cucumber/rake/task.rb +46 -9
  210. data/lib/cucumber/step_definition.rb +103 -0
  211. data/lib/cucumber/step_match.rb +49 -0
  212. data/lib/cucumber/step_mother.rb +184 -65
  213. data/lib/cucumber/version.rb +4 -3
  214. data/lib/cucumber/world.rb +53 -0
  215. data/lib/cucumber.rb +45 -21
  216. data/rails_generators/cucumber/cucumber_generator.rb +23 -3
  217. data/rails_generators/cucumber/templates/cucumber +2 -1
  218. data/rails_generators/cucumber/templates/cucumber.rake +13 -5
  219. data/rails_generators/cucumber/templates/env.rb +11 -2
  220. data/rails_generators/cucumber/templates/paths.rb +19 -0
  221. data/rails_generators/cucumber/templates/webrat_steps.rb +60 -40
  222. data/rails_generators/feature/feature_generator.rb +26 -2
  223. data/rails_generators/feature/templates/feature.erb +15 -12
  224. data/rails_generators/feature/templates/steps.erb +14 -16
  225. data/spec/cucumber/ast/background_spec.rb +49 -0
  226. data/spec/cucumber/ast/feature_factory.rb +63 -0
  227. data/spec/cucumber/ast/feature_spec.rb +37 -0
  228. data/spec/cucumber/ast/py_string_spec.rb +47 -0
  229. data/spec/cucumber/ast/scenario_outline_spec.rb +67 -0
  230. data/spec/cucumber/ast/scenario_spec.rb +65 -0
  231. data/spec/cucumber/ast/step_collection_spec.rb +8 -0
  232. data/spec/cucumber/ast/step_spec.rb +66 -0
  233. data/spec/cucumber/ast/table_spec.rb +149 -0
  234. data/spec/cucumber/ast/tags_spec.rb +19 -0
  235. data/spec/cucumber/broadcaster_spec.rb +6 -18
  236. data/spec/cucumber/cli/configuration_spec.rb +275 -0
  237. data/spec/cucumber/cli/main_spec.rb +203 -0
  238. data/spec/cucumber/core_ext/proc_spec.rb +27 -35
  239. data/spec/cucumber/core_ext/string_spec.rb +8 -0
  240. data/spec/cucumber/formatter/ansicolor_spec.rb +35 -0
  241. data/spec/cucumber/formatter/color_io_spec.rb +26 -0
  242. data/spec/cucumber/formatter/html/cucumber.css +37 -0
  243. data/spec/cucumber/formatter/html/cucumber.js +13 -0
  244. data/spec/cucumber/formatter/html/index.html +45 -0
  245. data/spec/cucumber/formatter/html/jquery-1.3.min.js +19 -0
  246. data/spec/cucumber/formatter/html/jquery.uitableedit.js +100 -0
  247. data/spec/cucumber/formatters/profile_formatter_spec.rb +22 -16
  248. data/spec/cucumber/parser/feature_parser_spec.rb +282 -0
  249. data/spec/cucumber/parser/table_parser_spec.rb +48 -0
  250. data/spec/cucumber/rails/stubs/mini_rails.rb +4 -3
  251. data/spec/cucumber/step_definition_spec.rb +81 -0
  252. data/spec/cucumber/step_mother_spec.rb +50 -51
  253. data/spec/cucumber/treetop_parser/empty_feature.feature +1 -1
  254. data/spec/cucumber/treetop_parser/empty_scenario_outline.feature +3 -0
  255. data/spec/cucumber/treetop_parser/invalid_scenario_outlines.feature +7 -0
  256. data/spec/cucumber/treetop_parser/multiple_tables.feature +6 -8
  257. data/spec/cucumber/treetop_parser/scenario_outline.feature +16 -0
  258. data/spec/cucumber/treetop_parser/spaces.feature +3 -1
  259. data/spec/cucumber/treetop_parser/with_comments.feature +1 -1
  260. data/spec/cucumber/treetop_parser/with_tags.feature +18 -0
  261. data/spec/cucumber/world/pending_spec.rb +47 -0
  262. data/spec/spec_helper.rb +4 -3
  263. metadata +192 -95
  264. data/TODO.txt +0 -26
  265. data/examples/calculator_ruby_features/features/addition.rb +0 -23
  266. data/examples/calculator_ruby_features/features/step_definitons/calculator_steps.rb +0 -43
  267. data/examples/cs/features/hello.feature +0 -11
  268. data/examples/cs/features/step_definitons/hello_steps.rb +0 -25
  269. data/examples/cs/features/step_definitons/tree_steps.rb +0 -14
  270. data/examples/cs/features/tree.feature +0 -9
  271. data/examples/cs/src/Hello.cs +0 -18
  272. data/examples/i18n/ja/README.txt +0 -5
  273. data/examples/selenium/features/step_definitons/stories_steps.rb +0 -41
  274. data/examples/watir/features/step_definitons/stories_steps.rb +0 -51
  275. data/features/see_features.feature +0 -8
  276. data/features/steps/features_steps.rb +0 -9
  277. data/gem_tasks/treetop.rake +0 -41
  278. data/lib/cucumber/cli.rb +0 -279
  279. data/lib/cucumber/executor.rb +0 -190
  280. data/lib/cucumber/formatters/ansicolor.rb +0 -109
  281. data/lib/cucumber/formatters/autotest_formatter.rb +0 -23
  282. data/lib/cucumber/formatters/cucumber.css +0 -132
  283. data/lib/cucumber/formatters/cucumber.js +0 -11
  284. data/lib/cucumber/formatters/html_formatter.rb +0 -128
  285. data/lib/cucumber/formatters/jquery.js +0 -32
  286. data/lib/cucumber/formatters/pretty_formatter.rb +0 -234
  287. data/lib/cucumber/formatters/profile_formatter.rb +0 -92
  288. data/lib/cucumber/formatters/progress_formatter.rb +0 -58
  289. data/lib/cucumber/formatters.rb +0 -1
  290. data/lib/cucumber/model/table.rb +0 -28
  291. data/lib/cucumber/model.rb +0 -1
  292. data/lib/cucumber/step_methods.rb +0 -49
  293. data/lib/cucumber/tree/feature.rb +0 -63
  294. data/lib/cucumber/tree/features.rb +0 -21
  295. data/lib/cucumber/tree/given_scenario.rb +0 -13
  296. data/lib/cucumber/tree/scenario.rb +0 -174
  297. data/lib/cucumber/tree/step.rb +0 -134
  298. data/lib/cucumber/tree/table.rb +0 -26
  299. data/lib/cucumber/tree/top_down_visitor.rb +0 -23
  300. data/lib/cucumber/tree.rb +0 -18
  301. data/lib/cucumber/treetop_parser/feature.treetop.erb +0 -206
  302. data/lib/cucumber/treetop_parser/feature_ar.rb +0 -1591
  303. data/lib/cucumber/treetop_parser/feature_cy.rb +0 -1591
  304. data/lib/cucumber/treetop_parser/feature_da.rb +0 -1591
  305. data/lib/cucumber/treetop_parser/feature_de.rb +0 -1591
  306. data/lib/cucumber/treetop_parser/feature_en-tx.rb +0 -1591
  307. data/lib/cucumber/treetop_parser/feature_en.rb +0 -1591
  308. data/lib/cucumber/treetop_parser/feature_es.rb +0 -1591
  309. data/lib/cucumber/treetop_parser/feature_et.rb +0 -1591
  310. data/lib/cucumber/treetop_parser/feature_fr.rb +0 -1591
  311. data/lib/cucumber/treetop_parser/feature_id.rb +0 -1591
  312. data/lib/cucumber/treetop_parser/feature_it.rb +0 -1591
  313. data/lib/cucumber/treetop_parser/feature_ja.rb +0 -1591
  314. data/lib/cucumber/treetop_parser/feature_lt.rb +0 -1591
  315. data/lib/cucumber/treetop_parser/feature_nl.rb +0 -1591
  316. data/lib/cucumber/treetop_parser/feature_no.rb +0 -1591
  317. data/lib/cucumber/treetop_parser/feature_parser.rb +0 -34
  318. data/lib/cucumber/treetop_parser/feature_pl.rb +0 -1591
  319. data/lib/cucumber/treetop_parser/feature_pt.rb +0 -1591
  320. data/lib/cucumber/treetop_parser/feature_ro.rb +0 -1591
  321. data/lib/cucumber/treetop_parser/feature_ro2.rb +0 -1591
  322. data/lib/cucumber/treetop_parser/feature_ru.rb +0 -1591
  323. data/lib/cucumber/treetop_parser/feature_se.rb +0 -1591
  324. data/lib/cucumber/treetop_parser/feature_zh-CN.rb +0 -1591
  325. data/script/console +0 -10
  326. data/script/console.cmd +0 -1
  327. data/script/destroy +0 -14
  328. data/script/destroy.cmd +0 -1
  329. data/script/generate +0 -14
  330. data/script/generate.cmd +0 -1
  331. data/script/txt2html +0 -74
  332. data/script/txt2html.cmd +0 -1
  333. data/setup.rb +0 -1585
  334. data/spec/cucumber/cli_spec.rb +0 -274
  335. data/spec/cucumber/executor_spec.rb +0 -298
  336. data/spec/cucumber/formatters/ansicolor_spec.rb +0 -35
  337. data/spec/cucumber/formatters/autotest_formatter_spec.rb +0 -26
  338. data/spec/cucumber/formatters/features.html +0 -269
  339. data/spec/cucumber/formatters/html_formatter_spec.rb +0 -74
  340. data/spec/cucumber/formatters/pretty_formatter_spec.rb +0 -204
  341. data/spec/cucumber/formatters/progress_formatter_spec.rb +0 -65
  342. data/spec/cucumber/model/table_spec.rb +0 -20
  343. data/spec/cucumber/tree/feature_spec.rb +0 -43
  344. data/spec/cucumber/tree/row_scenario_spec.rb +0 -55
  345. data/spec/cucumber/tree/scenario_spec.rb +0 -76
  346. data/spec/cucumber/tree/step_spec.rb +0 -50
  347. data/spec/cucumber/treetop_parser/feature_parser_spec.rb +0 -98
  348. /data/examples/{calculator_ruby_features → selenium_webrat}/Rakefile +0 -0
@@ -1,95 +1,214 @@
1
- require 'cucumber/tree/top_down_visitor'
2
- require 'cucumber/core_ext/proc'
1
+ require 'cucumber/step_definition'
2
+ require 'cucumber/world'
3
+ require 'cucumber/core_ext/instance_exec'
3
4
 
4
5
  module Cucumber
5
- class Pending < StandardError
6
- end
6
+ class Undefined < StandardError
7
+ attr_reader :step_name
8
+
9
+ def initialize(step_name)
10
+ super %{Undefined step: "#{step_name}"}
11
+ @step_name = step_name
12
+ end
13
+
14
+ def nested!
15
+ @nested = true
16
+ end
7
17
 
8
- class Duplicate < StandardError
18
+ def nested?
19
+ @nested
20
+ end
9
21
  end
10
22
 
11
- class Multiple < StandardError
23
+ # Raised when a StepDefinition's block invokes World#pending
24
+ class Pending < StandardError
12
25
  end
13
26
 
14
- class MissingProc < StandardError
15
- def message
16
- "Step definitions must always have a proc"
27
+ # Raised when a step matches 2 or more StepDefinition
28
+ class Ambiguous < StandardError
29
+ def initialize(step_name, step_definitions)
30
+ message = "Ambiguous match of \"#{step_name}\":\n\n"
31
+ message << step_definitions.map{|sd| sd.backtrace_line}.join("\n")
32
+ message << "\n\n"
33
+ super(message)
17
34
  end
18
35
  end
19
36
 
20
- class StepMother
21
- PENDING = lambda do |*_|
22
- raise Pending
37
+ # Raised when 2 or more StepDefinition have the same Regexp
38
+ class Redundant < StandardError
39
+ def initialize(step_def_1, step_def_2)
40
+ message = "Multiple step definitions have the same Regexp:\n\n"
41
+ message << step_def_1.backtrace_line << "\n"
42
+ message << step_def_2.backtrace_line << "\n\n"
43
+ super(message)
23
44
  end
24
- PENDING.extend(CoreExt::CallIn)
25
- PENDING.name = "PENDING"
45
+ end
26
46
 
27
- def initialize
28
- @step_procs = Hash.new(PENDING)
47
+ # This is the main interface for registering step definitions, which is done
48
+ # from <tt>*_steps.rb</tt> files. This module is included right at the top-level
49
+ # so #register_step_definition (and more interestingly - its aliases) are
50
+ # available from the top-level.
51
+ module StepMother
52
+ class << self
53
+ def alias_adverb(adverb)
54
+ adverb = adverb.gsub(/\s/, '')
55
+ alias_method adverb, :register_step_definition
56
+ end
29
57
  end
30
58
 
31
- def register_step_proc(key, &proc)
32
- raise MissingProc if proc.nil?
33
- regexp = case(key)
34
- when String
35
- # Replace the $foo and $bar style parameters
36
- pattern = key.gsub(/\$\w+/, '(.*)')
37
- Regexp.new("^#{pattern}$")
38
- when Regexp
39
- key
59
+ attr_writer :snippet_generator, :options, :visitor
60
+
61
+ def step_visited(step)
62
+ steps << step unless steps.index(step)
63
+ end
64
+
65
+ def steps(status = nil)
66
+ @steps ||= []
67
+ if(status)
68
+ @steps.select{|step| step.status == status}
40
69
  else
41
- raise "Step patterns must be Regexp or String, but was: #{key.inspect}"
70
+ @steps
42
71
  end
43
- proc.extend(CoreExt::CallIn)
44
- proc.name = key.inspect
45
-
46
- if @step_procs.has_key?(regexp)
47
- first_proc = @step_procs[regexp]
48
- message = %{Duplicate step definitions:
72
+ end
49
73
 
50
- #{first_proc.to_backtrace_line}
51
- #{proc.to_backtrace_line}
74
+ def scenarios
75
+ @scenarios ||= []
76
+ end
52
77
 
53
- }
54
- raise Duplicate.new(message)
78
+ # Registers a new StepDefinition. This method is aliased
79
+ # to <tt>Given</tt>, <tt>When</tt> and <tt>Then</tt>.
80
+ #
81
+ # See Cucumber#alias_steps for details on how to
82
+ # create your own aliases.
83
+ #
84
+ # The +&proc+ gets executed in the context of a <tt>world</tt>
85
+ # object, which is defined by #World. A new <tt>world</tt>
86
+ # object is created for each scenario and is shared across
87
+ # step definitions within that scenario.
88
+ def register_step_definition(regexp, &proc)
89
+ step_definition = StepDefinition.new(regexp, &proc)
90
+ step_definitions.each do |already|
91
+ raise Redundant.new(already, step_definition) if already.match(regexp)
55
92
  end
93
+ step_definitions << step_definition
94
+ step_definition
95
+ end
56
96
 
57
- @step_procs[regexp] = proc
58
- end
59
-
60
- def regexp_args_proc(step_name)
61
- candidates = @step_procs.map do |regexp, proc|
62
- if step_name =~ regexp
63
- [regexp, $~.captures, proc]
64
- end
65
- end.compact
66
-
67
- case(candidates.length)
68
- when 0
69
- [nil, [], PENDING]
70
- when 1
71
- candidates[0]
72
- else
73
- message = %{Multiple step definitions match #{step_name.inspect}:
97
+ # Registers a Before proc. You can call this method as many times as you
98
+ # want (typically from ruby scripts under <tt>support</tt>).
99
+ def Before(&proc)
100
+ (@before_procs ||= []) << proc
101
+ end
102
+
103
+ def After(&proc)
104
+ (@after_procs ||= []) << proc
105
+ end
106
+
107
+ # Registers a World proc. You can call this method as many times as you
108
+ # want (typically from ruby scripts under <tt>support</tt>).
109
+ def World(&proc)
110
+ (@world_procs ||= []) << proc
111
+ end
112
+
113
+ def current_world
114
+ @current_world
115
+ end
74
116
 
75
- #{candidates.map{|regexp, args, proc| proc.to_backtrace_line}.join("\n")}
117
+ def step_match(step_name, formatted_step_name=nil)
118
+ matches = step_definitions.map { |d| d.step_match(step_name, formatted_step_name) }.compact
119
+ raise Undefined.new(step_name) if matches.empty?
120
+ matches = best_matches(step_name, matches) if matches.size > 1 && options[:guess]
121
+ raise Ambiguous.new(step_name, matches) if matches.size > 1
122
+ matches[0]
123
+ end
76
124
 
77
- }
78
- raise Multiple.new(message)
125
+ def best_matches(step_name, step_matches)
126
+ max_arg_length = step_matches.map {|step_match| step_match.args.length }.max
127
+ top_groups = step_matches.select {|step_match| step_match.args.length == max_arg_length }
128
+
129
+ if top_groups.length > 1
130
+ shortest_capture_length = top_groups.map {|step_match| step_match.args.inject(0) {|sum, c| sum + c.length } }.min
131
+ top_groups.select {|step_match| step_match.args.inject(0) {|sum, c| sum + c.length } == shortest_capture_length }
132
+ else
133
+ top_groups
79
134
  end
80
- end
81
-
82
- def proc_for(regexp)
83
- @step_procs[regexp]
84
135
  end
85
136
 
86
- def has_step_definition?(step_name)
87
- _, _, proc = regexp_args_proc(step_name)
88
- proc != PENDING
137
+ def step_definitions
138
+ @step_definitions ||= []
139
+ end
140
+
141
+ def snippet_text(step_keyword, step_name)
142
+ @snippet_generator.snippet_text(step_keyword, step_name)
89
143
  end
90
144
 
91
- # TODO - move execute here?
92
- def execute(step)
145
+ def print_step_definitions(out)
146
+ step_definitions.each do |step_definition|
147
+ indent = max_step_definition_length - step_definition.text_length
148
+ out.puts(step_definition.to_s(indent))
149
+ end
150
+ end
151
+
152
+ def before_and_after(scenario, skip=false)
153
+ unless current_world || skip
154
+ new_world!
155
+ execute_before(scenario)
156
+ end
157
+ if block_given?
158
+ yield
159
+ execute_after(scenario) unless skip
160
+ nil_world!
161
+ scenario_visited(scenario)
162
+ end
163
+ end
164
+
165
+ private
166
+
167
+ def max_step_definition_length
168
+ @max_step_definition_length ||= step_definitions.map{|step_definition| step_definition.text_length}.max
169
+ end
170
+
171
+ def options
172
+ @options || {}
173
+ end
174
+
175
+ # Creates a new world instance
176
+ def new_world!
177
+ @current_world = Object.new
178
+ (@world_procs ||= []).each do |proc|
179
+ @current_world = proc.call(@current_world)
180
+ end
181
+
182
+ @current_world.extend(World)
183
+ @current_world.__cucumber_step_mother = self
184
+ @current_world.__cucumber_visitor = @visitor
185
+
186
+ @current_world.extend(::Spec::Matchers) if defined?(::Spec::Matchers)
187
+ @current_world
188
+ end
189
+
190
+ def nil_world!
191
+ @current_world = nil
192
+ end
193
+
194
+ def execute_before(scenario)
195
+ (@before_procs ||= []).each do |proc|
196
+ @current_world.cucumber_instance_exec(false, 'Before', scenario, &proc)
197
+ end
198
+ end
199
+
200
+ def execute_after(scenario)
201
+ (@after_procs ||= []).each do |proc|
202
+ @current_world.cucumber_instance_exec(false, 'After', scenario, &proc)
203
+ end
204
+ end
205
+
206
+ def scenario_visited(scenario)
207
+ scenarios << scenario unless scenarios.index(scenario)
208
+ end
209
+
210
+ def options
211
+ @options || {}
93
212
  end
94
213
  end
95
214
  end
@@ -1,9 +1,10 @@
1
1
  module Cucumber #:nodoc:
2
2
  class VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 1
5
- TINY = 10
4
+ MINOR = 2
5
+ TINY = 0
6
+ PATCH = nil # Set to nil for official release
6
7
 
7
- STRING = [MAJOR, MINOR, TINY].join('.')
8
+ STRING = [MAJOR, MINOR, TINY, PATCH].compact.join('.')
8
9
  end
9
10
  end
@@ -0,0 +1,53 @@
1
+ module Cucumber
2
+ # All steps are run in the context of an object that extends this module
3
+ module World
4
+ class << self
5
+ def alias_adverb(adverb)
6
+ alias_method adverb, :__cucumber_invoke
7
+ end
8
+ end
9
+
10
+ attr_writer :__cucumber_step_mother, :__cucumber_visitor, :__cucumber_current_step
11
+
12
+ # Call a step from within a step definition
13
+ def __cucumber_invoke(name, multiline_argument=nil) #:nodoc:
14
+ begin
15
+ step_match = @__cucumber_step_mother.step_match(name)
16
+ step_match.invoke(self, multiline_argument)
17
+ rescue Exception => e
18
+ e.nested! if Undefined === e
19
+ @__cucumber_current_step.exception = e
20
+ raise e
21
+ end
22
+ end
23
+
24
+ def table(text, file=nil, line_offset=0)
25
+ @table_parser ||= Parser::TableParser.new
26
+ @table_parser.parse_or_fail(text.strip, file, line_offset)
27
+ end
28
+
29
+ # Output +announcement+ alongside the formatted output.
30
+ # This is an alternative to using Kernel#puts - it will display
31
+ # nicer, and in all outputs (in case you use several formatters)
32
+ #
33
+ # Beware that the output will be printed *before* the corresponding
34
+ # step. This is because the step itself will not be printed until
35
+ # after it has run, so it can be coloured according to its status.
36
+ def announce(announcement)
37
+ @__cucumber_visitor.announce(announcement)
38
+ end
39
+
40
+ def pending(message = "TODO")
41
+ if block_given?
42
+ begin
43
+ yield
44
+ rescue Exception => e
45
+ raise Pending.new(message)
46
+ end
47
+ raise Pending.new("Expected pending '#{message}' to fail. No Error was raised. No longer pending?")
48
+ else
49
+ raise Pending.new(message)
50
+ end
51
+ end
52
+ end
53
+ end
data/lib/cucumber.rb CHANGED
@@ -1,39 +1,63 @@
1
1
  $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
- require 'jcode'
4
+ require 'yaml'
5
5
  require 'cucumber/platform'
6
- require 'rubygems'
7
- require 'treetop/runtime'
8
- require 'treetop/ruby_extensions'
6
+ require 'cucumber/parser'
9
7
  require 'cucumber/version'
10
- require 'cucumber/step_methods'
11
- require 'cucumber/tree'
12
- require 'cucumber/model'
13
- require 'cucumber/executor'
14
8
  require 'cucumber/step_mother'
15
- require 'cucumber/formatters'
16
- require 'cucumber/treetop_parser/feature_parser'
17
- require 'cucumber/cli'
9
+ require 'cucumber/cli/main'
18
10
  require 'cucumber/broadcaster'
11
+ require 'cucumber/core_ext/exception'
19
12
 
20
13
  module Cucumber
21
- LANGUAGE_FILE = File.expand_path(File.dirname(__FILE__) + '/cucumber/languages.yml')
22
-
14
+ KEYWORD_KEYS = %w{name native encoding feature background scenario scenario_outline examples given when then but}
15
+
23
16
  class << self
24
- attr_reader :language
17
+ attr_reader :lang
25
18
 
26
- def load_language(lang)
27
- @language = config[lang]
19
+ def load_language(lang) #:nodoc:
20
+ return if @lang
21
+ @lang = lang
22
+ alias_step_definitions(lang)
23
+ Parser.load_parser(keyword_hash)
24
+ end
25
+
26
+ def language_incomplete?(lang=@lang)
27
+ KEYWORD_KEYS.detect{|key| keyword_hash(lang)[key].nil?}
28
+ end
29
+
30
+ # File mode that accounts for Ruby platform and current language
31
+ def file_mode(m)
32
+ Cucumber::RUBY_1_9 ? "#{m}:#{keyword_hash['encoding']}" : m
33
+ end
34
+
35
+ # Returns a Hash of the currently active
36
+ # language, or for a specific language if +lang+ is
37
+ # specified.
38
+ def keyword_hash(lang=@lang)
39
+ LANGUAGES[lang]
28
40
  end
29
41
 
30
- def languages
31
- config.keys.sort
42
+ def alias_step_definitions(lang) #:nodoc:
43
+ keywords = %w{given when then and but}.map{|keyword| keyword_hash(lang)[keyword]}
44
+ alias_steps(keywords)
32
45
  end
33
46
 
34
- def config
35
- require 'yaml'
36
- @config ||= YAML.load_file(LANGUAGE_FILE)
47
+ # Sets up additional method aliases for Given, When and Then.
48
+ # This does *not* affect how feature files are parsed. If you
49
+ # want to create aliases in the parser, you have to do this in
50
+ # languages.yml. For example:
51
+ #
52
+ # and: And|With
53
+ def alias_steps(keywords)
54
+ keywords.each do |adverb|
55
+ StepMother.alias_adverb(adverb)
56
+ World.alias_adverb(adverb)
57
+ end
37
58
  end
38
59
  end
60
+
61
+ # Make sure we always have English aliases
62
+ alias_step_definitions('en')
39
63
  end
@@ -4,13 +4,17 @@ require 'rbconfig'
4
4
  class CucumberGenerator < Rails::Generator::Base
5
5
  DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
6
6
  Config::CONFIG['ruby_install_name'])
7
+
8
+ attr_accessor :framework
9
+
7
10
  def manifest
8
11
  record do |m|
9
12
  m.directory 'features/step_definitions'
10
- m.file 'webrat_steps.rb', 'features/step_definitions/webrat_steps.rb'
13
+ m.template 'webrat_steps.rb', 'features/step_definitions/webrat_steps.rb'
11
14
 
12
15
  m.directory 'features/support'
13
- m.file 'env.rb', 'features/support/env.rb'
16
+ m.template 'env.rb', 'features/support/env.rb'
17
+ m.file 'paths.rb', 'features/support/paths.rb'
14
18
 
15
19
  m.directory 'lib/tasks'
16
20
  m.file 'cucumber.rake', 'lib/tasks/cucumber.rake'
@@ -21,10 +25,26 @@ class CucumberGenerator < Rails::Generator::Base
21
25
  end
22
26
  end
23
27
 
28
+ def framework
29
+ options[:framework] || :rspec
30
+ end
31
+
24
32
  protected
25
33
 
26
34
  def banner
27
35
  "Usage: #{$0} cucumber"
28
36
  end
29
37
 
30
- end
38
+ def add_options!(opt)
39
+ opt.separator ''
40
+ opt.separator 'Options:'
41
+ opt.on('--rspec', 'Setup cucumber for use with RSpec (default)') do |value|
42
+ options[:framework] = :rspec
43
+ end
44
+
45
+ opt.on('--testunit', 'Setup cucumber for use with test/unit') do |value|
46
+ options[:framework] = :testunit
47
+ end
48
+ end
49
+
50
+ end
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  begin
3
3
  load File.expand_path(File.dirname(__FILE__) + "/../vendor/plugins/cucumber/bin/cucumber")
4
- rescue LoadError
4
+ rescue LoadError => e
5
+ raise unless e.to_s =~ /cucumber/
5
6
  require "rubygems"
6
7
  load File.join(Gem.bindir, "cucumber")
7
8
  end
@@ -1,7 +1,15 @@
1
- $:.unshift(RAILS_ROOT + '/vendor/plugins/cucumber/lib')
2
- require 'cucumber/rake/task'
1
+ $LOAD_PATH.unshift(RAILS_ROOT + '/vendor/plugins/cucumber/lib') if File.directory?(RAILS_ROOT + '/vendor/plugins/cucumber/lib')
3
2
 
4
- Cucumber::Rake::Task.new(:features) do |t|
5
- t.cucumber_opts = "--format pretty"
3
+ begin
4
+ require 'cucumber/rake/task'
5
+
6
+ Cucumber::Rake::Task.new(:features) do |t|
7
+ t.cucumber_opts = "--format pretty"
8
+ end
9
+ task :features => 'db:test:prepare'
10
+ rescue LoadError
11
+ desc 'Cucumber rake task not available'
12
+ task :features do
13
+ abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
14
+ end
6
15
  end
7
- task :features => 'db:test:prepare'
@@ -1,8 +1,17 @@
1
1
  # Sets up the Rails environment for Cucumber
2
- ENV["RAILS_ENV"] = "test"
2
+ ENV["RAILS_ENV"] ||= "test"
3
3
  require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
4
4
  require 'cucumber/rails/world'
5
+ require 'cucumber/formatters/unicode' # Comment out this line if you don't want Cucumber Unicode support
5
6
  Cucumber::Rails.use_transactional_fixtures
6
7
 
7
- # Comment out the next line if you're not using RSpec's matchers (should / should_not) in your steps.
8
+ require 'webrat'
9
+
10
+ Webrat.configure do |config|
11
+ config.mode = :rails
12
+ end
13
+ <% if framework == :rspec -%>
14
+
8
15
  require 'cucumber/rails/rspec'
16
+ require 'webrat/core/matchers'
17
+ <% end -%>
@@ -0,0 +1,19 @@
1
+ module NavigationHelpers
2
+ def path_to(page_name)
3
+ case page_name
4
+
5
+ when /the homepage/
6
+ root_path
7
+
8
+ # Add more page name => path mappings here
9
+
10
+ else
11
+ raise "Can't find mapping from \"#{page_name}\" to a path."
12
+ end
13
+ end
14
+ end
15
+
16
+ World do |world|
17
+ world.extend NavigationHelpers
18
+ world
19
+ end