jwilger-cucumber 0.3.11.200906161550

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 (411) hide show
  1. data/History.txt +830 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +410 -0
  4. data/README.txt +4 -0
  5. data/Rakefile +9 -0
  6. data/bin/cucumber +17 -0
  7. data/config/hoe.rb +76 -0
  8. data/config/requirements.rb +15 -0
  9. data/cucumber.yml +2 -0
  10. data/examples/cs/README.textile +1 -0
  11. data/examples/cs/Rakefile +12 -0
  12. data/examples/cs/compile.bat +1 -0
  13. data/examples/cs/features/addition.feature +16 -0
  14. data/examples/cs/features/step_definitons/calculator_steps.rb +19 -0
  15. data/examples/cs/src/demo/Calculator.cs +20 -0
  16. data/examples/dos_line_endings/Rakefile +6 -0
  17. data/examples/dos_line_endings/features/dos_line_endings.feature +9 -0
  18. data/examples/i18n/README.textile +18 -0
  19. data/examples/i18n/Rakefile +30 -0
  20. data/examples/i18n/ar/Rakefile +6 -0
  21. data/examples/i18n/ar/features/addition.feature +17 -0
  22. data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +24 -0
  23. data/examples/i18n/ar/lib/calculator.rb +11 -0
  24. data/examples/i18n/bg/Rakefile +6 -0
  25. data/examples/i18n/bg/features/addition.feature +12 -0
  26. data/examples/i18n/bg/features/consecutive_calculations.feature +19 -0
  27. data/examples/i18n/bg/features/division.feature +17 -0
  28. data/examples/i18n/bg/features/step_definitons/calculator_steps.rb +24 -0
  29. data/examples/i18n/bg/features/support/env.rb +6 -0
  30. data/examples/i18n/bg/features/support/world.rb +8 -0
  31. data/examples/i18n/bg/lib/calculator.rb +24 -0
  32. data/examples/i18n/cat/Rakefile +6 -0
  33. data/examples/i18n/cat/features/step_definitons/calculator_steps.rb +21 -0
  34. data/examples/i18n/cat/features/suma.feature +17 -0
  35. data/examples/i18n/cat/lib/calculadora.rb +16 -0
  36. data/examples/i18n/da/Rakefile +6 -0
  37. data/examples/i18n/da/features/step_definitons/kalkulator_steps.rb +24 -0
  38. data/examples/i18n/da/features/summering.feature +18 -0
  39. data/examples/i18n/da/lib/kalkulator.rb +11 -0
  40. data/examples/i18n/de/Rakefile +6 -0
  41. data/examples/i18n/de/features/addition.feature +17 -0
  42. data/examples/i18n/de/features/division.feature +10 -0
  43. data/examples/i18n/de/features/step_definitons/calculator_steps.rb +24 -0
  44. data/examples/i18n/de/lib/calculator.rb +14 -0
  45. data/examples/i18n/en/Rakefile +6 -0
  46. data/examples/i18n/en/features/addition.feature +17 -0
  47. data/examples/i18n/en/features/division.feature +10 -0
  48. data/examples/i18n/en/features/step_definitons/calculator_steps.rb +24 -0
  49. data/examples/i18n/en/lib/calculator.rb +14 -0
  50. data/examples/i18n/en-lol/Rakefile +6 -0
  51. data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +16 -0
  52. data/examples/i18n/en-lol/features/stuffing.feature +8 -0
  53. data/examples/i18n/en-lol/features/support/env.rb +8 -0
  54. data/examples/i18n/en-lol/lib/basket.rb +12 -0
  55. data/examples/i18n/en-lol/lib/belly.rb +11 -0
  56. data/examples/i18n/es/Rakefile +6 -0
  57. data/examples/i18n/es/features/adicion.feature +17 -0
  58. data/examples/i18n/es/features/step_definitons/calculador_steps.rb +21 -0
  59. data/examples/i18n/es/lib/calculador.rb +14 -0
  60. data/examples/i18n/et/Rakefile +6 -0
  61. data/examples/i18n/et/features/jagamine.feature +10 -0
  62. data/examples/i18n/et/features/liitmine.feature +17 -0
  63. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +24 -0
  64. data/examples/i18n/et/lib/kalkulaator.rb +14 -0
  65. data/examples/i18n/fi/Rakefile +6 -0
  66. data/examples/i18n/fi/features/jakolasku.feature +10 -0
  67. data/examples/i18n/fi/features/step_definitons/laskin_steps.rb +24 -0
  68. data/examples/i18n/fi/features/yhteenlasku.feature +16 -0
  69. data/examples/i18n/fi/lib/laskin.rb +14 -0
  70. data/examples/i18n/fr/Rakefile +6 -0
  71. data/examples/i18n/fr/features/addition.feature +18 -0
  72. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +25 -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/Rakefile +6 -0
  80. data/examples/i18n/hu/features/addition.feature +17 -0
  81. data/examples/i18n/hu/features/division.feature +10 -0
  82. data/examples/i18n/hu/features/step_definitons/calculator_steps.rb +25 -0
  83. data/examples/i18n/hu/lib/calculator.rb +14 -0
  84. data/examples/i18n/id/Rakefile +6 -0
  85. data/examples/i18n/id/features/addition.feature +17 -0
  86. data/examples/i18n/id/features/division.feature +10 -0
  87. data/examples/i18n/id/features/step_definitons/calculator_steps.rb +24 -0
  88. data/examples/i18n/id/lib/calculator.rb +14 -0
  89. data/examples/i18n/it/Rakefile +6 -0
  90. data/examples/i18n/it/features/somma.feature +11 -0
  91. data/examples/i18n/it/features/step_definitons/calcolatrice_steps.rb +24 -0
  92. data/examples/i18n/it/lib/calcolatrice.rb +11 -0
  93. data/examples/i18n/ja/Rakefile +6 -0
  94. data/examples/i18n/ja/features/addition.feature +17 -0
  95. data/examples/i18n/ja/features/division.feature +10 -0
  96. data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +24 -0
  97. data/examples/i18n/ja/lib/calculator.rb +14 -0
  98. data/examples/i18n/ko/Rakefile +6 -0
  99. data/examples/i18n/ko/features/addition.feature +17 -0
  100. data/examples/i18n/ko/features/division.feature +11 -0
  101. data/examples/i18n/ko/features/step_definitons/calculator_steps.rb +24 -0
  102. data/examples/i18n/ko/lib/calculator.rb +14 -0
  103. data/examples/i18n/lt/Rakefile +6 -0
  104. data/examples/i18n/lt/features/addition.feature +17 -0
  105. data/examples/i18n/lt/features/division.feature +10 -0
  106. data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +24 -0
  107. data/examples/i18n/lt/lib/calculator.rb +14 -0
  108. data/examples/i18n/lv/Rakefile +6 -0
  109. data/examples/i18n/lv/features/addition.feature +17 -0
  110. data/examples/i18n/lv/features/division.feature +10 -0
  111. data/examples/i18n/lv/features/step_definitons/calculator_steps.rb +24 -0
  112. data/examples/i18n/lv/lib/calculator.rb +14 -0
  113. data/examples/i18n/no/Rakefile +6 -0
  114. data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +17 -0
  115. data/examples/i18n/no/features/summering.feature +19 -0
  116. data/examples/i18n/no/features/support/env.rb +6 -0
  117. data/examples/i18n/no/lib/kalkulator.rb +11 -0
  118. data/examples/i18n/pl/Rakefile +6 -0
  119. data/examples/i18n/pl/features/addition.feature +17 -0
  120. data/examples/i18n/pl/features/division.feature +10 -0
  121. data/examples/i18n/pl/features/step_definitons/calculator_steps.rb +24 -0
  122. data/examples/i18n/pl/features/support/env.rb +6 -0
  123. data/examples/i18n/pl/lib/calculator.rb +14 -0
  124. data/examples/i18n/pt/Rakefile +6 -0
  125. data/examples/i18n/pt/features/adicao.feature +11 -0
  126. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +20 -0
  127. data/examples/i18n/pt/features/support/env.rb +6 -0
  128. data/examples/i18n/pt/lib/calculadora.rb +10 -0
  129. data/examples/i18n/ro/Rakefile +6 -0
  130. data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +24 -0
  131. data/examples/i18n/ro/features/suma.feature +11 -0
  132. data/examples/i18n/ro/lib/calculator.rb +11 -0
  133. data/examples/i18n/ru/Rakefile +6 -0
  134. data/examples/i18n/ru/features/addition.feature +11 -0
  135. data/examples/i18n/ru/features/consecutive_calculations.feature +17 -0
  136. data/examples/i18n/ru/features/division.feature +16 -0
  137. data/examples/i18n/ru/features/step_definitons/calculator_steps.rb +19 -0
  138. data/examples/i18n/ru/features/support/env.rb +6 -0
  139. data/examples/i18n/ru/features/support/world.rb +8 -0
  140. data/examples/i18n/ru/lib/calculator.rb +24 -0
  141. data/examples/i18n/se/Rakefile +6 -0
  142. data/examples/i18n/se/features/step_definitons/kalkulator_steps.rb +24 -0
  143. data/examples/i18n/se/features/summering.feature +18 -0
  144. data/examples/i18n/se/lib/kalkulator.rb +11 -0
  145. data/examples/i18n/sk/Rakefile +6 -0
  146. data/examples/i18n/sk/features/addition.feature +17 -0
  147. data/examples/i18n/sk/features/division.feature +10 -0
  148. data/examples/i18n/sk/features/step_definitons/calculator_steps.rb +24 -0
  149. data/examples/i18n/sk/lib/calculator.rb +14 -0
  150. data/examples/i18n/zh-CN/Rakefile +6 -0
  151. data/examples/i18n/zh-CN/features/addition.feature +18 -0
  152. data/examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb +26 -0
  153. data/examples/i18n/zh-CN/lib/calculator.rb +10 -0
  154. data/examples/i18n/zh-TW/Rakefile +6 -0
  155. data/examples/i18n/zh-TW/features/addition.feature +17 -0
  156. data/examples/i18n/zh-TW/features/division.feature +11 -0
  157. data/examples/i18n/zh-TW/features/step_definitons/calculator_steps.rb +24 -0
  158. data/examples/i18n/zh-TW/lib/calculator.rb +14 -0
  159. data/examples/java/README.textile +18 -0
  160. data/examples/java/build.xml +33 -0
  161. data/examples/java/features/hello.feature +11 -0
  162. data/examples/java/features/step_definitons/hello_steps.rb +23 -0
  163. data/examples/java/features/step_definitons/tree_steps.rb +14 -0
  164. data/examples/java/features/tree.feature +9 -0
  165. data/examples/java/src/cucumber/demo/Hello.java +16 -0
  166. data/examples/junit/features/one_passing_one_failing.feature +8 -0
  167. data/examples/junit/features/pending.feature +5 -0
  168. data/examples/junit/features/step_definitions/steps.rb +11 -0
  169. data/examples/pure_java/README.textile +5 -0
  170. data/examples/selenium/Rakefile +6 -0
  171. data/examples/selenium/features/search.feature +9 -0
  172. data/examples/selenium/features/step_definitons/search_steps.rb +13 -0
  173. data/examples/selenium/features/support/env.rb +19 -0
  174. data/examples/selenium_webrat/Rakefile +6 -0
  175. data/examples/selenium_webrat/config.ru +0 -0
  176. data/examples/selenium_webrat/features/search.feature +9 -0
  177. data/examples/selenium_webrat/features/step_definitons/search_steps.rb +13 -0
  178. data/examples/selenium_webrat/features/support/env.rb +45 -0
  179. data/examples/self_test/README.textile +6 -0
  180. data/examples/self_test/Rakefile +6 -0
  181. data/examples/self_test/features/background/background_tagged_before_on_outline.feature +12 -0
  182. data/examples/self_test/features/background/background_with_name.feature +7 -0
  183. data/examples/self_test/features/background/failing_background.feature +12 -0
  184. data/examples/self_test/features/background/failing_background_after_success.feature +11 -0
  185. data/examples/self_test/features/background/multiline_args_background.feature +32 -0
  186. data/examples/self_test/features/background/passing_background.feature +10 -0
  187. data/examples/self_test/features/background/pending_background.feature +10 -0
  188. data/examples/self_test/features/background/scenario_outline_failing_background.feature +16 -0
  189. data/examples/self_test/features/background/scenario_outline_passing_background.feature +16 -0
  190. data/examples/self_test/features/call_undefined_step_from_step_def.feature +7 -0
  191. data/examples/self_test/features/failing_expectation.feature +4 -0
  192. data/examples/self_test/features/lots_of_undefined.feature +8 -0
  193. data/examples/self_test/features/multiline_name.feature +27 -0
  194. data/examples/self_test/features/outline_sample.feature +15 -0
  195. data/examples/self_test/features/sample.feature +21 -0
  196. data/examples/self_test/features/search_sample.feature +32 -0
  197. data/examples/self_test/features/step_definitions/sample_steps.rb +81 -0
  198. data/examples/self_test/features/support/env.rb +17 -0
  199. data/examples/self_test/features/tons_of_cukes.feature +52 -0
  200. data/examples/self_test/features/undefined_multiline_args.feature +12 -0
  201. data/examples/sinatra/Rakefile +6 -0
  202. data/examples/sinatra/app.rb +14 -0
  203. data/examples/sinatra/features/add.feature +11 -0
  204. data/examples/sinatra/features/step_definitions/add_steps.rb +15 -0
  205. data/examples/sinatra/features/support/env.rb +28 -0
  206. data/examples/sinatra/views/add.erb +5 -0
  207. data/examples/sinatra/views/layout.erb +8 -0
  208. data/examples/steps_library/features/step_definitions/steps_lib1.rb +8 -0
  209. data/examples/steps_library/features/step_definitions/steps_lib2.rb +8 -0
  210. data/examples/test_unit/Rakefile +6 -0
  211. data/examples/test_unit/features/step_definitions/test_unit_steps.rb +23 -0
  212. data/examples/test_unit/features/test_unit.feature +9 -0
  213. data/examples/tickets/Rakefile +16 -0
  214. data/examples/tickets/features/172.feature +28 -0
  215. data/examples/tickets/features/177/1.feature +29 -0
  216. data/examples/tickets/features/177/2.feature +21 -0
  217. data/examples/tickets/features/177/3.feature +18 -0
  218. data/examples/tickets/features/180.feature +7 -0
  219. data/examples/tickets/features/229/tagged_hooks.feature +8 -0
  220. data/examples/tickets/features/229/tagged_hooks.rb +14 -0
  221. data/examples/tickets/features/236.feature +13 -0
  222. data/examples/tickets/features/241.feature +13 -0
  223. data/examples/tickets/features/246.feature +4 -0
  224. data/examples/tickets/features/248.feature +11 -0
  225. data/examples/tickets/features/270/back.feature +14 -0
  226. data/examples/tickets/features/270/back.steps.rb +14 -0
  227. data/examples/tickets/features/272/hooks.feature +26 -0
  228. data/examples/tickets/features/272/hooks_steps.rb +53 -0
  229. data/examples/tickets/features/279/py_string_indent.feature +25 -0
  230. data/examples/tickets/features/279/py_string_indent.steps.rb +12 -0
  231. data/examples/tickets/features/279/wrong.feature_ +11 -0
  232. data/examples/tickets/features/301/filter_background_tagged_hooks.feature +6 -0
  233. data/examples/tickets/features/301/filter_background_tagged_hooks_steps.rb +12 -0
  234. data/examples/tickets/features/306/only_background.feature +4 -0
  235. data/examples/tickets/features/lib/eatting_machine.rb +18 -0
  236. data/examples/tickets/features/lib/pantry.rb +20 -0
  237. data/examples/tickets/features/scenario_outline.feature +95 -0
  238. data/examples/tickets/features/step_definitons/246_steps.rb +3 -0
  239. data/examples/tickets/features/step_definitons/248_steps.rb +15 -0
  240. data/examples/tickets/features/step_definitons/scenario_outline_steps.rb +42 -0
  241. data/examples/tickets/features/step_definitons/tickets_steps.rb +66 -0
  242. data/examples/tickets/features/tickets.feature +28 -0
  243. data/examples/watir/README.textile +16 -0
  244. data/examples/watir/Rakefile +6 -0
  245. data/examples/watir/features/search.feature +12 -0
  246. data/examples/watir/features/step_definitons/search_steps.rb +22 -0
  247. data/examples/watir/features/support/env.rb +32 -0
  248. data/features/after_block_exceptions.feature +102 -0
  249. data/features/after_step_block_exceptions.feature +104 -0
  250. data/features/background.feature +311 -0
  251. data/features/bug_371.feature +32 -0
  252. data/features/cucumber_cli.feature +549 -0
  253. data/features/cucumber_cli_diff_disabled.feature +53 -0
  254. data/features/cucumber_cli_outlines.feature +109 -0
  255. data/features/custom_formatter.feature +11 -0
  256. data/features/drb_server_integration.feature +115 -0
  257. data/features/exclude_files.feature +20 -0
  258. data/features/expand.feature +49 -0
  259. data/features/html_formatter/a.html +185 -0
  260. data/features/html_formatter.feature +7 -0
  261. data/features/junit_formatter.feature +71 -0
  262. data/features/language_from_header.feature +30 -0
  263. data/features/multiline_names.feature +43 -0
  264. data/features/rake_task.feature +150 -0
  265. data/features/report_called_undefined_steps.feature +35 -0
  266. data/features/snippet.feature +22 -0
  267. data/features/step_definitions/cucumber_steps.rb +130 -0
  268. data/features/step_definitions/extra_steps.rb +2 -0
  269. data/features/steps_formatter.feature +25 -0
  270. data/features/support/env.rb +120 -0
  271. data/features/usage.feature +126 -0
  272. data/features/work_in_progress.feature +151 -0
  273. data/gem_tasks/deployment.rake +11 -0
  274. data/gem_tasks/environment.rake +7 -0
  275. data/gem_tasks/features.rake +10 -0
  276. data/gem_tasks/fix_cr_lf.rake +10 -0
  277. data/gem_tasks/flog.rake +4 -0
  278. data/gem_tasks/gemspec.rake +10 -0
  279. data/gem_tasks/rspec.rake +45 -0
  280. data/gem_tasks/sass.rake +4 -0
  281. data/gem_tasks/yard.rake +8 -0
  282. data/lib/autotest/cucumber.rb +6 -0
  283. data/lib/autotest/cucumber_mixin.rb +125 -0
  284. data/lib/autotest/cucumber_rails.rb +6 -0
  285. data/lib/autotest/cucumber_rails_rspec.rb +6 -0
  286. data/lib/autotest/cucumber_rspec.rb +6 -0
  287. data/lib/autotest/discover.rb +9 -0
  288. data/lib/cucumber/ast/background.rb +62 -0
  289. data/lib/cucumber/ast/comment.rb +30 -0
  290. data/lib/cucumber/ast/examples.rb +26 -0
  291. data/lib/cucumber/ast/feature.rb +58 -0
  292. data/lib/cucumber/ast/feature_element.rb +57 -0
  293. data/lib/cucumber/ast/features.rb +30 -0
  294. data/lib/cucumber/ast/outline_table.rb +143 -0
  295. data/lib/cucumber/ast/py_string.rb +57 -0
  296. data/lib/cucumber/ast/scenario.rb +83 -0
  297. data/lib/cucumber/ast/scenario_outline.rb +93 -0
  298. data/lib/cucumber/ast/step.rb +112 -0
  299. data/lib/cucumber/ast/step_collection.rb +75 -0
  300. data/lib/cucumber/ast/step_invocation.rb +136 -0
  301. data/lib/cucumber/ast/table.rb +334 -0
  302. data/lib/cucumber/ast/tags.rb +33 -0
  303. data/lib/cucumber/ast/visitor.rb +116 -0
  304. data/lib/cucumber/ast.rb +29 -0
  305. data/lib/cucumber/broadcaster.rb +13 -0
  306. data/lib/cucumber/cli/configuration.rb +427 -0
  307. data/lib/cucumber/cli/drb_client.rb +20 -0
  308. data/lib/cucumber/cli/language_help_formatter.rb +59 -0
  309. data/lib/cucumber/cli/main.rb +136 -0
  310. data/lib/cucumber/core_ext/exception.rb +53 -0
  311. data/lib/cucumber/core_ext/instance_exec.rb +67 -0
  312. data/lib/cucumber/core_ext/proc.rb +29 -0
  313. data/lib/cucumber/core_ext/string.rb +48 -0
  314. data/lib/cucumber/feature_file.rb +47 -0
  315. data/lib/cucumber/filter.rb +50 -0
  316. data/lib/cucumber/formatter/ansicolor.rb +110 -0
  317. data/lib/cucumber/formatter/color_io.rb +23 -0
  318. data/lib/cucumber/formatter/console.rb +149 -0
  319. data/lib/cucumber/formatter/cucumber.css +132 -0
  320. data/lib/cucumber/formatter/cucumber.sass +139 -0
  321. data/lib/cucumber/formatter/duration.rb +10 -0
  322. data/lib/cucumber/formatter/html.rb +258 -0
  323. data/lib/cucumber/formatter/junit.rb +75 -0
  324. data/lib/cucumber/formatter/pretty.rb +188 -0
  325. data/lib/cucumber/formatter/profile.rb +77 -0
  326. data/lib/cucumber/formatter/progress.rb +60 -0
  327. data/lib/cucumber/formatter/rerun.rb +44 -0
  328. data/lib/cucumber/formatter/steps.rb +49 -0
  329. data/lib/cucumber/formatter/tag_cloud.rb +28 -0
  330. data/lib/cucumber/formatter/unicode.rb +35 -0
  331. data/lib/cucumber/formatter/usage.rb +85 -0
  332. data/lib/cucumber/formatters/unicode.rb +7 -0
  333. data/lib/cucumber/languages.yml +532 -0
  334. data/lib/cucumber/parser/feature.rb +1787 -0
  335. data/lib/cucumber/parser/feature.tt +324 -0
  336. data/lib/cucumber/parser/i18n/language.rb +80 -0
  337. data/lib/cucumber/parser/i18n.tt +42 -0
  338. data/lib/cucumber/parser/table.rb +414 -0
  339. data/lib/cucumber/parser/table.tt +71 -0
  340. data/lib/cucumber/parser/treetop_ext.rb +52 -0
  341. data/lib/cucumber/parser.rb +6 -0
  342. data/lib/cucumber/platform.rb +23 -0
  343. data/lib/cucumber/rails/rspec.rb +10 -0
  344. data/lib/cucumber/rails/world.rb +99 -0
  345. data/lib/cucumber/rake/task.rb +233 -0
  346. data/lib/cucumber/rspec_neuter.rb +23 -0
  347. data/lib/cucumber/step_definition.rb +122 -0
  348. data/lib/cucumber/step_match.rb +61 -0
  349. data/lib/cucumber/step_mother.rb +362 -0
  350. data/lib/cucumber/version.rb +10 -0
  351. data/lib/cucumber/world.rb +53 -0
  352. data/lib/cucumber.rb +11 -0
  353. data/rails_generators/cucumber/USAGE +11 -0
  354. data/rails_generators/cucumber/cucumber_generator.rb +66 -0
  355. data/rails_generators/cucumber/templates/cucumber +8 -0
  356. data/rails_generators/cucumber/templates/cucumber.rake +20 -0
  357. data/rails_generators/cucumber/templates/cucumber_environment.rb +23 -0
  358. data/rails_generators/cucumber/templates/env.rb +26 -0
  359. data/rails_generators/cucumber/templates/paths.rb +27 -0
  360. data/rails_generators/cucumber/templates/spork_env.rb +36 -0
  361. data/rails_generators/cucumber/templates/webrat_steps.rb +147 -0
  362. data/rails_generators/feature/USAGE +12 -0
  363. data/rails_generators/feature/feature_generator.rb +40 -0
  364. data/rails_generators/feature/templates/feature.erb +31 -0
  365. data/rails_generators/feature/templates/steps.erb +20 -0
  366. data/spec/cucumber/ast/background_spec.rb +50 -0
  367. data/spec/cucumber/ast/feature_element_spec.rb +40 -0
  368. data/spec/cucumber/ast/feature_factory.rb +63 -0
  369. data/spec/cucumber/ast/feature_spec.rb +38 -0
  370. data/spec/cucumber/ast/py_string_spec.rb +51 -0
  371. data/spec/cucumber/ast/scenario_outline_spec.rb +67 -0
  372. data/spec/cucumber/ast/scenario_spec.rb +38 -0
  373. data/spec/cucumber/ast/step_collection_spec.rb +17 -0
  374. data/spec/cucumber/ast/step_spec.rb +66 -0
  375. data/spec/cucumber/ast/table_spec.rb +186 -0
  376. data/spec/cucumber/ast/visitor_spec.rb +27 -0
  377. data/spec/cucumber/broadcaster_spec.rb +15 -0
  378. data/spec/cucumber/cli/configuration_spec.rb +396 -0
  379. data/spec/cucumber/cli/drb_client_spec.rb +43 -0
  380. data/spec/cucumber/cli/main_spec.rb +140 -0
  381. data/spec/cucumber/core_ext/proc_spec.rb +54 -0
  382. data/spec/cucumber/core_ext/string_spec.rb +42 -0
  383. data/spec/cucumber/formatter/ansicolor_spec.rb +35 -0
  384. data/spec/cucumber/formatter/color_io_spec.rb +27 -0
  385. data/spec/cucumber/formatter/duration_spec.rb +22 -0
  386. data/spec/cucumber/formatter/progress_spec.rb +36 -0
  387. data/spec/cucumber/parser/feature_parser_spec.rb +387 -0
  388. data/spec/cucumber/parser/table_parser_spec.rb +48 -0
  389. data/spec/cucumber/rails/stubs/mini_rails.rb +18 -0
  390. data/spec/cucumber/rails/stubs/test_help.rb +1 -0
  391. data/spec/cucumber/rails/world_spec.rb +11 -0
  392. data/spec/cucumber/sell_cucumbers.feature +19 -0
  393. data/spec/cucumber/step_definition_spec.rb +101 -0
  394. data/spec/cucumber/step_mother_spec.rb +155 -0
  395. data/spec/cucumber/treetop_parser/empty_feature.feature +4 -0
  396. data/spec/cucumber/treetop_parser/empty_scenario.feature +9 -0
  397. data/spec/cucumber/treetop_parser/empty_scenario_outline.feature +3 -0
  398. data/spec/cucumber/treetop_parser/fit_scenario.feature +8 -0
  399. data/spec/cucumber/treetop_parser/given_scenario.feature +9 -0
  400. data/spec/cucumber/treetop_parser/invalid_scenario_outlines.feature +7 -0
  401. data/spec/cucumber/treetop_parser/multiline_steps.feature +17 -0
  402. data/spec/cucumber/treetop_parser/multiple_tables.feature +27 -0
  403. data/spec/cucumber/treetop_parser/scenario_outline.feature +16 -0
  404. data/spec/cucumber/treetop_parser/spaces.feature +12 -0
  405. data/spec/cucumber/treetop_parser/test_dos.feature +25 -0
  406. data/spec/cucumber/treetop_parser/with_comments.feature +10 -0
  407. data/spec/cucumber/treetop_parser/with_tags.feature +18 -0
  408. data/spec/cucumber/world/pending_spec.rb +47 -0
  409. data/spec/spec.opts +2 -0
  410. data/spec/spec_helper.rb +13 -0
  411. metadata +506 -0
@@ -0,0 +1,387 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'cucumber/parser/i18n/language'
3
+
4
+ module Cucumber
5
+ module Parser
6
+ describe Feature do
7
+ before do
8
+ @parser = I18n::Language['en'].parser
9
+ end
10
+
11
+ def parse(text)
12
+ feature = @parser.parse_or_fail(text)
13
+ end
14
+
15
+ def parse_file(file)
16
+ FeatureFile.new(File.dirname(__FILE__) + "/../treetop_parser/" + file).parse
17
+ end
18
+
19
+ def parse_example_file(file)
20
+ FeatureFile.new(File.dirname(__FILE__) + "/../../../examples/" + file).parse
21
+ end
22
+
23
+ describe "Comments" do
24
+ it "should parse a file with only a one line comment" do
25
+ parse(%{# My comment
26
+ Feature: hi
27
+ }).to_sexp.should ==
28
+ [:feature, nil, "Feature: hi",
29
+ [:comment, "# My comment\n"]]
30
+ end
31
+
32
+ it "should parse a file with only a multiline comment" do
33
+ parse(%{# Hello
34
+ # World
35
+ Feature: hi
36
+ }).to_sexp.should ==
37
+ [:feature, nil, "Feature: hi",
38
+ [:comment, "# Hello\n# World\n"]]
39
+ end
40
+
41
+ it "should parse a file with no comments" do
42
+ parse("Feature: hi\n").to_sexp.should ==
43
+ [:feature, nil, "Feature: hi"]
44
+ end
45
+
46
+ it "should parse a file with only a multiline comment with newlines" do
47
+ parse("# Hello\n\n# World\n").to_sexp.should ==
48
+ [:feature, nil, "",
49
+ [:comment, "# Hello\n\n# World\n"]]
50
+ end
51
+
52
+ it "should not consume comments as part of a multiline name" do
53
+ parse("Feature: hi\n Scenario: test\n\n#hello\n Scenario: another").to_sexp.should ==
54
+ [:feature, nil, "Feature: hi",
55
+ [:scenario, 2, "Scenario:", "test"],
56
+ [:scenario, 5, "Scenario:", "another",
57
+ [:comment, "#hello\n "]]]
58
+ end
59
+ end
60
+
61
+ describe "Tags" do
62
+ it "should parse a file with tags on a feature" do
63
+ parse("# My comment\n@hello @world Feature: hi\n").to_sexp.should ==
64
+ [:feature, nil, "Feature: hi",
65
+ [:comment, "# My comment\n"],
66
+ [:tag, "hello"],
67
+ [:tag, "world"]]
68
+ end
69
+
70
+ it "should not take the tags as part of a multiline name feature element" do
71
+ parse("Feature: hi\n Scenario: test\n\n@hello Scenario: another").to_sexp.should ==
72
+ [:feature, nil, "Feature: hi",
73
+ [:scenario, 2, "Scenario:", "test"],
74
+ [:scenario, 4, "Scenario:", "another",
75
+ [:tag, "hello"]]]
76
+ end
77
+
78
+ it "should parse a file with tags on a scenario" do
79
+ parse(%{# FC
80
+ @ft
81
+ Feature: hi
82
+
83
+ @st1 @st2
84
+ Scenario: First
85
+ Given Pepper
86
+
87
+ @st3
88
+ @st4 @ST5 @#^%&ST6**!
89
+ Scenario: Second}).to_sexp.should ==
90
+ [:feature, nil, "Feature: hi",
91
+ [:comment, "# FC\n "],
92
+ [:tag, "ft"],
93
+ [:scenario, 6, 'Scenario:', 'First',
94
+ [:tag, "st1"], [:tag, "st2"],
95
+ [:step_invocation, 7, "Given", "Pepper"]
96
+ ],
97
+ [:scenario, 11, 'Scenario:', 'Second',
98
+ [:tag, "st3"], [:tag, "st4"], [:tag, "ST5"], [:tag, "#^%&ST6**!"]]]
99
+ end
100
+ end
101
+
102
+ describe "Background" do
103
+ it "should have steps" do
104
+ parse("Feature: Hi\nBackground:\nGiven I am a step\n").to_sexp.should ==
105
+ [:feature, nil, "Feature: Hi",
106
+ [:background, 2, "Background:",
107
+ [:step, 3, "Given", "I am a step"]]]
108
+ end
109
+
110
+ it "should allow multiline names" do
111
+ parse(%{Feature: Hi
112
+ Background: It is my ambition to say
113
+ in ten sentences
114
+ what others say
115
+ in a whole book.
116
+ Given I am a step}).to_sexp.should ==
117
+ [:feature, nil, "Feature: Hi",
118
+ [:background, 2, "Background:", "It is my ambition to say\nin ten sentences\nwhat others say\nin a whole book.",
119
+ [:step, 6, "Given", "I am a step"]]]
120
+ end
121
+ end
122
+
123
+ describe "Scenarios" do
124
+ it "can be empty" do
125
+ parse("Feature: Hi\n\nScenario: Hello\n").to_sexp.should ==
126
+ [:feature, nil, "Feature: Hi",
127
+ [:scenario, 3, "Scenario:", "Hello"]]
128
+ end
129
+
130
+ it "should allow whitespace lines after the Scenario line" do
131
+ parse(%{Feature: Foo
132
+
133
+ Scenario: bar
134
+
135
+ Given baz})
136
+ end
137
+
138
+ it "should have steps" do
139
+ parse("Feature: Hi\nScenario: Hello\nGiven I am a step\n").to_sexp.should ==
140
+ [:feature, nil, "Feature: Hi",
141
+ [:scenario, 2, "Scenario:", "Hello",
142
+ [:step_invocation, 3, "Given", "I am a step"]]]
143
+ end
144
+
145
+ it "should have steps with inline table" do
146
+ parse(%{Feature: Hi
147
+ Scenario: Hello
148
+ Given I have a table
149
+ |a|b|
150
+ }).to_sexp.should ==
151
+ [:feature, nil, "Feature: Hi",
152
+ [:scenario, 2, "Scenario:", "Hello",
153
+ [:step_invocation, 3, "Given", "I have a table",
154
+ [:table,
155
+ [:row, 4,
156
+ [:cell, "a"],
157
+ [:cell, "b"]]]]]]
158
+ end
159
+
160
+ it "should have steps with inline py_string" do
161
+ parse(%{Feature: Hi
162
+ Scenario: Hello
163
+ Given I have a string
164
+
165
+
166
+ """
167
+ hello
168
+ world
169
+ """
170
+
171
+ }).to_sexp.should ==
172
+ [:feature, nil, "Feature: Hi",
173
+ [:scenario, 2, "Scenario:", "Hello",
174
+ [:step_invocation, 3, "Given", "I have a string",
175
+ [:py_string, "hello\nworld"]]]]
176
+ end
177
+
178
+ it "should allow multiline names" do
179
+ parse(%{Feature: Hi
180
+ Scenario: It is my ambition to say
181
+ in ten sentences
182
+ what others say
183
+ in a whole book.
184
+ Given I am a step
185
+
186
+ }).to_sexp.should ==
187
+ [:feature, nil, "Feature: Hi",
188
+ [:scenario, 2, "Scenario:", "It is my ambition to say\nin ten sentences\nwhat others say\nin a whole book.",
189
+ [:step_invocation, 6, "Given", "I am a step"]]]
190
+ end
191
+
192
+ it "should ignore gherkin keywords which are parts of other words in the name" do
193
+ parse(%{Feature: Parser bug
194
+ Scenario: I have a Button
195
+ Buttons are great
196
+ Given I have it
197
+ }).to_sexp.should ==
198
+ [:feature, nil, "Feature: Parser bug",
199
+ [:scenario, 2, "Scenario:", "I have a Button\nButtons are great",
200
+ [:step_invocation, 4, "Given", "I have it"]]]
201
+
202
+ end
203
+ end
204
+
205
+ describe "Scenario Outlines" do
206
+ it "can be empty" do
207
+ parse(%{Feature: Hi
208
+ Scenario Outline: Hello
209
+ Given a <what> cucumber
210
+ Examples:
211
+ |what|
212
+ |green|
213
+ }).to_sexp.should ==
214
+ [:feature, nil, "Feature: Hi",
215
+ [:scenario_outline, "Scenario Outline:", "Hello",
216
+ [:step, 3, "Given", "a <what> cucumber"],
217
+ [:examples, "Examples:", "",
218
+ [:table,
219
+ [:row, 5,
220
+ [:cell, "what"]],
221
+ [:row, 6,
222
+ [:cell, "green"]]]]]]
223
+ end
224
+
225
+ it "should have line numbered steps with inline table" do
226
+ parse(%{Feature: Hi
227
+ Scenario Outline: Hello
228
+
229
+ Given I have a table
230
+
231
+ |<a>|<b>|
232
+ Examples:
233
+ |a|b|
234
+ |c|d|
235
+ }).to_sexp.should ==
236
+ [:feature, nil, "Feature: Hi",
237
+ [:scenario_outline, "Scenario Outline:", "Hello",
238
+ [:step, 4, "Given", "I have a table",
239
+ [:table,
240
+ [:row, 6,
241
+ [:cell, "<a>"],
242
+ [:cell, "<b>"]]]],
243
+ [:examples, "Examples:", "",
244
+ [:table,
245
+ [:row, 8,
246
+ [:cell, "a"],
247
+ [:cell, "b"]],
248
+ [:row, 9,
249
+ [:cell, "c"],
250
+ [:cell, "d"]]]]]]
251
+ end
252
+
253
+ it "should have examples" do
254
+ parse("Feature: Hi
255
+
256
+ Scenario Outline: Hello
257
+
258
+ Given I have a table
259
+ |1|2|
260
+
261
+ Examples:
262
+ |x|y|
263
+ |5|6|
264
+
265
+ ").to_sexp.should ==
266
+ [:feature, nil, "Feature: Hi",
267
+ [:scenario_outline, "Scenario Outline:", "Hello",
268
+ [:step, 5, "Given", "I have a table",
269
+ [:table,
270
+ [:row, 6,
271
+ [:cell, "1"],
272
+ [:cell, "2"]]]],
273
+ [:examples, "Examples:", "",
274
+ [:table,
275
+ [:row, 9,
276
+ [:cell, "x"],
277
+ [:cell, "y"]],
278
+ [:row, 10,
279
+ [:cell, "5"],
280
+ [:cell, "6"]]]]]]
281
+ end
282
+
283
+ it "should allow multiline names" do
284
+ parse(%{Feature: Hi
285
+ Scenario Outline: It is my ambition to say
286
+ in ten sentences
287
+ what others say
288
+ in a whole book.
289
+ Given I am a step
290
+
291
+ }).to_sexp.should ==
292
+ [:feature, nil, "Feature: Hi",
293
+ [:scenario_outline, "Scenario Outline:", "It is my ambition to say\nin ten sentences\nwhat others say\nin a whole book.",
294
+ [:step, 6, "Given", "I am a step"]]]
295
+ end
296
+
297
+ it "should allow Examples to have multiline names" do
298
+ parse(%{Feature: Hi
299
+ Scenario Outline: name
300
+ Given I am a step
301
+
302
+ Examples: I'm a multiline name
303
+ and I'm ok
304
+ |x|
305
+ |5|
306
+
307
+ }).to_sexp.should ==
308
+ [:feature, nil, "Feature: Hi",
309
+ [:scenario_outline, "Scenario Outline:", "name",
310
+ [:step, 3, "Given", "I am a step"],
311
+ [:examples, "Examples:", "I'm a multiline name\nand I'm ok",
312
+ [:table,
313
+ [:row, 7,
314
+ [:cell, "x"]],
315
+ [:row, 8,
316
+ [:cell, "5"]]]]]]
317
+ end
318
+
319
+ it "should allow Examples to have multiline names" do
320
+ parse(%{Feature: Hi
321
+ Scenario: When I have when in scenario
322
+ I should be fine
323
+ Given I am a step
324
+ }).to_sexp.should ==
325
+ [:feature, nil, "Feature: Hi",
326
+ [:scenario, 2, "Scenario:", "When I have when in scenario\nI should be fine",
327
+ [:step_invocation, 4, "Given", "I am a step"]]]
328
+ end
329
+ end
330
+
331
+ describe "Syntax" do
332
+ it "should parse empty_feature" do
333
+ parse_file("empty_feature.feature")
334
+ end
335
+
336
+ it "should parse empty_scenario" do
337
+ parse_file("empty_scenario.feature")
338
+ end
339
+
340
+ it "should parse empty_scenario_outline" do
341
+ parse_file("empty_scenario_outline.feature")
342
+ end
343
+
344
+ it "should parse fit_scenario" do
345
+ parse_file("multiline_steps.feature")
346
+ end
347
+
348
+ it "should parse scenario_outline" do
349
+ parse_file("scenario_outline.feature")
350
+ end
351
+ end
352
+
353
+ describe "Filtering" do
354
+ it "should filter outline tables" do
355
+ ff = FeatureFile.new(
356
+ File.dirname(__FILE__) + '/../../../examples/self_test/features/outline_sample.feature:12')
357
+ f = ff.parse({:lang => 'en'})
358
+ f.to_sexp.should ==
359
+ [:feature,
360
+ "./spec/cucumber/parser/../../../examples/self_test/features/outline_sample.feature",
361
+ "Feature: Outline Sample",
362
+ [:scenario_outline,
363
+ "Scenario Outline:",
364
+ "Test state",
365
+ [:step, 6, "Given", "<state> without a table"],
366
+ [:step, 7, "Given", "<other_state> without a table"],
367
+ [:examples,
368
+ "Examples:",
369
+ "Rainbow colours",
370
+ [:table,
371
+ [:row, 9, [:cell, "state"], [:cell, "other_state"]],
372
+ # [:row, 10, [:cell, "missing"], [:cell, "passing"]],
373
+ # [:row, 11, [:cell, "passing"], [:cell, "passing"]],
374
+ [:row, 12, [:cell, "failing"], [:cell, "passing"]]]]
375
+ # ,
376
+ # [:examples,
377
+ # "Examples:",
378
+ # "Only passing",
379
+ # [:table,
380
+ # [:row, 14, [:cell, "state"], [:cell, "other_state"]],
381
+ # [:row, 15, [:cell, "passing"], [:cell, "passing"]]]]]
382
+ ]]
383
+ end
384
+ end
385
+ end
386
+ end
387
+ end
@@ -0,0 +1,48 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'treetop'
3
+ require 'cucumber/parser'
4
+
5
+ module Cucumber
6
+ module Parser
7
+ describe 'Tables' do
8
+ before do
9
+ @parser = I18n::EnglishParser.new
10
+ end
11
+
12
+ def parse(text)
13
+ @parser.__send__(:prepare_to_parse, text)
14
+ @parser.root = :table
15
+ table = @parser._nt_table
16
+ table.raw
17
+ end
18
+
19
+ it "should parse a 1x2 table with newline" do
20
+ parse(" | 1 | 2 | \n").should == [%w{1 2}]
21
+ end
22
+
23
+ it "should parse a 1x2 table without newline" do
24
+ parse("| 1 | 2 |").should == [%w{1 2}]
25
+ end
26
+
27
+ it "should parse a 1x2 table without spaces" do
28
+ parse("|1|2|").should == [%w{1 2}]
29
+ end
30
+
31
+ it "should parse a 2x2 table" do
32
+ parse("| 1 | 2 |\n| 3 | 4 |\n").should == [%w{1 2}, %w{3 4}]
33
+ end
34
+
35
+ it "should parse a 2x2 table with several newlines" do
36
+ parse("| 1 | 2 |\n| 3 | 4 |\n\n\n").should == [%w{1 2}, %w{3 4}]
37
+ end
38
+
39
+ it "should parse a 2x2 table with empty cells" do
40
+ parse("| 1 | |\n|| 4 |\n").should == [['1', nil], [nil, '4']]
41
+ end
42
+
43
+ it "should not parse a 2x2 table that isn't closed" do
44
+ parse("| 1 | |\n|| 4 ").should_not == [['1', nil], [nil, '4']]
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,18 @@
1
+ # Define some stubs to fake Rails...
2
+ module ActiveRecord
3
+ class Base
4
+ end
5
+ end
6
+
7
+ module ActionController
8
+ class Dispatcher
9
+ end
10
+
11
+ class Base
12
+ end
13
+
14
+ class IntegrationTest
15
+ def self.use_transactional_fixtures=(x)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1 @@
1
+ # This file is loaded by rails/world.rb
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ $:.unshift(File.dirname(__FILE__) + '/stubs')
3
+
4
+ describe "Rails world" do
5
+
6
+ it "should run without Test::Unit.run defined" do
7
+ require "mini_rails"
8
+ require "cucumber/rails/world"
9
+ end
10
+
11
+ end
@@ -0,0 +1,19 @@
1
+ Feature: Sell cucumbers
2
+ As a cucumber farmer
3
+ I want to sell cucumbers
4
+ So that I buy meat
5
+
6
+ Scenario: Sell a dozen
7
+ Given there are 5 cucumbers
8
+ When I sell 12 cucumbers
9
+ Then I should owe 7 cucumbers
10
+
11
+ Scenario: Sell twenty
12
+ Given there are 5 cucumbers
13
+ When I sell 20 cucumbers
14
+ Then I should owe 15 cucumbers
15
+
16
+ Scenario: Sell fifty
17
+ Given there are 5 cucumbers
18
+ When I sell 50 cucumbers
19
+ Then I should owe 45 cucumbers
@@ -0,0 +1,101 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ require 'cucumber/ast'
4
+ require 'cucumber/step_mother'
5
+ require 'cucumber/step_definition'
6
+
7
+ module Cucumber
8
+ describe StepDefinition do
9
+ before do
10
+ extend StepMother
11
+ @world = new_world!
12
+ $inside = nil
13
+ end
14
+
15
+ it "should allow calling of other steps" do
16
+ Given /Outside/ do
17
+ Given "Inside"
18
+ end
19
+ Given /Inside/ do
20
+ $inside = true
21
+ end
22
+
23
+ step_match("Outside").invoke(@world, nil)
24
+ $inside.should == true
25
+ end
26
+
27
+ it "should allow calling of other steps with inline arg" do
28
+ Given /Outside/ do
29
+ Given "Inside", Ast::Table.new([['inside']])
30
+ end
31
+ Given /Inside/ do |table|
32
+ $inside = table.raw[0][0]
33
+ end
34
+
35
+ step_match("Outside").invoke(@world, nil)
36
+ $inside.should == 'inside'
37
+ end
38
+
39
+ it "should raise Undefined when inside step is not defined" do
40
+ Given /Outside/ do
41
+ Given 'Inside'
42
+ end
43
+
44
+ step = mock('Step')
45
+ step.should_receive(:exception=)
46
+ lambda do
47
+ @world.__cucumber_current_step = step
48
+ step_match('Outside').invoke(@world, nil)
49
+ end.should raise_error(Undefined, 'Undefined step: "Inside"')
50
+ end
51
+
52
+ it "should allow forced pending" do
53
+ Given /Outside/ do
54
+ pending("Do me!")
55
+ end
56
+
57
+ lambda do
58
+ step_match("Outside").invoke(@world, nil)
59
+ end.should raise_error(Pending, "Do me!")
60
+ end
61
+
62
+ it "should allow announce" do
63
+ v = mock('visitor')
64
+ v.should_receive(:announce).with('wasup')
65
+ self.visitor = v
66
+ world = new_world!
67
+ Given /Loud/ do
68
+ announce 'wasup'
69
+ end
70
+ step_match("Loud").invoke(world, nil)
71
+ end
72
+
73
+ def unindented(s)
74
+ s.split("\n")[1..-2].join("\n").indent(-8)
75
+ end
76
+
77
+ it "should recognise quotes in name and make according regexp" do
78
+ StepDefinition.snippet_text('Given', 'A "first" arg').should == unindented(%{
79
+ Given /^A "([^\\"]*)" arg$/ do |arg1|
80
+ pending
81
+ end
82
+ })
83
+ end
84
+
85
+ it "should recognise several quoted words in name and make according regexp and args" do
86
+ StepDefinition.snippet_text('Given', 'A "first" and "second" arg').should == unindented(%{
87
+ Given /^A "([^\\"]*)" and "([^\\"]*)" arg$/ do |arg1, arg2|
88
+ pending
89
+ end
90
+ })
91
+ end
92
+
93
+ it "should not use quote group when there are no quotes" do
94
+ StepDefinition.snippet_text('Given', 'A first arg').should == unindented(%{
95
+ Given /^A first arg$/ do
96
+ pending
97
+ end
98
+ })
99
+ end
100
+ end
101
+ end