cucumber-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.travis.yml +16 -0
- data/Gemfile +2 -0
- data/LICENSE +20 -0
- data/README.md +9 -0
- data/Rakefile +24 -0
- data/cucumber-core.gemspec +32 -0
- data/lib/cucumber/core.rb +37 -0
- data/lib/cucumber/core/ast.rb +13 -0
- data/lib/cucumber/core/ast/background.rb +33 -0
- data/lib/cucumber/core/ast/comment.rb +17 -0
- data/lib/cucumber/core/ast/data_table.rb +326 -0
- data/lib/cucumber/core/ast/describes_itself.rb +16 -0
- data/lib/cucumber/core/ast/doc_string.rb +83 -0
- data/lib/cucumber/core/ast/empty_background.rb +12 -0
- data/lib/cucumber/core/ast/examples_table.rb +95 -0
- data/lib/cucumber/core/ast/feature.rb +62 -0
- data/lib/cucumber/core/ast/location.rb +140 -0
- data/lib/cucumber/core/ast/multiline_argument.rb +33 -0
- data/lib/cucumber/core/ast/names.rb +19 -0
- data/lib/cucumber/core/ast/outline_step.rb +51 -0
- data/lib/cucumber/core/ast/scenario.rb +43 -0
- data/lib/cucumber/core/ast/scenario_outline.rb +44 -0
- data/lib/cucumber/core/ast/step.rb +38 -0
- data/lib/cucumber/core/ast/tag.rb +14 -0
- data/lib/cucumber/core/compiler.rb +136 -0
- data/lib/cucumber/core/gherkin/ast_builder.rb +315 -0
- data/lib/cucumber/core/gherkin/document.rb +20 -0
- data/lib/cucumber/core/gherkin/parser.rb +45 -0
- data/lib/cucumber/core/gherkin/writer.rb +220 -0
- data/lib/cucumber/core/gherkin/writer/helpers.rb +178 -0
- data/lib/cucumber/core/platform.rb +30 -0
- data/lib/cucumber/core/test/case.rb +143 -0
- data/lib/cucumber/core/test/filters.rb +48 -0
- data/lib/cucumber/core/test/filters/tag_filter.rb +110 -0
- data/lib/cucumber/core/test/hook_compiler.rb +109 -0
- data/lib/cucumber/core/test/mapper.rb +56 -0
- data/lib/cucumber/core/test/mapping.rb +67 -0
- data/lib/cucumber/core/test/result.rb +191 -0
- data/lib/cucumber/core/test/runner.rb +149 -0
- data/lib/cucumber/core/test/step.rb +69 -0
- data/lib/cucumber/core/test/timer.rb +31 -0
- data/lib/cucumber/core/version.rb +9 -0
- data/lib/cucumber/initializer.rb +18 -0
- data/spec/capture_warnings.rb +68 -0
- data/spec/coverage.rb +10 -0
- data/spec/cucumber/core/ast/data_table_spec.rb +139 -0
- data/spec/cucumber/core/ast/doc_string_spec.rb +77 -0
- data/spec/cucumber/core/ast/examples_table_spec.rb +87 -0
- data/spec/cucumber/core/ast/location_spec.rb +105 -0
- data/spec/cucumber/core/ast/outline_step_spec.rb +77 -0
- data/spec/cucumber/core/ast/step_spec.rb +44 -0
- data/spec/cucumber/core/compiler_spec.rb +249 -0
- data/spec/cucumber/core/gherkin/parser_spec.rb +182 -0
- data/spec/cucumber/core/gherkin/writer_spec.rb +332 -0
- data/spec/cucumber/core/test/case_spec.rb +416 -0
- data/spec/cucumber/core/test/hook_compiler_spec.rb +78 -0
- data/spec/cucumber/core/test/mapper_spec.rb +68 -0
- data/spec/cucumber/core/test/mapping_spec.rb +103 -0
- data/spec/cucumber/core/test/result_spec.rb +178 -0
- data/spec/cucumber/core/test/runner_spec.rb +265 -0
- data/spec/cucumber/core/test/step_spec.rb +58 -0
- data/spec/cucumber/core/test/timer_spec.rb +13 -0
- data/spec/cucumber/core_spec.rb +419 -0
- data/spec/cucumber/initializer_spec.rb +49 -0
- metadata +221 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'cucumber/core/ast/location'
|
2
|
+
require 'cucumber/core/ast/describes_itself'
|
3
|
+
require 'cucumber/core/ast/step'
|
4
|
+
|
5
|
+
module Cucumber
|
6
|
+
module Core
|
7
|
+
module Ast
|
8
|
+
|
9
|
+
class OutlineStep
|
10
|
+
include HasLocation
|
11
|
+
include DescribesItself
|
12
|
+
|
13
|
+
attr_reader :language, :location, :keyword, :name, :multiline_arg
|
14
|
+
|
15
|
+
def initialize(language, location, keyword, name, multiline_arg=nil)
|
16
|
+
@language, @location, @keyword, @name, @multiline_arg = language, location, keyword, name, multiline_arg
|
17
|
+
@language || raise("Language is required!")
|
18
|
+
end
|
19
|
+
|
20
|
+
def gherkin_statement(statement=nil)
|
21
|
+
@gherkin_statement ||= statement
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_step(row)
|
25
|
+
Ast::Step.new(language, location, keyword, row.expand(name), replace_multiline_arg(row))
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def description_for_visitors
|
31
|
+
:outline_step
|
32
|
+
end
|
33
|
+
|
34
|
+
def children
|
35
|
+
# TODO use a null object
|
36
|
+
# TODO remove duplication with Step
|
37
|
+
# TODO spec
|
38
|
+
return [] unless @multiline_arg
|
39
|
+
[@multiline_arg]
|
40
|
+
end
|
41
|
+
|
42
|
+
def replace_multiline_arg(example_row)
|
43
|
+
return unless multiline_arg
|
44
|
+
multiline_arg.map { |cell| example_row.expand(cell) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'cucumber/initializer'
|
2
|
+
require 'cucumber/core/ast/describes_itself'
|
3
|
+
require 'cucumber/core/ast/names'
|
4
|
+
require 'cucumber/core/ast/empty_background'
|
5
|
+
require 'cucumber/core/ast/location'
|
6
|
+
|
7
|
+
module Cucumber
|
8
|
+
module Core
|
9
|
+
module Ast
|
10
|
+
class Scenario #:nodoc:
|
11
|
+
include Names
|
12
|
+
include HasLocation
|
13
|
+
include DescribesItself
|
14
|
+
|
15
|
+
attr_reader :feature_tags
|
16
|
+
attr_accessor :feature
|
17
|
+
attr_reader :comments, :tags, :keyword, :background, :title, :location, :gherkin_statement
|
18
|
+
|
19
|
+
include Cucumber.initializer(:gherkin_statement, :language, :location, :background, :comments, :tags, :feature_tags, :keyword, :title, :description, :raw_steps)
|
20
|
+
|
21
|
+
def children
|
22
|
+
raw_steps
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_sexp
|
26
|
+
sexp = [:scenario, line, keyword, name]
|
27
|
+
comment = comment.to_sexp
|
28
|
+
sexp += [comment] if comment
|
29
|
+
tags = tags.to_sexp
|
30
|
+
sexp += tags if tags.any?
|
31
|
+
sexp += step_invocations.to_sexp if step_invocations.any?
|
32
|
+
sexp
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def description_for_visitors
|
38
|
+
:scenario
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'cucumber/core/ast/names'
|
2
|
+
require 'cucumber/core/ast/location'
|
3
|
+
require 'cucumber/core/ast/empty_background'
|
4
|
+
require 'cucumber/core/ast/describes_itself'
|
5
|
+
|
6
|
+
module Cucumber
|
7
|
+
module Core
|
8
|
+
module Ast
|
9
|
+
class ScenarioOutline
|
10
|
+
include Names
|
11
|
+
include HasLocation
|
12
|
+
include DescribesItself
|
13
|
+
|
14
|
+
MissingExamples = Class.new(StandardError)
|
15
|
+
|
16
|
+
attr_accessor :feature
|
17
|
+
attr_reader :feature_tags
|
18
|
+
|
19
|
+
attr_reader :line
|
20
|
+
private :line
|
21
|
+
|
22
|
+
include Cucumber.initializer(:language, :location, :background, :comments, :tags, :feature_tags, :keyword, :title, :description, :steps, :examples_tables)
|
23
|
+
|
24
|
+
attr_reader :comments, :tags, :keyword, :background, :location
|
25
|
+
|
26
|
+
def gherkin_statement(node)
|
27
|
+
@gherkin_statement = node
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def children
|
33
|
+
@steps + @examples_tables
|
34
|
+
end
|
35
|
+
|
36
|
+
def description_for_visitors
|
37
|
+
:scenario_outline
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'cucumber/core/ast/describes_itself'
|
2
|
+
require 'cucumber/core/ast/location'
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
module Core
|
6
|
+
module Ast
|
7
|
+
class Step #:nodoc:
|
8
|
+
include HasLocation
|
9
|
+
include DescribesItself
|
10
|
+
|
11
|
+
attr_reader :keyword, :name, :language, :exception, :multiline_arg
|
12
|
+
|
13
|
+
def initialize(language, location, keyword, name, multiline_arg=nil)
|
14
|
+
@location, @keyword, @name, @multiline_arg = location, keyword, name, multiline_arg
|
15
|
+
end
|
16
|
+
|
17
|
+
def gherkin_statement(statement=nil)
|
18
|
+
@gherkin_statement ||= statement
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_sexp
|
22
|
+
[:step, line, keyword, name, (@multiline_arg.nil? ? nil : @multiline_arg.to_sexp)].compact
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def children
|
28
|
+
return [] unless @multiline_arg # TODO: use a null object
|
29
|
+
[@multiline_arg]
|
30
|
+
end
|
31
|
+
|
32
|
+
def description_for_visitors
|
33
|
+
:step
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'cucumber/initializer'
|
2
|
+
require 'cucumber/core/test/case'
|
3
|
+
require 'cucumber/core/test/step'
|
4
|
+
|
5
|
+
module Cucumber
|
6
|
+
module Core
|
7
|
+
class Compiler
|
8
|
+
include Cucumber.initializer(:receiver)
|
9
|
+
|
10
|
+
def feature(feature)
|
11
|
+
compiler = FeatureCompiler.new(TestCaseBuilder.new(receiver))
|
12
|
+
feature.describe_to(compiler)
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def done
|
17
|
+
receiver.done
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
class TestCaseBuilder
|
22
|
+
include Cucumber.initializer(:receiver)
|
23
|
+
|
24
|
+
def on_background_step(source)
|
25
|
+
background_test_steps << Test::Step.new(source)
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def on_step(source)
|
30
|
+
test_steps << Test::Step.new(source)
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def on_test_case(source)
|
35
|
+
Test::Case.new(test_steps, source).describe_to(receiver)
|
36
|
+
@test_steps = nil
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def background_test_steps
|
43
|
+
@background_test_steps ||= []
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_steps
|
47
|
+
@test_steps ||= background_test_steps.dup
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class FeatureCompiler
|
52
|
+
include Cucumber.initializer(:receiver)
|
53
|
+
|
54
|
+
def feature(feature, &descend)
|
55
|
+
@feature = feature
|
56
|
+
descend.call(self)
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def background(background, &descend)
|
61
|
+
source = [@feature, background]
|
62
|
+
compiler = BackgroundCompiler.new(source, receiver)
|
63
|
+
descend.call(compiler)
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
def scenario(scenario, &descend)
|
68
|
+
source = [@feature, scenario]
|
69
|
+
scenario_compiler = ScenarioCompiler.new(source, receiver)
|
70
|
+
descend.call(scenario_compiler)
|
71
|
+
receiver.on_test_case(source)
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
def scenario_outline(scenario_outline, &descend)
|
76
|
+
source = [@feature, scenario_outline]
|
77
|
+
compiler = ScenarioOutlineCompiler.new(source, receiver)
|
78
|
+
descend.call(compiler)
|
79
|
+
self
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class ScenarioOutlineCompiler
|
84
|
+
include Cucumber.initializer(:source, :receiver)
|
85
|
+
|
86
|
+
def outline_step(outline_step)
|
87
|
+
outline_steps << outline_step
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
def examples_table(examples_table, &descend)
|
92
|
+
@examples_table = examples_table
|
93
|
+
descend.call(self)
|
94
|
+
self
|
95
|
+
end
|
96
|
+
|
97
|
+
def examples_table_row(row)
|
98
|
+
steps(row).each do |step|
|
99
|
+
receiver.on_step(source + [@examples_table, row, step])
|
100
|
+
end
|
101
|
+
receiver.on_test_case(source + [@examples_table, row])
|
102
|
+
self
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def steps(row)
|
108
|
+
outline_steps.map { |s| s.to_step(row) }
|
109
|
+
end
|
110
|
+
|
111
|
+
def outline_steps
|
112
|
+
@outline_steps ||= []
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class ScenarioCompiler
|
117
|
+
include Cucumber.initializer(:source, :receiver)
|
118
|
+
|
119
|
+
def step(step)
|
120
|
+
receiver.on_step(source + [step])
|
121
|
+
self
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class BackgroundCompiler
|
126
|
+
include Cucumber.initializer(:source, :receiver)
|
127
|
+
|
128
|
+
def step(step)
|
129
|
+
receiver.on_background_step(source + [step])
|
130
|
+
self
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,315 @@
|
|
1
|
+
require 'cucumber/initializer'
|
2
|
+
require 'cucumber/core/ast'
|
3
|
+
require 'cucumber/core/platform'
|
4
|
+
|
5
|
+
module Cucumber
|
6
|
+
module Core
|
7
|
+
module Gherkin
|
8
|
+
# Builds an AST of a feature by listening to events from the
|
9
|
+
# Gherkin parser.
|
10
|
+
class AstBuilder
|
11
|
+
|
12
|
+
def initialize(path)
|
13
|
+
@path = path
|
14
|
+
end
|
15
|
+
|
16
|
+
def result
|
17
|
+
return nil unless @feature_builder
|
18
|
+
@feature_builder.result(language)
|
19
|
+
end
|
20
|
+
|
21
|
+
def language=(language)
|
22
|
+
@language = language
|
23
|
+
end
|
24
|
+
|
25
|
+
def uri(uri)
|
26
|
+
@path = uri
|
27
|
+
end
|
28
|
+
|
29
|
+
def feature(node)
|
30
|
+
@feature_builder = FeatureBuilder.new(file, node)
|
31
|
+
end
|
32
|
+
|
33
|
+
def background(node)
|
34
|
+
builder = BackgroundBuilder.new(file, node)
|
35
|
+
@feature_builder.background_builder = builder
|
36
|
+
@current = builder
|
37
|
+
end
|
38
|
+
|
39
|
+
def scenario(node)
|
40
|
+
builder = ScenarioBuilder.new(file, node)
|
41
|
+
@feature_builder.add_child builder
|
42
|
+
@current = builder
|
43
|
+
end
|
44
|
+
|
45
|
+
def scenario_outline(node)
|
46
|
+
builder = ScenarioOutlineBuilder.new(file, node)
|
47
|
+
@feature_builder.add_child builder
|
48
|
+
@current = builder
|
49
|
+
end
|
50
|
+
|
51
|
+
def examples(node)
|
52
|
+
@current.add_examples file, node
|
53
|
+
end
|
54
|
+
|
55
|
+
def step(node)
|
56
|
+
@current.add_step file, node
|
57
|
+
end
|
58
|
+
|
59
|
+
def eof
|
60
|
+
end
|
61
|
+
|
62
|
+
def syntax_error(state, event, legal_events, line)
|
63
|
+
# raise "SYNTAX ERROR"
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def language
|
69
|
+
@language || raise("Language has not been set")
|
70
|
+
end
|
71
|
+
|
72
|
+
def file
|
73
|
+
if Cucumber::WINDOWS && !ENV['CUCUMBER_FORWARD_SLASH_PATHS']
|
74
|
+
@path.gsub(/\//, '\\')
|
75
|
+
else
|
76
|
+
@path
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class Builder
|
81
|
+
include Cucumber.initializer(:file, :node)
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def tags
|
86
|
+
node.tags.map do |tag|
|
87
|
+
Ast::Tag.new(
|
88
|
+
Ast::Location.new(file, tag.line),
|
89
|
+
tag.name)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def location
|
94
|
+
Ast::Location.new(file, node.line)
|
95
|
+
end
|
96
|
+
|
97
|
+
def comments
|
98
|
+
node.comments.map do |comment|
|
99
|
+
Ast::Comment.new(
|
100
|
+
Ast::Location.new(file, comment.line),
|
101
|
+
comment.value
|
102
|
+
)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class FeatureBuilder < Builder
|
108
|
+
attr_accessor :background_builder
|
109
|
+
private :background_builder
|
110
|
+
|
111
|
+
def initialize(*)
|
112
|
+
super
|
113
|
+
@background_builder = nil
|
114
|
+
end
|
115
|
+
|
116
|
+
def result(language)
|
117
|
+
background = background(language)
|
118
|
+
feature = Ast::Feature.new(
|
119
|
+
location,
|
120
|
+
background,
|
121
|
+
comments,
|
122
|
+
tags,
|
123
|
+
node.keyword,
|
124
|
+
node.name.lstrip,
|
125
|
+
node.description.rstrip,
|
126
|
+
children.map { |builder| builder.result(background, language, tags) }
|
127
|
+
)
|
128
|
+
feature.gherkin_statement(node)
|
129
|
+
feature.language = language
|
130
|
+
feature
|
131
|
+
end
|
132
|
+
|
133
|
+
def add_child(child)
|
134
|
+
children << child
|
135
|
+
end
|
136
|
+
|
137
|
+
def children
|
138
|
+
@children ||= []
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def background(language)
|
144
|
+
return Ast::EmptyBackground.new unless background_builder
|
145
|
+
@background ||= background_builder.result(language)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class BackgroundBuilder < Builder
|
150
|
+
def result(language)
|
151
|
+
Ast::Background.new(
|
152
|
+
node,
|
153
|
+
language,
|
154
|
+
location,
|
155
|
+
comments,
|
156
|
+
node.keyword,
|
157
|
+
node.name,
|
158
|
+
node.description,
|
159
|
+
steps(language)
|
160
|
+
)
|
161
|
+
end
|
162
|
+
|
163
|
+
def add_step(file, node)
|
164
|
+
step_builders << ScenarioBuilder::StepBuilder.new(file, node)
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
def steps(language)
|
170
|
+
step_builders.map { |step_builder| step_builder.result(language) }
|
171
|
+
end
|
172
|
+
|
173
|
+
def step_builders
|
174
|
+
@step_builders ||= []
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
class ScenarioBuilder < Builder
|
180
|
+
def result(background, language, feature_tags)
|
181
|
+
Ast::Scenario.new(
|
182
|
+
node,
|
183
|
+
language,
|
184
|
+
location,
|
185
|
+
background,
|
186
|
+
comments,
|
187
|
+
tags,
|
188
|
+
feature_tags,
|
189
|
+
node.keyword,
|
190
|
+
node.name,
|
191
|
+
node.description,
|
192
|
+
steps(language)
|
193
|
+
)
|
194
|
+
end
|
195
|
+
|
196
|
+
def add_step(file, node)
|
197
|
+
step_builders << StepBuilder.new(file, node)
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
|
202
|
+
def steps(language)
|
203
|
+
step_builders.map { |step_builder| step_builder.result(language) }
|
204
|
+
end
|
205
|
+
|
206
|
+
def step_builders
|
207
|
+
@step_builders ||= []
|
208
|
+
end
|
209
|
+
|
210
|
+
class StepBuilder < Builder
|
211
|
+
def result(language)
|
212
|
+
step = Ast::Step.new(
|
213
|
+
language,
|
214
|
+
location,
|
215
|
+
node.keyword,
|
216
|
+
node.name,
|
217
|
+
Ast::MultilineArgument.from(node.doc_string || node.rows, location)
|
218
|
+
)
|
219
|
+
step.gherkin_statement(node)
|
220
|
+
step
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
class ScenarioOutlineBuilder < Builder
|
226
|
+
def result(background, language, feature_tags)
|
227
|
+
scenario_outline = Ast::ScenarioOutline.new(
|
228
|
+
language,
|
229
|
+
location,
|
230
|
+
background,
|
231
|
+
comments,
|
232
|
+
tags,
|
233
|
+
feature_tags,
|
234
|
+
node.keyword,
|
235
|
+
node.name,
|
236
|
+
node.description,
|
237
|
+
steps(language),
|
238
|
+
examples_tables
|
239
|
+
)
|
240
|
+
scenario_outline.gherkin_statement(node)
|
241
|
+
scenario_outline
|
242
|
+
end
|
243
|
+
|
244
|
+
def add_examples(file, node)
|
245
|
+
examples_tables << ExamplesTableBuilder.new(file, node).result
|
246
|
+
end
|
247
|
+
|
248
|
+
def add_step(file, node)
|
249
|
+
step_builders << StepBuilder.new(file, node)
|
250
|
+
end
|
251
|
+
|
252
|
+
private
|
253
|
+
|
254
|
+
def steps(language)
|
255
|
+
step_builders.map { |step_builder| step_builder.result(language) }
|
256
|
+
end
|
257
|
+
|
258
|
+
def step_builders
|
259
|
+
@step_builders ||= []
|
260
|
+
end
|
261
|
+
|
262
|
+
def examples_tables
|
263
|
+
@examples_tables ||= []
|
264
|
+
end
|
265
|
+
|
266
|
+
class ExamplesTableBuilder < Builder
|
267
|
+
|
268
|
+
def result
|
269
|
+
Ast::ExamplesTable.new(
|
270
|
+
location,
|
271
|
+
comments,
|
272
|
+
tags,
|
273
|
+
node.keyword,
|
274
|
+
node.name,
|
275
|
+
node.description,
|
276
|
+
header,
|
277
|
+
example_rows
|
278
|
+
)
|
279
|
+
end
|
280
|
+
|
281
|
+
private
|
282
|
+
|
283
|
+
def header
|
284
|
+
row = node.rows[0]
|
285
|
+
Ast::ExamplesTable::Header.new(row.cells, location)
|
286
|
+
end
|
287
|
+
|
288
|
+
def example_rows
|
289
|
+
_, *raw_examples = *node.rows
|
290
|
+
raw_examples.each_with_index.map do |row, index|
|
291
|
+
header.build_row(row.cells, index + 1, location.on_line(row.line))
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
end
|
296
|
+
|
297
|
+
class StepBuilder < Builder
|
298
|
+
def result(language)
|
299
|
+
step = Ast::OutlineStep.new(
|
300
|
+
language,
|
301
|
+
location,
|
302
|
+
node.keyword,
|
303
|
+
node.name,
|
304
|
+
Ast::MultilineArgument.from(node.doc_string || node.rows, location)
|
305
|
+
)
|
306
|
+
step.gherkin_statement(node)
|
307
|
+
step
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|