spinach 0.0.6 → 0.1.0

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 (41) hide show
  1. data/Gemfile +1 -0
  2. data/Readme.md +3 -0
  3. data/bin/spinach +3 -1
  4. data/features/steps/error_reporting.rb +4 -8
  5. data/features/steps/exit_status.rb +0 -1
  6. data/features/steps/feature_name_guessing.rb +1 -2
  7. data/features/support/spinach_runner.rb +0 -2
  8. data/lib/spinach/capybara.rb +8 -8
  9. data/lib/spinach/cli.rb +30 -18
  10. data/lib/spinach/config.rb +29 -10
  11. data/lib/spinach/dsl.rb +45 -21
  12. data/lib/spinach/exceptions.rb +21 -8
  13. data/lib/spinach/feature.rb +8 -4
  14. data/lib/spinach/parser.rb +13 -7
  15. data/lib/spinach/reporter/stdout.rb +251 -53
  16. data/lib/spinach/reporter.rb +43 -26
  17. data/lib/spinach/runner/feature.rb +39 -26
  18. data/lib/spinach/runner/scenario.rb +43 -28
  19. data/lib/spinach/runner.rb +40 -20
  20. data/lib/spinach/support.rb +8 -7
  21. data/lib/spinach/version.rb +2 -1
  22. data/lib/spinach.rb +17 -9
  23. data/spinach.gemspec +2 -1
  24. data/test/spinach/capybara_test.rb +32 -3
  25. data/test/spinach/cli_test.rb +32 -11
  26. data/test/spinach/config_test.rb +9 -6
  27. data/test/spinach/dsl_test.rb +8 -1
  28. data/test/spinach/feature_test.rb +14 -11
  29. data/test/spinach/parser_test.rb +33 -20
  30. data/test/spinach/reporter/stdout_test.rb +364 -103
  31. data/test/spinach/reporter_test.rb +145 -20
  32. data/test/spinach/runner/feature_test.rb +26 -51
  33. data/test/spinach/runner/scenario_test.rb +64 -35
  34. data/test/spinach/runner_test.rb +41 -32
  35. data/test/spinach/support_test.rb +2 -10
  36. data/test/spinach_test.rb +14 -14
  37. data/test/test_helper.rb +13 -5
  38. metadata +36 -28
  39. data/examples/steps/user_logs_in.rb +0 -23
  40. data/examples/user_logs_in.feature +0 -6
  41. data/examples/user_logs_in.rb +0 -23
@@ -3,142 +3,403 @@
3
3
  require_relative '../../test_helper'
4
4
 
5
5
  describe Spinach::Reporter::Stdout do
6
+ let(:exception) { StandardError.new('Something went wrong') }
7
+
8
+ let(:error) do
9
+ [{'name' => 'My feature'},
10
+ {'name' => 'A scenario'},
11
+ {'keyword' => 'Keyword', 'name' => 'step name'},
12
+ exception]
13
+ end
14
+
15
+ let(:steps) do
16
+ [error]
17
+ end
18
+
19
+
6
20
  before do
7
- @reporter = Spinach::Reporter::Stdout.new
21
+ @out = StringIO.new
22
+ @error = StringIO.new
23
+ @reporter = Spinach::Reporter::Stdout.new(
24
+ output: @out,
25
+ error: @error
26
+ )
27
+ end
28
+
29
+ describe '#before_feature_run' do
30
+ it 'outputs the feature' do
31
+ @reporter.before_feature_run('name' => 'A cool feature')
32
+
33
+ @out.string.must_include 'Feature'
34
+ @out.string.must_include 'A cool feature'
35
+ end
8
36
  end
9
37
 
10
- describe "#feature" do
11
- it "outputs a feature name" do
12
- out = capture_stdout do
13
- @reporter.feature "User authentication"
38
+ describe '#before_scenario_run' do
39
+ it 'outputs the scenario' do
40
+ @reporter.before_scenario_run('name' => 'Arbitrary scenario')
41
+
42
+ @out.string.must_include 'Scenario'
43
+ @out.string.must_include 'Arbitrary scenario'
44
+ end
45
+ end
46
+
47
+ describe '#after_scenario_run' do
48
+ describe 'in case of error' do
49
+ let(:exception) { anything }
50
+
51
+ before do
52
+ @reporter.scenario_error = exception
14
53
  end
15
- out.string.must_match /Feature:.*User authentication/
54
+
55
+ it 'reports the full error' do
56
+ @reporter.expects(:report_error).with(exception, :full)
57
+
58
+ @reporter.after_scenario_run('name' => 'Arbitrary scenario')
59
+ end
60
+
61
+ it 'resets the scenario error' do
62
+ @reporter.stubs(:report_error)
63
+ @reporter.after_scenario_run('name' => 'Arbitrary scenario')
64
+
65
+ @reporter.scenario_error.must_equal nil
66
+ end
67
+ end
68
+ end
69
+
70
+ describe '#on_successful_step' do
71
+ it 'adds the step to the output buffer' do
72
+ @reporter.on_successful_step({'keyword' => 'Given', 'name' => 'I am too cool'})
73
+
74
+ @out.string.must_include '✔'
75
+ @out.string.must_include 'Given'
76
+ @out.string.must_include 'am too cool'
77
+ end
78
+ end
79
+
80
+ describe '#on_failed_step' do
81
+ let(:step) { {'keyword' => 'Then', 'name' => 'I write failing steps'} }
82
+
83
+ it 'adds the step to the output buffer' do
84
+ @reporter.on_failed_step(step, anything)
85
+
86
+ @out.string.must_include '✘'
87
+ @out.string.must_include 'Then'
88
+ @out.string.must_include 'I write failing steps'
89
+ end
90
+
91
+ it 'sets the current scenario error' do
92
+ @reporter.on_failed_step(step, anything)
93
+
94
+ @reporter.scenario_error.must_include step
95
+ end
96
+
97
+ it 'adds the step to the failing steps' do
98
+ @reporter.on_failed_step(step, anything)
99
+
100
+ @reporter.failed_steps.last.must_include step
101
+ end
102
+ end
103
+
104
+ describe '#on_error_step' do
105
+ let(:step) { {'keyword' => 'And', 'name' => 'I even make syntax errors'} }
106
+
107
+ it 'adds the step to the output buffer' do
108
+ @reporter.on_error_step(step, anything)
109
+
110
+ @out.string.must_include '!'
111
+ @out.string.must_include 'And'
112
+ @out.string.must_include 'I even make syntax errors'
113
+ end
114
+
115
+ it 'sets the current scenario error' do
116
+ @reporter.on_error_step(step, anything)
117
+
118
+ @reporter.scenario_error.must_include step
119
+ end
120
+
121
+ it 'adds the step to the error steps' do
122
+ @reporter.on_error_step(step, anything)
123
+
124
+ @reporter.error_steps.last.must_include step
16
125
  end
17
126
  end
18
127
 
19
- describe "#scenario" do
20
- it "outputs a scenario name" do
21
- out = capture_stdout do
22
- @reporter.scenario "User logs in"
128
+ describe '#on_undefined_step' do
129
+ let(:step) { {'keyword' => 'When', 'name' => 'I forgot to write steps'} }
130
+
131
+ it 'adds the step to the output buffer' do
132
+ @reporter.on_undefined_step(step)
133
+
134
+ @out.string.must_include '?'
135
+ @out.string.must_include 'When'
136
+ @out.string.must_include 'I forgot to write steps'
137
+ end
138
+
139
+ it 'sets the current scenario error' do
140
+ @reporter.on_undefined_step(step)
141
+
142
+ @reporter.scenario_error.must_include step
143
+ end
144
+
145
+ it 'adds the step to the undefined steps' do
146
+ @reporter.on_undefined_step(step)
147
+
148
+ @reporter.undefined_steps.last.must_include step
149
+ end
150
+ end
151
+
152
+ describe '#on_skipped_step' do
153
+ it 'adds the step to the output buffer' do
154
+ @reporter.on_skipped_step({'keyword' => 'Then', 'name' => 'some steps are not even called'})
155
+
156
+ @out.string.must_include '~'
157
+ @out.string.must_include 'Then'
158
+ @out.string.must_include 'some steps are not even called'
159
+ end
160
+ end
161
+
162
+ describe '#output_step' do
163
+ it 'adds a step to the output buffer with nice colors' do
164
+ step = {'keyword' => 'Keyword', 'name' => 'step name'}
165
+ @reporter.output_step('symbol', step, :blue)
166
+
167
+ @out.string.must_include 'symbol'
168
+ @out.string.must_include 'Keyword'
169
+ @out.string.must_include 'step name'
170
+ end
171
+ end
172
+
173
+ describe '#after_run' do
174
+ describe 'when the run has succeed' do
175
+ it 'does nothing' do
176
+ @reporter.after_run(true).must_equal nil
177
+ end
178
+ end
179
+
180
+ describe 'when the run has succeed' do
181
+ it 'does nothing' do
182
+ @reporter.stubs(:error_summary).returns('Error summary')
183
+
184
+ @reporter.after_run(false).must_equal 'Error summary'
23
185
  end
24
- out.string.must_match /Scenario:.*User logs in/
25
186
  end
26
187
  end
27
188
 
28
- describe "#step" do
29
- before do
30
- @feature = stubs(name: "Some cool feature")
189
+ describe '#error_summary' do
190
+ it 'prints a summary with all the errors' do
191
+ @reporter.expects(:report_error_steps).once
192
+ @reporter.expects(:report_failed_steps).once
193
+ @reporter.expects(:report_undefined_steps).once
194
+
195
+ @reporter.error_summary
196
+
197
+ @error.string.must_include 'Error summary'
198
+ end
199
+ end
200
+
201
+ describe '#report_error_steps' do
202
+ describe 'when some steps have raised an error' do
203
+ it 'outputs the errors' do
204
+ steps = [anything]
205
+ @reporter.stubs(:error_steps).returns(steps)
206
+ @reporter.expects(:report_errors).with('Errors', steps, :light_red)
207
+
208
+ @reporter.report_error_steps
209
+ end
31
210
  end
32
- describe "when succeeding" do
33
- it "outputs the step name" do
34
- out = capture_stdout do
35
- @reporter.step "Given", "I say goodbye", :success
36
- end
37
- out.string.must_include "✔"
38
- out.string.must_match /Given.*I say goodbye/
211
+
212
+ describe 'when there are no error steps' do
213
+ it 'does nothing' do
214
+ @reporter.expects(:report_errors).never
215
+
216
+ @reporter.report_error_steps
39
217
  end
40
218
  end
219
+ end
220
+
221
+ describe '#report_failed_steps' do
222
+ describe 'when some steps have failed' do
223
+ it 'outputs the failing steps' do
224
+ steps = [anything]
225
+ @reporter.stubs(:failed_steps).returns(steps)
226
+ @reporter.expects(:report_errors).with('Failures', steps, :light_red)
41
227
 
42
- describe "when undefined" do
43
- it "outputs the step name with a question mark" do
44
- out = capture_stdout do
45
- @reporter.step "Given", "I say goodbye", :undefined_step
46
- end
47
- out.string.must_include "?"
48
- out.string.must_match /Given.*I say goodbye/
228
+ @reporter.report_failed_steps
49
229
  end
50
230
  end
51
231
 
52
- describe "when failing" do
53
- it "outputs the step name with a failure mark" do
54
- out = capture_stdout do
55
- @reporter.step "Given", "I say goodbye", :failure
56
- end
57
- out.string.must_include "✘"
58
- out.string.must_match /Given.*I say goodbye/
232
+ describe 'when there are no failed steps' do
233
+ it 'does nothing' do
234
+ @reporter.expects(:report_errors).never
235
+
236
+ @reporter.report_failed_steps
59
237
  end
60
238
  end
239
+ end
61
240
 
62
- describe "when failing" do
63
- it "outputs the step name with a failure mark" do
64
- out = capture_stdout do
65
- @reporter.step "Given", "I say goodbye", :error
66
- end
67
- out.string.must_include "!"
68
- out.string.must_match /Given.*I say goodbye/
241
+ describe '#report_undefined_steps' do
242
+ describe 'when some steps have undefined' do
243
+ it 'outputs the failing steps' do
244
+ steps = [anything]
245
+ @reporter.stubs(:undefined_steps).returns(steps)
246
+ @reporter.expects(:report_errors).with('Undefined steps', steps, :yellow)
247
+
248
+ @reporter.report_undefined_steps
69
249
  end
70
250
  end
71
251
 
72
- describe "when skipping" do
73
- it "outputs the step name with a failure mark" do
74
- out = capture_stdout do
75
- @reporter.step "Given", "I say nothing", :skip
76
- end
77
- out.string.must_include "~"
78
- out.string.must_match /Given.*I say nothing/
252
+ describe 'when there are no undefined steps' do
253
+ it 'does nothing' do
254
+ @reporter.expects(:report_errors).never
255
+
256
+ @reporter.report_undefined_steps
79
257
  end
80
258
  end
81
259
  end
82
260
 
83
- describe "#end" do
84
- it "outputs a blank line" do
85
- out = capture_stdout do
86
- @reporter.end
261
+ describe '#report_errors' do
262
+ describe 'when some steps have raised an error' do
263
+ it 'outputs a the banner with the number of steps given' do
264
+ @reporter.report_errors('Banner', steps, :blue)
265
+
266
+ @error.string.must_include 'Banner (1)'
267
+ end
268
+
269
+ it 'prints a summarized error' do
270
+ @reporter.report_errors('Banner', steps, :blue)
271
+
272
+ @error.string.must_include 'My feature :: A scenario :: Keyword step name'
273
+ end
274
+
275
+ it 'colorizes the output' do
276
+ String.any_instance.expects(:colorize).with(:blue).at_least_once
277
+
278
+ @reporter.report_errors('Banner', [], :blue)
279
+ end
280
+ end
281
+ end
282
+
283
+ describe '#report_error' do
284
+ it 'raises when given an unsupported format' do
285
+ proc {
286
+ @reporter.report_error(error, :nil)
287
+ }.must_raise RuntimeError, 'Format not defined'
288
+ end
289
+
290
+ it 'prints a summarized error by default' do
291
+ @reporter.expects(:summarized_error).with(error).returns('summarized error')
292
+
293
+ @reporter.report_error(error)
294
+
295
+ @error.string.must_include 'summarized error'
296
+ end
297
+
298
+ it 'prints a summarized error' do
299
+ @reporter.expects(:summarized_error).with(error).returns('summarized error')
300
+
301
+ @reporter.report_error(error, :summarized)
302
+
303
+ @error.string.must_include 'summarized error'
304
+ end
305
+
306
+ it 'prints a full error' do
307
+ @reporter.expects(:full_error).with(error).returns('full error')
308
+
309
+ @reporter.report_error(error, :full)
310
+
311
+ @error.string.must_include 'full error'
312
+ end
313
+ end
314
+
315
+ describe '#summarized_error' do
316
+ it 'prints the error' do
317
+ summary = @reporter.summarized_error(error)
318
+
319
+ summary.must_include 'My feature :: A scenario :: Keyword step name'
320
+ end
321
+
322
+ it 'colorizes the print' do
323
+ String.any_instance.expects(:red)
324
+
325
+ @reporter.summarized_error(error)
326
+ end
327
+
328
+ describe 'when given an undefined step exception' do
329
+ it 'prints the error in yellow' do
330
+ undefined_error = error
331
+ undefined_error.insert(3, Spinach::StepNotDefinedException.new(anything, anything))
332
+
333
+ String.any_instance.expects(:yellow)
334
+
335
+ @reporter.summarized_error(error)
87
336
  end
88
- out.string.must_include "\n"
89
337
  end
90
338
  end
91
339
 
92
- describe "#error_summary" do
340
+ describe '#full_error' do
93
341
  before do
94
- make_error = proc do |message|
95
- stub(
96
- message: message,
97
- backtrace: ["foo:1", "bar:2"]
98
- )
99
- end
100
-
101
- make_scenario = proc do |name|
102
- stub(
103
- feature_name: name,
104
- feature: stub_everything,
105
- name: name
106
- )
107
- end
108
-
109
- @errors = [
110
- [make_error.('omg'), "some_file", "3", make_scenario.('feature')],
111
- [make_error.('wtf'), "other_file", "9", make_scenario.('feature')],
112
- ]
113
-
114
- end
115
-
116
- it "outputs an error summary" do
117
- out = capture_stdout do
118
- @reporter.error_summary(@errors)
119
- end
120
- out.string.must_include "omg"
121
- out.string.must_include "some_file"
122
- out.string.must_include "(line 3)"
123
- out.string.must_include "wtf"
124
- out.string.must_include "other_file"
125
- out.string.must_include "(line 9)"
126
- out.string.wont_include "foo:1"
127
- out.string.wont_include "bar:2"
128
- end
129
- it "outputs an error summary with backtrace" do
130
- @reporter.options[:backtrace] = true
131
- out = capture_stdout do
132
- @reporter.error_summary(@errors)
133
- end
134
- out.string.must_include "omg"
135
- out.string.must_include "some_file"
136
- out.string.must_include "(line 3)"
137
- out.string.must_include "wtf"
138
- out.string.must_include "other_file"
139
- out.string.must_include "(line 9)"
140
- out.string.must_include "foo:1"
141
- out.string.must_include "bar:2"
342
+ @reporter.expects(:report_exception).with(exception).returns('Exception backtrace')
343
+ end
344
+
345
+ it 'returns the exception data' do
346
+ exception.expects(:backtrace).returns(['first backtrace line'])
347
+ output = @reporter.full_error(error)
348
+
349
+ output.must_include 'Exception backtrace'
350
+ end
351
+
352
+ it 'returns the first backtrace line' do
353
+ exception.expects(:backtrace).returns(['first backtrace line'])
354
+ output = @reporter.full_error(error)
355
+
356
+ output.must_include 'first backtrace line'
357
+ end
358
+
359
+ describe 'when the user wants to print the full backtrace' do
360
+ it 'prints the full backtrace' do
361
+ @reporter.stubs(:options).returns({backtrace: true})
362
+ exception.expects(:backtrace).returns(['first backtrace line', 'second backtrace line'])
363
+
364
+ output = @reporter.full_error(error)
365
+
366
+ output.must_include 'first backtrace line'
367
+ output.must_include 'second backtrace line'
368
+ end
369
+ end
370
+ end
371
+
372
+ describe '#full_step' do
373
+ it 'returns the step with keyword and name' do
374
+ @reporter.full_step({'keyword' => 'Keyword', 'name' => 'step name'}).must_equal 'Keyword step name'
375
+ end
376
+
377
+ it 'strips the arguments' do
378
+ @reporter.full_step({'keyword' => ' Keyword ', 'name' => ' step name '}).must_equal 'Keyword step name'
379
+ end
380
+ end
381
+
382
+ describe '#report_exception' do
383
+ it 'returns the exception data' do
384
+ output = @reporter.report_exception(exception)
385
+
386
+ output.must_include 'Something went wrong'
387
+ end
388
+
389
+ it 'colorizes the print' do
390
+ String.any_instance.expects(:red)
391
+
392
+ @reporter.report_exception(exception)
393
+ end
394
+
395
+ describe 'when given an undefined step exception' do
396
+ it 'prints the error in yellow' do
397
+ undefined_exception = Spinach::StepNotDefinedException.new(anything, anything)
398
+
399
+ String.any_instance.expects(:yellow)
400
+
401
+ @reporter.report_exception(undefined_exception)
402
+ end
142
403
  end
143
404
  end
144
405
  end
@@ -1,36 +1,161 @@
1
1
  # encoding: utf-8
2
2
  require_relative '../test_helper'
3
3
 
4
- describe Spinach::Reporter do
5
- describe "abstract methods" do
4
+ module Spinach
5
+ describe Reporter do
6
6
  before do
7
- @reporter = Spinach::Reporter.new
7
+ @options = {
8
+ backtrace: true
9
+ }
10
+ @reporter = Reporter.new(@options)
8
11
  end
9
- %w{feature scenario}.each do |abstract_method|
10
- describe "#{abstract_method}" do
11
- it "raises an error" do
12
- Proc.new{
13
- @reporter.send(abstract_method, "arbitrary name")
14
- }.must_raise RuntimeError
12
+
13
+ describe "#initialize" do
14
+ it "initializes the option hash" do
15
+ end
16
+ end
17
+
18
+ describe "#options" do
19
+ it "returns the options passed to the reporter" do
20
+ @reporter.options[:backtrace].must_equal true
21
+ end
22
+ end
23
+
24
+ describe "#current_feature" do
25
+ it "returns nil by default" do
26
+ @reporter.current_feature.must_equal nil
27
+ end
28
+ end
29
+
30
+ describe "#current_scenario" do
31
+ it "returns nil by default" do
32
+ @reporter.current_feature.must_equal nil
33
+ end
34
+ end
35
+
36
+ %w{undefined_steps failed_steps error_steps}.each do |errors|
37
+ describe "##{errors}" do
38
+ it "returns an empty array by default" do
39
+ @reporter.send(errors).must_be_empty
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "#bind" do
45
+ before do
46
+ @reporter.stubs(
47
+ runner: stub_everything,
48
+ feature_runner: stub_everything,
49
+ scenario_runner: stub_everything,
50
+ )
51
+ @callback = mock
52
+ @reporter.stubs(:method)
53
+ end
54
+ it "binds a callback after running all the suite" do
55
+ @reporter.expects(:method).with(:after_run).returns(@callback)
56
+ @reporter.runner.expects(:after_run).with(@callback)
57
+ @reporter.bind
58
+ end
59
+ it "binds a callback before running every feature" do
60
+ @reporter.expects(:method).with(:before_feature_run).returns(@callback)
61
+ @reporter.feature_runner.expects(:before_run).with(@callback)
62
+ @reporter.bind
63
+ end
64
+ it "binds a callback after running every feature" do
65
+ @reporter.expects(:method).with(:after_feature_run).returns(@callback)
66
+ @reporter.feature_runner.expects(:after_run).with(@callback)
67
+ @reporter.bind
68
+ end
69
+ it "binds a callback before running every scenario" do
70
+ @reporter.expects(:method).with(:before_scenario_run).returns(@callback)
71
+ @reporter.scenario_runner.expects(:before_run).with(@callback)
72
+ @reporter.bind
73
+ end
74
+ it "binds a callback after running every feature" do
75
+ @reporter.expects(:method).with(:after_scenario_run).returns(@callback)
76
+ @reporter.scenario_runner.expects(:after_run).with(@callback)
77
+ @reporter.bind
78
+ end
79
+ describe "when running steps" do
80
+ %w{successful failed error skipped}.each do |type|
81
+ it "binds a callback after running a #{type} step" do
82
+ @reporter.expects(:method).with(:"on_#{type}_step").returns(@callback)
83
+ @reporter.scenario_runner.expects(:"on_#{type}_step").with(@callback)
84
+ @reporter.bind
85
+ end
86
+ end
87
+ end
88
+ describe "binds the context methods" do
89
+ it "binds the current feature setter" do
90
+ @reporter.expects(:method).with(:current_feature=).returns(@callback)
91
+ @reporter.feature_runner.expects(:before_run).with(@callback)
92
+ @reporter.bind
93
+ end
94
+ it "binds the current feature clearer" do
95
+ @reporter.expects(:method).with(:clear_current_feature).returns(@callback)
96
+ @reporter.feature_runner.expects(:after_run).with(@callback)
97
+ @reporter.bind
98
+ end
99
+ it "binds the current scenario setter" do
100
+ @reporter.expects(:method).with(:current_scenario=).returns(@callback)
101
+ @reporter.scenario_runner.expects(:before_run).with(@callback)
102
+ @reporter.bind
103
+ end
104
+ it "binds the current feature clearer" do
105
+ @reporter.expects(:method).with(:clear_current_scenario).returns(@callback)
106
+ @reporter.scenario_runner.expects(:after_run).with(@callback)
107
+ @reporter.bind
15
108
  end
16
109
  end
17
110
  end
18
111
 
19
- describe "#step" do
20
- it "raises an error" do
21
- Proc.new{
22
- @reporter.step("Given", "arbitrary name", :success)
23
- }.must_raise RuntimeError
112
+ describe "#clear_current_feature" do
113
+ it "clears the current feature" do
114
+ @reporter.current_feature = mock
115
+ @reporter.clear_current_feature
116
+ @reporter.current_feature.must_equal nil
24
117
  end
25
118
  end
26
119
 
27
- describe "#end" do
28
- it "raises an error" do
29
- Proc.new{
30
- @reporter.end
31
- }.must_raise RuntimeError
120
+ describe "#clear_current_scenario" do
121
+ it "clears the current scenario" do
122
+ @reporter.current_scenario = mock
123
+ @reporter.clear_current_scenario
124
+ @reporter.current_scenario.must_equal nil
32
125
  end
33
126
  end
34
- end
35
127
 
128
+ describe "runner classes" do
129
+ describe "#feature_runner" do
130
+ it "returns a runner class" do
131
+ @reporter.feature_runner.must_be_kind_of Class
132
+ end
133
+ end
134
+ describe "#scenario_runner" do
135
+ it "returns a runner class" do
136
+ @reporter.scenario_runner.must_be_kind_of Class
137
+ end
138
+ end
139
+ describe "#runner" do
140
+ it "returns a runner class" do
141
+ @reporter.runner.must_be_kind_of Class
142
+ end
143
+ end
144
+ end
145
+
146
+ describe "callback methods" do
147
+ %w{
148
+ after_run before_feature_run after_feature_run before_scenario_run
149
+ after_scenario_run on_successful_step on_failed_step on_error_step
150
+ on_undefined_step on_skipped_step
151
+ }.each do |callback|
152
+ describe "##{callback}" do
153
+ it "does nothing" do
154
+ @reporter.send(callback)
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ end
36
161
  end