spinach 0.1.4 → 0.1.5
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.
- data/.gitignore +1 -0
- data/.yardopts +6 -0
- data/Gemfile +1 -0
- data/Guardfile +7 -0
- data/Rakefile +1 -0
- data/Readme.md +147 -10
- data/features/{generate_features.feature → automatic_feature_generation.feature} +0 -0
- data/features/steps/automatic_feature_generation.rb +5 -2
- data/features/steps/exit_status.rb +8 -3
- data/features/steps/feature_name_guessing.rb +4 -1
- data/features/steps/reporting/display_run_summary.rb +7 -4
- data/features/steps/reporting/error_reporting.rb +7 -2
- data/features/steps/reporting/show_step_source_location.rb +9 -5
- data/features/steps/reporting/undefined_feature_reporting.rb +4 -1
- data/features/steps/rspec_compatibility.rb +6 -2
- data/features/support/spinach_runner.rb +2 -9
- data/lib/spinach/capybara.rb +3 -4
- data/lib/spinach/cli.rb +0 -1
- data/lib/spinach/config.rb +0 -8
- data/lib/spinach/dsl.rb +4 -13
- data/lib/spinach/exceptions.rb +1 -1
- data/lib/spinach/feature_steps.rb +1 -9
- data/lib/spinach/generators/feature_generator.rb +3 -2
- data/lib/spinach/generators.rb +1 -1
- data/lib/spinach/hookable.rb +81 -0
- data/lib/spinach/hooks.rb +132 -0
- data/lib/spinach/reporter/stdout/error_reporting.rb +163 -0
- data/lib/spinach/reporter/stdout.rb +3 -151
- data/lib/spinach/reporter.rb +39 -25
- data/lib/spinach/runner/{feature.rb → feature_runner.rb} +5 -15
- data/lib/spinach/runner/scenario_runner.rb +65 -0
- data/lib/spinach/runner.rb +5 -11
- data/lib/spinach/version.rb +1 -1
- data/lib/spinach.rb +20 -8
- data/spinach.gemspec +2 -3
- data/test/spinach/capybara_test.rb +4 -3
- data/test/spinach/cli_test.rb +0 -1
- data/test/spinach/feature_steps_test.rb +6 -23
- data/test/spinach/generators/feature_generator_test.rb +2 -2
- data/test/spinach/generators_test.rb +2 -2
- data/test/spinach/hookable_test.rb +59 -0
- data/test/spinach/hooks_test.rb +28 -0
- data/test/spinach/reporter/stdout/error_reporting_test.rb +265 -0
- data/test/spinach/reporter/stdout_test.rb +1 -238
- data/test/spinach/reporter_test.rb +58 -103
- data/test/spinach/runner/{feature_test.rb → feature_runner_test.rb} +21 -23
- data/test/spinach/runner/scenario_runner_test.rb +111 -0
- data/test/spinach/runner_test.rb +1 -1
- data/test/spinach_test.rb +19 -18
- data/test/test_helper.rb +1 -1
- metadata +60 -61
- data/lib/spinach/runner/scenario.rb +0 -77
- data/test/spinach/runner/scenario_test.rb +0 -120
@@ -193,7 +193,7 @@ describe Spinach::Reporter::Stdout do
|
|
193
193
|
end
|
194
194
|
|
195
195
|
it 'tells the user what to write in the file' do
|
196
|
-
@out.string.must_include '
|
196
|
+
@out.string.must_include 'This feature does not exist'
|
197
197
|
end
|
198
198
|
end
|
199
199
|
|
@@ -238,219 +238,6 @@ describe Spinach::Reporter::Stdout do
|
|
238
238
|
end
|
239
239
|
end
|
240
240
|
|
241
|
-
describe '#error_summary' do
|
242
|
-
it 'prints a summary with all the errors' do
|
243
|
-
@reporter.expects(:report_error_steps).once
|
244
|
-
@reporter.expects(:report_failed_steps).once
|
245
|
-
@reporter.expects(:report_undefined_steps).once
|
246
|
-
@reporter.expects(:report_undefined_features).once
|
247
|
-
|
248
|
-
@reporter.error_summary
|
249
|
-
|
250
|
-
@error.string.must_include 'Error summary'
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
describe '#run_summary' do
|
255
|
-
it 'prints a run summary' do
|
256
|
-
@reporter.run_summary
|
257
|
-
|
258
|
-
@out.string.must_include 'Steps Summary:'
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
describe '#report_error_steps' do
|
263
|
-
describe 'when some steps have raised an error' do
|
264
|
-
it 'outputs the errors' do
|
265
|
-
steps = [anything]
|
266
|
-
@reporter.stubs(:error_steps).returns(steps)
|
267
|
-
@reporter.expects(:report_errors).with('Errors', steps, :light_red)
|
268
|
-
|
269
|
-
@reporter.report_error_steps
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
describe 'when there are no error steps' do
|
274
|
-
it 'does nothing' do
|
275
|
-
@reporter.expects(:report_errors).never
|
276
|
-
|
277
|
-
@reporter.report_error_steps
|
278
|
-
end
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
describe '#report_failed_steps' do
|
283
|
-
describe 'when some steps have failed' do
|
284
|
-
it 'outputs the failing steps' do
|
285
|
-
steps = [anything]
|
286
|
-
@reporter.stubs(:failed_steps).returns(steps)
|
287
|
-
@reporter.expects(:report_errors).with('Failures', steps, :light_red)
|
288
|
-
|
289
|
-
@reporter.report_failed_steps
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
describe 'when there are no failed steps' do
|
294
|
-
it 'does nothing' do
|
295
|
-
@reporter.expects(:report_errors).never
|
296
|
-
|
297
|
-
@reporter.report_failed_steps
|
298
|
-
end
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
describe '#report_undefined_steps' do
|
303
|
-
describe 'when some steps have undefined' do
|
304
|
-
it 'outputs the failing steps' do
|
305
|
-
steps = [anything]
|
306
|
-
@reporter.stubs(:undefined_steps).returns(steps)
|
307
|
-
@reporter.expects(:report_errors).with('Undefined steps', steps, :yellow)
|
308
|
-
|
309
|
-
@reporter.report_undefined_steps
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
describe 'when there are no undefined steps' do
|
314
|
-
it 'does nothing' do
|
315
|
-
@reporter.expects(:report_errors).never
|
316
|
-
|
317
|
-
@reporter.report_undefined_steps
|
318
|
-
end
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
describe '#report_undefined_features' do
|
323
|
-
describe 'when some features are undefined' do
|
324
|
-
it 'outputs the undefined features' do
|
325
|
-
@reporter.undefined_features << {'name' => 'Undefined feature name'}
|
326
|
-
@reporter.report_undefined_features
|
327
|
-
|
328
|
-
@error.string.must_include "Undefined features (1)"
|
329
|
-
@error.string.must_include "Undefined feature name"
|
330
|
-
end
|
331
|
-
end
|
332
|
-
|
333
|
-
describe 'when there are no undefined features' do
|
334
|
-
it 'does nothing' do
|
335
|
-
error = @error.string.dup
|
336
|
-
@reporter.report_undefined_steps
|
337
|
-
|
338
|
-
error.must_equal @error.string
|
339
|
-
end
|
340
|
-
end
|
341
|
-
end
|
342
|
-
|
343
|
-
describe '#report_errors' do
|
344
|
-
describe 'when some steps have raised an error' do
|
345
|
-
it 'outputs a the banner with the number of steps given' do
|
346
|
-
@reporter.report_errors('Banner', steps, :blue)
|
347
|
-
|
348
|
-
@error.string.must_include 'Banner (1)'
|
349
|
-
end
|
350
|
-
|
351
|
-
it 'prints a summarized error' do
|
352
|
-
@reporter.report_errors('Banner', steps, :blue)
|
353
|
-
|
354
|
-
@error.string.must_include 'My feature :: A scenario :: Keyword step name'
|
355
|
-
end
|
356
|
-
|
357
|
-
it 'colorizes the output' do
|
358
|
-
String.any_instance.expects(:colorize).with(:blue).at_least_once
|
359
|
-
|
360
|
-
@reporter.report_errors('Banner', [], :blue)
|
361
|
-
end
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
|
-
describe '#report_error' do
|
366
|
-
it 'raises when given an unsupported format' do
|
367
|
-
proc {
|
368
|
-
@reporter.report_error(error, :nil)
|
369
|
-
}.must_raise RuntimeError, 'Format not defined'
|
370
|
-
end
|
371
|
-
|
372
|
-
it 'prints a summarized error by default' do
|
373
|
-
@reporter.expects(:summarized_error).with(error).returns('summarized error')
|
374
|
-
|
375
|
-
@reporter.report_error(error)
|
376
|
-
|
377
|
-
@error.string.must_include 'summarized error'
|
378
|
-
end
|
379
|
-
|
380
|
-
it 'prints a summarized error' do
|
381
|
-
@reporter.expects(:summarized_error).with(error).returns('summarized error')
|
382
|
-
|
383
|
-
@reporter.report_error(error, :summarized)
|
384
|
-
|
385
|
-
@error.string.must_include 'summarized error'
|
386
|
-
end
|
387
|
-
|
388
|
-
it 'prints a full error' do
|
389
|
-
@reporter.expects(:full_error).with(error).returns('full error')
|
390
|
-
|
391
|
-
@reporter.report_error(error, :full)
|
392
|
-
|
393
|
-
@error.string.must_include 'full error'
|
394
|
-
end
|
395
|
-
end
|
396
|
-
|
397
|
-
describe '#summarized_error' do
|
398
|
-
it 'prints the error' do
|
399
|
-
summary = @reporter.summarized_error(error)
|
400
|
-
|
401
|
-
summary.must_include 'My feature :: A scenario :: Keyword step name'
|
402
|
-
end
|
403
|
-
|
404
|
-
it 'colorizes the print' do
|
405
|
-
String.any_instance.expects(:red)
|
406
|
-
|
407
|
-
@reporter.summarized_error(error)
|
408
|
-
end
|
409
|
-
|
410
|
-
describe 'when given an undefined step exception' do
|
411
|
-
it 'prints the error in yellow' do
|
412
|
-
undefined_error = error
|
413
|
-
undefined_error.insert(3, Spinach::StepNotDefinedException.new(anything))
|
414
|
-
|
415
|
-
String.any_instance.expects(:yellow)
|
416
|
-
|
417
|
-
@reporter.summarized_error(error)
|
418
|
-
end
|
419
|
-
end
|
420
|
-
end
|
421
|
-
|
422
|
-
describe '#full_error' do
|
423
|
-
before do
|
424
|
-
@reporter.expects(:report_exception).with(exception).returns('Exception backtrace')
|
425
|
-
end
|
426
|
-
|
427
|
-
it 'returns the exception data' do
|
428
|
-
exception.expects(:backtrace).returns(['first backtrace line'])
|
429
|
-
output = @reporter.full_error(error)
|
430
|
-
|
431
|
-
output.must_include 'Exception backtrace'
|
432
|
-
end
|
433
|
-
|
434
|
-
it 'returns the first backtrace line' do
|
435
|
-
exception.expects(:backtrace).returns(['first backtrace line'])
|
436
|
-
output = @reporter.full_error(error)
|
437
|
-
|
438
|
-
output.must_include 'first backtrace line'
|
439
|
-
end
|
440
|
-
|
441
|
-
describe 'when the user wants to print the full backtrace' do
|
442
|
-
it 'prints the full backtrace' do
|
443
|
-
@reporter.stubs(:options).returns({backtrace: true})
|
444
|
-
exception.expects(:backtrace).returns(['first backtrace line', 'second backtrace line'])
|
445
|
-
|
446
|
-
output = @reporter.full_error(error)
|
447
|
-
|
448
|
-
output.must_include 'first backtrace line'
|
449
|
-
output.must_include 'second backtrace line'
|
450
|
-
end
|
451
|
-
end
|
452
|
-
end
|
453
|
-
|
454
241
|
describe '#full_step' do
|
455
242
|
it 'returns the step with keyword and name' do
|
456
243
|
@reporter.full_step({'keyword' => 'Keyword', 'name' => 'step name'}).must_equal 'Keyword step name'
|
@@ -460,28 +247,4 @@ describe Spinach::Reporter::Stdout do
|
|
460
247
|
@reporter.full_step({'keyword' => ' Keyword ', 'name' => ' step name '}).must_equal 'Keyword step name'
|
461
248
|
end
|
462
249
|
end
|
463
|
-
|
464
|
-
describe '#report_exception' do
|
465
|
-
it 'returns the exception data' do
|
466
|
-
output = @reporter.report_exception(exception)
|
467
|
-
|
468
|
-
output.must_include 'Something went wrong'
|
469
|
-
end
|
470
|
-
|
471
|
-
it 'colorizes the print' do
|
472
|
-
String.any_instance.expects(:red)
|
473
|
-
|
474
|
-
@reporter.report_exception(exception)
|
475
|
-
end
|
476
|
-
|
477
|
-
describe 'when given an undefined step exception' do
|
478
|
-
it 'prints the error in yellow' do
|
479
|
-
undefined_exception = Spinach::StepNotDefinedException.new(anything)
|
480
|
-
|
481
|
-
String.any_instance.expects(:yellow)
|
482
|
-
|
483
|
-
@reporter.report_exception(undefined_exception)
|
484
|
-
end
|
485
|
-
end
|
486
|
-
end
|
487
250
|
end
|
@@ -10,11 +10,6 @@ module Spinach
|
|
10
10
|
@reporter = Reporter.new(@options)
|
11
11
|
end
|
12
12
|
|
13
|
-
describe "#initialize" do
|
14
|
-
it "initializes the option hash" do
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
13
|
describe "#options" do
|
19
14
|
it "returns the options passed to the reporter" do
|
20
15
|
@reporter.options[:backtrace].must_equal true
|
@@ -52,124 +47,84 @@ module Spinach
|
|
52
47
|
@reporter.stubs(:method)
|
53
48
|
end
|
54
49
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
it "binds a callback before running every feature" do
|
62
|
-
@reporter.expects(:method).with(:before_feature_run).returns(@callback)
|
63
|
-
@reporter.feature_runner.expects(:before_run).with(@callback)
|
64
|
-
@reporter.bind
|
65
|
-
end
|
66
|
-
|
67
|
-
it "binds a callback after running every feature" do
|
68
|
-
@reporter.expects(:method).with(:after_feature_run).returns(@callback)
|
69
|
-
@reporter.feature_runner.expects(:after_run).with(@callback)
|
70
|
-
@reporter.bind
|
71
|
-
end
|
72
|
-
|
73
|
-
it "binds a callback for not defined features" do
|
74
|
-
@reporter.expects(:method).with(:on_feature_not_found).returns(@callback)
|
75
|
-
@reporter.feature_runner.expects(:when_not_found).with(@callback)
|
76
|
-
@reporter.bind
|
77
|
-
end
|
78
|
-
|
79
|
-
it "binds a callback before running every scenario" do
|
80
|
-
@reporter.expects(:method).with(:before_scenario_run).returns(@callback)
|
81
|
-
@reporter.scenario_runner.expects(:before_run).with(@callback)
|
82
|
-
@reporter.bind
|
83
|
-
end
|
50
|
+
describe "bindings" do
|
51
|
+
before do
|
52
|
+
@reporter.bind
|
53
|
+
end
|
84
54
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
@reporter.bind
|
89
|
-
end
|
55
|
+
after do
|
56
|
+
Spinach.hooks.reset
|
57
|
+
end
|
90
58
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
@reporter.expects(:method).with(:"on_#{type}_step").returns(@callback)
|
95
|
-
@reporter.scenario_runner.expects(:"on_#{type}_step").with(@callback)
|
96
|
-
@reporter.bind
|
97
|
-
end
|
59
|
+
it "binds a callback after running" do
|
60
|
+
@reporter.expects(:after_run)
|
61
|
+
Spinach.hooks.run_after_run
|
98
62
|
end
|
99
|
-
end
|
100
63
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
@reporter.feature_runner.expects(:before_run).with(@callback)
|
105
|
-
@reporter.bind
|
64
|
+
it "binds a callback before running every feature" do
|
65
|
+
@reporter.expects(:before_feature_run)
|
66
|
+
Spinach.hooks.run_before_feature(anything)
|
106
67
|
end
|
107
68
|
|
108
|
-
it "binds
|
109
|
-
@reporter.expects(:
|
110
|
-
|
111
|
-
@reporter.bind
|
69
|
+
it "binds a callback after running every feature" do
|
70
|
+
@reporter.expects(:after_feature_run)
|
71
|
+
Spinach.hooks.run_after_feature
|
112
72
|
end
|
113
73
|
|
114
|
-
it "binds
|
115
|
-
@reporter.expects(:
|
116
|
-
|
117
|
-
@reporter.bind
|
74
|
+
it "binds a callback when a feature is not found" do
|
75
|
+
@reporter.expects(:on_feature_not_found)
|
76
|
+
Spinach.hooks.run_on_undefined_feature
|
118
77
|
end
|
119
78
|
|
120
|
-
it "binds
|
121
|
-
@reporter.expects(:
|
122
|
-
|
123
|
-
@reporter.bind
|
79
|
+
it "binds a callback before every scenario" do
|
80
|
+
@reporter.expects(:before_scenario_run)
|
81
|
+
Spinach.hooks.run_before_scenario(anything)
|
124
82
|
end
|
125
|
-
end
|
126
|
-
end
|
127
83
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
@reporter.current_feature.must_equal nil
|
133
|
-
end
|
134
|
-
end
|
84
|
+
it "binds a callback after every scenario" do
|
85
|
+
@reporter.expects(:after_scenario_run)
|
86
|
+
Spinach.hooks.run_after_scenario
|
87
|
+
end
|
135
88
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
@reporter.current_scenario.must_equal nil
|
141
|
-
end
|
142
|
-
end
|
89
|
+
it "binds a callback after every successful step" do
|
90
|
+
@reporter.expects(:on_successful_step)
|
91
|
+
Spinach.hooks.run_on_successful_step
|
92
|
+
end
|
143
93
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
@reporter.feature_runner.must_be_kind_of Class
|
94
|
+
it "binds a callback after every failed step" do
|
95
|
+
@reporter.expects(:on_failed_step)
|
96
|
+
Spinach.hooks.run_on_failed_step
|
148
97
|
end
|
149
|
-
end
|
150
98
|
|
151
|
-
|
152
|
-
|
153
|
-
|
99
|
+
it "binds a callback after every error step" do
|
100
|
+
@reporter.expects(:on_error_step)
|
101
|
+
Spinach.hooks.run_on_error_step
|
154
102
|
end
|
155
|
-
end
|
156
103
|
|
157
|
-
|
158
|
-
|
159
|
-
|
104
|
+
it "binds a callback after every skipped step" do
|
105
|
+
@reporter.expects(:on_skipped_step)
|
106
|
+
Spinach.hooks.run_on_skipped_step
|
160
107
|
end
|
161
|
-
end
|
162
|
-
end
|
163
108
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
109
|
+
describe "internals" do
|
110
|
+
it "binds a callback before running" do
|
111
|
+
@reporter.expects(:set_current_feature)
|
112
|
+
Spinach.hooks.run_before_feature({})
|
113
|
+
end
|
114
|
+
|
115
|
+
it "binds a callback after running" do
|
116
|
+
@reporter.expects(:clear_current_feature)
|
117
|
+
Spinach.hooks.run_after_feature
|
118
|
+
end
|
119
|
+
|
120
|
+
it "binds a callback before every scenario" do
|
121
|
+
@reporter.expects(:set_current_scenario)
|
122
|
+
Spinach.hooks.run_before_scenario
|
123
|
+
end
|
124
|
+
|
125
|
+
it "binds a callback after every scenario" do
|
126
|
+
@reporter.expects(:clear_current_scenario)
|
127
|
+
Spinach.hooks.run_after_scenario
|
173
128
|
end
|
174
129
|
end
|
175
130
|
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
require_relative '../../test_helper'
|
2
2
|
|
3
|
-
describe Spinach::Runner::
|
3
|
+
describe Spinach::Runner::FeatureRunner do
|
4
4
|
let(:filename) { 'feature/a_cool_feature.feature' }
|
5
|
-
|
5
|
+
subject{ Spinach::Runner::FeatureRunner.new(filename) }
|
6
6
|
|
7
7
|
describe '#initialize' do
|
8
8
|
it 'initializes the given filename' do
|
9
|
-
|
9
|
+
subject.filename.must_equal filename
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'initalizes the given scenario line' do
|
13
13
|
@filename = 'feature/a_cool_feature.feature:12'
|
14
|
-
@feature = Spinach::Runner::
|
14
|
+
@feature = Spinach::Runner::FeatureRunner.new(@filename)
|
15
15
|
|
16
16
|
@feature.instance_variable_get(:@scenario_line).must_equal '12'
|
17
17
|
end
|
@@ -22,77 +22,75 @@ describe Spinach::Runner::Feature do
|
|
22
22
|
parsed_data = {name: 'A cool feature'}
|
23
23
|
parser = stub(parse: parsed_data)
|
24
24
|
Spinach::Parser.expects(:open_file).returns(parser)
|
25
|
-
|
25
|
+
subject.data.must_equal parsed_data
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
describe '#scenarios' do
|
30
30
|
it 'returns the parsed scenarios' do
|
31
|
-
|
32
|
-
|
31
|
+
subject.stubs(data: {'elements' => [1, 2, 3]})
|
32
|
+
subject.scenarios.must_equal [1,2,3]
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
describe '#run' do
|
37
37
|
before do
|
38
|
-
|
38
|
+
subject.stubs(data: {
|
39
39
|
'name' => 'A cool feature',
|
40
40
|
'elements' => [{'keyword'=>'Scenario', 'name'=>'Basic guess', 'line'=>6, 'description'=>'', 'type'=>'scenario'},
|
41
41
|
{'keyword'=>'Scenario', 'name'=>'Basic guess II', 'line'=>12, 'description'=>'', 'type'=>'scenario'},
|
42
42
|
{'keyword'=>'Scenario', 'name'=>'Basic guess III', 'line'=>18, 'description'=>'', 'type'=>'scenario'}]
|
43
43
|
})
|
44
|
-
|
44
|
+
subject.stubs(feature: stub_everything)
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'calls the steps as expected' do
|
48
48
|
seq = sequence('feature')
|
49
49
|
3.times do
|
50
|
-
Spinach::Runner::
|
50
|
+
Spinach::Runner::ScenarioRunner.
|
51
51
|
expects(:new).
|
52
52
|
returns(stub_everything).
|
53
53
|
in_sequence(seq)
|
54
54
|
end
|
55
|
-
|
55
|
+
subject.run
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'returns true if the execution succeeds' do
|
59
|
-
Spinach::Runner::
|
59
|
+
Spinach::Runner::ScenarioRunner.any_instance.
|
60
60
|
expects(run: true).times(3)
|
61
|
-
|
61
|
+
subject.run.must_equal true
|
62
62
|
end
|
63
63
|
|
64
64
|
it 'returns false if the execution fails' do
|
65
|
-
Spinach::Runner::
|
65
|
+
Spinach::Runner::ScenarioRunner.any_instance.
|
66
66
|
expects(run: false).times(3)
|
67
|
-
|
67
|
+
subject.run.must_equal false
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'calls only the given scenario' do
|
71
71
|
@filename = 'feature/a_cool_feature.feature:12'
|
72
|
-
@feature = Spinach::Runner::
|
72
|
+
@feature = Spinach::Runner::FeatureRunner.new(@filename)
|
73
73
|
@feature.stubs(data: {
|
74
74
|
'name' => 'A cool feature',
|
75
75
|
'elements' => [{'keyword'=>'Scenario', 'name'=>'Basic guess', 'line'=>6, 'description'=>'', 'type'=>'scenario'},
|
76
76
|
{'keyword'=>'Scenario', 'name'=>'Basic guess II', 'line'=>12, 'description'=>'', 'type'=>'scenario'},
|
77
77
|
{'keyword'=>'Scenario', 'name'=>'Basic guess III', 'line'=>18, 'description'=>'', 'type'=>'scenario'}]
|
78
78
|
})
|
79
|
-
@feature.stubs(feature: stub_everything)
|
80
79
|
|
81
|
-
Spinach::Runner::
|
80
|
+
Spinach::Runner::ScenarioRunner.expects(:new).with(anything, @feature.scenarios[1], anything).once.returns(stub_everything)
|
82
81
|
@feature.run
|
83
82
|
end
|
84
83
|
|
85
84
|
it "fires a hook if the feature is not defined" do
|
86
|
-
feature = Spinach::Runner::Feature.new(filename)
|
87
85
|
data = mock
|
88
86
|
exception = Spinach::FeatureStepsNotFoundException.new([anything, anything])
|
89
|
-
|
90
|
-
|
87
|
+
subject.stubs(:scenarios).raises(exception)
|
88
|
+
subject.stubs(:data).returns(data)
|
91
89
|
not_found_called = false
|
92
|
-
|
90
|
+
Spinach.hooks.on_undefined_feature do |data, exception|
|
93
91
|
not_found_called = [data, exception]
|
94
92
|
end
|
95
|
-
|
93
|
+
subject.run
|
96
94
|
not_found_called.must_equal [data, exception]
|
97
95
|
end
|
98
96
|
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require_relative '../../test_helper'
|
2
|
+
|
3
|
+
describe Spinach::Runner::ScenarioRunner do
|
4
|
+
let(:data) do
|
5
|
+
{
|
6
|
+
'name' => 'A cool scenario',
|
7
|
+
'steps' => [
|
8
|
+
{'keyword' => 'Given', 'name' => 'I herd you like steps'},
|
9
|
+
{'keyword' => 'When', 'name' => 'I test steps'},
|
10
|
+
{'keyword' => 'Then', 'name' => 'I go step by step'}
|
11
|
+
]
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:feature_steps) { stub_everything }
|
16
|
+
let(:feature_name) { 'My feature' }
|
17
|
+
subject{
|
18
|
+
scenario = Spinach::Runner::ScenarioRunner.new(feature_name, data)
|
19
|
+
scenario.stubs(feature_steps: feature_steps)
|
20
|
+
scenario
|
21
|
+
}
|
22
|
+
|
23
|
+
describe '#initialize' do
|
24
|
+
it 'lists all the steps' do
|
25
|
+
subject.steps.count.must_equal 3
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'sets the feature' do
|
29
|
+
subject.feature_steps.must_equal feature_steps
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#feature' do
|
34
|
+
it 'finds the feature given a feature name' do
|
35
|
+
subject.unstub(:feature_steps)
|
36
|
+
@feature = stub_everything
|
37
|
+
subject.stubs(feature_name: 'A cool feature')
|
38
|
+
Spinach.expects(:find_feature_steps).with('A cool feature').returns(@feature)
|
39
|
+
subject.feature_steps
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#run' do
|
44
|
+
it 'calls the appropiate feature steps' do
|
45
|
+
feature_steps.expects(:execute_step).with('I herd you like steps')
|
46
|
+
feature_steps.expects(:execute_step).with('I test steps')
|
47
|
+
feature_steps.expects(:execute_step).with('I go step by step')
|
48
|
+
subject.run
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'when throwing exceptions' do
|
52
|
+
it 'rescues a MiniTest::Assertion' do
|
53
|
+
feature_steps.expects(:execute_step).raises(MiniTest::Assertion)
|
54
|
+
Spinach.hooks.expects("run_before_scenario").with(has_value("A cool scenario"))
|
55
|
+
Spinach.hooks.expects("run_after_scenario").with(has_value("A cool scenario"))
|
56
|
+
Spinach.hooks.expects('run_on_failed_step').with(anything, anything, anything)
|
57
|
+
Spinach.hooks.expects('run_on_skipped_step').with(anything, anything).twice
|
58
|
+
subject.run
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'rescues a Spinach::StepNotDefinedException' do
|
62
|
+
feature_steps.expects(:execute_step).raises(
|
63
|
+
Spinach::StepNotDefinedException.new('bar'))
|
64
|
+
Spinach.hooks.expects("run_before_scenario").with(has_value("A cool scenario"))
|
65
|
+
Spinach.hooks.expects("run_after_scenario").with(has_value("A cool scenario"))
|
66
|
+
Spinach.hooks.expects("run_on_undefined_step").with(
|
67
|
+
anything, anything, anything)
|
68
|
+
Spinach.hooks.expects("run_on_skipped_step").with(
|
69
|
+
anything, anything).twice
|
70
|
+
subject.run
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'rescues any other error' do
|
74
|
+
feature_steps.expects(:execute_step).raises
|
75
|
+
Spinach.hooks.expects("run_after_scenario").with(has_value("A cool scenario"))
|
76
|
+
Spinach.hooks.expects("run_before_scenario").with(has_value("A cool scenario"))
|
77
|
+
Spinach.hooks.expects("run_on_error_step").with(anything, anything, anything)
|
78
|
+
Spinach.hooks.expects("run_on_skipped_step").with(anything, anything).twice
|
79
|
+
subject.run
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'returns an failure' do
|
83
|
+
feature_steps.expects(:execute_step).raises(MiniTest::Assertion)
|
84
|
+
subject.run.wont_equal nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'runs a step' do
|
89
|
+
feature_steps.expects(:execute_step).with(anything).times(3)
|
90
|
+
subject.run.must_equal true
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'hooks' do
|
94
|
+
it 'fires up the scenario hooks' do
|
95
|
+
feature_steps.expects(:execute_step).raises(Spinach::StepNotDefinedException.new('bar'))
|
96
|
+
Spinach.hooks.expects(:run_before_scenario).with(has_value("A cool scenario"))
|
97
|
+
Spinach.hooks.expects(:run_after_scenario).with(has_value("A cool scenario"))
|
98
|
+
subject.run
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'fires up the step hooks' do
|
102
|
+
feature_steps.expects(:execute_step).raises(Spinach::StepNotDefinedException.new('bar'))
|
103
|
+
%w{before_step after_step}.each do |hook|
|
104
|
+
Spinach.hooks.expects("run_#{hook}").with(kind_of(Hash)).times(3)
|
105
|
+
end
|
106
|
+
|
107
|
+
subject.run
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|