spinach 0.1.5.4 → 0.2.0.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.
- data/Gemfile +2 -0
- data/README.markdown +18 -12
- data/features/background.feature +13 -0
- data/features/reporting/show_step_source_location.feature +11 -1
- data/features/steps/automatic_feature_generation.rb +7 -7
- data/features/steps/background.rb +30 -0
- data/features/steps/exit_status.rb +12 -13
- data/features/steps/feature_name_guessing.rb +7 -7
- data/features/steps/reporting/display_run_summary.rb +22 -22
- data/features/steps/reporting/error_reporting.rb +7 -7
- data/features/steps/reporting/show_step_source_location.rb +63 -14
- data/features/steps/reporting/undefined_feature_reporting.rb +7 -7
- data/features/steps/rspec_compatibility.rb +14 -14
- data/features/support/error_reporting.rb +5 -5
- data/features/support/filesystem.rb +71 -0
- data/features/support/spinach_runner.rb +5 -6
- data/lib/spinach.rb +11 -6
- data/lib/spinach/background.rb +11 -0
- data/lib/spinach/capybara.rb +7 -1
- data/lib/spinach/cli.rb +36 -13
- data/lib/spinach/config.rb +40 -6
- data/lib/spinach/dsl.rb +14 -11
- data/lib/spinach/exceptions.rb +1 -1
- data/lib/spinach/feature.rb +16 -0
- data/lib/spinach/frameworks.rb +2 -0
- data/lib/spinach/{suites → frameworks}/minitest.rb +0 -0
- data/lib/spinach/{suites → frameworks}/rspec.rb +0 -0
- data/lib/spinach/generators/feature_generator.rb +12 -23
- data/lib/spinach/generators/step_generator.rb +5 -5
- data/lib/spinach/hookable.rb +6 -4
- data/lib/spinach/hooks.rb +12 -4
- data/lib/spinach/parser.rb +6 -8
- data/lib/spinach/parser/visitor.rb +109 -0
- data/lib/spinach/reporter.rb +10 -6
- data/lib/spinach/reporter/stdout.rb +41 -16
- data/lib/spinach/reporter/stdout/error_reporting.rb +2 -2
- data/lib/spinach/runner.rb +9 -6
- data/lib/spinach/runner/feature_runner.rb +40 -34
- data/lib/spinach/runner/scenario_runner.rb +63 -36
- data/lib/spinach/scenario.rb +12 -0
- data/lib/spinach/step.rb +10 -0
- data/lib/spinach/version.rb +1 -1
- data/spinach.gemspec +3 -3
- data/test/spinach/background_test.rb +6 -0
- data/test/spinach/capybara_test.rb +30 -13
- data/test/spinach/cli_test.rb +46 -1
- data/test/spinach/config_test.rb +39 -0
- data/test/spinach/dsl_test.rb +12 -10
- data/test/spinach/feature_steps_test.rb +3 -3
- data/test/spinach/feature_test.rb +6 -0
- data/test/spinach/{suites → frameworks}/minitest_test.rb +2 -2
- data/test/spinach/generators/feature_generator_test.rb +18 -58
- data/test/spinach/generators/step_generator_test.rb +3 -3
- data/test/spinach/generators_test.rb +12 -10
- data/test/spinach/hookable_test.rb +8 -0
- data/test/spinach/hooks_test.rb +6 -7
- data/test/spinach/parser/visitor_test.rb +173 -0
- data/test/spinach/parser_test.rb +14 -27
- data/test/spinach/reporter/stdout/error_reporting_test.rb +9 -9
- data/test/spinach/reporter/stdout_test.rb +15 -19
- data/test/spinach/reporter_test.rb +15 -0
- data/test/spinach/runner/feature_runner_test.rb +79 -69
- data/test/spinach/runner/scenario_runner_test.rb +118 -92
- data/test/spinach/runner_test.rb +10 -6
- data/test/spinach/scenario_test.rb +6 -0
- data/test/spinach/step_test.rb +6 -0
- data/test/spinach_test.rb +7 -7
- metadata +60 -39
- data/lib/spinach/suites.rb +0 -2
data/test/spinach/parser_test.rb
CHANGED
@@ -2,38 +2,25 @@ require_relative '../test_helper'
|
|
2
2
|
|
3
3
|
describe Spinach::Parser do
|
4
4
|
before do
|
5
|
-
@
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
@contents = """
|
6
|
+
Feature: User authentication
|
7
|
+
|
8
|
+
Scenario: User logs in
|
9
|
+
Given I am on the front page
|
10
|
+
When I fill in the login form and press 'login'
|
11
|
+
Then I should be on my dashboard
|
12
|
+
"""
|
13
|
+
@parser = Spinach::Parser.new(@contents)
|
12
14
|
end
|
13
15
|
|
14
16
|
let(:parsed) { @parser.parse }
|
15
17
|
|
16
18
|
describe '#parse' do
|
17
|
-
it 'parses the
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
before do
|
23
|
-
@scenario = parsed['elements'][0]
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'parses the scenario name' do
|
27
|
-
@scenario['name'].must_equal 'User logs in'
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'parses the scenario steps' do
|
31
|
-
@scenario['steps'][0]['name'].must_equal 'I am on the front page'
|
32
|
-
@scenario['steps'][1]['name'].must_equal(
|
33
|
-
'I fill in the login form and press \'login\''
|
34
|
-
)
|
35
|
-
@scenario['steps'][2]['name'].must_equal 'I should be on my dashboard'
|
36
|
-
end
|
19
|
+
it 'parses the file' do
|
20
|
+
Gherkin.expects(:parse).with(@contents.strip).returns ast = stub
|
21
|
+
Spinach::Parser::Visitor.stubs(:new).returns visitor = stub
|
22
|
+
visitor.expects(:visit).with ast
|
23
|
+
@parser.parse
|
37
24
|
end
|
38
25
|
end
|
39
26
|
|
@@ -6,9 +6,9 @@ describe Spinach::Reporter::Stdout do
|
|
6
6
|
let(:exception) { StandardError.new('Something went wrong') }
|
7
7
|
|
8
8
|
let(:error) do
|
9
|
-
[
|
10
|
-
|
11
|
-
|
9
|
+
[stub(name: 'My feature'),
|
10
|
+
stub(name: 'A scenario'),
|
11
|
+
stub(keyword: 'Keyword', name: 'step name'),
|
12
12
|
exception]
|
13
13
|
end
|
14
14
|
|
@@ -110,7 +110,7 @@ describe Spinach::Reporter::Stdout do
|
|
110
110
|
describe '#report_undefined_features' do
|
111
111
|
describe 'when some features are undefined' do
|
112
112
|
it 'outputs the undefined features' do
|
113
|
-
@reporter.undefined_features <<
|
113
|
+
@reporter.undefined_features << stub(name: 'Undefined feature name')
|
114
114
|
@reporter.report_undefined_features
|
115
115
|
|
116
116
|
@error.string.must_include "Undefined features (1)"
|
@@ -242,10 +242,10 @@ describe Spinach::Reporter::Stdout do
|
|
242
242
|
|
243
243
|
describe "when it's a step not defined exception" do
|
244
244
|
it "returns a suggestion" do
|
245
|
-
@exception = Spinach::StepNotDefinedException.new("foo")
|
246
|
-
@error = [
|
247
|
-
|
248
|
-
|
245
|
+
@exception = Spinach::StepNotDefinedException.new(stub(name: "foo"))
|
246
|
+
@error = [stub(name: 'My feature'),
|
247
|
+
stub(name: 'A scenario'),
|
248
|
+
stub(keyword: 'Given', name: 'foo'),
|
249
249
|
@exception]
|
250
250
|
output = @reporter.full_error(@error)
|
251
251
|
output.must_include "Given"
|
@@ -269,7 +269,7 @@ describe Spinach::Reporter::Stdout do
|
|
269
269
|
|
270
270
|
describe 'when given an undefined step exception' do
|
271
271
|
it 'prints the error in yellow' do
|
272
|
-
undefined_exception = Spinach::StepNotDefinedException.new(
|
272
|
+
undefined_exception = Spinach::StepNotDefinedException.new(stub(name: 'some step'))
|
273
273
|
|
274
274
|
String.any_instance.expects(:yellow)
|
275
275
|
|
@@ -6,9 +6,9 @@ describe Spinach::Reporter::Stdout do
|
|
6
6
|
let(:exception) { StandardError.new('Something went wrong') }
|
7
7
|
|
8
8
|
let(:error) do
|
9
|
-
[
|
10
|
-
|
11
|
-
|
9
|
+
[stub(name: 'My feature'),
|
10
|
+
stub(name: 'A scenario'),
|
11
|
+
stub(keyword: 'Keyword', name: 'step name'),
|
12
12
|
exception]
|
13
13
|
end
|
14
14
|
|
@@ -28,7 +28,8 @@ describe Spinach::Reporter::Stdout do
|
|
28
28
|
|
29
29
|
describe '#before_feature_run' do
|
30
30
|
it 'outputs the feature' do
|
31
|
-
|
31
|
+
feature = stub_everything(name: 'A cool feature')
|
32
|
+
@reporter.before_feature_run(feature)
|
32
33
|
|
33
34
|
@out.string.must_include 'Feature'
|
34
35
|
@out.string.must_include 'A cool feature'
|
@@ -37,7 +38,8 @@ describe Spinach::Reporter::Stdout do
|
|
37
38
|
|
38
39
|
describe '#before_scenario_run' do
|
39
40
|
it 'outputs the scenario' do
|
40
|
-
|
41
|
+
scenario = stub_everything(name: 'Arbitrary scenario', steps: [])
|
42
|
+
@reporter.before_scenario_run(scenario)
|
41
43
|
|
42
44
|
@out.string.must_include 'Scenario'
|
43
45
|
@out.string.must_include 'Arbitrary scenario'
|
@@ -68,7 +70,7 @@ describe Spinach::Reporter::Stdout do
|
|
68
70
|
end
|
69
71
|
|
70
72
|
describe '#on_successful_step' do
|
71
|
-
let(:step) {
|
73
|
+
let(:step) { stub(keyword: 'Given', name: 'I am too cool') }
|
72
74
|
let(:step_location){['error_step_location', 1]}
|
73
75
|
it 'adds the step to the output buffer' do
|
74
76
|
@reporter.on_successful_step(step, step_location)
|
@@ -92,7 +94,7 @@ describe Spinach::Reporter::Stdout do
|
|
92
94
|
end
|
93
95
|
|
94
96
|
describe '#on_failed_step' do
|
95
|
-
let(:step) {
|
97
|
+
let(:step) { stub(keyword: 'Then', name: 'I write failing steps') }
|
96
98
|
let(:step_location){['error_step_location', 1]}
|
97
99
|
|
98
100
|
it 'adds the step to the output buffer' do
|
@@ -117,7 +119,7 @@ describe Spinach::Reporter::Stdout do
|
|
117
119
|
end
|
118
120
|
|
119
121
|
describe '#on_error_step' do
|
120
|
-
let(:step) {
|
122
|
+
let(:step) { stub(keyword: 'And', name: 'I even make syntax errors') }
|
121
123
|
let(:step_location){['error_step_location', 1]}
|
122
124
|
|
123
125
|
it 'adds the step to the output buffer' do
|
@@ -142,7 +144,7 @@ describe Spinach::Reporter::Stdout do
|
|
142
144
|
end
|
143
145
|
|
144
146
|
describe '#on_undefined_step' do
|
145
|
-
let(:step) {
|
147
|
+
let(:step) { stub(keyword: 'When', name: 'I forgot to write steps') }
|
146
148
|
|
147
149
|
it 'adds the step to the output buffer' do
|
148
150
|
@reporter.on_undefined_step(step, anything)
|
@@ -167,9 +169,7 @@ describe Spinach::Reporter::Stdout do
|
|
167
169
|
|
168
170
|
describe "#on_feature_not_found" do
|
169
171
|
before do
|
170
|
-
@feature =
|
171
|
-
'name' => 'This feature does not exist'
|
172
|
-
}
|
172
|
+
@feature = stub(name: 'This feature does not exist', scenarios: [], background_steps: [])
|
173
173
|
Spinach.config.stubs(:step_definitions_path).returns('my/path')
|
174
174
|
@reporter.on_feature_not_found(@feature)
|
175
175
|
end
|
@@ -195,7 +195,7 @@ describe Spinach::Reporter::Stdout do
|
|
195
195
|
|
196
196
|
describe '#on_skipped_step' do
|
197
197
|
it 'adds the step to the output buffer' do
|
198
|
-
@reporter.on_skipped_step(
|
198
|
+
@reporter.on_skipped_step(stub(keyword: 'Then', name: 'some steps are not even called'))
|
199
199
|
|
200
200
|
@out.string.must_include '~'
|
201
201
|
@out.string.must_include 'Then'
|
@@ -205,7 +205,7 @@ describe Spinach::Reporter::Stdout do
|
|
205
205
|
|
206
206
|
describe '#output_step' do
|
207
207
|
it 'adds a step to the output buffer with nice colors' do
|
208
|
-
step =
|
208
|
+
step = stub(keyword: 'Keyword', name: 'step name')
|
209
209
|
@reporter.output_step('symbol', step, :blue)
|
210
210
|
|
211
211
|
@out.string.must_include 'symbol'
|
@@ -236,11 +236,7 @@ describe Spinach::Reporter::Stdout do
|
|
236
236
|
|
237
237
|
describe '#full_step' do
|
238
238
|
it 'returns the step with keyword and name' do
|
239
|
-
@reporter.full_step(
|
240
|
-
end
|
241
|
-
|
242
|
-
it 'strips the arguments' do
|
243
|
-
@reporter.full_step({'keyword' => ' Keyword ', 'name' => ' step name '}).must_equal 'Keyword step name'
|
239
|
+
@reporter.full_step(stub(keyword: 'Keyword', name: 'step name')).must_equal 'Keyword step name'
|
244
240
|
end
|
245
241
|
end
|
246
242
|
end
|
@@ -81,6 +81,21 @@ module Spinach
|
|
81
81
|
Spinach.hooks.run_before_scenario(anything)
|
82
82
|
end
|
83
83
|
|
84
|
+
it "binds a callback around every scenario" do
|
85
|
+
@reporter.expects(:around_scenario_run)
|
86
|
+
Spinach.hooks.run_around_scenario(anything) do
|
87
|
+
yield
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it "yields to around scenario callback" do
|
92
|
+
called = false
|
93
|
+
@reporter.around_scenario_run do
|
94
|
+
called = true
|
95
|
+
end
|
96
|
+
called.must_equal true
|
97
|
+
end
|
98
|
+
|
84
99
|
it "binds a callback after every scenario" do
|
85
100
|
@reporter.expects(:after_scenario_run)
|
86
101
|
Spinach.hooks.run_after_scenario
|
@@ -1,100 +1,110 @@
|
|
1
1
|
require_relative '../../test_helper'
|
2
2
|
|
3
3
|
describe Spinach::Runner::FeatureRunner do
|
4
|
-
let(:
|
5
|
-
subject{ Spinach::Runner::FeatureRunner.new(
|
4
|
+
let(:feature) { stub('feature', name: 'Feature') }
|
5
|
+
subject{ Spinach::Runner::FeatureRunner.new(feature) }
|
6
6
|
|
7
7
|
describe '#initialize' do
|
8
8
|
it 'initializes the given filename' do
|
9
|
-
subject.
|
9
|
+
subject.feature.must_equal feature
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'initalizes the given scenario line' do
|
13
|
-
@
|
14
|
-
@
|
15
|
-
|
16
|
-
@feature.instance_variable_get(:@scenario_line).must_equal '12'
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe '#data' do
|
21
|
-
it 'returns the parsed data' do
|
22
|
-
parsed_data = {name: 'A cool feature'}
|
23
|
-
parser = stub(parse: parsed_data)
|
24
|
-
Spinach::Parser.expects(:open_file).returns(parser)
|
25
|
-
subject.data.must_equal parsed_data
|
13
|
+
@runner = Spinach::Runner::FeatureRunner.new(feature, '34')
|
14
|
+
@runner.instance_variable_get(:@line).must_equal 34
|
26
15
|
end
|
27
16
|
end
|
28
17
|
|
29
18
|
describe '#scenarios' do
|
30
|
-
it '
|
31
|
-
subject.stubs(
|
19
|
+
it 'delegates to the feature' do
|
20
|
+
subject.feature.stubs(scenarios: [1,2,3])
|
32
21
|
subject.scenarios.must_equal [1,2,3]
|
33
22
|
end
|
34
23
|
end
|
35
24
|
|
36
25
|
describe '#run' do
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
{'keyword'=>'Scenario', 'name'=>'Basic guess III', 'line'=>18, 'description'=>'', 'type'=>'scenario'}]
|
43
|
-
})
|
44
|
-
subject.stubs(feature: stub_everything)
|
45
|
-
end
|
26
|
+
it 'runs the hooks in order' do
|
27
|
+
hooks = sequence('hooks')
|
28
|
+
Spinach.hooks.expects(:run_before_feature).with(feature).in_sequence(hooks)
|
29
|
+
Spinach.expects(:find_step_definitions).returns(false).in_sequence(hooks)
|
30
|
+
Spinach.hooks.expects(:run_after_feature).with(feature).in_sequence(hooks)
|
46
31
|
|
47
|
-
it 'calls the steps as expected' do
|
48
|
-
Spinach.expects(:find_feature_steps).returns(true)
|
49
|
-
seq = sequence('feature')
|
50
|
-
3.times do
|
51
|
-
Spinach::Runner::ScenarioRunner.
|
52
|
-
expects(:new).
|
53
|
-
returns(stub_everything).
|
54
|
-
in_sequence(seq)
|
55
|
-
end
|
56
32
|
subject.run
|
57
33
|
end
|
58
34
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
35
|
+
describe 'when the steps exist' do
|
36
|
+
before do
|
37
|
+
@feature = stub('feature', name: 'Feature')
|
38
|
+
Spinach.stubs(:find_step_definitions).returns(true)
|
39
|
+
@scenarios = [
|
40
|
+
scenario = stub,
|
41
|
+
another_scenario = stub
|
42
|
+
]
|
43
|
+
@feature.stubs(:scenarios).returns @scenarios
|
44
|
+
@runner = Spinach::Runner::FeatureRunner.new(@feature)
|
45
|
+
end
|
65
46
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
47
|
+
describe 'and the scenarios pass' do
|
48
|
+
it 'runs the scenarios and returns true' do
|
49
|
+
@scenarios.each do |scenario|
|
50
|
+
runner = stub(run: true)
|
51
|
+
Spinach::Runner::ScenarioRunner.expects(:new).with(scenario).returns runner
|
52
|
+
end
|
53
|
+
|
54
|
+
@runner.run.must_equal true
|
55
|
+
end
|
56
|
+
end
|
72
57
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
'elements' => [{'keyword'=>'Scenario', 'name'=>'Basic guess', 'line'=>6, 'description'=>'', 'type'=>'scenario'},
|
80
|
-
{'keyword'=>'Scenario', 'name'=>'Basic guess II', 'line'=>12, 'description'=>'', 'type'=>'scenario'},
|
81
|
-
{'keyword'=>'Scenario', 'name'=>'Basic guess III', 'line'=>18, 'description'=>'', 'type'=>'scenario'}]
|
82
|
-
})
|
58
|
+
describe 'and the scenarios fail' do
|
59
|
+
it 'runs the scenarios and returns false' do
|
60
|
+
@scenarios.each do |scenario|
|
61
|
+
runner = stub(run: false)
|
62
|
+
Spinach::Runner::ScenarioRunner.expects(:new).with(scenario).returns runner
|
63
|
+
end
|
83
64
|
|
84
|
-
|
85
|
-
|
65
|
+
@runner.run.must_equal false
|
66
|
+
end
|
67
|
+
end
|
86
68
|
end
|
87
69
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
70
|
+
describe "when the steps don't exist" do
|
71
|
+
it 'runs the corresponding hooks and returns false' do
|
72
|
+
Spinach.stubs(:find_step_definitions).returns(false)
|
73
|
+
Spinach.hooks.expects(:run_on_undefined_feature).with(feature)
|
74
|
+
subject.run.must_equal false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "when a line is given" do
|
79
|
+
before do
|
80
|
+
@feature = stub('feature', name: 'Feature')
|
81
|
+
Spinach.stubs(:find_step_definitions).returns(true)
|
82
|
+
@scenarios = [
|
83
|
+
scenario = stub(line: 4),
|
84
|
+
another_scenario = stub(line: 12)
|
85
|
+
]
|
86
|
+
@feature.stubs(:scenarios).returns @scenarios
|
87
|
+
end
|
88
|
+
it "runs exactly matching scenario" do
|
89
|
+
Spinach::Runner::ScenarioRunner.expects(:new).with(@scenarios[1]).returns stub(run: true)
|
90
|
+
@runner = Spinach::Runner::FeatureRunner.new(@feature, "12")
|
91
|
+
@runner.run
|
92
|
+
end
|
93
|
+
it "runs no scenario and returns false" do
|
94
|
+
Spinach::Runner::ScenarioRunner.expects(:new).never
|
95
|
+
@runner = Spinach::Runner::FeatureRunner.new(@feature, "3")
|
96
|
+
@runner.run
|
97
|
+
end
|
98
|
+
it "runs matching scenario" do
|
99
|
+
Spinach::Runner::ScenarioRunner.expects(:new).with(@scenarios[0]).returns stub(run: true)
|
100
|
+
@runner = Spinach::Runner::FeatureRunner.new(@feature, "8")
|
101
|
+
@runner.run
|
102
|
+
end
|
103
|
+
it "runs last scenario" do
|
104
|
+
Spinach::Runner::ScenarioRunner.expects(:new).with(@scenarios[1]).returns stub(run: true)
|
105
|
+
@runner = Spinach::Runner::FeatureRunner.new(@feature, "15")
|
106
|
+
@runner.run
|
95
107
|
end
|
96
|
-
subject.run
|
97
|
-
not_found_called.must_equal data
|
98
108
|
end
|
99
109
|
end
|
100
110
|
end
|
@@ -1,111 +1,137 @@
|
|
1
1
|
require_relative '../../test_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
3
|
+
module Spinach
|
4
|
+
class Runner
|
5
|
+
describe ScenarioRunner do
|
6
|
+
let(:feature) { stub(name: 'Feature', background_steps: []) }
|
7
|
+
let(:steps) { [stub(name: 'go shopping'), stub(name: 'do something')] }
|
8
|
+
let(:scenario) do
|
9
|
+
stub(
|
10
|
+
feature: feature,
|
11
|
+
steps: steps
|
12
|
+
)
|
13
|
+
end
|
32
14
|
|
33
|
-
|
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
|
15
|
+
subject { ScenarioRunner.new(scenario) }
|
42
16
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
feature_steps.expects(:execute_step).with('I go step by step')
|
48
|
-
subject.run
|
49
|
-
end
|
17
|
+
describe 'delegations' do
|
18
|
+
it 'delegates #feature to the scenario' do
|
19
|
+
subject.feature.must_equal feature
|
20
|
+
end
|
50
21
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
feature_steps.expects(:execute_step).raises(MiniTest::Assertion)
|
55
|
-
Spinach.hooks.expects("run_before_scenario").with(has_value("A cool scenario"))
|
56
|
-
Spinach.hooks.expects("run_after_scenario").with(has_value("A cool scenario"))
|
57
|
-
Spinach.hooks.expects('run_on_failed_step').with(anything, anything, anything)
|
58
|
-
Spinach.hooks.expects('run_on_skipped_step').with(anything, anything).twice
|
59
|
-
subject.run
|
22
|
+
it 'delegates #steps to the scenario' do
|
23
|
+
subject.steps.must_equal steps
|
24
|
+
end
|
60
25
|
end
|
61
26
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
anything, anything, anything)
|
69
|
-
Spinach.hooks.expects("run_on_skipped_step").with(
|
70
|
-
anything, anything).twice
|
71
|
-
subject.run
|
27
|
+
describe '#step_definitions' do
|
28
|
+
it 'looks up the step definitions' do
|
29
|
+
klass = Class.new
|
30
|
+
Spinach.expects(:find_step_definitions).with('Feature').returns klass
|
31
|
+
subject.step_definitions
|
32
|
+
end
|
72
33
|
end
|
73
34
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
Spinach.hooks.expects("run_on_skipped_step").with(anything, anything).twice
|
80
|
-
subject.run
|
81
|
-
end
|
35
|
+
describe '#run' do
|
36
|
+
describe 'hooks' do
|
37
|
+
it 'runs hooks in order' do
|
38
|
+
hooks = sequence('hooks')
|
39
|
+
subject.stubs(:step_definitions).returns step_definitions = stub
|
82
40
|
|
83
|
-
|
84
|
-
|
85
|
-
subject.run.wont_equal nil
|
86
|
-
end
|
87
|
-
end
|
41
|
+
Spinach.hooks.expects(:run_before_scenario).with(scenario).in_sequence(hooks)
|
42
|
+
Spinach.hooks.expects(:run_around_scenario).with(scenario).in_sequence(hooks).yields
|
88
43
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
44
|
+
Spinach.hooks.expects(:run_before_step).with(steps.first).in_sequence(hooks)
|
45
|
+
subject.expects(:run_step).with(steps.first)
|
46
|
+
Spinach.hooks.expects(:run_after_step).with(steps.first).in_sequence(hooks)
|
47
|
+
|
48
|
+
Spinach.hooks.expects(:run_before_step).with(steps.last).in_sequence(hooks)
|
49
|
+
subject.expects(:run_step).with(steps.last)
|
50
|
+
Spinach.hooks.expects(:run_after_step).with(steps.last).in_sequence(hooks)
|
51
|
+
|
52
|
+
Spinach.hooks.expects(:run_after_scenario).with(scenario).in_sequence(hooks)
|
93
53
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
54
|
+
subject.run
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'raises if around hook does not yield' do
|
58
|
+
subject.stubs(:step_definitions).returns stub
|
59
|
+
|
60
|
+
Spinach.hooks.stubs(:run_around_scenario).with(scenario)
|
61
|
+
|
62
|
+
proc do
|
63
|
+
subject.run
|
64
|
+
end.must_raise RuntimeError
|
65
|
+
end
|
66
|
+
end
|
100
67
|
end
|
101
68
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
69
|
+
describe '#run_step' do
|
70
|
+
before do
|
71
|
+
@step = stub(name: 'Go shopping')
|
72
|
+
@step_definitions = stub
|
73
|
+
@step_definitions.stubs(:step_location_for).with('Go shopping').returns @location = stub
|
74
|
+
subject.stubs(:step_definitions).returns @step_definitions
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'when the step is successful' do
|
78
|
+
it 'runs the successful hooks' do
|
79
|
+
@step_definitions.stubs(:execute).with(@step).returns true
|
80
|
+
Spinach.hooks.expects(:run_on_successful_step).with(@step, @location)
|
81
|
+
|
82
|
+
subject.run_step(@step)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe 'when the step fails' do
|
87
|
+
before do
|
88
|
+
@failure_exception = Class.new(StandardError)
|
89
|
+
Spinach.stubs(:config).returns({ failure_exceptions: [@failure_exception] })
|
90
|
+
@step_definitions.stubs(:execute).with(@step).raises @failure_exception
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'sets the exception' do
|
94
|
+
subject.run_step(@step)
|
95
|
+
subject.instance_variable_get(:@exception).must_be_kind_of(@failure_exception)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'runs the failed hooks' do
|
99
|
+
Spinach.hooks.expects(:run_on_failed_step).with(@step, kind_of(@failure_exception), @location)
|
100
|
+
subject.run_step(@step)
|
101
|
+
end
|
106
102
|
end
|
107
103
|
|
108
|
-
|
104
|
+
describe 'when the step is undefined' do
|
105
|
+
before do
|
106
|
+
@step_definitions.stubs(:execute).with(@step).raises Spinach::StepNotDefinedException, @step
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'sets the exception' do
|
110
|
+
subject.run_step(@step)
|
111
|
+
subject.instance_variable_get(:@exception).must_be_kind_of(Spinach::StepNotDefinedException)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'runs the undefined hooks' do
|
115
|
+
Spinach.hooks.expects(:run_on_undefined_step).with(@step, kind_of(Spinach::StepNotDefinedException))
|
116
|
+
subject.run_step(@step)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe 'when the step raises an error' do
|
121
|
+
before do
|
122
|
+
@step_definitions.stubs(:execute).with(@step).raises StandardError
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'sets the exception' do
|
126
|
+
subject.run_step(@step)
|
127
|
+
subject.instance_variable_get(:@exception).must_be_kind_of(StandardError)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'runs the error hooks' do
|
131
|
+
Spinach.hooks.expects(:run_on_error_step).with(@step, kind_of(StandardError), @location)
|
132
|
+
subject.run_step(@step)
|
133
|
+
end
|
134
|
+
end
|
109
135
|
end
|
110
136
|
end
|
111
137
|
end
|