spinach 0.6.0 → 0.6.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 +1 -1
- data/README.markdown +61 -1
- data/features/support/env.rb +5 -0
- data/features/support/filesystem.rb +4 -0
- data/lib/spinach/cli.rb +45 -20
- data/lib/spinach/config.rb +5 -0
- data/lib/spinach/generators.rb +12 -14
- data/lib/spinach/generators/feature_generator.rb +1 -0
- data/lib/spinach/version.rb +1 -1
- data/spinach.gemspec +1 -1
- data/test/spinach/cli_test.rb +53 -34
- metadata +7 -7
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -6,7 +6,7 @@ executable specifications of your application or library's acceptance criteria.
|
|
6
6
|
|
7
7
|
Conceived as an alternative to Cucumber, here are some of its design goals:
|
8
8
|
|
9
|
-
* Step
|
9
|
+
* Step maintainability: since features map to their own classes, their steps are
|
10
10
|
just methods of that class. This encourages step encapsulation.
|
11
11
|
|
12
12
|
* Step reusability: In case you want to reuse steps across features, you can
|
@@ -149,6 +149,65 @@ end
|
|
149
149
|
|
150
150
|
Then run your feature again running `spinach` and watch it all turn green! :)
|
151
151
|
|
152
|
+
## Shared Steps
|
153
|
+
|
154
|
+
You'll often find that some steps need to be used in many
|
155
|
+
features. In this case, it makes sense to put these steps in reusable
|
156
|
+
modules. For example, let's say you need a step that logs the
|
157
|
+
user into the site.
|
158
|
+
|
159
|
+
This is one way to make that reusable:
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
# ... features/steps/common_steps/login.rb
|
163
|
+
module CommonSteps
|
164
|
+
module Login
|
165
|
+
extend ActiveSupport::Concern
|
166
|
+
|
167
|
+
def self.included(mod)
|
168
|
+
mod.send(:Given, 'I am logged in') do
|
169
|
+
# log in stuff...
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# within a rails app, you might want to use ActiveSupport::Concern
|
176
|
+
module CommonSteps
|
177
|
+
module Login
|
178
|
+
extend ActiveSupport::Concern
|
179
|
+
|
180
|
+
included do
|
181
|
+
Given 'I am logged in' do
|
182
|
+
# log in stuff...
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
```
|
188
|
+
|
189
|
+
Using the module (in any feature):
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
# ... features/steps/buying_a_widget.rb
|
193
|
+
class BuyAWidget < Spinach::FeatureSteps
|
194
|
+
# simply include this module and you are good to go
|
195
|
+
include CommonSteps::Login
|
196
|
+
end
|
197
|
+
```
|
198
|
+
|
199
|
+
Also, don't forgot to require all of these common steps in your env.rb:
|
200
|
+
|
201
|
+
```ruby
|
202
|
+
# env.rb
|
203
|
+
common_steps = Dir.glob(Rails.root.join("features/steps/common_steps/**/*.rb"))
|
204
|
+
|
205
|
+
common_steps.each do |f|
|
206
|
+
require f
|
207
|
+
end
|
208
|
+
```
|
209
|
+
|
210
|
+
|
152
211
|
## Tags
|
153
212
|
|
154
213
|
Feature and Scenarios can be marked with tags in the form: `@tag`. Tags can be
|
@@ -275,6 +334,7 @@ Check out our [spinach-sinatra demo](https://github.com/codegram/spinach-sinatra
|
|
275
334
|
|
276
335
|
* [guard-spinach](http://github.com/codegram/guard-spinach)
|
277
336
|
* [spinach-rails](http://github.com/codegram/spinach-rails)
|
337
|
+
* [spinach-console-reporter](https://github.com/ywen/spinach-console-reporter) (to be used with Jenkins)
|
278
338
|
|
279
339
|
### Demos
|
280
340
|
|
data/features/support/env.rb
CHANGED
data/lib/spinach/cli.rb
CHANGED
@@ -21,7 +21,13 @@ module Spinach
|
|
21
21
|
# @api public
|
22
22
|
def run
|
23
23
|
options
|
24
|
-
|
24
|
+
|
25
|
+
# only generating steps, do not run tests
|
26
|
+
if Spinach.config.generate
|
27
|
+
exit 0
|
28
|
+
else
|
29
|
+
Spinach::Runner.new(feature_files).run
|
30
|
+
end
|
25
31
|
end
|
26
32
|
|
27
33
|
# @return [Hash]
|
@@ -36,6 +42,38 @@ module Spinach
|
|
36
42
|
@options ||= parse_options
|
37
43
|
end
|
38
44
|
|
45
|
+
# Uses given args to list the feature files to run. It will find a single
|
46
|
+
# feature, features in a folder and subfolders or every feature file in the
|
47
|
+
# feature path.
|
48
|
+
#
|
49
|
+
# @return [Array]
|
50
|
+
# An array with the feature file names.
|
51
|
+
#
|
52
|
+
# @api public
|
53
|
+
def feature_files
|
54
|
+
files_to_run = []
|
55
|
+
|
56
|
+
@args.each do |arg|
|
57
|
+
if arg.match /\.feature/
|
58
|
+
if File.exists? arg.gsub(/:\d*/, '')
|
59
|
+
files_to_run << arg
|
60
|
+
else
|
61
|
+
fail! "#{arg} could not be found"
|
62
|
+
end
|
63
|
+
elsif File.directory?(arg)
|
64
|
+
files_to_run << Dir.glob(File.join(arg, '**', '*.feature'))
|
65
|
+
else
|
66
|
+
fail! "invalid argument - #{arg}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
if !files_to_run.empty?
|
71
|
+
files_to_run.flatten
|
72
|
+
else
|
73
|
+
Dir.glob(File.join(Spinach.config[:features_path], '**', '*.feature'))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
39
77
|
private
|
40
78
|
|
41
79
|
# Parses the arguments into options.
|
@@ -73,7 +111,8 @@ module Spinach
|
|
73
111
|
|
74
112
|
opts.on('-g', '--generate',
|
75
113
|
'Auto-generate the feature steps files') do
|
76
|
-
|
114
|
+
config[:generate] = true
|
115
|
+
Spinach::Generators.run(feature_files)
|
77
116
|
end
|
78
117
|
|
79
118
|
opts.on_tail('--version', 'Show version') do
|
@@ -104,24 +143,10 @@ module Spinach
|
|
104
143
|
end
|
105
144
|
end
|
106
145
|
|
107
|
-
#
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
# @return [Array]
|
112
|
-
# An array with the feature file names.
|
113
|
-
#
|
114
|
-
# @api private
|
115
|
-
def feature_files
|
116
|
-
path = @args.first.to_s
|
117
|
-
|
118
|
-
if File.file?(path.split(":").first.to_s)
|
119
|
-
@args
|
120
|
-
elsif File.directory?(path)
|
121
|
-
Dir.glob(File.join(path, '**', '*.feature'))
|
122
|
-
else
|
123
|
-
Dir.glob(File.join(Spinach.config[:features_path], '**', '*.feature'))
|
124
|
-
end
|
146
|
+
# exit test run with an optional message to the user
|
147
|
+
def fail!(message=nil)
|
148
|
+
puts message if message
|
149
|
+
exit 1
|
125
150
|
end
|
126
151
|
end
|
127
152
|
end
|
data/lib/spinach/config.rb
CHANGED
@@ -29,6 +29,7 @@ module Spinach
|
|
29
29
|
:failure_exceptions,
|
30
30
|
:config_path,
|
31
31
|
:tags,
|
32
|
+
:generate,
|
32
33
|
:save_and_open_page_on_failure,
|
33
34
|
:reporter_class,
|
34
35
|
:reporter_options
|
@@ -85,6 +86,10 @@ module Spinach
|
|
85
86
|
@support_path || "#{self.features_path}/support"
|
86
87
|
end
|
87
88
|
|
89
|
+
def generate
|
90
|
+
@generate || false
|
91
|
+
end
|
92
|
+
|
88
93
|
# Allows you to read the config object using a hash-like syntax.
|
89
94
|
#
|
90
95
|
# @param [String] attribute
|
data/lib/spinach/generators.rb
CHANGED
@@ -3,21 +3,19 @@ module Spinach
|
|
3
3
|
# given some parsed feature data.
|
4
4
|
#
|
5
5
|
module Generators
|
6
|
-
#
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
# generates steps for features
|
7
|
+
# @files [Array]
|
8
|
+
# filenames to evaluate for step generation
|
9
|
+
def self.run(files)
|
10
|
+
files.each do |file|
|
11
|
+
feature = Parser.open_file(file).parse
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
rescue FeatureGeneratorException => e
|
20
|
-
$stderr.puts e
|
13
|
+
begin
|
14
|
+
FeatureGenerator.new(feature).store
|
15
|
+
rescue FeatureGeneratorException
|
16
|
+
# probably not optimal, but ignoring this
|
17
|
+
end
|
18
|
+
end
|
21
19
|
end
|
22
20
|
end
|
23
21
|
end
|
data/lib/spinach/version.rb
CHANGED
data/spinach.gemspec
CHANGED
@@ -14,7 +14,7 @@ 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', '~> 2.0.0'
|
18
18
|
gem.add_development_dependency 'pry'
|
19
19
|
gem.add_development_dependency 'simplecov'
|
20
20
|
gem.add_development_dependency 'rspec'
|
data/test/spinach/cli_test.rb
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
require_relative '../test_helper'
|
2
2
|
|
3
3
|
describe Spinach::Cli do
|
4
|
+
describe '#run' do
|
5
|
+
it 'gets the options and runs the features' do
|
6
|
+
cli = Spinach::Cli.new(['features/some_feature.feature'])
|
7
|
+
cli.stubs(:feature_files).returns(['features/some_feature.feature'])
|
8
|
+
|
9
|
+
cli.expects(:options)
|
10
|
+
Spinach::Runner.any_instance.expects(:run)
|
11
|
+
cli.run
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
4
15
|
describe '#options' do
|
5
16
|
it 'sets the default options' do
|
6
17
|
config = Spinach::Config.new
|
@@ -131,7 +142,7 @@ tags:
|
|
131
142
|
describe 'generate' do
|
132
143
|
%w{-g --generate}.each do |opt|
|
133
144
|
it 'inits the generator if #{opt}' do
|
134
|
-
Spinach::Generators.expects(:
|
145
|
+
Spinach::Generators.expects(:run)
|
135
146
|
cli = Spinach::Cli.new([opt])
|
136
147
|
options = cli.options
|
137
148
|
end
|
@@ -185,59 +196,67 @@ tags:
|
|
185
196
|
end
|
186
197
|
end
|
187
198
|
|
188
|
-
describe '#
|
199
|
+
describe '#feature_files' do
|
189
200
|
describe 'when a particular feature list is passed' do
|
190
|
-
|
201
|
+
describe 'the feature really exists' do
|
202
|
+
it 'runs the feature' do
|
203
|
+
cli = Spinach::Cli.new(['features/some_feature.feature'])
|
204
|
+
File.stubs(:exists?).returns(true)
|
205
|
+
cli.feature_files.must_equal ['features/some_feature.feature']
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe 'it fails if the feature does not exist' do
|
191
210
|
cli = Spinach::Cli.new(['features/some_feature.feature'])
|
192
|
-
File.
|
211
|
+
File.stubs(:exists?).returns(false)
|
212
|
+
cli.expects(:fail!).with('features/some_feature.feature could not be found')
|
193
213
|
|
194
|
-
|
195
|
-
returns(stub(:run))
|
196
|
-
cli.run
|
214
|
+
cli.feature_files
|
197
215
|
end
|
198
216
|
end
|
199
217
|
|
200
218
|
describe 'when a particular feature list is passed with line' do
|
201
|
-
it '
|
219
|
+
it 'returns the feature with the line number' do
|
202
220
|
cli = Spinach::Cli.new(['features/some_feature.feature:10'])
|
203
|
-
File.
|
221
|
+
File.stubs(:exists?).returns(true)
|
204
222
|
|
205
|
-
|
206
|
-
returns(stub(:run))
|
207
|
-
cli.run
|
223
|
+
cli.feature_files.must_equal ['features/some_feature.feature:10']
|
208
224
|
end
|
209
225
|
end
|
210
226
|
|
211
227
|
describe 'when no feature is passed' do
|
212
|
-
it '
|
228
|
+
it 'returns all the features' do
|
213
229
|
cli = Spinach::Cli.new([])
|
214
|
-
Dir.expects(:glob).with('features/**/*.feature')
|
215
|
-
|
216
|
-
|
217
|
-
returns(stub(:run))
|
218
|
-
cli.run
|
230
|
+
Dir.expects(:glob).with('features/**/*.feature')
|
231
|
+
|
232
|
+
cli.feature_files
|
219
233
|
end
|
220
234
|
end
|
221
235
|
|
222
236
|
describe 'when a folder is given' do
|
223
|
-
it '
|
237
|
+
it 'returns all feature files in the folder and subfolders' do
|
224
238
|
cli = Spinach::Cli.new(['path/to/features'])
|
225
239
|
|
226
|
-
File.
|
227
|
-
Dir.expects(:glob).with('path/to/features/**/*.feature')
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
240
|
+
File.stubs(:directory?).returns(true)
|
241
|
+
Dir.expects(:glob).with('path/to/features/**/*.feature')
|
242
|
+
|
243
|
+
cli.feature_files
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
describe 'when multiple arguments are passed in' do
|
248
|
+
describe 'a folder followed by file' do
|
249
|
+
it 'returns the features in the folder and the particular file' do
|
250
|
+
cli = Spinach::Cli.new(['path/to/features', 'some_feature.feature'])
|
251
|
+
|
252
|
+
File.stubs(:directory?).returns(true)
|
253
|
+
Dir.expects(:glob).with('path/to/features/**/*.feature')
|
254
|
+
.returns(['several features'])
|
255
|
+
|
256
|
+
File.stubs(:exists?).returns(true)
|
257
|
+
|
258
|
+
cli.feature_files.must_equal ['several features', 'some_feature.feature']
|
259
|
+
end
|
241
260
|
end
|
242
261
|
end
|
243
262
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spinach
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-
|
15
|
+
date: 2012-12-16 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: gherkin-ruby
|
@@ -101,7 +101,7 @@ dependencies:
|
|
101
101
|
requirements:
|
102
102
|
- - ~>
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
104
|
+
version: 2.0.0
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
requirements:
|
110
110
|
- - ~>
|
111
111
|
- !ruby/object:Gem::Version
|
112
|
-
version:
|
112
|
+
version: 2.0.0
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: pry
|
115
115
|
requirement: !ruby/object:Gem::Requirement
|
@@ -316,7 +316,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
316
316
|
version: '0'
|
317
317
|
segments:
|
318
318
|
- 0
|
319
|
-
hash: -
|
319
|
+
hash: -2192107922436848750
|
320
320
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
321
321
|
none: false
|
322
322
|
requirements:
|
@@ -325,10 +325,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
325
325
|
version: '0'
|
326
326
|
segments:
|
327
327
|
- 0
|
328
|
-
hash: -
|
328
|
+
hash: -2192107922436848750
|
329
329
|
requirements: []
|
330
330
|
rubyforge_project:
|
331
|
-
rubygems_version: 1.8.
|
331
|
+
rubygems_version: 1.8.23
|
332
332
|
signing_key:
|
333
333
|
specification_version: 3
|
334
334
|
summary: Spinach is a BDD framework on top of gherkin
|