cucumber-core 0.2.0 → 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
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