cucumber-core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.travis.yml +16 -0
  6. data/Gemfile +2 -0
  7. data/LICENSE +20 -0
  8. data/README.md +9 -0
  9. data/Rakefile +24 -0
  10. data/cucumber-core.gemspec +32 -0
  11. data/lib/cucumber/core.rb +37 -0
  12. data/lib/cucumber/core/ast.rb +13 -0
  13. data/lib/cucumber/core/ast/background.rb +33 -0
  14. data/lib/cucumber/core/ast/comment.rb +17 -0
  15. data/lib/cucumber/core/ast/data_table.rb +326 -0
  16. data/lib/cucumber/core/ast/describes_itself.rb +16 -0
  17. data/lib/cucumber/core/ast/doc_string.rb +83 -0
  18. data/lib/cucumber/core/ast/empty_background.rb +12 -0
  19. data/lib/cucumber/core/ast/examples_table.rb +95 -0
  20. data/lib/cucumber/core/ast/feature.rb +62 -0
  21. data/lib/cucumber/core/ast/location.rb +140 -0
  22. data/lib/cucumber/core/ast/multiline_argument.rb +33 -0
  23. data/lib/cucumber/core/ast/names.rb +19 -0
  24. data/lib/cucumber/core/ast/outline_step.rb +51 -0
  25. data/lib/cucumber/core/ast/scenario.rb +43 -0
  26. data/lib/cucumber/core/ast/scenario_outline.rb +44 -0
  27. data/lib/cucumber/core/ast/step.rb +38 -0
  28. data/lib/cucumber/core/ast/tag.rb +14 -0
  29. data/lib/cucumber/core/compiler.rb +136 -0
  30. data/lib/cucumber/core/gherkin/ast_builder.rb +315 -0
  31. data/lib/cucumber/core/gherkin/document.rb +20 -0
  32. data/lib/cucumber/core/gherkin/parser.rb +45 -0
  33. data/lib/cucumber/core/gherkin/writer.rb +220 -0
  34. data/lib/cucumber/core/gherkin/writer/helpers.rb +178 -0
  35. data/lib/cucumber/core/platform.rb +30 -0
  36. data/lib/cucumber/core/test/case.rb +143 -0
  37. data/lib/cucumber/core/test/filters.rb +48 -0
  38. data/lib/cucumber/core/test/filters/tag_filter.rb +110 -0
  39. data/lib/cucumber/core/test/hook_compiler.rb +109 -0
  40. data/lib/cucumber/core/test/mapper.rb +56 -0
  41. data/lib/cucumber/core/test/mapping.rb +67 -0
  42. data/lib/cucumber/core/test/result.rb +191 -0
  43. data/lib/cucumber/core/test/runner.rb +149 -0
  44. data/lib/cucumber/core/test/step.rb +69 -0
  45. data/lib/cucumber/core/test/timer.rb +31 -0
  46. data/lib/cucumber/core/version.rb +9 -0
  47. data/lib/cucumber/initializer.rb +18 -0
  48. data/spec/capture_warnings.rb +68 -0
  49. data/spec/coverage.rb +10 -0
  50. data/spec/cucumber/core/ast/data_table_spec.rb +139 -0
  51. data/spec/cucumber/core/ast/doc_string_spec.rb +77 -0
  52. data/spec/cucumber/core/ast/examples_table_spec.rb +87 -0
  53. data/spec/cucumber/core/ast/location_spec.rb +105 -0
  54. data/spec/cucumber/core/ast/outline_step_spec.rb +77 -0
  55. data/spec/cucumber/core/ast/step_spec.rb +44 -0
  56. data/spec/cucumber/core/compiler_spec.rb +249 -0
  57. data/spec/cucumber/core/gherkin/parser_spec.rb +182 -0
  58. data/spec/cucumber/core/gherkin/writer_spec.rb +332 -0
  59. data/spec/cucumber/core/test/case_spec.rb +416 -0
  60. data/spec/cucumber/core/test/hook_compiler_spec.rb +78 -0
  61. data/spec/cucumber/core/test/mapper_spec.rb +68 -0
  62. data/spec/cucumber/core/test/mapping_spec.rb +103 -0
  63. data/spec/cucumber/core/test/result_spec.rb +178 -0
  64. data/spec/cucumber/core/test/runner_spec.rb +265 -0
  65. data/spec/cucumber/core/test/step_spec.rb +58 -0
  66. data/spec/cucumber/core/test/timer_spec.rb +13 -0
  67. data/spec/cucumber/core_spec.rb +419 -0
  68. data/spec/cucumber/initializer_spec.rb +49 -0
  69. metadata +221 -0
@@ -0,0 +1,68 @@
1
+ require 'cucumber/core/test/mapper'
2
+ require 'cucumber/core/test/case'
3
+ require 'cucumber/core/test/step'
4
+
5
+ module Cucumber
6
+ module Core
7
+ module Test
8
+ describe Mapper do
9
+
10
+ ExampleMappings = Struct.new(:app) do
11
+ def test_step(test_step, mapper)
12
+ mapper.map { app.do_something } if test_step.name == 'mapped'
13
+ end
14
+ end
15
+
16
+ let(:mapper) { Mapper.new(mappings, receiver) }
17
+ let(:receiver) { double('receiver') }
18
+ before { receiver.stub(:test_case).and_yield }
19
+ let(:mappings) { ExampleMappings.new(app) }
20
+ let(:app) { double('app') }
21
+
22
+ context "an unmapped step" do
23
+ let(:test_step) { Test::Step.new([double(name: 'unmapped')]) }
24
+ let(:test_case) { Test::Case.new([test_step], double) }
25
+
26
+ it "maps to a step that executes to an undefined result" do
27
+ expect( receiver ).to receive(:test_step) do |test_step|
28
+ expect( test_step.name ).to eq 'unmapped'
29
+ expect( test_step.execute ).to be_undefined
30
+ end.once.ordered
31
+ test_case.describe_to mapper
32
+ end
33
+ end
34
+
35
+ context "a mapped step" do
36
+ let(:test_step) { Test::Step.new([double(name: 'mapped')]) }
37
+ let(:test_case) { Test::Case.new([test_step], double) }
38
+
39
+ it "maps to a step that executes the block" do
40
+ expect( receiver ).to receive(:test_step) do |test_step|
41
+ expect( test_step.name ).to eq 'mapped'
42
+ expect( app ).to receive(:do_something)
43
+ test_step.execute
44
+ end.once.ordered
45
+ test_case.describe_to mapper
46
+ end
47
+ end
48
+
49
+ context "a combination" do
50
+ let(:mapped) { Test::Step.new([double(name: 'passing')]) }
51
+ let(:unmapped) { Test::Step.new([double(name: 'unmapped')]) }
52
+ let(:test_case) { Test::Case.new([mapped, unmapped], double) }
53
+
54
+ it "maps each of the test steps" do
55
+ expect( receiver ).to receive(:test_step) do |test_step|
56
+ expect( test_step.name ).to eq 'passing'
57
+ end.once.ordered
58
+ expect( receiver ).to receive(:test_step) do |test_step|
59
+ expect( test_step.name ).to eq 'unmapped'
60
+ end.once.ordered
61
+ test_case.describe_to mapper
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,103 @@
1
+ require 'cucumber/core/test/mapping'
2
+
3
+ module Cucumber
4
+ module Core
5
+ module Test
6
+
7
+ describe Mapping do
8
+
9
+ context "constructed without a block" do
10
+ it "raises an error" do
11
+ expect { Mapping.new }.to raise_error(ArgumentError)
12
+ end
13
+ end
14
+
15
+ context "executing" do
16
+ it "executes the block passed to the constructor" do
17
+ executed = false
18
+ mapping = Mapping.new { executed = true }
19
+ mapping.execute
20
+ expect( executed ).to be_true
21
+ end
22
+
23
+ it "returns a passed result if the block doesn't fail" do
24
+ mapping = Mapping.new {}
25
+ expect( mapping.execute ).to be_passed
26
+ end
27
+
28
+ it "returns a failed result when the block raises an error" do
29
+ exception = StandardError.new
30
+ mapping = Mapping.new { raise exception }
31
+ result = mapping.execute
32
+ expect( result ).to be_failed
33
+ expect( result.exception ).to eq exception
34
+ end
35
+
36
+ it "returns a pending result if a pending error is raised" do
37
+ exception = Result::Pending.new("TODO")
38
+ mapping = Mapping.new { raise exception }
39
+ result = mapping.execute
40
+ expect( result ).to be_pending
41
+ expect( result.message ).to eq "TODO"
42
+ end
43
+
44
+ context "recording the duration" do
45
+ before do
46
+ time = double
47
+ Time.stub(now: time)
48
+ time.stub(:nsec).and_return(946752000, 946752001)
49
+ time.stub(:to_i).and_return(1377009235, 1377009235)
50
+ end
51
+
52
+ it "records the nanoseconds duration of the execution on the result" do
53
+ mapping = Mapping.new { }
54
+ duration = mapping.execute.duration
55
+ expect( duration ).to eq 1
56
+ end
57
+
58
+ it "records the duration of a failed execution" do
59
+ mapping = Mapping.new { raise StandardError }
60
+ duration = mapping.execute.duration
61
+ expect( duration ).to eq 1
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ context "skipping" do
68
+ it "does not execute the block" do
69
+ executed = false
70
+ mapping = Mapping.new { executed = true }
71
+ mapping.skip
72
+ expect( executed ).to be_false
73
+ end
74
+
75
+ it "returns a skipped result" do
76
+ mapping = Mapping.new {}
77
+ expect( mapping.skip ).to be_skipped
78
+ end
79
+ end
80
+ end
81
+
82
+ describe UndefinedMapping do
83
+ let(:mapping) { UndefinedMapping.new }
84
+ let(:test_step) { double }
85
+
86
+ context "executing" do
87
+ it "returns an undefined result" do
88
+ expect( mapping.execute ).to be_undefined
89
+ end
90
+ end
91
+
92
+ context "skipping" do
93
+ it "returns an undefined result" do
94
+ expect( mapping.skip ).to be_undefined
95
+ end
96
+ end
97
+
98
+ end
99
+
100
+ end
101
+ end
102
+ end
103
+
@@ -0,0 +1,178 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'cucumber/core/test/result'
3
+
4
+ module Cucumber::Core::Test
5
+ describe Result do
6
+
7
+ let(:visitor) { double('visitor') }
8
+ let(:args) { double('args') }
9
+
10
+ describe Result::Passed do
11
+ subject(:result) { Result::Passed.new(duration) }
12
+ let(:duration) { 1 * 1000 * 1000 }
13
+
14
+ it "describes itself to a visitor" do
15
+ expect( visitor ).to receive(:passed).with(args)
16
+ expect( visitor ).to receive(:duration).with(duration, args)
17
+ result.describe_to(visitor, args)
18
+ end
19
+
20
+ it "converts to a string" do
21
+ expect( result.to_s ).to eq "✓"
22
+ end
23
+
24
+ it "has a duration" do
25
+ expect( result.duration ).to eq duration
26
+ end
27
+
28
+ it "requires the constructor argument" do
29
+ expect { Result::Passed.new }.to raise_error(ArgumentError)
30
+ end
31
+
32
+ it { expect( result ).to be_passed }
33
+ it { expect( result ).not_to be_failed }
34
+ it { expect( result ).not_to be_undefined }
35
+ it { expect( result ).not_to be_unknown }
36
+ it { expect( result ).not_to be_skipped }
37
+ end
38
+
39
+ describe Result::Failed do
40
+ subject(:result) { Result::Failed.new(duration, exception) }
41
+ let(:duration) { 1 * 1000 * 1000 }
42
+ let(:exception) { StandardError.new("error message") }
43
+
44
+ it "describes itself to a visitor" do
45
+ expect( visitor ).to receive(:failed).with(args)
46
+ expect( visitor ).to receive(:duration).with(duration, args)
47
+ expect( visitor ).to receive(:exception).with(exception, args)
48
+ result.describe_to(visitor, args)
49
+ end
50
+
51
+ it "has a duration" do
52
+ expect( result.duration ).to eq duration
53
+ end
54
+
55
+ it "requires both constructor arguments" do
56
+ expect { Result::Failed.new }.to raise_error(ArgumentError)
57
+ expect { Result::Failed.new(duration) }.to raise_error(ArgumentError)
58
+ end
59
+
60
+ it { expect( result ).not_to be_passed }
61
+ it { expect( result ).to be_failed }
62
+ it { expect( result ).not_to be_undefined }
63
+ it { expect( result ).not_to be_unknown }
64
+ it { expect( result ).not_to be_skipped }
65
+ end
66
+
67
+ describe Result::Unknown do
68
+ subject(:result) { Result::Unknown.new }
69
+
70
+ it "doesn't describe itself to a visitor" do
71
+ visitor = double('never receives anything')
72
+ result.describe_to(visitor, args)
73
+ end
74
+
75
+ it "has no duration" do
76
+ expect { result.duration }.to raise_error NoMethodError
77
+ end
78
+
79
+ it { expect( result ).not_to be_passed }
80
+ it { expect( result ).not_to be_failed }
81
+ it { expect( result ).not_to be_undefined }
82
+ it { expect( result ).to be_unknown }
83
+ it { expect( result ).not_to be_skipped }
84
+ end
85
+
86
+ describe Result::Undefined do
87
+ subject(:result) { Result::Undefined.new }
88
+
89
+ it "describes itself to a visitor" do
90
+ expect( visitor ).to receive(:undefined).with(args)
91
+ result.describe_to(visitor, args)
92
+ end
93
+
94
+ it { expect( result ).not_to be_passed }
95
+ it { expect( result ).not_to be_failed }
96
+ it { expect( result ).to be_undefined }
97
+ it { expect( result ).not_to be_unknown }
98
+ it { expect( result ).not_to be_skipped }
99
+ end
100
+
101
+ describe Result::Skipped do
102
+ subject(:result) { Result::Skipped.new }
103
+
104
+ it "describes itself to a visitor" do
105
+ expect( visitor ).to receive(:skipped).with(args)
106
+ result.describe_to(visitor, args)
107
+ end
108
+
109
+ it "has no duration" do
110
+ expect { result.duration }.to raise_error NoMethodError
111
+ end
112
+
113
+ it { expect( result ).not_to be_passed }
114
+ it { expect( result ).not_to be_failed }
115
+ it { expect( result ).not_to be_undefined }
116
+ it { expect( result ).not_to be_unknown }
117
+ it { expect( result ).to be_skipped }
118
+ end
119
+
120
+ describe Result::Summary do
121
+ let(:summary) { Result::Summary.new }
122
+ let(:failed) { Result::Failed.new(10, exception) }
123
+ let(:passed) { Result::Passed.new(11) }
124
+ let(:skipped) { Result::Skipped.new }
125
+ let(:unknown) { Result::Unknown.new }
126
+ let(:undefined) { Result::Undefined.new }
127
+ let(:exception) { StandardError.new }
128
+
129
+ it "counts failed results" do
130
+ failed.describe_to summary
131
+ expect( summary.total_failed ).to eq 1
132
+ expect( summary.total ).to eq 1
133
+ end
134
+
135
+ it "counts passed results" do
136
+ passed.describe_to summary
137
+ expect( summary.total_passed ).to eq 1
138
+ expect( summary.total ).to eq 1
139
+ end
140
+
141
+ it "counts skipped results" do
142
+ skipped.describe_to summary
143
+ expect( summary.total_skipped ).to eq 1
144
+ expect( summary.total ).to eq 1
145
+ end
146
+
147
+ it "counts undefined results" do
148
+ undefined.describe_to summary
149
+ expect( summary.total_undefined ).to eq 1
150
+ expect( summary.total ).to eq 1
151
+ end
152
+
153
+ it "doesn't count unknown results" do
154
+ unknown.describe_to summary
155
+ expect( summary.total ).to eq 0
156
+ end
157
+
158
+ it "counts combinations" do
159
+ [passed, passed, failed, skipped, undefined].each { |r| r.describe_to summary }
160
+ expect( summary.total ).to eq 5
161
+ expect( summary.total_passed ).to eq 2
162
+ expect( summary.total_failed ).to eq 1
163
+ expect( summary.total_skipped ).to eq 1
164
+ expect( summary.total_undefined ).to eq 1
165
+ end
166
+
167
+ it "records durations" do
168
+ [passed, failed].each { |r| r.describe_to summary }
169
+ expect( summary.durations ).to eq [11, 10]
170
+ end
171
+
172
+ it "records exceptions" do
173
+ [passed, failed].each { |r| r.describe_to summary }
174
+ expect( summary.exceptions ).to eq [exception]
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,265 @@
1
+ require 'cucumber/core/test/runner'
2
+ require 'cucumber/core/test/case'
3
+ require 'cucumber/core/test/step'
4
+
5
+ module Cucumber::Core::Test
6
+ describe Runner do
7
+
8
+ let(:test_case) { Case.new(test_steps, source) }
9
+ let(:source) { double }
10
+ let(:runner) { Runner.new(report) }
11
+ let(:report) { double.as_null_object }
12
+ let(:passing) { Step.new([double]).map {} }
13
+ let(:failing) { Step.new([double]).map { raise exception } }
14
+ let(:pending) { Step.new([double]).map { raise Result::Pending.new("TODO") } }
15
+ let(:undefined) { Step.new([double]) }
16
+ let(:exception) { StandardError.new('test error') }
17
+
18
+ context "reporting the duration of a test case" do
19
+ before do
20
+ time = double
21
+ Time.stub(now: time)
22
+ time.stub(:nsec).and_return(946752000, 946752001)
23
+ time.stub(:to_i).and_return(1377009235, 1377009235)
24
+ end
25
+
26
+ context "for a passing test case" do
27
+ let(:test_steps) { [passing] }
28
+
29
+ it "records the nanoseconds duration of the execution on the result" do
30
+ expect( report ).to receive(:after_test_case) do |reported_test_case, result|
31
+ expect( result.duration ).to eq 1
32
+ end
33
+ test_case.describe_to runner
34
+ end
35
+ end
36
+
37
+ context "for a failing test case" do
38
+ let(:test_steps) { [failing] }
39
+
40
+ it "records the duration" do
41
+ expect( report ).to receive(:after_test_case) do |reported_test_case, result|
42
+ expect( result.duration ).to eq 1
43
+ end
44
+ test_case.describe_to runner
45
+ end
46
+ end
47
+ end
48
+
49
+ context "reporting the exception that failed a test case" do
50
+ let(:test_steps) { [failing] }
51
+ it "sets the exception on the result" do
52
+ expect( report ).to receive(:after_test_case) do |reported_test_case, result|
53
+ expect( result.exception ).to eq exception
54
+ end
55
+ test_case.describe_to runner
56
+ end
57
+ end
58
+
59
+ context "with a single case" do
60
+ context "without steps" do
61
+ let(:test_steps) { [] }
62
+
63
+ it "calls the report before running the case" do
64
+ expect( report ).to receive(:before_test_case).with(test_case)
65
+ test_case.describe_to runner
66
+ end
67
+
68
+ it "calls the report after running the case" do
69
+ expect( report ).to receive(:after_test_case) do |reported_test_case, result|
70
+ expect( reported_test_case ).to eq test_case
71
+ expect( result ).to be_unknown
72
+ end
73
+ test_case.describe_to runner
74
+ end
75
+ end
76
+
77
+ context 'with steps' do
78
+ context 'that all pass' do
79
+ let(:test_steps) { [ passing, passing ] }
80
+
81
+ it 'reports a passing test case' do
82
+ expect( report ).to receive(:after_test_case) do |test_case, result|
83
+ expect( result ).to be_passed
84
+ end
85
+ test_case.describe_to runner
86
+ end
87
+ end
88
+
89
+ context 'an undefined step' do
90
+ let(:test_steps) { [ undefined ] }
91
+
92
+ it 'reports an undefined test case' do
93
+ expect( report ).to receive(:after_test_case) do |test_case, result|
94
+ expect( result ).to be_undefined
95
+ end
96
+ test_case.describe_to runner
97
+ end
98
+ end
99
+
100
+ context 'a pending step' do
101
+ let(:test_steps) { [ pending ] }
102
+
103
+ it 'reports a pending test case' do
104
+ expect( report ).to receive(:after_test_case) do |test_case, result|
105
+ expect( result ).to be_pending
106
+ end
107
+ test_case.describe_to runner
108
+ end
109
+ end
110
+
111
+ context 'that fail' do
112
+ let(:test_steps) { [ failing ] }
113
+
114
+ it 'reports a failing test case' do
115
+ expect( report ).to receive(:after_test_case) do |test_case, result|
116
+ expect( result ).to be_failed
117
+ end
118
+ test_case.describe_to runner
119
+ end
120
+ end
121
+
122
+ context 'where the first step fails' do
123
+ let(:test_steps) { [ failing, passing ] }
124
+
125
+ it 'reports the first step as failed' do
126
+ expect( report ).to receive(:after_test_step).with(failing, anything) do |test_step, result|
127
+ expect( result ).to be_failed
128
+ end
129
+ test_case.describe_to runner
130
+ end
131
+
132
+ it 'reports the second step as skipped' do
133
+ expect( report ).to receive(:after_test_step).with(passing, anything) do |test_step, result|
134
+ expect( result ).to be_skipped
135
+ end
136
+ test_case.describe_to runner
137
+ end
138
+
139
+ it 'reports the test case as failed' do
140
+ expect( report ).to receive(:after_test_case) do |test_case, result|
141
+ expect( result ).to be_failed
142
+ expect( result.exception ).to eq exception
143
+ end
144
+ test_case.describe_to runner
145
+ end
146
+
147
+ it 'skips, rather than executing the second step' do
148
+ expect( passing ).not_to receive(:execute)
149
+ expect( passing ).to receive(:skip)
150
+ test_case.describe_to runner
151
+ end
152
+ end
153
+
154
+ end
155
+ end
156
+
157
+ context 'with multiple test cases' do
158
+ context 'when the first test case fails' do
159
+ let(:first_test_case) { Case.new([failing], source) }
160
+ let(:last_test_case) { Case.new([passing], source) }
161
+ let(:test_cases) { [first_test_case, last_test_case] }
162
+
163
+ it 'reports the results correctly for the following test case' do
164
+ expect( report ).to receive(:after_test_case).with(last_test_case, anything) do |reported_test_case, result|
165
+ expect( result ).to be_passed
166
+ end
167
+
168
+ test_cases.each { |c| c.describe_to runner }
169
+ end
170
+ end
171
+ end
172
+
173
+ end
174
+
175
+ describe 'with the dry run strategy' do
176
+
177
+ let(:report) { double(:report).as_null_object }
178
+ let(:source) { double(:source) }
179
+ let(:runner) { Runner.new(report, :run_mode => :dry_run) }
180
+ let(:passing) { Step.new([double]).map {} }
181
+ let(:undefined) { Step.new([double]) }
182
+ let(:test_case) { Case.new(test_steps, source) }
183
+
184
+ context 'with a passing step' do
185
+ let(:test_steps) { [passing] }
186
+
187
+ it 'reports the test case as skipped' do
188
+ report.should_receive(:after_test_case) do |test_case, result|
189
+ result.should be_skipped
190
+ end
191
+ test_case.describe_to runner
192
+ end
193
+
194
+ it 'reports the test step has been skipped' do
195
+ report.should_receive(:after_test_step) do |test_step, result|
196
+ result.should be_skipped
197
+ end
198
+ test_case.describe_to runner
199
+ end
200
+ end
201
+
202
+ context 'with a undefined step' do
203
+ let(:test_steps) { [undefined] }
204
+
205
+ it 'reports the test case as undefined' do
206
+ report.should_receive(:after_test_case) do |test_case, result|
207
+ result.should be_undefined
208
+ end
209
+ test_case.describe_to runner
210
+ end
211
+
212
+
213
+ it 'reports the test step as undefined' do
214
+ report.should_receive(:after_test_step) do |test_step, result|
215
+ result.should be_undefined
216
+ end
217
+ test_case.describe_to runner
218
+ end
219
+ end
220
+
221
+ context 'with passing and undefined steps' do
222
+ let(:test_steps) { [passing, undefined] }
223
+
224
+ it 'reports the test case as undefined' do
225
+ report.should_receive(:after_test_case) do |test_case, result|
226
+ result.should be_undefined
227
+ end
228
+ test_case.describe_to runner
229
+ end
230
+
231
+ it 'reports the passing step as skipped' do
232
+ report.should_receive(:after_test_step).with(passing, anything) do |test_case, result|
233
+ result.should be_skipped
234
+ end
235
+ test_case.describe_to runner
236
+ end
237
+
238
+ it 'reports the undefined step as undefined' do
239
+ report.should_receive(:after_test_step).with(undefined, anything) do |test_case, result|
240
+ result.should be_undefined
241
+ end
242
+ test_case.describe_to runner
243
+ end
244
+ end
245
+
246
+ context 'with multiple test cases' do
247
+ context 'when the first test case is undefined' do
248
+ let(:first_test_case) { Case.new([undefined], source) }
249
+ let(:last_test_case) { Case.new([passing], source) }
250
+ let(:test_cases) { [first_test_case, last_test_case] }
251
+
252
+ it 'reports the results correctly for the following test case' do
253
+ report.
254
+ should_receive(:after_test_case).
255
+ with(last_test_case, anything) do |reported_test_case, result|
256
+ result.should be_skipped
257
+ end
258
+
259
+ test_cases.each { |c| c.describe_to runner }
260
+ end
261
+ end
262
+ end
263
+ end
264
+
265
+ end