spinach 0.5.2 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -1
- data/Gemfile +1 -1
- data/README.markdown +158 -112
- data/bin/spinach +0 -1
- data/features/before_and_after_hooks.feature +10 -0
- data/features/before_and_after_hooks_inheritance.feature +12 -0
- data/features/reporting/customized_reporter.feature +9 -0
- data/features/reporting/show_step_source_location.feature +1 -1
- data/features/steps/before_and_after_hooks.rb +21 -0
- data/features/steps/before_and_after_hooks_inheritance.rb +43 -0
- data/features/steps/reporting/use_customized_reporter.rb +98 -0
- data/lib/spinach.rb +1 -0
- data/lib/spinach/cli.rb +12 -20
- data/lib/spinach/config.rb +22 -1
- data/lib/spinach/dsl.rb +82 -0
- data/lib/spinach/feature_steps.rb +3 -0
- data/lib/spinach/helpers.rb +16 -0
- data/lib/spinach/runner.rb +9 -0
- data/lib/spinach/runner/feature_runner.rb +1 -1
- data/lib/spinach/runner/scenario_runner.rb +2 -0
- data/lib/spinach/tags_matcher.rb +15 -8
- data/lib/spinach/version.rb +1 -1
- data/spinach.gemspec +2 -2
- data/test/spinach/cli_test.rb +70 -18
- data/test/spinach/config_test.rb +74 -63
- data/test/spinach/dsl_test.rb +108 -0
- data/test/spinach/feature_steps_test.rb +8 -0
- data/test/spinach/helpers_test.rb +9 -0
- data/test/spinach/runner/feature_runner_test.rb +19 -1
- data/test/spinach/runner/scenario_runner_test.rb +28 -5
- data/test/spinach/runner_test.rb +41 -0
- metadata +101 -31
data/lib/spinach/version.rb
CHANGED
data/spinach.gemspec
CHANGED
@@ -14,11 +14,11 @@ Gem::Specification.new do |gem|
|
|
14
14
|
gem.add_development_dependency 'rake'
|
15
15
|
gem.add_development_dependency 'mocha'
|
16
16
|
gem.add_development_dependency 'sinatra'
|
17
|
-
gem.add_development_dependency 'capybara'
|
17
|
+
gem.add_development_dependency 'capybara', '~> 1.1.3'
|
18
18
|
gem.add_development_dependency 'pry'
|
19
19
|
gem.add_development_dependency 'simplecov'
|
20
20
|
gem.add_development_dependency 'rspec'
|
21
|
-
gem.add_development_dependency 'minitest'
|
21
|
+
gem.add_development_dependency 'minitest', "4.1.0"
|
22
22
|
gem.add_development_dependency 'turn'
|
23
23
|
|
24
24
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
data/test/spinach/cli_test.rb
CHANGED
@@ -3,17 +3,61 @@ require_relative '../test_helper'
|
|
3
3
|
describe Spinach::Cli do
|
4
4
|
describe '#options' do
|
5
5
|
it 'sets the default options' do
|
6
|
+
config = Spinach::Config.new
|
7
|
+
Spinach.stubs(:config).returns(config)
|
6
8
|
cli = Spinach::Cli.new([])
|
7
9
|
options = cli.options
|
8
|
-
|
10
|
+
config[:reporter_options].must_equal({})
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'sets default tags' do
|
14
|
+
config = Spinach::Config.new
|
15
|
+
Spinach.stubs(:config).returns(config)
|
16
|
+
cli = Spinach::Cli.new([])
|
17
|
+
cli.options
|
18
|
+
config[:tags].must_equal [['~wip']]
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'sets default tags some are defined in config file' do
|
22
|
+
in_current_dir do
|
23
|
+
config = Spinach::Config.new
|
24
|
+
config.config_path = "spinach.yml"
|
25
|
+
File.open(config.config_path, "w") do |f|
|
26
|
+
f.write <<-EOS
|
27
|
+
---
|
28
|
+
tags:
|
29
|
+
- v1
|
30
|
+
- - ~external
|
31
|
+
- js
|
32
|
+
EOS
|
33
|
+
end
|
34
|
+
Spinach.stubs(:config).returns(config)
|
35
|
+
cli = Spinach::Cli.new([])
|
36
|
+
cli.options
|
37
|
+
config[:tags].must_equal [['~wip'], 'v1', ['~external', 'js']]
|
38
|
+
end
|
9
39
|
end
|
10
40
|
|
11
41
|
describe 'backtrace' do
|
12
42
|
%w{-b --backtrace}.each do |opt|
|
13
43
|
it 'sets the backtrace if #{opt}' do
|
44
|
+
config = Spinach::Config.new
|
45
|
+
Spinach.stubs(:config).returns(config)
|
14
46
|
cli = Spinach::Cli.new([opt])
|
15
47
|
options = cli.options
|
16
|
-
|
48
|
+
config[:reporter_options][:backtrace].must_equal true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'reporter class' do
|
54
|
+
%w{-r --reporter}.each do |opt|
|
55
|
+
it 'sets the reporter class' do
|
56
|
+
config = Spinach::Config.new
|
57
|
+
Spinach.stubs(:config).returns(config)
|
58
|
+
cli = Spinach::Cli.new([opt, "String"])
|
59
|
+
options = cli.options
|
60
|
+
config.reporter_class.must_equal 'String'
|
17
61
|
end
|
18
62
|
end
|
19
63
|
end
|
@@ -55,6 +99,24 @@ describe Spinach::Cli do
|
|
55
99
|
cli.options
|
56
100
|
config.tags.must_equal [['~wip', 'javascript']]
|
57
101
|
end
|
102
|
+
|
103
|
+
it 'has precedence over tags specified in config file' do
|
104
|
+
in_current_dir do
|
105
|
+
config = Spinach::Config.new
|
106
|
+
config.config_path = "spinach.yml"
|
107
|
+
File.open(config.config_path, "w") do |f|
|
108
|
+
f.write <<-EOS
|
109
|
+
---
|
110
|
+
tags:
|
111
|
+
- v1
|
112
|
+
EOS
|
113
|
+
end
|
114
|
+
Spinach.stubs(:config).returns(config)
|
115
|
+
cli = Spinach::Cli.new([opt,'javascript'])
|
116
|
+
cli.options
|
117
|
+
config[:tags].must_equal [['~wip', 'javascript']]
|
118
|
+
end
|
119
|
+
end
|
58
120
|
end
|
59
121
|
|
60
122
|
it 'sets AND-ed tags' do
|
@@ -123,16 +185,6 @@ describe Spinach::Cli do
|
|
123
185
|
end
|
124
186
|
end
|
125
187
|
|
126
|
-
describe '#init_reporter' do
|
127
|
-
it 'inits the default reporter' do
|
128
|
-
cli = Spinach::Cli.new([])
|
129
|
-
reporter = stub
|
130
|
-
reporter.expects(:bind)
|
131
|
-
Spinach::Reporter::Stdout.stubs(new: reporter)
|
132
|
-
cli.init_reporter
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
188
|
describe '#run' do
|
137
189
|
describe 'when a particular feature list is passed' do
|
138
190
|
it 'runs the feature' do
|
@@ -179,13 +231,13 @@ describe Spinach::Cli do
|
|
179
231
|
'path/to/features/domain/feature4.feature'])
|
180
232
|
|
181
233
|
Spinach::Runner.expects(:new).with([
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
234
|
+
'path/to/features/feature1.feature',
|
235
|
+
'path/to/features/feature2.feature',
|
236
|
+
'path/to/features/feature3.feature',
|
237
|
+
'path/to/features/domain/feature4.feature']).
|
238
|
+
returns(stub(:run))
|
187
239
|
|
188
|
-
|
240
|
+
cli.run
|
189
241
|
end
|
190
242
|
end
|
191
243
|
end
|
data/test/spinach/config_test.rb
CHANGED
@@ -16,79 +16,90 @@ describe Spinach::Config do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
it 'can be overwritten' do
|
25
|
-
subject[:step_definitions_path] = 'steps'
|
26
|
-
subject[:step_definitions_path].must_equal 'steps'
|
27
|
-
end
|
28
|
-
end
|
19
|
+
describe '#reporter_class' do
|
20
|
+
it 'returns a default' do
|
21
|
+
subject[:reporter_class].must_equal "Spinach::Reporter::Stdout"
|
22
|
+
end
|
29
23
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
24
|
+
it 'can be overwritten' do
|
25
|
+
subject[:reporter_class] = "MyOwnReporter"
|
26
|
+
subject[:reporter_class].must_equal "MyOwnReporter"
|
27
|
+
end
|
28
|
+
end
|
34
29
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
30
|
+
describe '#step_definitions_path' do
|
31
|
+
it 'returns a default' do
|
32
|
+
subject[:step_definitions_path].must_be_kind_of String
|
33
|
+
end
|
40
34
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
35
|
+
it 'can be overwritten' do
|
36
|
+
subject[:step_definitions_path] = 'steps'
|
37
|
+
subject[:step_definitions_path].must_equal 'steps'
|
38
|
+
end
|
39
|
+
end
|
45
40
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
41
|
+
describe '#support_path' do
|
42
|
+
it 'returns a default' do
|
43
|
+
subject[:support_path].must_be_kind_of String
|
44
|
+
end
|
50
45
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
46
|
+
it 'can be overwritten' do
|
47
|
+
subject[:support_path] = 'support'
|
48
|
+
subject[:support_path].must_equal 'support'
|
49
|
+
end
|
50
|
+
end
|
56
51
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
52
|
+
describe '#failure_exceptions' do
|
53
|
+
it 'returns a default' do
|
54
|
+
subject[:failure_exceptions].must_be_kind_of Array
|
55
|
+
end
|
61
56
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
57
|
+
it 'can be overwritten' do
|
58
|
+
subject[:failure_exceptions] = [1, 2, 3]
|
59
|
+
subject[:failure_exceptions].must_equal [1,2,3]
|
60
|
+
end
|
67
61
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
62
|
+
it 'allows adding elements' do
|
63
|
+
subject[:failure_exceptions] << RuntimeError
|
64
|
+
subject[:failure_exceptions].must_include RuntimeError
|
65
|
+
end
|
66
|
+
end
|
74
67
|
|
75
|
-
|
76
|
-
|
77
|
-
|
68
|
+
describe '#config_path' do
|
69
|
+
it 'returns a default' do
|
70
|
+
subject[:config_path].must_equal 'config/spinach.yml'
|
71
|
+
end
|
78
72
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
73
|
+
it 'can be overwritten' do
|
74
|
+
subject[:config_path] = 'my_config_file.yml'
|
75
|
+
subject[:config_path].must_equal 'my_config_file.yml'
|
76
|
+
end
|
77
|
+
end
|
83
78
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
79
|
+
describe '#parse_from_file' do
|
80
|
+
before do
|
81
|
+
subject[:config_path] = 'a_path'
|
82
|
+
YAML.stubs(:load_file).returns({support_path: 'my_path', config_path: 'another_path'})
|
83
|
+
subject.parse_from_file
|
84
|
+
end
|
88
85
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
86
|
+
it 'sets the options' do
|
87
|
+
subject[:support_path].must_equal 'my_path'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "doesn't set the config_path option" do
|
91
|
+
subject[:config_path].must_equal 'a_path'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#tags' do
|
96
|
+
it 'returns a default' do
|
97
|
+
subject[:tags].must_be_kind_of Array
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'can be overwritten' do
|
101
|
+
subject[:tags] = ['wip']
|
102
|
+
subject[:tags].must_equal ['wip']
|
103
|
+
end
|
104
|
+
end
|
94
105
|
end
|
data/test/spinach/dsl_test.rb
CHANGED
@@ -28,6 +28,114 @@ describe Spinach::DSL do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
describe "#after" do
|
32
|
+
let(:super_class) {
|
33
|
+
Class.new do
|
34
|
+
attr_reader :var1
|
35
|
+
def after_each
|
36
|
+
@var1 = 30
|
37
|
+
@var2 = 60
|
38
|
+
end
|
39
|
+
end
|
40
|
+
}
|
41
|
+
|
42
|
+
let(:feature) {
|
43
|
+
Class.new(super_class) do
|
44
|
+
attr_accessor :var2
|
45
|
+
include Spinach::DSL
|
46
|
+
after do
|
47
|
+
self.var2 = 40
|
48
|
+
end
|
49
|
+
end
|
50
|
+
}
|
51
|
+
|
52
|
+
let(:object) { feature.new }
|
53
|
+
|
54
|
+
it "defines after_each method and calls the super first" do
|
55
|
+
object.after_each
|
56
|
+
object.var1.must_equal 30
|
57
|
+
end
|
58
|
+
|
59
|
+
it "defines after_each method and runs the block second" do
|
60
|
+
object.after_each
|
61
|
+
object.var2.must_equal 40
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "deep inheritance" do
|
65
|
+
let(:sub_feature) {
|
66
|
+
Class.new(feature) do
|
67
|
+
include Spinach::DSL
|
68
|
+
attr_reader :var3
|
69
|
+
|
70
|
+
after do
|
71
|
+
@var3 = 15
|
72
|
+
end
|
73
|
+
end
|
74
|
+
}
|
75
|
+
|
76
|
+
let(:sub_object) { sub_feature.new }
|
77
|
+
|
78
|
+
it "works with the 3rd layer of inheritance" do
|
79
|
+
sub_object.after_each
|
80
|
+
sub_object.var2.must_equal 40
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#before" do
|
86
|
+
let(:super_class) {
|
87
|
+
Class.new do
|
88
|
+
attr_reader :var1
|
89
|
+
def before_each
|
90
|
+
@var1 = 30
|
91
|
+
@var2 = 60
|
92
|
+
end
|
93
|
+
end
|
94
|
+
}
|
95
|
+
|
96
|
+
let(:feature) {
|
97
|
+
Class.new(super_class) do
|
98
|
+
attr_accessor :var2
|
99
|
+
include Spinach::DSL
|
100
|
+
before do
|
101
|
+
self.var2 = 40
|
102
|
+
end
|
103
|
+
end
|
104
|
+
}
|
105
|
+
|
106
|
+
let(:object) { feature.new }
|
107
|
+
|
108
|
+
it "defines before_each method and calls the super first" do
|
109
|
+
object.before_each
|
110
|
+
object.var1.must_equal 30
|
111
|
+
end
|
112
|
+
|
113
|
+
it "defines before_each method and runs the block second" do
|
114
|
+
object.before_each
|
115
|
+
object.var2.must_equal 40
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "deep inheritance" do
|
119
|
+
let(:sub_feature) {
|
120
|
+
Class.new(feature) do
|
121
|
+
include Spinach::DSL
|
122
|
+
attr_reader :var3
|
123
|
+
|
124
|
+
before do
|
125
|
+
@var3 = 15
|
126
|
+
end
|
127
|
+
end
|
128
|
+
}
|
129
|
+
|
130
|
+
let(:sub_object) { sub_feature.new }
|
131
|
+
|
132
|
+
it "works with the 3rd layer of inheritance" do
|
133
|
+
sub_object.before_each
|
134
|
+
sub_object.var2.must_equal 40
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
31
139
|
describe '#feature' do
|
32
140
|
it 'sets the name for this feature' do
|
33
141
|
@feature.feature('User salutes')
|
@@ -31,6 +31,14 @@ describe Spinach::FeatureSteps do
|
|
31
31
|
end.new
|
32
32
|
end
|
33
33
|
|
34
|
+
it "responds to before_each" do
|
35
|
+
feature.must_respond_to(:before_each)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "responds to after_each" do
|
39
|
+
feature.must_respond_to(:after_each)
|
40
|
+
end
|
41
|
+
|
34
42
|
describe 'execute' do
|
35
43
|
it 'runs defined step correctly' do
|
36
44
|
feature.execute(stub(name: 'I go to the toilet'))
|
@@ -1,7 +1,13 @@
|
|
1
1
|
require_relative '../../test_helper'
|
2
2
|
|
3
3
|
describe Spinach::Runner::FeatureRunner do
|
4
|
-
let(:feature) {
|
4
|
+
let(:feature) {
|
5
|
+
stub('feature',
|
6
|
+
name: 'Feature',
|
7
|
+
scenarios: [],
|
8
|
+
background_steps: []
|
9
|
+
)
|
10
|
+
}
|
5
11
|
subject{ Spinach::Runner::FeatureRunner.new(feature) }
|
6
12
|
|
7
13
|
describe '#initialize' do
|
@@ -153,6 +159,18 @@ describe Spinach::Runner::FeatureRunner do
|
|
153
159
|
@runner = Spinach::Runner::FeatureRunner.new(@feature)
|
154
160
|
@runner.run
|
155
161
|
end
|
162
|
+
|
163
|
+
it "doesn't accumulate tags from one scenario to the next" do
|
164
|
+
next_scenario = stub(line: 14, tags: [])
|
165
|
+
@feature.stubs(:scenarios).returns [@scenario, next_scenario]
|
166
|
+
|
167
|
+
Spinach::TagsMatcher.expects(:match).with(["feature_tag", "scenario_tag"]).returns true
|
168
|
+
Spinach::TagsMatcher.expects(:match).with(["feature_tag"]).returns false
|
169
|
+
Spinach::Runner::ScenarioRunner.expects(:new).with(@scenario).returns stub(run: true)
|
170
|
+
|
171
|
+
@runner = Spinach::Runner::FeatureRunner.new(@feature)
|
172
|
+
@runner.run
|
173
|
+
end
|
156
174
|
end
|
157
175
|
end
|
158
176
|
end
|