cucumber-core 0.2.0 → 1.0.0.beta.1

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/cucumber-core.gemspec +1 -1
  4. data/lib/cucumber/core.rb +6 -6
  5. data/lib/cucumber/core/ast/data_table.rb +8 -0
  6. data/lib/cucumber/core/ast/describes_itself.rb +1 -1
  7. data/lib/cucumber/core/ast/examples_table.rb +8 -2
  8. data/lib/cucumber/core/ast/feature.rb +2 -3
  9. data/lib/cucumber/core/ast/location.rb +11 -6
  10. data/lib/cucumber/core/ast/names.rb +10 -1
  11. data/lib/cucumber/core/ast/outline_step.rb +6 -3
  12. data/lib/cucumber/core/ast/scenario.rb +0 -1
  13. data/lib/cucumber/core/ast/scenario_outline.rb +2 -3
  14. data/lib/cucumber/core/ast/step.rb +2 -2
  15. data/lib/cucumber/core/gherkin/ast_builder.rb +4 -1
  16. data/lib/cucumber/core/test/case.rb +10 -6
  17. data/lib/cucumber/core/test/filters/debug_filter.rb +28 -0
  18. data/lib/cucumber/core/test/filters/tag_filter.rb +1 -1
  19. data/lib/cucumber/core/test/hooks.rb +76 -0
  20. data/lib/cucumber/core/test/mapper.rb +101 -19
  21. data/lib/cucumber/core/test/mapping.rb +15 -4
  22. data/lib/cucumber/core/test/result.rb +39 -27
  23. data/lib/cucumber/core/test/runner.rb +76 -81
  24. data/lib/cucumber/core/test/step.rb +10 -18
  25. data/lib/cucumber/core/version.rb +1 -1
  26. data/spec/cucumber/core/ast/data_table_spec.rb +12 -0
  27. data/spec/cucumber/core/ast/location_spec.rb +8 -1
  28. data/spec/cucumber/core/ast/outline_step_spec.rb +11 -4
  29. data/spec/cucumber/core/ast/step_spec.rb +2 -2
  30. data/spec/cucumber/core/compiler_spec.rb +6 -6
  31. data/spec/cucumber/core/gherkin/parser_spec.rb +31 -18
  32. data/spec/cucumber/core/test/case_spec.rb +24 -24
  33. data/spec/cucumber/core/test/hooks_spec.rb +30 -0
  34. data/spec/cucumber/core/test/mapper_spec.rb +115 -1
  35. data/spec/cucumber/core/test/mapping_spec.rb +22 -6
  36. data/spec/cucumber/core/test/result_spec.rb +0 -8
  37. data/spec/cucumber/core/test/runner_spec.rb +31 -97
  38. data/spec/cucumber/core/test/step_spec.rb +24 -16
  39. data/spec/cucumber/core_spec.rb +109 -16
  40. data/spec/report_api_spy.rb +24 -0
  41. metadata +32 -28
  42. data/lib/cucumber/core/test/hook_compiler.rb +0 -109
  43. data/spec/cucumber/core/test/hook_compiler_spec.rb +0 -78
@@ -7,6 +7,7 @@ module Cucumber
7
7
  module Test
8
8
  class Step
9
9
  include Cucumber.initializer(:source)
10
+ attr_reader :source
10
11
 
11
12
  def initialize(source, mapping = Test::UndefinedMapping.new)
12
13
  raise ArgumentError if source.any?(&:nil?)
@@ -19,17 +20,10 @@ module Cucumber
19
20
  end
20
21
 
21
22
  def describe_source_to(visitor, *args)
22
- source.each do |node|
23
+ source.reverse.each do |node|
23
24
  node.describe_to(visitor, *args)
24
25
  end
25
- end
26
-
27
- def name
28
- step.name
29
- end
30
-
31
- def multiline_arg
32
- step.multiline_arg
26
+ self
33
27
  end
34
28
 
35
29
  def skip
@@ -40,12 +34,16 @@ module Cucumber
40
34
  @mapping.execute
41
35
  end
42
36
 
43
- def map(&block)
37
+ def with_mapping(&block)
44
38
  self.class.new(source, Test::Mapping.new(&block))
45
39
  end
46
40
 
41
+ def name
42
+ source.last.name
43
+ end
44
+
47
45
  def location
48
- step.location
46
+ source.last.location
49
47
  end
50
48
 
51
49
  def match_locations?(queried_locations)
@@ -54,13 +52,7 @@ module Cucumber
54
52
  end
55
53
 
56
54
  def inspect
57
- "#{self.class}: #{location}"
58
- end
59
-
60
- private
61
-
62
- def step
63
- source.last
55
+ "<#{self.class}: #{location}>"
64
56
  end
65
57
 
66
58
  end
@@ -2,7 +2,7 @@ module Cucumber
2
2
  module Core
3
3
  class Version
4
4
  def self.to_s
5
- "0.2.0"
5
+ "1.0.0.beta.1"
6
6
  end
7
7
  end
8
8
  end
@@ -133,6 +133,18 @@ module Cucumber
133
133
  ]
134
134
  expect( @table.to_sexp ).to eq sexp_value
135
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]
145
+ end
146
+ end
147
+
136
148
  end
137
149
  end
138
150
  end
@@ -15,6 +15,13 @@ module Cucumber::Core::Ast
15
15
  it "is not equal to a wild card of the same file" do
16
16
  expect( Location.new(file, line) ).not_to eq Location.new(file)
17
17
  end
18
+
19
+ context "collections of locations" do
20
+ it "behave as expected with uniq" do
21
+ unique_collection = [Location.new(file, line), Location.new(file, line)].uniq
22
+ expect( unique_collection ).to eq [Location.new(file, line)]
23
+ end
24
+ end
18
25
  end
19
26
 
20
27
  describe "to_s" do
@@ -68,7 +75,7 @@ module Cucumber::Core::Ast
68
75
 
69
76
  context 'a range wildcard' do
70
77
  let(:range) { Location.new("foo.feature", 13..17) }
71
-
78
+
72
79
  it "matches the first line in the same file" do
73
80
  other = Location.new("foo.feature", 13)
74
81
  expect( range ).to be_match(other)
@@ -2,6 +2,7 @@ require 'cucumber/core/ast/outline_step'
2
2
  require 'cucumber/core/ast/examples_table'
3
3
  require 'cucumber/core/ast/data_table'
4
4
  require 'cucumber/core/ast/doc_string'
5
+ require 'cucumber/core/ast/empty_multiline_argument'
5
6
 
6
7
  module Cucumber
7
8
  module Core
@@ -20,7 +21,7 @@ module Cucumber
20
21
  end
21
22
 
22
23
  it 'knows the file and line' do
23
- location.stub(:to_s) { 'file_name:8' }
24
+ allow( location ).to receive(:to_s) { 'file_name:8' }
24
25
  expect( outline_step.file_colon_line ).to eq 'file_name:8'
25
26
  end
26
27
  end
@@ -34,6 +35,12 @@ module Cucumber
34
35
  expect( outline_step.to_step(row).name ).to eq 'a green cucumber'
35
36
  end
36
37
 
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
+
37
44
  end
38
45
 
39
46
  context "when the step has a DataTable" do
@@ -43,8 +50,8 @@ module Cucumber
43
50
 
44
51
  it "replaces the arguments in the DataTable" do
45
52
  visitor = double
46
- visitor.stub(:step).and_yield
47
- expect( visitor ).to receive(:table) do |data_table| # TODO: rename this message to :data_table
53
+ allow( visitor ).to receive(:step).and_yield(visitor)
54
+ expect( visitor ).to receive(:data_table) do |data_table|
48
55
  expect( data_table.raw ).to eq [['x', 'y'], ['a', 'a replacement']]
49
56
  end
50
57
  row = ExamplesTable::Row.new({'arg' => 'replacement'}, 1, location)
@@ -61,7 +68,7 @@ module Cucumber
61
68
 
62
69
  it "replaces the arguments in the DocString" do
63
70
  visitor = double
64
- visitor.stub(:step).and_yield
71
+ allow( visitor ).to receive(:step).and_yield(visitor)
65
72
  expect( visitor ).to receive(:doc_string) do |doc_string|
66
73
  expect( doc_string.content ).to eq "a replacement that needs replacing"
67
74
  end
@@ -20,7 +20,7 @@ module Cucumber
20
20
 
21
21
  context "with no multiline argument" do
22
22
  it "does not try to describe any children" do
23
- visitor.stub(:step).with(step).and_yield
23
+ allow( visitor ).to receive(:step).with(step).and_yield(visitor)
24
24
  step.describe_to(visitor)
25
25
  end
26
26
  end
@@ -30,7 +30,7 @@ module Cucumber
30
30
  let(:multiline_arg) { double }
31
31
 
32
32
  it "tells its multiline argument to describe itself" do
33
- visitor.stub(:step).with(step).and_yield
33
+ allow( visitor ).to receive(:step).with(step).and_yield(visitor)
34
34
  expect( multiline_arg ).to receive(:describe_to).with(visitor)
35
35
  step.describe_to(visitor)
36
36
  end
@@ -24,7 +24,7 @@ module Cucumber::Core
24
24
  end
25
25
  ]
26
26
  compile(gherkin_documents) do |visitor|
27
- expect( visitor ).to receive(:test_case).once.ordered.and_yield
27
+ expect( visitor ).to receive(:test_case).once.ordered.and_yield(visitor)
28
28
  expect( visitor ).to receive(:test_step).once.ordered
29
29
  expect( visitor ).to receive(:done).once.ordered
30
30
  end
@@ -45,7 +45,7 @@ module Cucumber::Core
45
45
  end
46
46
  ]
47
47
  compile(gherkin_documents) do |visitor|
48
- expect( visitor ).to receive(:test_case).once.ordered.and_yield
48
+ expect( visitor ).to receive(:test_case).once.ordered.and_yield(visitor)
49
49
  expect( visitor ).to receive(:test_step).exactly(2).times.ordered
50
50
  expect( visitor ).to receive(:done).once.ordered
51
51
  end
@@ -111,7 +111,7 @@ module Cucumber::Core
111
111
  end
112
112
  ]
113
113
  compile(gherkin_documents) do |visitor|
114
- expect( visitor ).to receive(:test_case).exactly(3).times.and_yield
114
+ expect( visitor ).to receive(:test_case).exactly(3).times.and_yield(visitor)
115
115
  expect( visitor ).to receive(:test_step).exactly(9).times
116
116
  expect( visitor ).to receive(:done).once
117
117
  end
@@ -202,7 +202,7 @@ module Cucumber::Core
202
202
  )
203
203
 
204
204
  it "sets the source correctly on the test steps" do
205
- outline_step.stub(to_step: outline_ast_step)
205
+ allow( outline_step ).to receive(:to_step) { outline_ast_step }
206
206
  expect( receiver ).to receive(:on_step).with(
207
207
  [feature, scenario_outline, examples_table_1, examples_table_1_row_1, outline_ast_step]
208
208
  ).ordered
@@ -238,8 +238,8 @@ module Cucumber::Core
238
238
 
239
239
  def compile(gherkin_documents)
240
240
  visitor = double
241
- visitor.stub(:test_suite).and_yield
242
- visitor.stub(:test_case).and_yield
241
+ allow( visitor ).to receive(:test_suite).and_yield(visitor)
242
+ allow( visitor ).to receive(:test_case).and_yield(visitor)
243
243
  yield visitor
244
244
  super(gherkin_documents, visitor)
245
245
  end
@@ -34,7 +34,7 @@ module Cucumber
34
34
 
35
35
  def feature
36
36
  result = nil
37
- receiver.stub(:feature) { |feature| result = feature }
37
+ allow( receiver ).to receive(:feature) { |feature| result = feature }
38
38
  parse
39
39
  result
40
40
  end
@@ -45,7 +45,7 @@ module Cucumber
45
45
  end
46
46
 
47
47
  it "sets the language from the Gherkin" do
48
- feature.language.iso_code.should == 'ja'
48
+ expect( feature.language.iso_code ).to eq 'ja'
49
49
  end
50
50
  end
51
51
 
@@ -61,9 +61,9 @@ module Cucumber
61
61
  end
62
62
 
63
63
  it "parses doc strings without error" do
64
- visitor.stub(:feature).and_yield
65
- visitor.stub(:scenario).and_yield
66
- visitor.stub(:step).and_yield
64
+ allow( visitor ).to receive(:feature).and_yield(visitor)
65
+ allow( visitor ).to receive(:scenario).and_yield(visitor)
66
+ allow( visitor ).to receive(:step).and_yield(visitor)
67
67
 
68
68
  location = double
69
69
  expected = Ast::DocString.new("content", "", location)
@@ -89,12 +89,12 @@ module Cucumber
89
89
 
90
90
  it "parses the DataTable" do
91
91
  visitor = double
92
- visitor.stub(:feature).and_yield
93
- visitor.stub(:scenario).and_yield
94
- visitor.stub(:step).and_yield
92
+ allow( visitor ).to receive(:feature).and_yield(visitor)
93
+ allow( visitor ).to receive(:scenario).and_yield(visitor)
94
+ allow( visitor ).to receive(:step).and_yield(visitor)
95
95
 
96
96
  expected = Ast::DataTable.new([['name', 'surname'], ['rob', 'westgeest']], Ast::Location.new('foo.feature', 23))
97
- expect( visitor ).to receive(:table).with(expected)
97
+ expect( visitor ).to receive(:data_table).with(expected)
98
98
  feature.describe_to(visitor)
99
99
  end
100
100
  end
@@ -109,7 +109,7 @@ module Cucumber
109
109
 
110
110
  it "parses the comment into the AST" do
111
111
  visitor = double
112
- visitor.stub(:feature).and_yield
112
+ allow( visitor ).to receive(:feature).and_yield(visitor)
113
113
  expect( visitor ).to receive(:scenario) do |scenario|
114
114
  expect( scenario.comments.join ).to eq "# wow"
115
115
  end
@@ -138,7 +138,7 @@ module Cucumber
138
138
  end
139
139
 
140
140
  it "creates a scenario outline node" do
141
- visitor.stub(:feature).and_yield
141
+ allow( visitor ).to receive(:feature).and_yield(visitor)
142
142
  expect( visitor ).to receive(:scenario_outline) do |outline|
143
143
  expect( outline.name ).to eq 'outline name'
144
144
  end
@@ -146,9 +146,9 @@ module Cucumber
146
146
  end
147
147
 
148
148
  it "creates a step node for each step of the scenario outline" do
149
- visitor.stub(:feature).and_yield
150
- visitor.stub(:scenario_outline).and_yield
151
- visitor.stub(:examples_table)
149
+ allow( visitor ).to receive(:feature).and_yield(visitor)
150
+ allow( visitor ).to receive(:scenario_outline).and_yield(visitor)
151
+ allow( visitor ).to receive(:examples_table)
152
152
  expect( visitor ).to receive(:outline_step) do |step|
153
153
  expect( step.name ).to eq 'passing <arg>'
154
154
  end
@@ -156,10 +156,10 @@ module Cucumber
156
156
  end
157
157
 
158
158
  it "creates an examples table node for each examples table" do
159
- visitor.stub(:feature).and_yield
160
- visitor.stub(:scenario_outline).and_yield
161
- visitor.stub(:outline_step)
162
- expect( visitor ).to receive(:examples_table).exactly(2).times.and_yield
159
+ allow( visitor ).to receive(:feature).and_yield(visitor)
160
+ allow( visitor ).to receive(:scenario_outline).and_yield(visitor)
161
+ allow( visitor ).to receive(:outline_step)
162
+ expect( visitor ).to receive(:examples_table).exactly(2).times.and_yield(visitor)
163
163
  expect( visitor ).to receive(:examples_table_row) do |row|
164
164
  expect( row.number ).to eq 1
165
165
  expect( row.values ).to eq ['1']
@@ -176,6 +176,19 @@ module Cucumber
176
176
  end
177
177
 
178
178
  end
179
+
180
+ context "a Scenario Outline with no Examples" do
181
+ source do
182
+ feature do
183
+ scenario_outline do
184
+ step 'passing <arg>'
185
+ end
186
+ end
187
+ end
188
+ it "throws an error" do
189
+ expect { feature.describe_to(double.as_null_object) }.to raise_error(ParseError)
190
+ end
191
+ end
179
192
  end
180
193
  end
181
194
  end
@@ -31,16 +31,16 @@ module Cucumber
31
31
  test_steps.each do |test_step|
32
32
  expect( test_step ).to receive(:describe_to).with(visitor, args)
33
33
  end
34
- visitor.stub(:test_case).and_yield
34
+ allow( visitor ).to receive(:test_case).and_yield(visitor)
35
35
  test_case.describe_to(visitor, args)
36
36
  end
37
37
 
38
38
  it "describes around hooks in order" do
39
39
  visitor = double
40
- visitor.stub(:test_case).and_yield
40
+ allow( visitor ).to receive(:test_case).and_yield(visitor)
41
41
  first_hook, second_hook = double, double
42
- first_hook.should_receive(:describe_to).ordered.and_yield
43
- second_hook.should_receive(:describe_to).ordered.and_yield
42
+ expect( first_hook ).to receive(:describe_to).ordered.and_yield
43
+ expect( second_hook ).to receive(:describe_to).ordered.and_yield
44
44
  around_hooks = [first_hook, second_hook]
45
45
  Test::Case.new([], [], around_hooks).describe_to(visitor, double)
46
46
  end
@@ -192,7 +192,7 @@ module Cucumber
192
192
  end
193
193
  receiver = double.as_null_object
194
194
  expect( receiver ).to receive(:test_case) do |test_case|
195
- expect( test_case.match_tags?('@a') ).to be_true
195
+ expect( test_case.match_tags?('@a') ).to be_truthy
196
196
  end
197
197
  compile [gherkin], receiver
198
198
  end
@@ -209,7 +209,7 @@ module Cucumber
209
209
  end
210
210
  receiver = double.as_null_object
211
211
  expect( receiver ).to receive(:test_case) do |test_case|
212
- expect( test_case.match_name?(/feature/) ).to be_true
212
+ expect( test_case.match_name?(/feature/) ).to be_truthy
213
213
  end
214
214
  compile [gherkin], receiver
215
215
  end
@@ -235,7 +235,7 @@ module Cucumber
235
235
  let(:test_cases) do
236
236
  receiver = double.as_null_object
237
237
  result = []
238
- receiver.stub(:test_case) { |test_case| result << test_case }
238
+ allow( receiver ).to receive(:test_case) { |test_case| result << test_case }
239
239
  compile [source], receiver
240
240
  result
241
241
  end
@@ -278,44 +278,44 @@ module Cucumber
278
278
 
279
279
  it 'matches the precise location of the scenario' do
280
280
  location = Ast::Location.new(file, 8)
281
- expect( test_case.match_locations?([location]) ).to be_true
281
+ expect( test_case.match_locations?([location]) ).to be_truthy
282
282
  end
283
283
 
284
284
  it 'matches the precise location of an empty scenario' do
285
285
  empty_scenario_test_case = test_cases.find { |c| c.name == 'Scenario: empty' }
286
286
  location = Ast::Location.new(file, 26)
287
- expect( empty_scenario_test_case.match_locations?([location]) ).to be_true
287
+ expect( empty_scenario_test_case.match_locations?([location]) ).to be_truthy
288
288
  end
289
289
 
290
290
  it 'matches multiple locations' do
291
291
  good_location = Ast::Location.new(file, 8)
292
292
  bad_location = Ast::Location.new(file, 5)
293
- expect( test_case.match_locations?([good_location, bad_location]) ).to be_true
293
+ expect( test_case.match_locations?([good_location, bad_location]) ).to be_truthy
294
294
  end
295
295
 
296
296
  it 'matches a location on the last step of the scenario' do
297
297
  location = Ast::Location.new(file, 10)
298
- expect( test_case.match_locations?([location]) ).to be_true
298
+ expect( test_case.match_locations?([location]) ).to be_truthy
299
299
  end
300
300
 
301
301
  it "matches a location on the scenario's comment" do
302
302
  location = Ast::Location.new(file, 6)
303
- expect( test_case.match_locations?([location]) ).to be_true
303
+ expect( test_case.match_locations?([location]) ).to be_truthy
304
304
  end
305
305
 
306
306
  it "matches a location on the scenario's tags" do
307
307
  location = Ast::Location.new(file, 7)
308
- expect( test_case.match_locations?([location]) ).to be_true
308
+ expect( test_case.match_locations?([location]) ).to be_truthy
309
309
  end
310
310
 
311
311
  it "doesn't match a location after the last step of the scenario" do
312
312
  location = Ast::Location.new(file, 11)
313
- expect( test_case.match_locations?([location]) ).to be_false
313
+ expect( test_case.match_locations?([location]) ).to be_falsey
314
314
  end
315
315
 
316
316
  it "doesn't match a location before the scenario" do
317
317
  location = Ast::Location.new(file, 5)
318
- expect( test_case.match_locations?([location]) ).to be_false
318
+ expect( test_case.match_locations?([location]) ).to be_falsey
319
319
  end
320
320
 
321
321
  context "with a docstring" do
@@ -325,12 +325,12 @@ module Cucumber
325
325
 
326
326
  it "matches a location at the start the docstring" do
327
327
  location = Ast::Location.new(file, 17)
328
- expect( test_case.match_locations?([location]) ).to be_true
328
+ expect( test_case.match_locations?([location]) ).to be_truthy
329
329
  end
330
330
 
331
331
  it "matches a location in the middle of the docstring" do
332
332
  location = Ast::Location.new(file, 18)
333
- expect( test_case.match_locations?([location]) ).to be_true
333
+ expect( test_case.match_locations?([location]) ).to be_truthy
334
334
  end
335
335
  end
336
336
 
@@ -341,7 +341,7 @@ module Cucumber
341
341
 
342
342
  it "matches a location on the first table row" do
343
343
  location = Ast::Location.new(file, 23)
344
- expect( test_case.match_locations?([location]) ).to be_true
344
+ expect( test_case.match_locations?([location]) ).to be_truthy
345
345
  end
346
346
  end
347
347
  end
@@ -381,32 +381,32 @@ module Cucumber
381
381
 
382
382
  it 'matches the precise location of the scenario outline examples table row' do
383
383
  location = Ast::Location.new(file, 16)
384
- expect( test_case.match_locations?([location]) ).to be_true
384
+ expect( test_case.match_locations?([location]) ).to be_truthy
385
385
  end
386
386
 
387
387
  it 'matches a location on a step of the scenario outline' do
388
388
  location = Ast::Location.new(file, 10)
389
- expect( test_case.match_locations?([location]) ).to be_true
389
+ expect( test_case.match_locations?([location]) ).to be_truthy
390
390
  end
391
391
 
392
392
  it "matches a location on the scenario outline's comment" do
393
393
  location = Ast::Location.new(file, 6)
394
- expect( test_case.match_locations?([location]) ).to be_true
394
+ expect( test_case.match_locations?([location]) ).to be_truthy
395
395
  end
396
396
 
397
397
  it "matches a location on the scenario outline's tags" do
398
398
  location = Ast::Location.new(file, 7)
399
- expect( test_case.match_locations?([location]) ).to be_true
399
+ expect( test_case.match_locations?([location]) ).to be_truthy
400
400
  end
401
401
 
402
402
  it "doesn't match a location after the last row of the examples table" do
403
403
  location = Ast::Location.new(file, 17)
404
- expect( test_case.match_locations?([location]) ).to be_false
404
+ expect( test_case.match_locations?([location]) ).to be_falsey
405
405
  end
406
406
 
407
407
  it "doesn't match a location before the scenario outline" do
408
408
  location = Ast::Location.new(file, 5)
409
- expect( test_case.match_locations?([location]) ).to be_false
409
+ expect( test_case.match_locations?([location]) ).to be_falsey
410
410
  end
411
411
  end
412
412
  end