kosmas58-cucumber 0.1.16.6 → 0.1.99.21

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 (248) hide show
  1. data/History.txt +126 -2
  2. data/License.txt +1 -1
  3. data/Manifest.txt +0 -270
  4. data/Rakefile +1 -1
  5. data/bin/cucumber +2 -2
  6. data/config/hoe.rb +7 -2
  7. data/examples/cs/features/step_definitons/calculator_steps.rb +1 -1
  8. data/examples/i18n/README.textile +1 -1
  9. data/examples/i18n/Rakefile +3 -3
  10. data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -6
  11. data/examples/i18n/da/features/step_definitons/kalkulator_steps.rb +1 -1
  12. data/examples/i18n/de/features/addition.feature +6 -6
  13. data/examples/i18n/de/features/step_definitons/calculator_steps.rb +2 -2
  14. data/examples/i18n/en/features/addition.feature +6 -6
  15. data/examples/i18n/en/features/step_definitons/calculator_steps.rb +2 -2
  16. data/examples/i18n/es/features/adicion.feature +11 -12
  17. data/examples/i18n/es/features/step_definitons/calculador_steps.rb +7 -10
  18. data/examples/i18n/es/lib/calculador.rb +4 -1
  19. data/examples/i18n/et/features/liitmine.feature +7 -6
  20. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +1 -1
  21. data/examples/i18n/fi/features/step_definitons/laskin_steps.rb +1 -1
  22. data/examples/i18n/fi/features/yhteenlasku.feature +2 -2
  23. data/examples/i18n/fr/features/addition.feature +2 -2
  24. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +1 -1
  25. data/examples/i18n/id/features/addition.feature +6 -6
  26. data/examples/i18n/id/features/step_definitons/calculator_steps.rb +2 -2
  27. data/examples/i18n/it/features/step_definitons/calcolatrice_steps.rb +1 -1
  28. data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +2 -3
  29. data/examples/i18n/ko/features/step_definitons/calculator_steps.rb +1 -1
  30. data/examples/i18n/lt/features/addition.feature +7 -6
  31. data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +2 -2
  32. data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +7 -7
  33. data/examples/i18n/no/features/summering.feature +1 -0
  34. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +1 -1
  35. data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +1 -1
  36. data/examples/i18n/se/features/step_definitons/kalkulator_steps.rb +1 -1
  37. data/examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb +2 -2
  38. data/examples/java/src/cucumber/demo/Hello.java +16 -0
  39. data/examples/jbehave/README.textile +17 -0
  40. data/examples/jbehave/features/support/env.rb +7 -0
  41. data/examples/jbehave/features/trading.feature +24 -0
  42. data/examples/jbehave/pom.xml +48 -0
  43. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/converters/TraderConverter.java +32 -0
  44. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Stock.java +42 -0
  45. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Trader.java +29 -0
  46. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/persistence/TraderPersister.java +22 -0
  47. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/scenarios/TraderSteps.java +65 -0
  48. data/examples/self_test/README.textile +4 -1
  49. data/examples/{calculator_ruby_features → self_test}/Rakefile +3 -3
  50. data/examples/self_test/features/background/failing_background.feature +10 -0
  51. data/examples/self_test/features/background/failing_background_after_success.feature +11 -0
  52. data/examples/self_test/features/background/multiline_args_background.feature +32 -0
  53. data/examples/self_test/features/background/passing_background.feature +10 -0
  54. data/examples/self_test/features/background/pending_background.feature +10 -0
  55. data/examples/self_test/features/background/scenario_outline_failing_background.feature +16 -0
  56. data/examples/self_test/features/background/scenario_outline_passing_background.feature +16 -0
  57. data/examples/self_test/features/call_undefined_step_from_step_def.feature +7 -0
  58. data/examples/self_test/features/lots_of_undefined.feature +8 -0
  59. data/examples/self_test/features/outline_sample.feature +11 -5
  60. data/examples/self_test/features/sample.feature +8 -3
  61. data/examples/self_test/features/step_definitions/sample_steps.rb +53 -4
  62. data/examples/self_test/features/support/env.rb +1 -0
  63. data/examples/self_test/features/support/tag_count_formatter.rb +25 -0
  64. data/examples/tickets/features/172.feature +28 -0
  65. data/examples/tickets/features/177/1.feature +29 -0
  66. data/examples/tickets/features/177/2.feature +21 -0
  67. data/examples/tickets/features/177/3.feature +18 -0
  68. data/examples/tickets/features/180.feature +7 -0
  69. data/examples/tickets/features/scenario_outline.feature +6 -1
  70. data/examples/tickets/features/step_definitons/tickets_steps.rb +27 -3
  71. data/examples/tickets/features/tickets.feature +4 -0
  72. data/features/background.feature +223 -0
  73. data/features/cucumber_cli.feature +218 -98
  74. data/features/cucumber_cli_outlines.feature +54 -37
  75. data/features/custom_formatter.feature +11 -0
  76. data/features/report_called_undefined_steps.feature +32 -0
  77. data/features/step_definitions/cucumber_steps.rb +7 -3
  78. data/features/step_definitions/extra_steps.rb +1 -1
  79. data/features/support/env.rb +2 -1
  80. data/gem_tasks/flog.rake +1 -1
  81. data/gem_tasks/gemspec.rake +2 -2
  82. data/gem_tasks/jar.rake +67 -0
  83. data/lib/autotest/cucumber_mixin.rb +17 -23
  84. data/lib/cucumber.rb +63 -11
  85. data/lib/cucumber/ast.rb +29 -0
  86. data/lib/cucumber/ast/background.rb +88 -0
  87. data/lib/cucumber/ast/comment.rb +26 -0
  88. data/lib/cucumber/ast/examples.rb +26 -0
  89. data/lib/cucumber/ast/feature.rb +66 -0
  90. data/lib/cucumber/ast/features.rb +39 -0
  91. data/lib/cucumber/ast/filter.rb +22 -0
  92. data/lib/cucumber/ast/outline_table.rb +49 -0
  93. data/lib/cucumber/ast/py_string.rb +52 -0
  94. data/lib/cucumber/ast/scenario.rb +103 -0
  95. data/lib/cucumber/ast/scenario_outline.rb +92 -0
  96. data/lib/cucumber/ast/step.rb +161 -0
  97. data/lib/cucumber/ast/steps.rb +13 -0
  98. data/lib/cucumber/ast/table.rb +218 -0
  99. data/lib/cucumber/ast/tags.rb +40 -0
  100. data/lib/cucumber/ast/visitor.rb +109 -0
  101. data/lib/cucumber/broadcaster.rb +1 -6
  102. data/lib/cucumber/cli/configuration.rb +339 -0
  103. data/lib/cucumber/cli/language_help_formatter.rb +59 -0
  104. data/lib/cucumber/cli/main.rb +100 -0
  105. data/lib/cucumber/core_ext/exception.rb +41 -8
  106. data/lib/cucumber/core_ext/instance_exec.rb +54 -0
  107. data/lib/cucumber/core_ext/proc.rb +29 -65
  108. data/lib/cucumber/core_ext/string.rb +19 -0
  109. data/lib/cucumber/formatter.rb +1 -0
  110. data/lib/cucumber/{formatters → formatter}/ansicolor.rb +14 -16
  111. data/lib/cucumber/formatter/color_io.rb +17 -0
  112. data/lib/cucumber/formatter/console.rb +119 -0
  113. data/lib/cucumber/formatter/cucumber.css +55 -0
  114. data/lib/cucumber/formatter/cucumber.sass +49 -0
  115. data/lib/cucumber/formatter/html.rb +121 -0
  116. data/lib/cucumber/formatter/pretty.rb +167 -0
  117. data/lib/cucumber/formatter/profile.rb +77 -0
  118. data/lib/cucumber/formatter/progress.rb +68 -0
  119. data/lib/cucumber/formatter/rerun.rb +35 -0
  120. data/lib/cucumber/formatter/unicode.rb +35 -0
  121. data/lib/cucumber/formatters/unicode.rb +2 -35
  122. data/lib/cucumber/jbehave.rb +102 -0
  123. data/lib/cucumber/languages.yml +128 -75
  124. data/lib/cucumber/parser.rb +43 -0
  125. data/lib/cucumber/parser/basic.rb +0 -0
  126. data/lib/cucumber/parser/feature.rb +1490 -0
  127. data/lib/cucumber/parser/feature.tt +188 -0
  128. data/lib/cucumber/parser/i18n.tt +31 -0
  129. data/lib/cucumber/parser/table.rb +402 -0
  130. data/lib/cucumber/parser/table.tt +59 -0
  131. data/lib/cucumber/parser/treetop_ext.rb +75 -0
  132. data/lib/cucumber/platform.rb +3 -17
  133. data/lib/cucumber/rails/rspec.rb +5 -2
  134. data/lib/cucumber/step_definition.rb +87 -0
  135. data/lib/cucumber/step_mother.rb +151 -66
  136. data/lib/cucumber/version.rb +2 -2
  137. data/rails_generators/cucumber/USAGE +3 -2
  138. data/rails_generators/cucumber/cucumber_generator.rb +33 -23
  139. data/rails_generators/cucumber/templates/cucumber +2 -1
  140. data/rails_generators/cucumber/templates/cucumber.rake +6 -1
  141. data/rails_generators/cucumber/templates/env.rb +1 -1
  142. data/rails_generators/feature/USAGE +3 -0
  143. data/rails_generators/feature/feature_generator.rb +30 -6
  144. data/spec/cucumber/ast/background_spec.rb +58 -0
  145. data/spec/cucumber/ast/feature_factory.rb +54 -0
  146. data/spec/cucumber/ast/feature_spec.rb +60 -0
  147. data/spec/cucumber/ast/py_string_spec.rb +40 -0
  148. data/spec/cucumber/ast/scenario_outline_spec.rb +64 -0
  149. data/spec/cucumber/ast/scenario_spec.rb +82 -0
  150. data/spec/cucumber/ast/step_spec.rb +45 -0
  151. data/spec/cucumber/ast/table_spec.rb +81 -0
  152. data/spec/cucumber/ast/tags_spec.rb +23 -0
  153. data/spec/cucumber/broadcaster_spec.rb +4 -17
  154. data/spec/cucumber/cli/configuration_spec.rb +239 -0
  155. data/spec/cucumber/cli/main_spec.rb +164 -0
  156. data/spec/cucumber/core_ext/proc_spec.rb +27 -35
  157. data/spec/cucumber/core_ext/string_spec.rb +8 -0
  158. data/spec/cucumber/{formatters → formatter}/ansicolor_spec.rb +2 -2
  159. data/spec/cucumber/formatter/html/cucumber.css +37 -0
  160. data/spec/cucumber/formatter/html/cucumber.js +13 -0
  161. data/spec/cucumber/formatter/html/index.html +45 -0
  162. data/spec/cucumber/formatter/html/jquery-1.3.min.js +19 -0
  163. data/spec/cucumber/formatter/html/jquery.uitableedit.js +100 -0
  164. data/spec/cucumber/formatters/profile_formatter_spec.rb +17 -16
  165. data/spec/cucumber/parser/feature_parser_spec.rb +281 -0
  166. data/spec/cucumber/parser/table_parser_spec.rb +48 -0
  167. data/spec/cucumber/step_definition_spec.rb +62 -0
  168. data/spec/cucumber/step_mother_spec.rb +50 -51
  169. data/spec/cucumber/treetop_parser/empty_feature.feature +1 -1
  170. data/spec/cucumber/treetop_parser/scenario_outline.feature +1 -1
  171. data/spec/cucumber/treetop_parser/spaces.feature +3 -1
  172. data/spec/cucumber/treetop_parser/with_comments.feature +1 -1
  173. data/spec/cucumber/treetop_parser/with_tags.feature +18 -0
  174. data/spec/cucumber/world/pending_spec.rb +13 -12
  175. data/spec/spec_helper.rb +1 -1
  176. metadata +107 -79
  177. data/examples/calculator_ruby_features/features/addition.rb +0 -39
  178. data/examples/calculator_ruby_features/features/step_definitons/calculator_steps.rb +0 -43
  179. data/gem_tasks/treetop.rake +0 -41
  180. data/lib/cucumber/cli.rb +0 -355
  181. data/lib/cucumber/executor.rb +0 -205
  182. data/lib/cucumber/formatters.rb +0 -1
  183. data/lib/cucumber/formatters/autotest_formatter.rb +0 -23
  184. data/lib/cucumber/formatters/cucumber.css +0 -132
  185. data/lib/cucumber/formatters/cucumber.js +0 -11
  186. data/lib/cucumber/formatters/html_formatter.rb +0 -152
  187. data/lib/cucumber/formatters/jquery.js +0 -32
  188. data/lib/cucumber/formatters/pretty_formatter.rb +0 -285
  189. data/lib/cucumber/formatters/profile_formatter.rb +0 -92
  190. data/lib/cucumber/formatters/progress_formatter.rb +0 -61
  191. data/lib/cucumber/model.rb +0 -1
  192. data/lib/cucumber/model/table.rb +0 -32
  193. data/lib/cucumber/step_methods.rb +0 -49
  194. data/lib/cucumber/tree.rb +0 -16
  195. data/lib/cucumber/tree/feature.rb +0 -105
  196. data/lib/cucumber/tree/features.rb +0 -21
  197. data/lib/cucumber/tree/given_scenario.rb +0 -13
  198. data/lib/cucumber/tree/scenario.rb +0 -240
  199. data/lib/cucumber/tree/step.rb +0 -173
  200. data/lib/cucumber/tree/table.rb +0 -26
  201. data/lib/cucumber/tree/top_down_visitor.rb +0 -23
  202. data/lib/cucumber/treetop_parser/feature.treetop.erb +0 -254
  203. data/lib/cucumber/treetop_parser/feature_ar.rb +0 -1951
  204. data/lib/cucumber/treetop_parser/feature_cy.rb +0 -1951
  205. data/lib/cucumber/treetop_parser/feature_da.rb +0 -1951
  206. data/lib/cucumber/treetop_parser/feature_de.rb +0 -1951
  207. data/lib/cucumber/treetop_parser/feature_en-lol.rb +0 -1951
  208. data/lib/cucumber/treetop_parser/feature_en-tx.rb +0 -1951
  209. data/lib/cucumber/treetop_parser/feature_en.rb +0 -1951
  210. data/lib/cucumber/treetop_parser/feature_es.rb +0 -1951
  211. data/lib/cucumber/treetop_parser/feature_et.rb +0 -1951
  212. data/lib/cucumber/treetop_parser/feature_fi.rb +0 -1951
  213. data/lib/cucumber/treetop_parser/feature_fr.rb +0 -1951
  214. data/lib/cucumber/treetop_parser/feature_id.rb +0 -1951
  215. data/lib/cucumber/treetop_parser/feature_it.rb +0 -1951
  216. data/lib/cucumber/treetop_parser/feature_ja.rb +0 -1951
  217. data/lib/cucumber/treetop_parser/feature_ko.rb +0 -1951
  218. data/lib/cucumber/treetop_parser/feature_lt.rb +0 -1951
  219. data/lib/cucumber/treetop_parser/feature_nl.rb +0 -1951
  220. data/lib/cucumber/treetop_parser/feature_no.rb +0 -1951
  221. data/lib/cucumber/treetop_parser/feature_parser.rb +0 -36
  222. data/lib/cucumber/treetop_parser/feature_pl.rb +0 -1951
  223. data/lib/cucumber/treetop_parser/feature_pt.rb +0 -1951
  224. data/lib/cucumber/treetop_parser/feature_ro.rb +0 -1951
  225. data/lib/cucumber/treetop_parser/feature_ro2.rb +0 -1951
  226. data/lib/cucumber/treetop_parser/feature_ru.rb +0 -1951
  227. data/lib/cucumber/treetop_parser/feature_se.rb +0 -1951
  228. data/lib/cucumber/treetop_parser/feature_zh-CN.rb +0 -1951
  229. data/lib/cucumber/world.rb +0 -1
  230. data/lib/cucumber/world/pending.rb +0 -22
  231. data/setup.rb +0 -1585
  232. data/spec/cucumber/cli_spec.rb +0 -521
  233. data/spec/cucumber/executor_spec.rb +0 -382
  234. data/spec/cucumber/formatters/autotest_formatter_spec.rb +0 -26
  235. data/spec/cucumber/formatters/features.html +0 -269
  236. data/spec/cucumber/formatters/html_formatter_spec.rb +0 -110
  237. data/spec/cucumber/formatters/pretty_formatter_spec.rb +0 -410
  238. data/spec/cucumber/formatters/progress_formatter_spec.rb +0 -81
  239. data/spec/cucumber/model/table_spec.rb +0 -32
  240. data/spec/cucumber/tree/feature_spec.rb +0 -122
  241. data/spec/cucumber/tree/row_scenario_outline_spec.rb +0 -73
  242. data/spec/cucumber/tree/row_scenario_spec.rb +0 -55
  243. data/spec/cucumber/tree/row_step_outline_spec.rb +0 -38
  244. data/spec/cucumber/tree/scenario_outline_spec.rb +0 -50
  245. data/spec/cucumber/tree/scenario_spec.rb +0 -134
  246. data/spec/cucumber/tree/step_outline_spec.rb +0 -17
  247. data/spec/cucumber/tree/step_spec.rb +0 -59
  248. data/spec/cucumber/treetop_parser/feature_parser_spec.rb +0 -120
@@ -0,0 +1,26 @@
1
+ module Cucumber
2
+ module Ast
3
+ # Holds the value of a comment parsed from a feature file:
4
+ #
5
+ # # Lorem ipsum
6
+ # # dolor sit amet
7
+ #
8
+ # This gets parsed into a Comment with value <tt>"# Lorem ipsum\n# dolor sit amet\n"</tt>
9
+ #
10
+ class Comment
11
+ def initialize(value)
12
+ @value = value
13
+ end
14
+
15
+ def accept(visitor)
16
+ @value.split("\n").each do |line|
17
+ visitor.visit_comment_line(line.strip)
18
+ end
19
+ end
20
+
21
+ def to_sexp
22
+ (@value.nil? || @value == '') ? nil : [:comment, @value]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ module Cucumber
2
+ module Ast
3
+ class Examples
4
+ def initialize(line, keyword, name, outline_table)
5
+ @keyword, @name, @outline_table = keyword, name, outline_table
6
+ end
7
+
8
+ def accept(visitor)
9
+ visitor.visit_examples_name(@keyword, @name)
10
+ visitor.visit_outline_table(@outline_table)
11
+ end
12
+
13
+ def each_example_row(&proc)
14
+ @outline_table.each_cells_row(&proc)
15
+ end
16
+
17
+ def at_lines?(lines)
18
+ lines.empty? || lines.index(@line) || @outline_table.at_lines?(lines)
19
+ end
20
+
21
+ def to_sexp
22
+ [:examples, @keyword, @name, @outline_table.to_sexp]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,66 @@
1
+ module Cucumber
2
+ module Ast
3
+ # Represents the root node of a parsed feature.
4
+ class Feature
5
+ attr_accessor :file
6
+ attr_writer :features, :lines
7
+
8
+ def initialize(comment, tags, name, feature_elements, background = nil)
9
+ @comment, @tags, @name, @feature_elements, @background = comment, tags, name, feature_elements, background
10
+ feature_elements.each do |feature_element|
11
+ feature_element.feature = self
12
+ feature_element.background = background if background
13
+ end
14
+ background.feature = self if background
15
+ @lines = []
16
+ end
17
+
18
+ def tagged_with?(tag_names, check_elements=true)
19
+ @tags.among?(tag_names) ||
20
+ (check_elements && @feature_elements.detect{|e| e.tagged_with?(tag_names)})
21
+ end
22
+
23
+ def matches_scenario_names?(scenario_names)
24
+ @feature_elements.detect{|e| e.matches_scenario_names?(scenario_names)}
25
+ end
26
+
27
+ def accept(visitor)
28
+ visitor.current_feature_lines = @lines
29
+ visitor.visit_comment(@comment)
30
+ visitor.visit_tags(@tags)
31
+ visitor.visit_feature_name(@name)
32
+
33
+ @feature_elements.each do |feature_element|
34
+ visitor.visit_feature_element(feature_element) if @features.visit?(feature_element, @lines)
35
+ end
36
+ end
37
+
38
+ def scenario_executed(scenario)
39
+ @features.scenario_executed(scenario) if @features
40
+ end
41
+
42
+ def step_executed(step)
43
+ @features.step_executed(step) if @features
44
+ end
45
+
46
+ def backtrace_line(step_name, line)
47
+ "#{file_line(line)}:in `#{step_name}'"
48
+ end
49
+
50
+ def file_line(line)
51
+ "#{@file}:#{line}"
52
+ end
53
+
54
+ def to_sexp
55
+ sexp = [:feature, @name]
56
+ comment = @comment.to_sexp
57
+ sexp += [comment] if comment
58
+ tags = @tags.to_sexp
59
+ sexp += tags if tags.any?
60
+ sexp += [@background.to_sexp] if @background
61
+ sexp += @feature_elements.map{|e| e.to_sexp}
62
+ sexp
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,39 @@
1
+ module Cucumber
2
+ module Ast
3
+ class Features
4
+ attr_reader :steps, :scenarios
5
+
6
+ def initialize(filter)
7
+ @filter = filter
8
+
9
+ @features = []
10
+ @scenarios = []
11
+ @steps = Hash.new{|steps, status| steps[status] = []}
12
+ end
13
+
14
+ def add_feature(feature)
15
+ feature.features = self
16
+ @features << feature
17
+ end
18
+
19
+ def visit?(node, lines)
20
+ @filter.matched?(node) &&
21
+ (lines.empty? ? true : node.at_lines?(lines))
22
+ end
23
+
24
+ def scenario_executed(scenario)
25
+ @scenarios << scenario
26
+ end
27
+
28
+ def step_executed(step)
29
+ @steps[step.status] << step
30
+ end
31
+
32
+ def accept(visitor)
33
+ @features.each do |feature|
34
+ visitor.visit_feature(feature) if visit?(feature, [])
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,22 @@
1
+ module Cucumber
2
+ module Ast
3
+ class Filter
4
+ def initialize(options)
5
+ @options = options
6
+ end
7
+
8
+ def matched?(node)
9
+ matched_by_tags?(node) &&
10
+ matched_by_scenario_names?(node)
11
+ end
12
+
13
+ def matched_by_tags?(node)
14
+ @options[:tags].empty? || node.tagged_with?(@options[:tags])
15
+ end
16
+
17
+ def matched_by_scenario_names?(node)
18
+ @options[:scenario_names].empty? || node.matches_scenario_names?(@options[:scenario_names])
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,49 @@
1
+ module Cucumber
2
+ module Ast
3
+ class OutlineTable < Table
4
+ def initialize(raw, scenario_outline)
5
+ super(raw)
6
+ @scenario_outline = scenario_outline
7
+ @cells_class = ExampleCells
8
+ end
9
+
10
+ def accept(visitor, status)
11
+ cells_rows.each_with_index do |row, n|
12
+ should_visit = n == 0 ||
13
+ row.at_lines?(visitor.current_feature_lines) ||
14
+ @scenario_outline.at_header_or_step_lines?(visitor.current_feature_lines)
15
+
16
+ if should_visit
17
+ visitor.visit_table_row(row, status)
18
+ end
19
+ end
20
+ nil
21
+ end
22
+
23
+ def execute_row(cells, visitor, &proc)
24
+ @scenario_outline.execute_row(cells, visitor, &proc)
25
+ end
26
+
27
+ class ExampleCells < Cells
28
+ def accept(visitor, status)
29
+ if header?
30
+ @cells.each do |cell|
31
+ visitor.visit_table_cell(cell, :thead)
32
+ end
33
+ nil
34
+ else
35
+ exception = @table.execute_row(self, visitor) do |cell, status|
36
+ visitor.visit_table_cell(cell, status)
37
+ end
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def header?
44
+ index == 0
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,52 @@
1
+ module Cucumber
2
+ module Ast
3
+ # Represents an inline argument in a step. Example:
4
+ #
5
+ # Given the message
6
+ # """
7
+ # I like
8
+ # Cucumber sandwich
9
+ # """
10
+ #
11
+ # The text between the pair of <tt>"""</tt> is stored inside a PyString,
12
+ # which is yielded to the StepDefinition block as the last argument.
13
+ #
14
+ # The StepDefinition can then access the String via the #to_s method. In the
15
+ # example above, that would return: <tt>"I like\nCucumber sandwich"</tt>
16
+ #
17
+ # Note how the indentation from the source is stripped away.
18
+ #
19
+ class PyString
20
+ def initialize(start_line, end_line, string, quotes_indent)
21
+ @start_line, @end_line = start_line, end_line
22
+ @string, @quotes_indent = string.gsub(/\\"/, '"'), quotes_indent
23
+ end
24
+
25
+ def to_s
26
+ @string.indent(-@quotes_indent)
27
+ end
28
+
29
+ def at_lines?(lines)
30
+ lines.detect{|l| l >= @start_line && l <= @end_line}
31
+ end
32
+
33
+ def accept(visitor, status)
34
+ visitor.visit_py_string(to_s, status)
35
+ end
36
+
37
+ def arguments_replaced(arguments) #:nodoc:
38
+ string = @string
39
+ arguments.each do |name, value|
40
+ string = string.gsub(name, value)
41
+ end
42
+ PyString.new(@start_line, @end_line, string, @quotes_indent)
43
+ end
44
+
45
+ # For testing only
46
+ def to_sexp #:nodoc:
47
+ [:py_string, to_s]
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,103 @@
1
+ module Cucumber
2
+ module Ast
3
+ class Scenario
4
+ attr_writer :feature, :background
5
+
6
+ def initialize(comment, tags, line, keyword, name, steps)
7
+ @comment, @tags, @line, @keyword, @name = comment, tags, line, keyword, name
8
+ steps.each {|step| step.scenario = self}
9
+ @steps = steps
10
+ @steps_helper = Steps.new(self)
11
+ end
12
+
13
+ def status
14
+ @steps.map{|step| step.status}
15
+ end
16
+
17
+ def tagged_with?(tag_names)
18
+ @tags.among?(tag_names) || @feature.tagged_with?(tag_names, false)
19
+ end
20
+
21
+ def matches_scenario_names?(scenario_names)
22
+ scenario_names.detect{|name| @name == name}
23
+ end
24
+
25
+ def accept(visitor)
26
+ visitor.visit_background(@background) if @background
27
+ visitor.visit_comment(@comment)
28
+ visitor.visit_tags(@tags)
29
+ visitor.visit_scenario_name(@keyword, @name, file_line(@line), source_indent(text_length))
30
+ visitor.visit_steps(@steps_helper)
31
+
32
+ @feature.scenario_executed(self) if @feature && !@executed
33
+ @executed = true
34
+ end
35
+
36
+ def accept_steps(visitor)
37
+ prior_world = @background ? @background.world : nil
38
+ visitor.world(self, prior_world) do |world|
39
+ previous = @background ? @background.status : :passed
40
+ @steps.each do |step|
41
+ step.previous = previous
42
+ step.world = world
43
+ visitor.visit_step(step)
44
+ previous = step.status
45
+ end
46
+ end
47
+ end
48
+
49
+ def source_indent(text_length)
50
+ max_line_length - text_length
51
+ end
52
+
53
+ def max_line_length
54
+ lengths = (@steps + [self]).map{|e| e.text_length}
55
+ lengths.max
56
+ end
57
+
58
+ def text_length
59
+ @keyword.jlength + @name.jlength
60
+ end
61
+
62
+ def at_lines?(lines)
63
+ at_header_or_step_lines?(lines)
64
+ end
65
+
66
+ def at_header_or_step_lines?(lines)
67
+ lines.empty? || lines.index(@line) || @steps.detect {|step| step.at_lines?(lines)} || @tags.at_lines?(lines)
68
+ end
69
+
70
+ def undefined?
71
+ @steps.empty?
72
+ end
73
+
74
+ def step_executed(step)
75
+ @feature.step_executed(step) if @feature
76
+ end
77
+
78
+ def backtrace_line(name = "#{@keyword} #{@name}", line = @line)
79
+ @feature.backtrace_line(name, line) if @feature
80
+ end
81
+
82
+ def file_line(line = @line)
83
+ @feature.file_line(line) if @feature
84
+ end
85
+
86
+ def previous_step(step)
87
+ i = @steps.index(step) || -1
88
+ @steps[i-1]
89
+ end
90
+
91
+ def to_sexp
92
+ sexp = [:scenario, @line, @keyword, @name]
93
+ comment = @comment.to_sexp
94
+ sexp += [comment] if comment
95
+ tags = @tags.to_sexp
96
+ sexp += tags if tags.any?
97
+ steps = @steps.map{|step| step.to_sexp}
98
+ sexp += steps if steps.any?
99
+ sexp
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,92 @@
1
+ module Cucumber
2
+ module Ast
3
+ class ScenarioOutline < Scenario
4
+ # The +example_sections+ argument must be an Array where each element is another array representing
5
+ # an Examples section. This array has 3 elements:
6
+ #
7
+ # * Examples keyword
8
+ # * Examples section name
9
+ # * Raw matrix
10
+ def initialize(comment, tags, line, keyword, name, steps, example_sections)
11
+ super(comment, tags, line, keyword, name, steps)
12
+ steps.each {|step| step.status = :outline}
13
+
14
+ @examples_array = example_sections.map do |example_section|
15
+ examples_line = example_section[0]
16
+ examples_keyword = example_section[1]
17
+ examples_name = example_section[2]
18
+ examples_matrix = example_section[3]
19
+
20
+ examples_table = OutlineTable.new(examples_matrix, self)
21
+ Examples.new(examples_line, examples_keyword, examples_name, examples_table)
22
+ end
23
+ end
24
+
25
+ def at_lines?(lines)
26
+ super || @examples_array.detect { |examples| examples.at_lines?(lines) }
27
+ end
28
+
29
+ def accept(visitor)
30
+ visitor.visit_background(@background) if @background
31
+ visitor.visit_comment(@comment)
32
+ visitor.visit_tags(@tags)
33
+ visitor.visit_scenario_name(@keyword, @name, file_line(@line), source_indent(text_length))
34
+ visitor.visit_steps(@steps_helper)
35
+
36
+ @examples_array.each do |examples|
37
+ visitor.visit_examples(examples)
38
+ end
39
+ end
40
+
41
+ def each_example_row(&proc)
42
+ @examples_array.each do |examples|
43
+ examples.each_example_row(&proc)
44
+ end
45
+ end
46
+
47
+ def execute_row(cells, visitor, &proc)
48
+ exception = nil
49
+
50
+ prior_world = @background ? @background.world : nil
51
+ visitor.world(self, prior_world) do |world|
52
+
53
+ previous_status = @background ? @background.status : :passed
54
+ argument_hash = cells.to_hash
55
+ cell_index = 0
56
+ @steps.each do |step|
57
+ executed_step, previous_status, matched_args =
58
+ step.execute_with_arguments(argument_hash, world, previous_status, visitor, cells[0].line)
59
+ # There might be steps that don't have any arguments
60
+ # If there are no matched args, we'll still iterate once
61
+ matched_args = [nil] if matched_args.empty?
62
+
63
+ matched_args.each do
64
+ cell = cells[cell_index]
65
+ if cell
66
+ proc.call(cell, previous_status)
67
+ cell_index += 1
68
+ end
69
+ end
70
+ exception ||= executed_step.exception
71
+ end
72
+ end
73
+ @feature.scenario_executed(self) if @feature
74
+ exception
75
+ end
76
+
77
+ def pending? ; false ; end
78
+
79
+ def to_sexp
80
+ sexp = [:scenario_outline, @keyword, @name]
81
+ comment = @comment.to_sexp
82
+ sexp += [comment] if comment
83
+ tags = @tags.to_sexp
84
+ sexp += tags if tags.any?
85
+ steps = @steps.map{|step| step.to_sexp}
86
+ sexp += steps if steps.any?
87
+ sexp += @examples_array.map{|e| e.to_sexp}
88
+ sexp
89
+ end
90
+ end
91
+ end
92
+ end