cucumber-core 1.0.0.beta.2 → 1.0.0.beta.3
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 +4 -4
- data/lib/cucumber/core.rb +0 -1
- data/lib/cucumber/core/ast.rb +0 -1
- data/lib/cucumber/core/ast/data_table.rb +8 -223
- data/lib/cucumber/core/ast/examples_table.rb +2 -6
- data/lib/cucumber/core/ast/feature.rb +3 -8
- data/lib/cucumber/core/ast/location.rb +12 -8
- data/lib/cucumber/core/ast/outline_step.rb +4 -11
- data/lib/cucumber/core/ast/scenario_outline.rb +2 -6
- data/lib/cucumber/core/ast/step.rb +28 -7
- data/lib/cucumber/core/gherkin/ast_builder.rb +36 -23
- data/lib/cucumber/core/test/{mapping.rb → action.rb} +10 -11
- data/lib/cucumber/core/test/mapper.rb +3 -3
- data/lib/cucumber/core/test/runner.rb +2 -2
- data/lib/cucumber/core/test/step.rb +7 -7
- data/lib/cucumber/core/version.rb +1 -1
- data/spec/cucumber/core/ast/data_table_spec.rb +5 -92
- data/spec/cucumber/core/ast/location_spec.rb +8 -0
- data/spec/cucumber/core/ast/outline_step_spec.rb +4 -9
- data/spec/cucumber/core/ast/step_spec.rb +70 -3
- data/spec/cucumber/core/test/{mapping_spec.rb → action_spec.rb} +36 -27
- data/spec/cucumber/core/test/mapper_spec.rb +13 -12
- data/spec/cucumber/core/test/runner_spec.rb +14 -0
- data/spec/cucumber/core/test/step_spec.rb +4 -3
- data/spec/cucumber/core_spec.rb +4 -4
- metadata +6 -8
- data/lib/cucumber/core/ast/multiline_argument.rb +0 -34
- data/lib/cucumber/core/test/filters/debug_filter.rb +0 -28
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'cucumber/initializer'
|
2
2
|
require 'cucumber/core/ast'
|
3
3
|
require 'cucumber/core/platform'
|
4
|
+
require 'gherkin/rubify'
|
4
5
|
|
5
6
|
module Cucumber
|
6
7
|
module Core
|
@@ -70,11 +71,7 @@ module Cucumber
|
|
70
71
|
end
|
71
72
|
|
72
73
|
def file
|
73
|
-
|
74
|
-
@path.gsub(/\//, '\\')
|
75
|
-
else
|
76
|
-
@path
|
77
|
-
end
|
74
|
+
@path
|
78
75
|
end
|
79
76
|
|
80
77
|
class Builder
|
@@ -115,7 +112,9 @@ module Cucumber
|
|
115
112
|
|
116
113
|
def result(language)
|
117
114
|
background = background(language)
|
118
|
-
|
115
|
+
Ast::Feature.new(
|
116
|
+
node,
|
117
|
+
language,
|
119
118
|
location,
|
120
119
|
background,
|
121
120
|
comments,
|
@@ -125,9 +124,6 @@ module Cucumber
|
|
125
124
|
node.description.rstrip,
|
126
125
|
children.map { |builder| builder.result(background, language, tags) }
|
127
126
|
)
|
128
|
-
feature.gherkin_statement(node)
|
129
|
-
feature.language = language
|
130
|
-
feature
|
131
127
|
end
|
132
128
|
|
133
129
|
def add_child(child)
|
@@ -209,15 +205,15 @@ module Cucumber
|
|
209
205
|
|
210
206
|
class StepBuilder < Builder
|
211
207
|
def result(language)
|
212
|
-
|
208
|
+
Ast::Step.new(
|
209
|
+
node,
|
213
210
|
language,
|
214
211
|
location,
|
215
212
|
node.keyword,
|
216
213
|
node.name,
|
217
|
-
|
214
|
+
|
215
|
+
MultilineArgument.from(node.doc_string || node.rows, location)
|
218
216
|
)
|
219
|
-
step.gherkin_statement(node)
|
220
|
-
step
|
221
217
|
end
|
222
218
|
end
|
223
219
|
end
|
@@ -225,7 +221,8 @@ module Cucumber
|
|
225
221
|
class ScenarioOutlineBuilder < Builder
|
226
222
|
def result(background, language, feature_tags)
|
227
223
|
raise ParseError.new("Missing Examples section for Scenario Outline at #{location}") if examples_tables.empty?
|
228
|
-
|
224
|
+
Ast::ScenarioOutline.new(
|
225
|
+
node,
|
229
226
|
language,
|
230
227
|
location,
|
231
228
|
background,
|
@@ -238,8 +235,6 @@ module Cucumber
|
|
238
235
|
steps(language),
|
239
236
|
examples_tables
|
240
237
|
)
|
241
|
-
scenario_outline.gherkin_statement(node)
|
242
|
-
scenario_outline
|
243
238
|
end
|
244
239
|
|
245
240
|
def add_examples(file, node)
|
@@ -267,7 +262,8 @@ module Cucumber
|
|
267
262
|
class ExamplesTableBuilder < Builder
|
268
263
|
|
269
264
|
def result
|
270
|
-
|
265
|
+
Ast::ExamplesTable.new(
|
266
|
+
node,
|
271
267
|
location,
|
272
268
|
comments,
|
273
269
|
tags,
|
@@ -277,8 +273,6 @@ module Cucumber
|
|
277
273
|
header,
|
278
274
|
example_rows
|
279
275
|
)
|
280
|
-
examples_table.gherkin_statement(node)
|
281
|
-
examples_table
|
282
276
|
end
|
283
277
|
|
284
278
|
private
|
@@ -299,15 +293,34 @@ module Cucumber
|
|
299
293
|
|
300
294
|
class StepBuilder < Builder
|
301
295
|
def result(language)
|
302
|
-
|
296
|
+
Ast::OutlineStep.new(
|
297
|
+
node,
|
303
298
|
language,
|
304
299
|
location,
|
305
300
|
node.keyword,
|
306
301
|
node.name,
|
307
|
-
|
302
|
+
MultilineArgument.from(node.doc_string || node.rows, location)
|
308
303
|
)
|
309
|
-
|
310
|
-
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
module MultilineArgument
|
309
|
+
class << self
|
310
|
+
include ::Gherkin::Rubify
|
311
|
+
|
312
|
+
def from(argument, parent_location)
|
313
|
+
return Ast::EmptyMultilineArgument.new unless argument
|
314
|
+
argument = rubify(argument)
|
315
|
+
case argument
|
316
|
+
when ::Gherkin::Formatter::Model::DocString
|
317
|
+
Ast::DocString.new(argument.value, argument.content_type, parent_location.on_line(argument.line_range))
|
318
|
+
when Array
|
319
|
+
location = parent_location.on_line(argument.first.line..argument.last.line)
|
320
|
+
Ast::DataTable.new(argument.map{|row| row.cells}, location)
|
321
|
+
else
|
322
|
+
raise ArgumentError, "Don't know how to convert #{argument.inspect} into a MultilineArgument"
|
323
|
+
end
|
311
324
|
end
|
312
325
|
end
|
313
326
|
end
|
@@ -6,21 +6,20 @@ require 'cucumber/core/ast/location'
|
|
6
6
|
module Cucumber
|
7
7
|
module Core
|
8
8
|
module Test
|
9
|
-
|
10
|
-
class Mapping
|
9
|
+
class Action
|
11
10
|
def initialize(&block)
|
12
11
|
raise ArgumentError, "Passing a block to execute the mapping is mandatory." unless block
|
13
12
|
@block = block
|
14
13
|
@timer = Timer.new
|
15
14
|
end
|
16
15
|
|
17
|
-
def skip
|
16
|
+
def skip(last_result)
|
18
17
|
skipped
|
19
18
|
end
|
20
19
|
|
21
|
-
def execute
|
20
|
+
def execute(last_result)
|
22
21
|
@timer.start
|
23
|
-
@block.call
|
22
|
+
@block.call(last_result)
|
24
23
|
passed
|
25
24
|
rescue Result::Raisable => exception
|
26
25
|
exception.with_duration(@timer.duration)
|
@@ -51,18 +50,18 @@ module Cucumber
|
|
51
50
|
end
|
52
51
|
end
|
53
52
|
|
54
|
-
class
|
55
|
-
def skip
|
56
|
-
execute
|
53
|
+
class UnskippableAction < Action
|
54
|
+
def skip(last_result)
|
55
|
+
execute(last_result)
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
60
|
-
class
|
61
|
-
def execute
|
59
|
+
class UndefinedAction
|
60
|
+
def execute(last_result)
|
62
61
|
undefined
|
63
62
|
end
|
64
63
|
|
65
|
-
def skip
|
64
|
+
def skip(last_result)
|
66
65
|
undefined
|
67
66
|
end
|
68
67
|
|
@@ -110,15 +110,15 @@ module Cucumber
|
|
110
110
|
include Cucumber.initializer(:source)
|
111
111
|
|
112
112
|
def after(block)
|
113
|
-
build_hook_step(block, Hooks::AfterHook, Test::
|
113
|
+
build_hook_step(block, Hooks::AfterHook, Test::UnskippableAction)
|
114
114
|
end
|
115
115
|
|
116
116
|
def before(block)
|
117
|
-
build_hook_step(block, Hooks::BeforeHook, Test::
|
117
|
+
build_hook_step(block, Hooks::BeforeHook, Test::UnskippableAction)
|
118
118
|
end
|
119
119
|
|
120
120
|
def after_step(block)
|
121
|
-
build_hook_step(block, Hooks::AfterStepHook, Test::
|
121
|
+
build_hook_step(block, Hooks::AfterStepHook, Test::Action)
|
122
122
|
end
|
123
123
|
|
124
124
|
private
|
@@ -60,7 +60,7 @@ module Cucumber
|
|
60
60
|
include Cucumber.initializer(:step_result)
|
61
61
|
|
62
62
|
def execute(test_step, monitor)
|
63
|
-
result = test_step.execute
|
63
|
+
result = test_step.execute(monitor.result)
|
64
64
|
result.describe_to(monitor, result)
|
65
65
|
end
|
66
66
|
|
@@ -83,7 +83,7 @@ module Cucumber
|
|
83
83
|
|
84
84
|
class Failing < Base
|
85
85
|
def execute(test_step, monitor)
|
86
|
-
test_step.skip
|
86
|
+
test_step.skip(monitor.result)
|
87
87
|
end
|
88
88
|
|
89
89
|
def result(duration)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'cucumber/initializer'
|
2
2
|
require 'cucumber/core/test/result'
|
3
|
-
require 'cucumber/core/test/
|
3
|
+
require 'cucumber/core/test/action'
|
4
4
|
|
5
5
|
module Cucumber
|
6
6
|
module Core
|
@@ -9,7 +9,7 @@ module Cucumber
|
|
9
9
|
include Cucumber.initializer(:source)
|
10
10
|
attr_reader :source
|
11
11
|
|
12
|
-
def initialize(source, mapping = Test::
|
12
|
+
def initialize(source, mapping = Test::UndefinedAction.new)
|
13
13
|
raise ArgumentError if source.any?(&:nil?)
|
14
14
|
@mapping = mapping
|
15
15
|
super(source)
|
@@ -26,16 +26,16 @@ module Cucumber
|
|
26
26
|
self
|
27
27
|
end
|
28
28
|
|
29
|
-
def skip
|
30
|
-
@mapping.skip
|
29
|
+
def skip(last_result)
|
30
|
+
@mapping.skip(last_result)
|
31
31
|
end
|
32
32
|
|
33
|
-
def execute
|
34
|
-
@mapping.execute
|
33
|
+
def execute(last_result)
|
34
|
+
@mapping.execute(last_result)
|
35
35
|
end
|
36
36
|
|
37
37
|
def with_mapping(&block)
|
38
|
-
self.class.new(source, Test::
|
38
|
+
self.class.new(source, Test::Action.new(&block))
|
39
39
|
end
|
40
40
|
|
41
41
|
def name
|
@@ -12,43 +12,6 @@ module Cucumber
|
|
12
12
|
%w{one four seven},
|
13
13
|
%w{4444 55555 666666}
|
14
14
|
], location)
|
15
|
-
def @table.cells_rows; super; end
|
16
|
-
def @table.columns; super; end
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should have rows" do
|
20
|
-
expect( @table.cells_rows[0].map{|cell| cell.value} ).to eq %w{one four seven}
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should have columns" do
|
24
|
-
expect( @table.columns[1].map{|cell| cell.value} ).to eq %w{four 55555}
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should have headers" do
|
28
|
-
expect( @table.headers ).to eq %w{one four seven}
|
29
|
-
end
|
30
|
-
|
31
|
-
it "should have same cell objects in rows and columns" do
|
32
|
-
# 666666
|
33
|
-
expect( @table.cells_rows[1].__send__(:[], 2) ).to eq @table.columns[2].__send__(:[], 1)
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should know about max width of a row" do
|
37
|
-
expect( @table.columns[1].__send__(:width) ).to eq 5
|
38
|
-
end
|
39
|
-
|
40
|
-
it "should be convertible to an array of hashes" do
|
41
|
-
expect( @table.hashes ).to eq [
|
42
|
-
{'one' => '4444', 'four' => '55555', 'seven' => '666666'}
|
43
|
-
]
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should accept symbols as keys for the hashes" do
|
47
|
-
expect( @table.hashes.first[:one] ).to eq '4444'
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should return the row values in order" do
|
51
|
-
expect( @table.rows.first ).to eq %w{4444 55555 666666}
|
52
15
|
end
|
53
16
|
|
54
17
|
describe "equality" do
|
@@ -86,62 +49,12 @@ module Cucumber
|
|
86
49
|
], location)
|
87
50
|
end
|
88
51
|
|
89
|
-
it "should
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
describe "#rows_hash" do
|
95
|
-
|
96
|
-
it "should return a hash of the rows" do
|
97
|
-
table = DataTable.new([
|
98
|
-
%w{one 1111},
|
99
|
-
%w{two 22222}
|
100
|
-
], location)
|
101
|
-
expect( table.rows_hash ).to eq({'one' => '1111', 'two' => '22222'})
|
102
|
-
end
|
103
|
-
|
104
|
-
it "should fail if the table doesn't have two columns" do
|
105
|
-
faulty_table = DataTable.new([
|
106
|
-
%w{one 1111 abc},
|
107
|
-
%w{two 22222 def}
|
52
|
+
it "should transpose the table" do
|
53
|
+
transposed = DataTable.new([
|
54
|
+
%w{one two},
|
55
|
+
%w{1111 22222}
|
108
56
|
], location)
|
109
|
-
expect
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
describe "#new" do
|
114
|
-
it "should allow Array of Hash" do
|
115
|
-
t1 = DataTable.new([{'name' => 'aslak', 'male' => 'true'}], location)
|
116
|
-
expect( t1.hashes ).to eq [{'name' => 'aslak', 'male' => 'true'}]
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
it "should convert to sexp" do
|
121
|
-
sexp_value =
|
122
|
-
[:table,
|
123
|
-
[:row, -1,
|
124
|
-
[:cell, "one"],
|
125
|
-
[:cell, "four"],
|
126
|
-
[:cell, "seven"]
|
127
|
-
],
|
128
|
-
[:row, -1,
|
129
|
-
[:cell, "4444"],
|
130
|
-
[:cell, "55555"],
|
131
|
-
[:cell, "666666"]
|
132
|
-
]
|
133
|
-
]
|
134
|
-
expect( @table.to_sexp ).to eq sexp_value
|
135
|
-
end
|
136
|
-
|
137
|
-
describe "#each_cell" do
|
138
|
-
it "runs the given block on each cell in the table" do
|
139
|
-
table = DataTable.new([[1,2],[3,4]], location)
|
140
|
-
values = []
|
141
|
-
table.each_cell do |cell|
|
142
|
-
values << cell.value
|
143
|
-
end
|
144
|
-
expect( values ).to eq [1,2,3,4]
|
57
|
+
expect( @table.transpose ).to eq( transposed )
|
145
58
|
end
|
146
59
|
end
|
147
60
|
|
@@ -24,6 +24,14 @@ module Cucumber::Core::Ast
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
describe "line" do
|
28
|
+
it "is an integer" do
|
29
|
+
expect(Location.new(file, line).line).to be_kind_of(Integer)
|
30
|
+
expect(Location.new(file, 1..2).line).to be_kind_of(Integer)
|
31
|
+
expect(Location.of_caller.line).to be_kind_of(Integer)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
27
35
|
describe "to_s" do
|
28
36
|
it "is file:line for a precise location" do
|
29
37
|
expect( Location.new("foo.feature", 12).to_s ).to eq "foo.feature:12"
|
@@ -8,7 +8,8 @@ module Cucumber
|
|
8
8
|
module Core
|
9
9
|
module Ast
|
10
10
|
describe OutlineStep do
|
11
|
-
let(:outline_step) { OutlineStep.new(language, location, keyword, name, multiline_arg) }
|
11
|
+
let(:outline_step) { OutlineStep.new(node, language, location, keyword, name, multiline_arg) }
|
12
|
+
let(:node) { double }
|
12
13
|
let(:language) { double }
|
13
14
|
let(:location) { double }
|
14
15
|
let(:keyword) { double }
|
@@ -35,16 +36,10 @@ module Cucumber
|
|
35
36
|
expect( outline_step.to_step(row).name ).to eq 'a green cucumber'
|
36
37
|
end
|
37
38
|
|
38
|
-
it "knows the name of the outline step" do
|
39
|
-
row = ExamplesTable::Row.new({'color' => 'green'}, 1, location)
|
40
|
-
outline_step.gherkin_statement(double(:name => name))
|
41
|
-
expect( outline_step.to_step(row).gherkin_statement.name ).to eq name
|
42
|
-
end
|
43
|
-
|
44
39
|
end
|
45
40
|
|
46
41
|
context "when the step has a DataTable" do
|
47
|
-
let(:outline_step) { OutlineStep.new(language, location, keyword, name, table) }
|
42
|
+
let(:outline_step) { OutlineStep.new(node, language, location, keyword, name, table) }
|
48
43
|
let(:name) { "anything" }
|
49
44
|
let(:table) { DataTable.new([['x', 'y'],['a', 'a <arg>']], Location.new('foo.feature', 23)) }
|
50
45
|
|
@@ -62,7 +57,7 @@ module Cucumber
|
|
62
57
|
|
63
58
|
context "when the step has a DocString" do
|
64
59
|
let(:location) { double }
|
65
|
-
let(:outline_step) { OutlineStep.new(language, location, keyword, name, doc_string) }
|
60
|
+
let(:outline_step) { OutlineStep.new(node, language, location, keyword, name, doc_string) }
|
66
61
|
let(:doc_string) { DocString.new('a <arg> that needs replacing', '', location) }
|
67
62
|
let(:name) { 'anything' }
|
68
63
|
|
@@ -5,9 +5,9 @@ module Cucumber
|
|
5
5
|
module Ast
|
6
6
|
describe Step do
|
7
7
|
let(:step) do
|
8
|
-
language, location, keyword, name = *double
|
8
|
+
node, language, location, keyword, name = *double
|
9
9
|
multiline_arg = EmptyMultilineArgument.new
|
10
|
-
Step.new(language, location, keyword, name, multiline_arg)
|
10
|
+
Step.new(node, language, location, keyword, name, multiline_arg)
|
11
11
|
end
|
12
12
|
|
13
13
|
describe "describing itself" do
|
@@ -26,7 +26,7 @@ module Cucumber
|
|
26
26
|
end
|
27
27
|
|
28
28
|
context "with a multiline argument" do
|
29
|
-
let(:step) { Step.new(double, double, double, double, multiline_arg) }
|
29
|
+
let(:step) { Step.new(double, double, double, double, double, multiline_arg) }
|
30
30
|
let(:multiline_arg) { double }
|
31
31
|
|
32
32
|
it "tells its multiline argument to describe itself" do
|
@@ -38,6 +38,73 @@ module Cucumber
|
|
38
38
|
|
39
39
|
end
|
40
40
|
|
41
|
+
describe "backtrace line" do
|
42
|
+
let(:step) { Step.new(double, double, "path/file.feature:10", "Given ", "this step passes", double) }
|
43
|
+
|
44
|
+
it "knows how to form the backtrace line" do
|
45
|
+
expect( step.backtrace_line ).to eq("path/file.feature:10:in `Given this step passes'")
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe ExpandedOutlineStep do
|
53
|
+
let(:outline_step) { double }
|
54
|
+
let(:step) do
|
55
|
+
node, language, location, keyword, name = *double
|
56
|
+
multiline_arg = EmptyMultilineArgument.new
|
57
|
+
ExpandedOutlineStep.new(outline_step, node, language, location, keyword, name, multiline_arg)
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "describing itself" do
|
61
|
+
let(:visitor) { double }
|
62
|
+
|
63
|
+
it "describes itself as a step" do
|
64
|
+
expect( visitor ).to receive(:step).with(step)
|
65
|
+
step.describe_to(visitor)
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with no multiline argument" do
|
69
|
+
it "does not try to describe any children" do
|
70
|
+
allow( visitor ).to receive(:step).with(step).and_yield(visitor)
|
71
|
+
step.describe_to(visitor)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "with a multiline argument" do
|
76
|
+
let(:step) { Step.new(double, double, double, double, double, multiline_arg) }
|
77
|
+
let(:multiline_arg) { double }
|
78
|
+
|
79
|
+
it "tells its multiline argument to describe itself" do
|
80
|
+
allow( visitor ).to receive(:step).with(step).and_yield(visitor)
|
81
|
+
expect( multiline_arg ).to receive(:describe_to).with(visitor)
|
82
|
+
step.describe_to(visitor)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "matching location" do
|
89
|
+
let(:location) { double }
|
90
|
+
|
91
|
+
it "also match the outline steps location" do
|
92
|
+
allow( location).to receive(:any?).and_return(nil)
|
93
|
+
expect( outline_step ).to receive(:match_locations?).with(location)
|
94
|
+
step.match_locations?(location)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "backtrace line" do
|
99
|
+
let(:outline_step) { OutlineStep.new(double, double, "path/file.feature:5", "Given ", "this step <state>", double) }
|
100
|
+
let(:step) { ExpandedOutlineStep.new(outline_step, double, double, "path/file.feature:10", "Given ", "this step passes", double) }
|
101
|
+
|
102
|
+
it "includes the outline step in the backtrace line" do
|
103
|
+
expect( step.backtrace_line ).to eq("path/file.feature:10:in `Given this step passes'\n" +
|
104
|
+
"path/file.feature:5:in `Given this step <state>'")
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
41
108
|
end
|
42
109
|
end
|
43
110
|
end
|