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.
@@ -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
- if Cucumber::WINDOWS && !ENV['CUCUMBER_FORWARD_SLASH_PATHS']
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
- feature = Ast::Feature.new(
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
- step = Ast::Step.new(
208
+ Ast::Step.new(
209
+ node,
213
210
  language,
214
211
  location,
215
212
  node.keyword,
216
213
  node.name,
217
- Ast::MultilineArgument.from(node.doc_string || node.rows, location)
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
- scenario_outline = Ast::ScenarioOutline.new(
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
- examples_table = Ast::ExamplesTable.new(
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
- step = Ast::OutlineStep.new(
296
+ Ast::OutlineStep.new(
297
+ node,
303
298
  language,
304
299
  location,
305
300
  node.keyword,
306
301
  node.name,
307
- Ast::MultilineArgument.from(node.doc_string || node.rows, location)
302
+ MultilineArgument.from(node.doc_string || node.rows, location)
308
303
  )
309
- step.gherkin_statement(node)
310
- step
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 UnskippableMapping < Mapping
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 UndefinedMapping
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::UnskippableMapping)
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::UnskippableMapping)
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::Mapping)
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/mapping'
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::UndefinedMapping.new)
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::Mapping.new(&block))
38
+ self.class.new(source, Test::Action.new(&block))
39
39
  end
40
40
 
41
41
  def name
@@ -2,7 +2,7 @@ module Cucumber
2
2
  module Core
3
3
  class Version
4
4
  def self.to_s
5
- "1.0.0.beta.2"
5
+ "1.0.0.beta.3"
6
6
  end
7
7
  end
8
8
  end
@@ -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 be convertible in to an array where each row is a hash" do
90
- expect( @table.transpose.hashes[0] ).to eq({'one' => '1111', 'two' => '22222'})
91
- end
92
- end
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 { faulty_table.rows_hash }.to raise_error('The table must have exactly 2 columns')
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