spinach 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -9,7 +9,7 @@ group :test do
9
9
  gem 'guard'
10
10
  gem 'guard-minitest'
11
11
  gem 'guard-spinach'
12
- gem 'capybara', '~> 1.1.3'
12
+ gem 'capybara', '~> 2.0.0'
13
13
  end
14
14
 
15
15
  group :darwin do
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 maintanability: since features map to their own classes, their steps are
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
 
@@ -1 +1,6 @@
1
1
  require 'minitest/spec'
2
+ require_relative 'filesystem'
3
+
4
+ Spinach.hooks.after_run do |scenario|
5
+ FileUtils.rm_rf(Filesystem.dirs)
6
+ end
@@ -4,6 +4,10 @@ require 'fileutils'
4
4
  # and lets the host know about it.
5
5
  #
6
6
  module Filesystem
7
+ def self.dirs
8
+ ['tmp/fs']
9
+ end
10
+
7
11
  # Writes a file with some contents.
8
12
  #
9
13
  # @param [String] filename
data/lib/spinach/cli.rb CHANGED
@@ -21,7 +21,13 @@ module Spinach
21
21
  # @api public
22
22
  def run
23
23
  options
24
- Spinach::Runner.new(feature_files).run
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
- Spinach::Generators.bind
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
- # Uses given args to list the feature files to run. It will find a single
108
- # feature, features in a folder and subfolders or every feature file in the
109
- # feature path.
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
@@ -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
@@ -3,21 +3,19 @@ module Spinach
3
3
  # given some parsed feature data.
4
4
  #
5
5
  module Generators
6
- # Binds the feature generator to the "feature not found" hook
7
- def self.bind
8
- Spinach.hooks.on_undefined_feature do |data|
9
- Spinach::Generators.generate_feature(data)
10
- end
11
- end
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
- # Generates a feature given a parsed feature data
14
- #
15
- # @param [Hash] data
16
- # the parsed feature data
17
- def self.generate_feature(data)
18
- FeatureGenerator.new(data).store
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
@@ -75,6 +75,7 @@ module Spinach
75
75
  FileUtils.mkdir_p path
76
76
  File.open(filename_with_path, 'w') do |file|
77
77
  file.write(generate)
78
+ puts "generating #{File.basename(filename_with_path)}"
78
79
  end
79
80
  end
80
81
  end
@@ -1,4 +1,4 @@
1
1
  module Spinach
2
2
  # Spinach version.
3
- VERSION = "0.6.0"
3
+ VERSION = "0.6.1"
4
4
  end
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', '~> 1.1.3'
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'
@@ -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(:bind)
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 '#run' do
199
+ describe '#feature_files' do
189
200
  describe 'when a particular feature list is passed' do
190
- it 'runs the feature' do
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.expects(:file?).with('features/some_feature.feature').returns(true)
211
+ File.stubs(:exists?).returns(false)
212
+ cli.expects(:fail!).with('features/some_feature.feature could not be found')
193
213
 
194
- Spinach::Runner.expects(:new).with(['features/some_feature.feature']).
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 'runs the feature' do
219
+ it 'returns the feature with the line number' do
202
220
  cli = Spinach::Cli.new(['features/some_feature.feature:10'])
203
- File.expects(:file?).with('features/some_feature.feature').returns(true)
221
+ File.stubs(:exists?).returns(true)
204
222
 
205
- Spinach::Runner.expects(:new).with(['features/some_feature.feature:10']).
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 'runs the feature' do
228
+ it 'returns all the features' do
213
229
  cli = Spinach::Cli.new([])
214
- Dir.expects(:glob).with('features/**/*.feature').
215
- returns(['features/some_feature.feature'])
216
- Spinach::Runner.expects(:new).with(['features/some_feature.feature']).
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 'runs all feature files in the folder and subfolders' do
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.expects(:directory?).with('path/to/features').returns(true)
227
- Dir.expects(:glob).with('path/to/features/**/*.feature').
228
- returns(['path/to/features/feature1.feature',
229
- 'path/to/features/feature2.feature',
230
- 'path/to/features/feature3.feature',
231
- 'path/to/features/domain/feature4.feature'])
232
-
233
- Spinach::Runner.expects(:new).with([
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))
239
-
240
- cli.run
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.0
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-11-27 00:00:00.000000000 Z
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: 1.1.3
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: 1.1.3
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: -489699544028213773
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: -489699544028213773
328
+ hash: -2192107922436848750
329
329
  requirements: []
330
330
  rubyforge_project:
331
- rubygems_version: 1.8.24
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