gherkin 2.12.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (333) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -15
  3. data/CONTRIBUTING.md +23 -0
  4. data/Gemfile +0 -3
  5. data/LICENSE +18 -17
  6. data/Makefile +65 -0
  7. data/README.md +9 -268
  8. data/Rakefile +17 -19
  9. data/bin/gherkin-generate-ast +21 -0
  10. data/bin/gherkin-generate-pickles +25 -0
  11. data/bin/gherkin-generate-tokens +12 -0
  12. data/gherkin-ruby.razor +218 -0
  13. data/gherkin.gemspec +22 -76
  14. data/lib/gherkin/ast_builder.rb +243 -0
  15. data/lib/gherkin/ast_node.rb +30 -0
  16. data/lib/gherkin/dialect.rb +58 -0
  17. data/lib/gherkin/errors.rb +45 -0
  18. data/lib/gherkin/gherkin-languages.json +2968 -0
  19. data/lib/gherkin/gherkin_line.rb +95 -0
  20. data/lib/gherkin/parser.rb +1910 -0
  21. data/lib/gherkin/pickles/compiler.rb +164 -0
  22. data/lib/gherkin/token.rb +18 -0
  23. data/lib/gherkin/token_formatter_builder.rb +39 -0
  24. data/lib/gherkin/token_matcher.rb +169 -0
  25. data/lib/gherkin/token_scanner.rb +40 -0
  26. data/spec/capture_warnings.rb +68 -0
  27. data/spec/coverage.rb +10 -0
  28. data/spec/gherkin/parser_spec.rb +146 -0
  29. metadata +60 -567
  30. data/.gitattributes +0 -2
  31. data/.mailmap +0 -2
  32. data/.rbenv-gemsets +0 -1
  33. data/.rspec +0 -1
  34. data/.ruby-gemset +0 -1
  35. data/.ruby-version +0 -1
  36. data/.yardopts +0 -5
  37. data/History.md +0 -881
  38. data/build_native_gems.sh +0 -7
  39. data/cucumber.yml +0 -5
  40. data/examples/parse_and_output_json.rb +0 -19
  41. data/ext/gherkin_lexer_ar/extconf.rb +0 -6
  42. data/ext/gherkin_lexer_ar/gherkin_lexer_ar.c +0 -1432
  43. data/ext/gherkin_lexer_bg/extconf.rb +0 -6
  44. data/ext/gherkin_lexer_bg/gherkin_lexer_bg.c +0 -1655
  45. data/ext/gherkin_lexer_bm/extconf.rb +0 -6
  46. data/ext/gherkin_lexer_bm/gherkin_lexer_bm.c +0 -1516
  47. data/ext/gherkin_lexer_ca/extconf.rb +0 -6
  48. data/ext/gherkin_lexer_ca/gherkin_lexer_ca.c +0 -1581
  49. data/ext/gherkin_lexer_cs/extconf.rb +0 -6
  50. data/ext/gherkin_lexer_cs/gherkin_lexer_cs.c +0 -1515
  51. data/ext/gherkin_lexer_cy_gb/extconf.rb +0 -6
  52. data/ext/gherkin_lexer_cy_gb/gherkin_lexer_cy_gb.c +0 -1282
  53. data/ext/gherkin_lexer_da/extconf.rb +0 -6
  54. data/ext/gherkin_lexer_da/gherkin_lexer_da.c +0 -1298
  55. data/ext/gherkin_lexer_de/extconf.rb +0 -6
  56. data/ext/gherkin_lexer_de/gherkin_lexer_de.c +0 -1425
  57. data/ext/gherkin_lexer_el/extconf.rb +0 -6
  58. data/ext/gherkin_lexer_el/gherkin_lexer_el.c +0 -1919
  59. data/ext/gherkin_lexer_en/extconf.rb +0 -6
  60. data/ext/gherkin_lexer_en/gherkin_lexer_en.c +0 -1418
  61. data/ext/gherkin_lexer_en_au/extconf.rb +0 -6
  62. data/ext/gherkin_lexer_en_au/gherkin_lexer_en_au.c +0 -1765
  63. data/ext/gherkin_lexer_en_lol/extconf.rb +0 -6
  64. data/ext/gherkin_lexer_en_lol/gherkin_lexer_en_lol.c +0 -1177
  65. data/ext/gherkin_lexer_en_old/extconf.rb +0 -6
  66. data/ext/gherkin_lexer_en_old/gherkin_lexer_en_old.c +0 -1309
  67. data/ext/gherkin_lexer_en_pirate/extconf.rb +0 -6
  68. data/ext/gherkin_lexer_en_pirate/gherkin_lexer_en_pirate.c +0 -1471
  69. data/ext/gherkin_lexer_en_scouse/extconf.rb +0 -6
  70. data/ext/gherkin_lexer_en_scouse/gherkin_lexer_en_scouse.c +0 -1634
  71. data/ext/gherkin_lexer_en_tx/extconf.rb +0 -6
  72. data/ext/gherkin_lexer_en_tx/gherkin_lexer_en_tx.c +0 -1265
  73. data/ext/gherkin_lexer_eo/extconf.rb +0 -6
  74. data/ext/gherkin_lexer_eo/gherkin_lexer_eo.c +0 -1241
  75. data/ext/gherkin_lexer_es/extconf.rb +0 -6
  76. data/ext/gherkin_lexer_es/gherkin_lexer_es.c +0 -1399
  77. data/ext/gherkin_lexer_et/extconf.rb +0 -6
  78. data/ext/gherkin_lexer_et/gherkin_lexer_et.c +0 -1236
  79. data/ext/gherkin_lexer_fa/extconf.rb +0 -6
  80. data/ext/gherkin_lexer_fa/gherkin_lexer_fa.c +0 -1475
  81. data/ext/gherkin_lexer_fi/extconf.rb +0 -6
  82. data/ext/gherkin_lexer_fi/gherkin_lexer_fi.c +0 -1215
  83. data/ext/gherkin_lexer_fr/extconf.rb +0 -6
  84. data/ext/gherkin_lexer_fr/gherkin_lexer_fr.c +0 -1493
  85. data/ext/gherkin_lexer_gl/extconf.rb +0 -6
  86. data/ext/gherkin_lexer_gl/gherkin_lexer_gl.c +0 -1374
  87. data/ext/gherkin_lexer_he/extconf.rb +0 -6
  88. data/ext/gherkin_lexer_he/gherkin_lexer_he.c +0 -1374
  89. data/ext/gherkin_lexer_hi/extconf.rb +0 -6
  90. data/ext/gherkin_lexer_hi/gherkin_lexer_hi.c +0 -1848
  91. data/ext/gherkin_lexer_hr/extconf.rb +0 -6
  92. data/ext/gherkin_lexer_hr/gherkin_lexer_hr.c +0 -1323
  93. data/ext/gherkin_lexer_hu/extconf.rb +0 -6
  94. data/ext/gherkin_lexer_hu/gherkin_lexer_hu.c +0 -1376
  95. data/ext/gherkin_lexer_id/extconf.rb +0 -6
  96. data/ext/gherkin_lexer_id/gherkin_lexer_id.c +0 -1208
  97. data/ext/gherkin_lexer_is/extconf.rb +0 -6
  98. data/ext/gherkin_lexer_is/gherkin_lexer_is.c +0 -1376
  99. data/ext/gherkin_lexer_it/extconf.rb +0 -6
  100. data/ext/gherkin_lexer_it/gherkin_lexer_it.c +0 -1340
  101. data/ext/gherkin_lexer_ja/extconf.rb +0 -6
  102. data/ext/gherkin_lexer_ja/gherkin_lexer_ja.c +0 -1699
  103. data/ext/gherkin_lexer_kn/extconf.rb +0 -6
  104. data/ext/gherkin_lexer_kn/gherkin_lexer_kn.c +0 -1965
  105. data/ext/gherkin_lexer_ko/extconf.rb +0 -6
  106. data/ext/gherkin_lexer_ko/gherkin_lexer_ko.c +0 -1360
  107. data/ext/gherkin_lexer_lt/extconf.rb +0 -6
  108. data/ext/gherkin_lexer_lt/gherkin_lexer_lt.c +0 -1296
  109. data/ext/gherkin_lexer_lu/extconf.rb +0 -6
  110. data/ext/gherkin_lexer_lu/gherkin_lexer_lu.c +0 -1389
  111. data/ext/gherkin_lexer_lv/extconf.rb +0 -6
  112. data/ext/gherkin_lexer_lv/gherkin_lexer_lv.c +0 -1425
  113. data/ext/gherkin_lexer_nl/extconf.rb +0 -6
  114. data/ext/gherkin_lexer_nl/gherkin_lexer_nl.c +0 -1368
  115. data/ext/gherkin_lexer_no/extconf.rb +0 -6
  116. data/ext/gherkin_lexer_no/gherkin_lexer_no.c +0 -1311
  117. data/ext/gherkin_lexer_pa/extconf.rb +0 -6
  118. data/ext/gherkin_lexer_pa/gherkin_lexer_pa.c +0 -2160
  119. data/ext/gherkin_lexer_pl/extconf.rb +0 -6
  120. data/ext/gherkin_lexer_pl/gherkin_lexer_pl.c +0 -1738
  121. data/ext/gherkin_lexer_pt/extconf.rb +0 -6
  122. data/ext/gherkin_lexer_pt/gherkin_lexer_pt.c +0 -1711
  123. data/ext/gherkin_lexer_ro/extconf.rb +0 -6
  124. data/ext/gherkin_lexer_ro/gherkin_lexer_ro.c +0 -1427
  125. data/ext/gherkin_lexer_ru/extconf.rb +0 -6
  126. data/ext/gherkin_lexer_ru/gherkin_lexer_ru.c +0 -2071
  127. data/ext/gherkin_lexer_sk/extconf.rb +0 -6
  128. data/ext/gherkin_lexer_sk/gherkin_lexer_sk.c +0 -1739
  129. data/ext/gherkin_lexer_sr_cyrl/extconf.rb +0 -6
  130. data/ext/gherkin_lexer_sr_cyrl/gherkin_lexer_sr_cyrl.c +0 -2112
  131. data/ext/gherkin_lexer_sr_latn/extconf.rb +0 -6
  132. data/ext/gherkin_lexer_sr_latn/gherkin_lexer_sr_latn.c +0 -1567
  133. data/ext/gherkin_lexer_sv/extconf.rb +0 -6
  134. data/ext/gherkin_lexer_sv/gherkin_lexer_sv.c +0 -1324
  135. data/ext/gherkin_lexer_th/extconf.rb +0 -6
  136. data/ext/gherkin_lexer_th/gherkin_lexer_th.c +0 -2840
  137. data/ext/gherkin_lexer_tl/extconf.rb +0 -6
  138. data/ext/gherkin_lexer_tl/gherkin_lexer_tl.c +0 -2021
  139. data/ext/gherkin_lexer_tr/extconf.rb +0 -6
  140. data/ext/gherkin_lexer_tr/gherkin_lexer_tr.c +0 -1347
  141. data/ext/gherkin_lexer_tt/extconf.rb +0 -6
  142. data/ext/gherkin_lexer_tt/gherkin_lexer_tt.c +0 -1936
  143. data/ext/gherkin_lexer_uk/extconf.rb +0 -6
  144. data/ext/gherkin_lexer_uk/gherkin_lexer_uk.c +0 -1941
  145. data/ext/gherkin_lexer_uz/extconf.rb +0 -6
  146. data/ext/gherkin_lexer_uz/gherkin_lexer_uz.c +0 -1651
  147. data/ext/gherkin_lexer_vi/extconf.rb +0 -6
  148. data/ext/gherkin_lexer_vi/gherkin_lexer_vi.c +0 -1458
  149. data/ext/gherkin_lexer_zh_cn/extconf.rb +0 -6
  150. data/ext/gherkin_lexer_zh_cn/gherkin_lexer_zh_cn.c +0 -1314
  151. data/ext/gherkin_lexer_zh_tw/extconf.rb +0 -6
  152. data/ext/gherkin_lexer_zh_tw/gherkin_lexer_zh_tw.c +0 -1307
  153. data/features/.cucumber/stepdefs.json +0 -244
  154. data/features/escaped_pipes.feature +0 -8
  155. data/features/feature_parser.feature +0 -237
  156. data/features/json_formatter.feature +0 -498
  157. data/features/json_parser.feature +0 -331
  158. data/features/native_lexer.feature +0 -19
  159. data/features/parser_with_native_lexer.feature +0 -205
  160. data/features/pretty_formatter.feature +0 -17
  161. data/features/step_definitions/eyeball_steps.rb +0 -3
  162. data/features/step_definitions/gherkin_steps.rb +0 -29
  163. data/features/step_definitions/json_formatter_steps.rb +0 -30
  164. data/features/step_definitions/json_parser_steps.rb +0 -21
  165. data/features/step_definitions/pretty_formatter_steps.rb +0 -85
  166. data/features/steps_parser.feature +0 -46
  167. data/features/support/env.rb +0 -41
  168. data/install_mingw_os_x.sh +0 -5
  169. data/js/.npmignore +0 -1
  170. data/js/lib/gherkin/lexer/.npmignore +0 -0
  171. data/lib/gherkin.rb +0 -2
  172. data/lib/gherkin/README.md +0 -7
  173. data/lib/gherkin/c_lexer.rb +0 -17
  174. data/lib/gherkin/formatter/ansi_escapes.rb +0 -97
  175. data/lib/gherkin/formatter/argument.rb +0 -16
  176. data/lib/gherkin/formatter/escaping.rb +0 -15
  177. data/lib/gherkin/formatter/filter_formatter.rb +0 -150
  178. data/lib/gherkin/formatter/hashable.rb +0 -25
  179. data/lib/gherkin/formatter/json_formatter.rb +0 -133
  180. data/lib/gherkin/formatter/line_filter.rb +0 -26
  181. data/lib/gherkin/formatter/model.rb +0 -281
  182. data/lib/gherkin/formatter/pretty_formatter.rb +0 -245
  183. data/lib/gherkin/formatter/regexp_filter.rb +0 -21
  184. data/lib/gherkin/formatter/step_printer.rb +0 -21
  185. data/lib/gherkin/formatter/tag_count_formatter.rb +0 -47
  186. data/lib/gherkin/formatter/tag_filter.rb +0 -19
  187. data/lib/gherkin/i18n.json +0 -786
  188. data/lib/gherkin/i18n.rb +0 -176
  189. data/lib/gherkin/json_parser.rb +0 -177
  190. data/lib/gherkin/lexer/ar.rb +0 -1170
  191. data/lib/gherkin/lexer/bg.rb +0 -1382
  192. data/lib/gherkin/lexer/bm.rb +0 -1250
  193. data/lib/gherkin/lexer/ca.rb +0 -1310
  194. data/lib/gherkin/lexer/cs.rb +0 -1246
  195. data/lib/gherkin/lexer/cy_gb.rb +0 -1032
  196. data/lib/gherkin/lexer/da.rb +0 -1048
  197. data/lib/gherkin/lexer/de.rb +0 -1166
  198. data/lib/gherkin/lexer/el.rb +0 -1628
  199. data/lib/gherkin/lexer/en.rb +0 -1156
  200. data/lib/gherkin/lexer/en_au.rb +0 -1486
  201. data/lib/gherkin/lexer/en_lol.rb +0 -934
  202. data/lib/gherkin/lexer/en_old.rb +0 -1037
  203. data/lib/gherkin/lexer/en_pirate.rb +0 -1210
  204. data/lib/gherkin/lexer/en_scouse.rb +0 -1362
  205. data/lib/gherkin/lexer/en_tx.rb +0 -1016
  206. data/lib/gherkin/lexer/encoding.rb +0 -41
  207. data/lib/gherkin/lexer/eo.rb +0 -995
  208. data/lib/gherkin/lexer/es.rb +0 -1140
  209. data/lib/gherkin/lexer/et.rb +0 -990
  210. data/lib/gherkin/lexer/fa.rb +0 -1214
  211. data/lib/gherkin/lexer/fi.rb +0 -969
  212. data/lib/gherkin/lexer/fr.rb +0 -1228
  213. data/lib/gherkin/lexer/gl.rb +0 -1117
  214. data/lib/gherkin/lexer/he.rb +0 -1118
  215. data/lib/gherkin/lexer/hi.rb +0 -1559
  216. data/lib/gherkin/lexer/hr.rb +0 -1066
  217. data/lib/gherkin/lexer/hu.rb +0 -1118
  218. data/lib/gherkin/lexer/i18n_lexer.rb +0 -48
  219. data/lib/gherkin/lexer/id.rb +0 -963
  220. data/lib/gherkin/lexer/is.rb +0 -1120
  221. data/lib/gherkin/lexer/it.rb +0 -1086
  222. data/lib/gherkin/lexer/ja.rb +0 -1418
  223. data/lib/gherkin/lexer/kn.rb +0 -1672
  224. data/lib/gherkin/lexer/ko.rb +0 -1102
  225. data/lib/gherkin/lexer/lt.rb +0 -1045
  226. data/lib/gherkin/lexer/lu.rb +0 -1132
  227. data/lib/gherkin/lexer/lv.rb +0 -1166
  228. data/lib/gherkin/lexer/nl.rb +0 -1115
  229. data/lib/gherkin/lexer/no.rb +0 -1060
  230. data/lib/gherkin/lexer/pa.rb +0 -1852
  231. data/lib/gherkin/lexer/pl.rb +0 -1457
  232. data/lib/gherkin/lexer/pt.rb +0 -1430
  233. data/lib/gherkin/lexer/ro.rb +0 -1164
  234. data/lib/gherkin/lexer/ru.rb +0 -1766
  235. data/lib/gherkin/lexer/sk.rb +0 -1452
  236. data/lib/gherkin/lexer/sr_cyrl.rb +0 -1803
  237. data/lib/gherkin/lexer/sr_latn.rb +0 -1294
  238. data/lib/gherkin/lexer/sv.rb +0 -1070
  239. data/lib/gherkin/lexer/th.rb +0 -2492
  240. data/lib/gherkin/lexer/tl.rb +0 -1726
  241. data/lib/gherkin/lexer/tr.rb +0 -1092
  242. data/lib/gherkin/lexer/tt.rb +0 -1643
  243. data/lib/gherkin/lexer/uk.rb +0 -1646
  244. data/lib/gherkin/lexer/uz.rb +0 -1376
  245. data/lib/gherkin/lexer/vi.rb +0 -1198
  246. data/lib/gherkin/lexer/zh_cn.rb +0 -1058
  247. data/lib/gherkin/lexer/zh_tw.rb +0 -1052
  248. data/lib/gherkin/listener/event.rb +0 -45
  249. data/lib/gherkin/listener/formatter_listener.rb +0 -150
  250. data/lib/gherkin/native.rb +0 -7
  251. data/lib/gherkin/native/java.rb +0 -72
  252. data/lib/gherkin/native/null.rb +0 -5
  253. data/lib/gherkin/native/therubyracer.rb +0 -41
  254. data/lib/gherkin/parser/meta.txt +0 -5
  255. data/lib/gherkin/parser/parser.rb +0 -166
  256. data/lib/gherkin/parser/root.txt +0 -11
  257. data/lib/gherkin/parser/steps.txt +0 -4
  258. data/lib/gherkin/platform.rb +0 -13
  259. data/lib/gherkin/rubify.rb +0 -31
  260. data/lib/gherkin/tag_expression.rb +0 -63
  261. data/ragel/lexer.c.rl.erb +0 -454
  262. data/ragel/lexer.java.rl.erb +0 -219
  263. data/ragel/lexer.js.rl.erb +0 -322
  264. data/ragel/lexer.rb.rl.erb +0 -179
  265. data/ragel/lexer_common.rl.erb +0 -50
  266. data/spec/gherkin/c_lexer_spec.rb +0 -22
  267. data/spec/gherkin/fixtures/1.feature +0 -8
  268. data/spec/gherkin/fixtures/comments_in_table.feature +0 -9
  269. data/spec/gherkin/fixtures/complex.feature +0 -45
  270. data/spec/gherkin/fixtures/complex.json +0 -139
  271. data/spec/gherkin/fixtures/complex_for_filtering.feature +0 -60
  272. data/spec/gherkin/fixtures/complex_with_tags.feature +0 -61
  273. data/spec/gherkin/fixtures/dos_line_endings.feature +0 -45
  274. data/spec/gherkin/fixtures/examples_with_only_header.feature +0 -14
  275. data/spec/gherkin/fixtures/hantu_pisang.feature +0 -35
  276. data/spec/gherkin/fixtures/i18n_fr.feature +0 -14
  277. data/spec/gherkin/fixtures/i18n_fr2.feature +0 -8
  278. data/spec/gherkin/fixtures/i18n_no.feature +0 -7
  279. data/spec/gherkin/fixtures/i18n_pt1.feature +0 -44
  280. data/spec/gherkin/fixtures/i18n_pt2.feature +0 -4
  281. data/spec/gherkin/fixtures/i18n_pt3.feature +0 -4
  282. data/spec/gherkin/fixtures/i18n_pt4.feature +0 -4
  283. data/spec/gherkin/fixtures/i18n_zh-CN.feature +0 -9
  284. data/spec/gherkin/fixtures/iso-8859-1.feature +0 -6
  285. data/spec/gherkin/fixtures/issue_145.feature +0 -22
  286. data/spec/gherkin/fixtures/scenario_outline_with_tags.feature +0 -13
  287. data/spec/gherkin/fixtures/scenario_without_steps.feature +0 -5
  288. data/spec/gherkin/fixtures/simple_with_comments.feature +0 -7
  289. data/spec/gherkin/fixtures/simple_with_tags.feature +0 -11
  290. data/spec/gherkin/fixtures/with_bom.feature +0 -3
  291. data/spec/gherkin/fixtures/with_bom_and_language_spec.feature +0 -4
  292. data/spec/gherkin/formatter/ansi_escapes_spec.rb +0 -32
  293. data/spec/gherkin/formatter/filter_formatter_spec.rb +0 -204
  294. data/spec/gherkin/formatter/json_formatter_spec.rb +0 -179
  295. data/spec/gherkin/formatter/model_spec.rb +0 -28
  296. data/spec/gherkin/formatter/pretty_formatter_spec.rb +0 -184
  297. data/spec/gherkin/formatter/spaces.feature +0 -9
  298. data/spec/gherkin/formatter/step_printer_spec.rb +0 -55
  299. data/spec/gherkin/formatter/tabs.feature +0 -9
  300. data/spec/gherkin/formatter/tag_count_formatter_spec.rb +0 -30
  301. data/spec/gherkin/i18n_spec.rb +0 -256
  302. data/spec/gherkin/java_lexer_spec.rb +0 -20
  303. data/spec/gherkin/json_parser_spec.rb +0 -165
  304. data/spec/gherkin/lexer/i18n_lexer_spec.rb +0 -65
  305. data/spec/gherkin/native_lexer_spec.rb +0 -29
  306. data/spec/gherkin/parser/parser_spec.rb +0 -16
  307. data/spec/gherkin/rubify_spec.rb +0 -23
  308. data/spec/gherkin/sexp_recorder.rb +0 -59
  309. data/spec/gherkin/shared/doc_string_group.rb +0 -161
  310. data/spec/gherkin/shared/encoding_group.rb +0 -48
  311. data/spec/gherkin/shared/lexer_group.rb +0 -589
  312. data/spec/gherkin/shared/row_group.rb +0 -123
  313. data/spec/gherkin/shared/tags_group.rb +0 -52
  314. data/spec/gherkin/tag_expression_spec.rb +0 -146
  315. data/spec/spec_helper.rb +0 -94
  316. data/tasks/apidoc.rake +0 -32
  317. data/tasks/bench.rake +0 -184
  318. data/tasks/bench/feature_builder.rb +0 -49
  319. data/tasks/bench/null_listener.rb +0 -4
  320. data/tasks/compile.rake +0 -83
  321. data/tasks/cucumber.rake +0 -23
  322. data/tasks/gems.rake +0 -46
  323. data/tasks/ikvm.rake +0 -126
  324. data/tasks/ragel_task.rb +0 -124
  325. data/tasks/release.rake +0 -34
  326. data/tasks/rspec.rake +0 -6
  327. data/tasks/yard/default/layout/html/bubble_32x32.png +0 -0
  328. data/tasks/yard/default/layout/html/bubble_48x48.png +0 -0
  329. data/tasks/yard/default/layout/html/footer.erb +0 -5
  330. data/tasks/yard/default/layout/html/index.erb +0 -1
  331. data/tasks/yard/default/layout/html/layout.erb +0 -25
  332. data/tasks/yard/default/layout/html/logo.erb +0 -1
  333. data/tasks/yard/default/layout/html/setup.rb +0 -4
@@ -1,65 +0,0 @@
1
- #encoding: utf-8
2
- require 'spec_helper'
3
-
4
- module Gherkin
5
- module Lexer
6
- describe I18nLexer do
7
- context "when default ios_code is 'en'" do
8
- before do
9
- @lexer = Gherkin::Lexer::I18nLexer.new(Gherkin::SexpRecorder.new, false)
10
- end
11
-
12
- it "should store the i18n language of the last scanned feature" do
13
- @lexer.scan("# language: fr\n")
14
- # This if is kind of dumb - it's just to avoid warnings from ruby
15
- if(@lexer.i18n_language.iso_code.should == "fr")
16
- @lexer.scan("# language: no\n")
17
- @lexer.i18n_language.iso_code.should == "no"
18
- else
19
- fail
20
- end
21
- end
22
-
23
- it "should detect language when there are spaces and CRLF" do
24
- @lexer.scan("# language: da \r\n")
25
- @lexer.i18n_language.iso_code.should == "da"
26
- end
27
-
28
- it "should detect language when the language comment is not the first line" do
29
- @lexer.scan("# hello\n# language: no\n")
30
- @lexer.i18n_language.iso_code.should == "no"
31
- end
32
-
33
- it "should detect language when the language is on the third line, and there are empty lines above" do
34
- @lexer.scan("# hello\n\n# language: no\n")
35
- @lexer.i18n_language.iso_code.should == "no"
36
- end
37
-
38
- it "should use English i18n by default" do
39
- @lexer.scan("Feature: foo\n")
40
- @lexer.i18n_language.iso_code.should == "en"
41
- end
42
-
43
- it "should === its ruby class, even when the impl is Java" do
44
- Gherkin::Lexer::I18nLexer.should === Gherkin::Lexer::I18nLexer.new(Gherkin::SexpRecorder.new, true)
45
- end
46
- end
47
-
48
- context "when default ios_code is 'ja'" do
49
- before do
50
- @lexer = Gherkin::Lexer::I18nLexer.new(Gherkin::SexpRecorder.new, false, 'ja')
51
- end
52
-
53
- it "should store the i18n language of the last scanned feature" do
54
- @lexer.scan("# language: en")
55
- @lexer.i18n_language.iso_code.should == "en"
56
- end
57
-
58
- it "should use Japanese" do
59
- @lexer.scan("機能: foo\n")
60
- @lexer.i18n_language.iso_code.should == "ja"
61
- end
62
- end
63
- end
64
- end
65
- end
@@ -1,29 +0,0 @@
1
- #encoding: utf-8
2
- require 'spec_helper'
3
-
4
- module Gherkin
5
- module Lexer
6
- begin
7
- require 'gherkin/lexer/en'
8
- rescue LoadError
9
- # For Java/JRuby we might not have the generated ruby lexer, which
10
- # won't be used anyway. Just define a stub.
11
- class En
12
- native_impl('gherkin')
13
- end
14
- end
15
-
16
- describe "Native Lexer" do
17
- before do
18
- @listener = Gherkin::SexpRecorder.new
19
- @lexer = Gherkin::Lexer::En.new(@listener)
20
- end
21
-
22
- it_should_behave_like "a Gherkin lexer"
23
- it_should_behave_like "a Gherkin lexer lexing tags"
24
- it_should_behave_like "a Gherkin lexer lexing doc_strings"
25
- it_should_behave_like "a Gherkin lexer lexing rows"
26
- it_should_behave_like "encoding" unless ENV['GHERKIN_JS_NATIVE']
27
- end
28
- end
29
- end
@@ -1,16 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Gherkin
4
- module Parser
5
- describe Parser do
6
- unless defined?(JRUBY_VERSION)
7
- it "should raise when feature doesn't parse" do
8
- p = Parser.new(double('formatter').as_null_object)
9
- lambda do
10
- p.parse("Feature: f\nFeature: f", __FILE__, __LINE__-1)
11
- end.should raise_error(Regexp.new("Parse error at #{__FILE__}:\\d+"))
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,23 +0,0 @@
1
- #encoding: utf-8
2
- if defined?(JRUBY_VERSION)
3
- require 'spec_helper'
4
- include Gherkin::Rubify
5
-
6
- module Gherkin
7
- module Rubify
8
- describe "rubify" do
9
- before do
10
- @java_collection = [double("Java.java.util.ArrayList")]
11
- @java_collection.stub(:===).and_return(Java.java.util.Collection)
12
- @java_collection.stub(:line).and_return(15)
13
- @rubified_array = rubify(@java_collection)
14
- end
15
-
16
- it "should keep the line number attribute from Java object" do
17
- @rubified_array.should respond_to(:line)
18
- @rubified_array.line.should == 15
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,59 +0,0 @@
1
- require 'gherkin/rubify'
2
- require 'gherkin/formatter/model'
3
-
4
- module Gherkin
5
- class SexpRecorder
6
- include Rubify
7
-
8
- def initialize
9
- @sexps = []
10
- end
11
-
12
- # We can't use method_missing - therubyracer isn't able to invoke methods like that.
13
- [:comment, :tag, :feature, :background, :scenario, :scenario_outline, :examples, :step, :doc_string, :row, :eof, :uri, :syntax_error].each do |event|
14
- define_method(event) do |*args|
15
- args = rubify(args)
16
- args = sexpify(args)
17
- @sexps << [event] + args
18
- end
19
- end
20
-
21
- def to_sexp
22
- @sexps
23
- end
24
-
25
- # Useful in IRB
26
- def reset!
27
- @sexps = []
28
- end
29
-
30
- def errors
31
- @sexps.select { |sexp| sexp[0] == :syntax_error }
32
- end
33
-
34
- def line(number)
35
- @sexps.find { |sexp| sexp.last == number }
36
- end
37
-
38
- def sexpify(o)
39
- array = (defined?(JRUBY_VERSION) && Java.java.util.Collection === o) ||
40
- (defined?(V8) && V8::Array === o) ||
41
- Array === o
42
- if array
43
- o.map{|e| sexpify(e)}
44
- elsif(Formatter::Model::Row === o)
45
- {
46
- "cells" => sexpify(o.cells),
47
- "comments" => sexpify(o.comments),
48
- "line" => o.line,
49
- }
50
- elsif(Formatter::Model::Comment === o)
51
- o.value
52
- elsif(Formatter::Model::Tag === o)
53
- o.name
54
- else
55
- o
56
- end
57
- end
58
- end
59
- end
@@ -1,161 +0,0 @@
1
- # encoding: utf-8
2
- module Gherkin
3
- module Lexer
4
- shared_examples_for "a Gherkin lexer lexing doc_strings" do
5
- def scan(gherkin)
6
- @lexer.scan(gherkin)
7
- end
8
-
9
- def ps(content)
10
- '"""%s"""' % ("\n" + content + "\n")
11
- end
12
-
13
- it "should provide the amount of indentation of the triple quotes to the listener" do
14
- str = <<EOS
15
- Feature: some feature
16
- Scenario: some scenario
17
- Given foo
18
- """
19
- Hello
20
- Goodbye
21
- """
22
- Then bar
23
- EOS
24
- @listener.should_receive(:doc_string).with('', " Hello\nGoodbye", 4)
25
- scan(str)
26
- end
27
-
28
- it "should parse a simple doc_string" do
29
- @listener.should_receive(:doc_string).with('', "I am a doc_string", 1)
30
- scan ps("I am a doc_string")
31
- end
32
-
33
- it "should parse an empty doc_string" do
34
- @listener.should_receive(:doc_string).with('', '', 4)
35
- scan("Feature: Hi\nScenario: Hi\nGiven a step\n\"\"\"\n\"\"\"")
36
- end
37
-
38
- it "should treat a string containing only newlines as only newlines" do
39
- doc_string = <<EOS
40
- """
41
-
42
-
43
-
44
- """
45
- EOS
46
- @listener.should_receive(:doc_string).with('', "\n\n", 1)
47
- scan(doc_string)
48
- end
49
-
50
- it "should parse content separated by two newlines" do
51
- scan ps("A\n\nB")
52
- @listener.to_sexp.should == [
53
- [:doc_string, '', "A\n\nB", 1],
54
- [:eof]
55
- ]
56
- end
57
-
58
- it "should parse a multiline string" do
59
- @listener.should_receive(:doc_string).with('', "A\nB\nC\nD", 1)
60
- scan ps("A\nB\nC\nD")
61
- end
62
-
63
- it "should ignore unescaped quotes inside the string delimeters" do
64
- @listener.should_receive(:doc_string).with('', "What does \"this\" mean?", 1)
65
- scan ps('What does "this" mean?')
66
- end
67
-
68
- it "should preserve whitespace within the triple quotes" do
69
- str = <<EOS
70
- """
71
- Line one
72
- Line two
73
- """
74
- EOS
75
- @listener.should_receive(:doc_string).with('', " Line one\nLine two", 1)
76
- scan(str)
77
- end
78
-
79
- it "should preserve tabs within the content" do
80
- @listener.should_receive(:doc_string).with('', "I have\tsome tabs\nInside\t\tthe content", 1)
81
- scan ps("I have\tsome tabs\nInside\t\tthe content")
82
- end
83
-
84
- it "should handle complex doc_strings" do
85
- doc_string = <<EOS
86
- # Feature comment
87
- @one
88
- Feature: Sample
89
-
90
- @two @three
91
- Scenario: Missing
92
- Given missing
93
-
94
- 1 scenario (1 passed)
95
- 1 step (1 passed)
96
-
97
- EOS
98
-
99
- @listener.should_receive(:doc_string).with('', doc_string, 1)
100
- scan ps(doc_string)
101
- end
102
-
103
- it "should allow whitespace after the closing doc_string delimiter" do
104
- str = <<EOS
105
- """
106
- Line one
107
- """
108
- EOS
109
- @listener.should_receive(:doc_string).with('', " Line one", 1)
110
- scan(str)
111
- end
112
-
113
- it "should preserve the last newline(s) at the end of a doc_string" do
114
- str = <<EOS
115
- """
116
- DocString text
117
-
118
-
119
- """
120
- EOS
121
- @listener.should_receive(:doc_string).with('', "DocString text\n\n", 1)
122
- scan(str)
123
- end
124
-
125
- it "should preserve CRLFs within doc_strings" do
126
- @listener.should_receive(:doc_string).with('', "Line one\r\nLine two\r\n", 1)
127
- scan("\"\"\"\r\nLine one\r\nLine two\r\n\r\n\"\"\"")
128
- end
129
-
130
- it "should unescape escaped triple quotes" do
131
- str = <<EOS
132
- """
133
- \\"\\"\\"
134
- """
135
- EOS
136
- @listener.should_receive(:doc_string).with('', '"""', 1)
137
- scan(str)
138
- end
139
-
140
- it "should not unescape escaped single quotes" do
141
- str = <<EOS
142
- """
143
- \\" \\"\\"
144
- """
145
- EOS
146
- @listener.should_receive(:doc_string).with('', '\" \"\"', 1)
147
- scan(str)
148
- end
149
-
150
- it "should lex doc_string content_types" do
151
- str = <<EOS
152
- """gherkin type
153
- Feature: Doc String Types
154
- """
155
- EOS
156
- @listener.should_receive(:doc_string).with('gherkin type', 'Feature: Doc String Types', 1)
157
- scan(str)
158
- end
159
- end
160
- end
161
- end
@@ -1,48 +0,0 @@
1
- #encoding: utf-8
2
- module Gherkin
3
- module Lexer
4
- shared_examples_for "encoding" do
5
- describe "with BOM" do
6
- it "should work just fine" do
7
- scan_file("with_bom.feature")
8
- @listener.to_sexp.should == [
9
- [:feature, "Feature", "Feature Text", "", 1],
10
- [:scenario, "Scenario", "Reading a Scenario", "", 2],
11
- [:step, "Given ", "there is a step", 3],
12
- [:eof]
13
- ]
14
- end
15
-
16
- describe "and language specification" do
17
- it "should work just fine" do
18
- @lexer = Gherkin::Lexer::I18nLexer.new(@listener)
19
- scan_file("with_bom_and_language_spec.feature")
20
- @listener.to_sexp.should == [
21
- [:comment, "# language: nl", 1],
22
- [:feature, "Functionaliteit", "Feature Text", "", 2],
23
- [:scenario, "Scenario", "Reading a Scenario", "", 3],
24
- [:step, "Gegeven ", "there is a step", 4],
25
- [:eof]
26
- ]
27
- end
28
- end
29
-
30
- describe "with ISO-8859-1 encoding" do
31
- it "should work just fine" do
32
- @lexer = Gherkin::Lexer::I18nLexer.new(@listener)
33
- scan_file("iso-8859-1.feature")
34
- @listener.to_sexp.should == [
35
- [:comment, "# language: no", 1],
36
- [:comment, "# encoding: iSo-8859-1", 2],
37
- [:feature, "Egenskap", "ISO-8859-1", "", 3],
38
- [:scenario, "Scenario", "ÆØÅ", "", 4],
39
- [:step, "Når ", "this is encoded as Latin-1", 5],
40
- [:step, "Så ", "everything should parse", 6],
41
- [:eof]
42
- ]
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,589 +0,0 @@
1
- #encoding: utf-8
2
- module Gherkin
3
- module Lexer
4
- shared_examples_for "a Gherkin lexer" do
5
- def scan(gherkin)
6
- @lexer.scan(gherkin)
7
- end
8
-
9
- describe "Comments" do
10
- it "should parse a one line comment" do
11
- scan("# My comment\n")
12
- @listener.to_sexp.should == [
13
- [:comment, "# My comment", 1],
14
- [:eof]
15
- ]
16
- end
17
-
18
- it "should parse a multiline comment" do
19
- scan("# Hello\n\n# World\n")
20
- @listener.to_sexp.should == [
21
- [:comment, "# Hello", 1],
22
- [:comment, "# World", 3],
23
- [:eof]
24
- ]
25
- end
26
-
27
- it "should not consume comments as part of a multiline name" do
28
- scan("Scenario: test\n#hello\n Scenario: another")
29
- @listener.to_sexp.should == [
30
- [:scenario, "Scenario", "test", "", 1],
31
- [:comment, "#hello", 2],
32
- [:scenario, "Scenario", "another", "", 3],
33
- [:eof]
34
- ]
35
- end
36
-
37
- it "should not consume comments as part of a multiline example name" do
38
- scan("Examples: thing\n# ho hum\n| 1 | 2 |\n| 3 | 4 |\n")
39
- @listener.to_sexp.should == [
40
- [:examples, "Examples", "thing", "", 1],
41
- [:comment, "# ho hum", 2],
42
- [:row, ["1","2"], 3],
43
- [:row, ["3","4"], 4],
44
- [:eof]
45
- ]
46
- end
47
-
48
- it "should allow empty comment lines" do
49
- scan("#\n # A comment\n #\n")
50
- @listener.to_sexp.should == [
51
- [:comment, "#", 1],
52
- [:comment, "# A comment", 2],
53
- [:comment, "#", 3],
54
- [:eof]
55
- ]
56
- end
57
-
58
- it "should not allow comments within the Feature description" do
59
- lambda {
60
- scan("Feature: something\nAs a something\n# Comment\nI want something")
61
- }.should raise_error(/Lexing error on line 4/)
62
- end
63
- end
64
-
65
- describe "Tags" do
66
- it "should not take the tags as part of a multiline name feature element" do
67
- scan("Feature: hi\n Scenario: test\n\n@hello\n Scenario: another")
68
- @listener.to_sexp.should == [
69
- [:feature, "Feature", "hi", "", 1],
70
- [:scenario, "Scenario", "test", "", 2],
71
- [:tag, "@hello", 4],
72
- [:scenario, "Scenario", "another", "", 5],
73
- [:eof]
74
- ]
75
- end
76
- end
77
-
78
- describe "Background" do
79
- it "should allow an empty background name and description" do
80
- scan("Background:\nGiven I am a step\n")
81
- @listener.to_sexp.should == [
82
- [:background, "Background", "", "", 1],
83
- [:step, "Given ", "I am a step", 2],
84
- [:eof]
85
- ]
86
- end
87
-
88
- it "should allow an empty background description" do
89
- scan("Background: Yeah\nGiven I am a step\n")
90
- @listener.to_sexp.should == [
91
- [:background, "Background", "Yeah", "", 1],
92
- [:step, "Given ", "I am a step", 2],
93
- [:eof]
94
- ]
95
- end
96
-
97
- it "should allow multiline descriptions ending at eof" do
98
- scan("Background: I have several\n Lines to look at\n None starting with Given")
99
- @listener.to_sexp.should == [
100
- [:background, "Background", "I have several", " Lines to look at\n None starting with Given", 1],
101
- [:eof]
102
- ]
103
- end
104
-
105
- it "should allow multiline descriptions, including whitespace" do
106
- scan(%{Feature: Hi
107
- Background: It is my ambition to say
108
- in ten sentences
109
- what others say
110
- in a whole book.
111
- Given I am a step})
112
- @listener.to_sexp.should == [
113
- [:feature, "Feature", "Hi", "", 1],
114
- [:background, "Background", "It is my ambition to say", "in ten sentences\n what others say \nin a whole book.",2],
115
- [:step, "Given ", "I am a step", 6],
116
- [:eof]
117
- ]
118
- end
119
- end
120
-
121
- describe "Scenarios" do
122
- it "should be parsed" do
123
- scan("Scenario: Hello\n")
124
- @listener.to_sexp.should == [
125
- [:scenario, "Scenario", "Hello", "", 1],
126
- [:eof]
127
- ]
128
- end
129
-
130
- it "should allow whitespace lines after the Scenario line" do
131
- scan(%{Scenario: bar
132
-
133
- Given baz
134
- })
135
- @listener.to_sexp.should == [
136
- [:scenario, "Scenario", "bar", "", 1],
137
- [:step, "Given ", "baz", 3],
138
- [:eof]
139
- ]
140
- end
141
-
142
- it "should allow multiline descriptions, including whitespace" do
143
- scan(%{Scenario: It is my ambition to say
144
- in ten sentences
145
- what others say
146
- in a whole book.
147
- Given I am a step
148
- })
149
- @listener.to_sexp.should == [
150
- [:scenario, "Scenario", "It is my ambition to say", "in ten sentences\nwhat others say \n in a whole book.", 1],
151
- [:step, "Given ", "I am a step", 5],
152
- [:eof]
153
- ]
154
- end
155
-
156
- it "should allow multiline names ending at eof" do
157
- scan("Scenario: I have several\nLines to look at\n None starting with Given")
158
- @listener.to_sexp.should == [
159
- [:scenario, "Scenario", "I have several", "Lines to look at\nNone starting with Given", 1],
160
- [:eof]
161
- ]
162
- end
163
-
164
- it "should ignore gherkin keywords embedded in other words" do
165
- scan(%{Scenario: I have a Button
166
- Buttons are great
167
- Given I have some
168
- But I might not because I am a Charles Dickens character
169
- })
170
- @listener.to_sexp.should == [
171
- [:scenario, "Scenario", "I have a Button", "Buttons are great", 1],
172
- [:step, "Given ", "I have some", 3],
173
- [:step, "But ", "I might not because I am a Charles Dickens character", 4],
174
- [:eof]
175
- ]
176
- end
177
-
178
- it "should allow step keywords in Scenario names" do
179
- scan(%{Scenario: When I have when in scenario
180
- I should be fine
181
- Given I am a step
182
- })
183
- @listener.to_sexp.should == [
184
- [:scenario, "Scenario", "When I have when in scenario", "I should be fine", 1],
185
- [:step, "Given ", "I am a step", 3],
186
- [:eof]
187
- ]
188
- end
189
- end
190
-
191
- describe "Scenario Outlines" do
192
- it "should be parsed" do
193
- scan(<<-HERE)
194
- Scenario Outline: Hello
195
- With a description
196
- Given a <what> cucumber
197
- Examples: With a name
198
- and a description
199
- |what|
200
- |green|
201
- HERE
202
- @listener.to_sexp.should == [
203
- [:scenario_outline, "Scenario Outline", "Hello", "With a description", 1],
204
- [:step, "Given ", "a <what> cucumber", 3],
205
- [:examples, "Examples", "With a name", "and a description", 4],
206
- [:row, ["what"], 6],
207
- [:row, ["green"], 7],
208
- [:eof]
209
- ]
210
- end
211
-
212
-
213
- it "should parse with no steps or examples" do
214
- scan(%{Scenario Outline: Hello
215
-
216
- Scenario: My Scenario
217
- })
218
- @listener.to_sexp.should == [
219
- [:scenario_outline, "Scenario Outline", "Hello", "", 1],
220
- [:scenario, "Scenario", "My Scenario", "", 3],
221
- [:eof]
222
- ]
223
- end
224
-
225
- it "should allow multiline description" do
226
- scan(<<-HERE)
227
- Scenario Outline: It is my ambition to say
228
- in ten sentences
229
- what others say
230
- in a whole book.
231
- Given I am a step
232
- HERE
233
- @listener.to_sexp.should == [
234
- [:scenario_outline, "Scenario Outline", "It is my ambition to say", "in ten sentences\n what others say \nin a whole book.", 1],
235
- [:step, "Given ", "I am a step", 5],
236
- [:eof]
237
- ]
238
- end
239
- end
240
-
241
- describe "Examples" do
242
- it "should be parsed" do
243
- scan(%{Examples:
244
- |x|y|
245
- |5|6|
246
- })
247
- @listener.to_sexp.should == [
248
- [:examples, "Examples", "", "", 1],
249
- [:row, ["x","y"], 2],
250
- [:row, ["5","6"], 3],
251
- [:eof]
252
- ]
253
- end
254
-
255
- it "should parse multiline example names" do
256
- scan(%{Examples: I'm a multiline name
257
- and I'm ok
258
- f'real
259
- |x|
260
- |5|
261
- })
262
- @listener.to_sexp.should == [
263
- [:examples, "Examples", "I'm a multiline name", "and I'm ok\nf'real", 1],
264
- [:row, ["x"], 4],
265
- [:row, ["5"], 5],
266
- [:eof]
267
- ]
268
- end
269
- end
270
-
271
- describe "Steps" do
272
- it "should parse steps with inline table" do
273
- scan(%{Given I have a table
274
- |a|b|
275
- })
276
- @listener.to_sexp.should == [
277
- [:step, "Given ", "I have a table", 1],
278
- [:row, ['a','b'], 2],
279
- [:eof]
280
- ]
281
- end
282
-
283
- it "should parse steps with inline doc_string" do
284
- scan("Given I have a string\n\"\"\"\nhello\nworld\n\"\"\"")
285
- @listener.to_sexp.should == [
286
- [:step, "Given ", "I have a string", 1],
287
- [:doc_string, '', "hello\nworld", 2],
288
- [:eof]
289
- ]
290
- end
291
-
292
- it "should parse steps with an empty name" do
293
- scan("Given ")
294
- @listener.to_sexp.should == [
295
- [:step, "Given ", "", 1],
296
- [:eof]
297
- ]
298
- end
299
- end
300
-
301
- describe "A single feature, single scenario, single step" do
302
- it "should find the feature, scenario, and step" do
303
- scan("Feature: Feature Text\n Scenario: Reading a Scenario\n Given there is a step\n")
304
- @listener.to_sexp.should == [
305
- [:feature, "Feature", "Feature Text", "", 1],
306
- [:scenario, "Scenario", "Reading a Scenario", "", 2],
307
- [:step, "Given ", "there is a step", 3],
308
- [:eof]
309
- ]
310
- end
311
- end
312
-
313
- describe "A feature ending in whitespace" do
314
- it "should not raise an error when whitespace follows the Feature, Scenario, and Steps" do
315
- scan("Feature: Feature Text\n Scenario: Reading a Scenario\n Given there is a step\n ")
316
- @listener.to_sexp.should == [
317
- [:feature, "Feature", "Feature Text", "", 1],
318
- [:scenario, "Scenario", "Reading a Scenario", "", 2],
319
- [:step, "Given ", "there is a step", 3],
320
- [:eof]
321
- ]
322
- end
323
- end
324
-
325
- describe "A single feature, single scenario, three steps" do
326
-
327
- it "should find the feature, scenario, and three steps" do
328
- scan("Feature: Feature Text\n Scenario: Reading a Scenario\n Given there is a step\n And another step\n And a third step\n")
329
- @listener.to_sexp.should == [
330
- [:feature, "Feature", "Feature Text", "", 1],
331
- [:scenario, "Scenario", "Reading a Scenario", "", 2],
332
- [:step, "Given ", "there is a step", 3],
333
- [:step, "And ", "another step", 4],
334
- [:step, "And ", "a third step", 5],
335
- [:eof]
336
- ]
337
- end
338
- end
339
-
340
- describe "A single feature with no scenario" do
341
- it "should find the feature" do
342
- scan("Feature: Feature Text\n")
343
- @listener.to_sexp.should == [
344
- [:feature, "Feature", "Feature Text", "", 1],
345
- [:eof]
346
- ]
347
- end
348
-
349
- it "should parse a one line feature with no newline" do
350
- scan("Feature: hi")
351
- @listener.to_sexp.should == [
352
- [:feature, "Feature", "hi", "", 1],
353
- [:eof]
354
- ]
355
- end
356
- end
357
-
358
- describe "A multi-line feature with no scenario" do
359
- it "should find the feature" do
360
- scan("Feature: Feature Text\n And some more text")
361
- @listener.to_sexp.should == [
362
- [:feature, "Feature", "Feature Text", "And some more text", 1],
363
- [:eof]
364
- ]
365
- end
366
- end
367
-
368
- describe "A feature with a scenario but no steps" do
369
- it "should find the feature and scenario" do
370
- scan("Feature: Feature Text\nScenario: Reading a Scenario\n")
371
- @listener.to_sexp.should == [
372
- [:feature, "Feature", "Feature Text", "", 1],
373
- [:scenario, "Scenario", "Reading a Scenario", "", 2],
374
- [:eof]
375
- ]
376
- end
377
- end
378
-
379
- describe "A feature with two scenarios" do
380
- it "should find the feature and two scenarios" do
381
- scan("Feature: Feature Text\nScenario: Reading a Scenario\n Given a step\n\nScenario: A second scenario\n Given another step\n")
382
- @listener.to_sexp.should == [
383
- [:feature, "Feature", "Feature Text", "", 1],
384
- [:scenario, "Scenario", "Reading a Scenario", "", 2],
385
- [:step, "Given ", "a step", 3],
386
- [:scenario, "Scenario", "A second scenario", "", 5],
387
- [:step, "Given ", "another step", 6],
388
- [:eof]
389
- ]
390
- end
391
-
392
- it "should find the feature and two scenarios without indentation" do
393
- scan("Feature: Feature Text\nScenario: Reading a Scenario\nGiven a step\nScenario: A second scenario\nGiven another step\n")
394
- @listener.to_sexp.should == [
395
- [:feature, "Feature", "Feature Text", "", 1],
396
- [:scenario, "Scenario", "Reading a Scenario", "", 2],
397
- [:step, "Given ", "a step", 3],
398
- [:scenario, "Scenario", "A second scenario", "", 4],
399
- [:step, "Given ", "another step", 5],
400
- [:eof]
401
- ]
402
- end
403
- end
404
-
405
- describe "A simple feature with comments" do
406
- it "should find the feature, scenarios, steps, and comments in the proper order" do
407
- scan_file("simple_with_comments.feature")
408
- @listener.to_sexp.should == [
409
- [:comment, "# Here is a comment", 1],
410
- [:feature, "Feature", "Feature Text", "", 2],
411
- [:comment, "# Here is another # comment", 3],
412
- [:scenario, "Scenario", "Reading a Scenario", "", 4],
413
- [:comment, "# Here is a third comment", 5],
414
- [:step, "Given ", "there is a step", 6],
415
- [:comment, "# Here is a fourth comment", 7],
416
- [:eof]
417
- ]
418
- end
419
-
420
- it "should support comments in tables" do
421
- scan_file("comments_in_table.feature")
422
- @listener.to_sexp.should == [
423
- [:feature, "Feature", "x", "", 1],
424
- [:scenario_outline, "Scenario Outline", "x", "", 3],
425
- [:step, "Then ", "x is <state>", 4],
426
- [:examples, "Examples", "", "", 6],
427
- [:row, ["state"], 7],
428
- [:comment, "# comment", 8],
429
- [:row, ["1"], 9],
430
- [:eof]
431
- ]
432
- end
433
- end
434
-
435
- describe "A feature with tags everywhere" do
436
- it "should find the feature, scenario, step, and tags in the proper order" do
437
- scan_file("simple_with_tags.feature")
438
- @listener.to_sexp.should == [
439
- [:comment, "# FC", 1],
440
- [:tag, "@ft",2],
441
- [:feature, "Feature", "hi", "", 3],
442
- [:tag, "@st1", 5],
443
- [:tag, "@st2", 5],
444
- [:scenario, "Scenario", "First", "", 6],
445
- [:step, "Given ", "Pepper", 7],
446
- [:tag, "@st3", 9],
447
- [:tag, "@st4", 10],
448
- [:tag, "@ST5", 10],
449
- [:tag, "@#^%&ST6**!", 10],
450
- [:scenario, "Scenario", "Second", "", 11],
451
- [:eof]
452
- ]
453
- end
454
- end
455
-
456
- describe "Comment or tag between Feature elements where previous narrative starts with same letter as a keyword" do
457
- it "should lex this feature properly" do
458
- scan_file("1.feature")
459
- @listener.to_sexp.should == [
460
- [:feature, "Feature", "Logging in", "So that I can be myself", 1],
461
- [:comment, "# Comment", 3],
462
- [:scenario, "Scenario", "Anonymous user can get a login form.", "Scenery here", 4],
463
- [:tag, "@tag", 7],
464
- [:scenario, "Scenario", "Another one", "", 8],
465
- [:eof]
466
- ]
467
- end
468
- end
469
-
470
- describe "A complex feature with tags, comments, multiple scenarios, and multiple steps and tables" do
471
- it "should find things in the right order" do
472
- scan_file("complex.feature")
473
- @listener.to_sexp.should == [
474
- [:comment, "#Comment on line 1", 1],
475
- [:comment, "#Comment on line 2", 2],
476
- [:tag, "@tag1", 3],
477
- [:tag, "@tag2", 3],
478
- [:feature, "Feature", "Feature Text", "In order to test multiline forms\nAs a ragel writer\nI need to check for complex combinations", 4],
479
- [:comment, "#Comment on line 9", 9],
480
- [:comment, "#Comment on line 11", 11],
481
- [:background, "Background", "", "", 13],
482
- [:step, "Given ", "this is a background step", 14],
483
- [:step, "And ", "this is another one", 15],
484
- [:tag, "@tag3", 17],
485
- [:tag, "@tag4", 17],
486
- [:scenario, "Scenario", "Reading a Scenario", "", 18],
487
- [:step, "Given ", "there is a step", 19],
488
- [:step, "But ", "not another step", 20],
489
- [:tag, "@tag3", 22],
490
- [:scenario, "Scenario", "Reading a second scenario", "With two lines of text", 23],
491
- [:comment, "#Comment on line 24", 25],
492
- [:step, "Given ", "a third step with a table", 26],
493
- [:row, %w{a b}, 27],
494
- [:row, %w{c d}, 28],
495
- [:row, %w{e f}, 29],
496
- [:step, "And ", "I am still testing things", 30],
497
- [:row, %w{g h}, 31],
498
- [:row, %w{e r}, 32],
499
- [:row, %w{k i}, 33],
500
- [:row, ['n', ''], 34],
501
- [:step, "And ", "I am done testing these tables", 35],
502
- [:comment, "#Comment on line 29", 36],
503
- [:step, "Then ", "I am happy", 37],
504
- [:scenario, "Scenario", "Hammerzeit", "", 39],
505
- [:step, "Given ", "All work and no play", 40],
506
- [:doc_string, '', "Makes Homer something something\nAnd something else", 41 ],
507
- [:step, "Then ", "crazy", 45],
508
- [:eof]
509
- ]
510
- end
511
- end
512
-
513
- describe "Windows stuff" do
514
- it "should find things in the right order for CRLF features" do
515
- scan_file("dos_line_endings.feature")
516
- @listener.to_sexp.should == [
517
- [:comment, "#Comment on line 1", 1],
518
- [:comment, "#Comment on line 2", 2],
519
- [:tag, "@tag1", 3],
520
- [:tag, "@tag2", 3],
521
- [:feature, "Feature", "Feature Text", "In order to test multiline forms\r\nAs a ragel writer\r\nI need to check for complex combinations", 4],
522
- [:comment, "#Comment on line 9", 9],
523
- [:comment, "#Comment on line 11", 11],
524
- [:background, "Background", "", "", 13],
525
- [:step, "Given ", "this is a background step", 14],
526
- [:step, "And ", "this is another one", 15],
527
- [:tag, "@tag3", 17],
528
- [:tag, "@tag4", 17],
529
- [:scenario, "Scenario", "Reading a Scenario", "", 18],
530
- [:step, "Given ", "there is a step", 19],
531
- [:step, "But ", "not another step", 20],
532
- [:tag, "@tag3", 22],
533
- [:scenario, "Scenario", "Reading a second scenario", "With two lines of text", 23],
534
- [:comment, "#Comment on line 24", 25],
535
- [:step, "Given ", "a third step with a table", 26],
536
- [:row, %w{a b}, 27],
537
- [:row, %w{c d}, 28],
538
- [:row, %w{e f}, 29],
539
- [:step, "And ", "I am still testing things", 30],
540
- [:row, %w{g h}, 31],
541
- [:row, %w{e r}, 32],
542
- [:row, %w{k i}, 33],
543
- [:row, ['n', ''], 34],
544
- [:step, "And ", "I am done testing these tables", 35],
545
- [:comment, "#Comment on line 29", 36],
546
- [:step, "Then ", "I am happy", 37],
547
- [:scenario, "Scenario", "Hammerzeit", "", 39],
548
- [:step, "Given ", "All work and no play", 40],
549
- [:doc_string, '', "Makes Homer something something\r\nAnd something else", 41],
550
- [:step, "Then ", "crazy", 45],
551
- [:eof]
552
- ]
553
- end
554
- end
555
-
556
- describe "errors" do
557
- it "should raise a Lexing error if an unparseable token is found" do
558
- ["Some text\nFeature: Hi",
559
- "Feature: Hi\nBackground:\nGiven something\nScenario A scenario",
560
- "Scenario: My scenario\nGiven foo\nAand bar\nScenario: another one\nGiven blah"].each do |text|
561
- lambda { scan(text) }.should raise_error(/Lexing error on line/)
562
- end
563
- end
564
-
565
- it "should include the line number and context of the error" do
566
- lambda {
567
- scan("Feature: hello\nScenario: My scenario\nGiven foo\nAand blah\nHmmm wrong\nThen something something")
568
- }.should raise_error(/Lexing error on line 4/)
569
- end
570
-
571
- it "Feature keyword should terminate narratives for multiline capable tokens" do
572
- scan("Feature:\nBackground:\nFeature:\nScenario Outline:\nFeature:\nScenario:\nFeature:\nExamples:\nFeature:\n")
573
- @listener.to_sexp.should == [
574
- [:feature, "Feature", "", "", 1],
575
- [:background, "Background", "", "", 2],
576
- [:feature, "Feature", "", "", 3],
577
- [:scenario_outline, "Scenario Outline", "", "", 4],
578
- [:feature, "Feature", "", "", 5],
579
- [:scenario, "Scenario", "", "", 6],
580
- [:feature, "Feature", "", "", 7],
581
- [:examples, "Examples", "","", 8],
582
- [:feature, "Feature", "", "", 9],
583
- [:eof]
584
- ]
585
- end
586
- end
587
- end
588
- end
589
- end