spinach 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -71,7 +71,7 @@ Spinach will detect your features and generate the following class:
71
71
  ## features/steps/test_how_spinach_works.rb
72
72
 
73
73
  ```ruby
74
- class TestHowSpinachWorks < Spinach::FeatureSteps
74
+ class Spinach::Features::TestHowSpinachWorks < Spinach::FeatureSteps
75
75
  Given 'I have an empty array' do
76
76
  end
77
77
 
@@ -96,7 +96,7 @@ Then, you can fill it in with your logic - remember, it's just a class, you can
96
96
  use private methods, mix in modules or whatever!
97
97
 
98
98
  ```ruby
99
- class TestHowSpinachWorks < Spinach::FeatureSteps
99
+ class Spinach::Features::TestHowSpinachWorks < Spinach::FeatureSteps
100
100
  Given 'I have an empty array' do
101
101
  @array = Array.new
102
102
  end
@@ -190,7 +190,7 @@ Using the module (in any feature):
190
190
 
191
191
  ```ruby
192
192
  # ... features/steps/buying_a_widget.rb
193
- class BuyAWidget < Spinach::FeatureSteps
193
+ class Spinach::Features::BuyAWidget < Spinach::FeatureSteps
194
194
  # simply include this module and you are good to go
195
195
  include CommonSteps::Login
196
196
  end
@@ -299,7 +299,7 @@ Full hook documentation is here:
299
299
  Sometimes it feels awkward to add steps into feature file just because you need to do some test setup and cleanup. And it is equally awkward to add a global hooks for this purpose. For example, if you want to add a session timeout feature, to do so, you want to set the session timeout time to 1 second just for this feature, and put the normal timeout back after this feature. It doesn't make sense to add two steps in the feature file just to change the session timeout value. In this scenario, a ```before``` and ```after``` blocks are perfect for this kind of tasks. Below is an example implementation:
300
300
 
301
301
  ```ruby
302
- class SessionTimeout < Spinach::FeatureSteps
302
+ class Spinach::Features::SessionTimeout < Spinach::FeatureSteps
303
303
  attr_accessor :original_timeout_value
304
304
  before do
305
305
  self.original_timeout_value = session_timeout_value
@@ -1,10 +1,7 @@
1
- class ShowStepSourceLocation < Spinach::FeatureSteps
2
-
3
- feature "Show step source location"
4
-
1
+ class Spinach::Features::ShowStepSourceLocation < Spinach::FeatureSteps
5
2
  include Integration::SpinachRunner
6
3
 
7
- Given "I have a feature that has no error or failure" do
4
+ step "I have a feature that has no error or failure" do
8
5
  write_file('features/success_feature.feature', """
9
6
  Feature: A success feature
10
7
 
@@ -13,25 +10,25 @@ Feature: A success feature
13
10
  """)
14
11
 
15
12
  write_file('features/steps/success_feature.rb',
16
- 'class ASuccessFeature < Spinach::FeatureSteps
13
+ 'class Spinach::Features::ASuccessFeature < Spinach::FeatureSteps
17
14
  feature "A success feature"
18
- Then "I succeed" do
15
+ step "I succeed" do
19
16
  end
20
17
  end')
21
18
  @feature = "features/success_feature.feature"
22
19
  end
23
20
 
24
- When "I run it" do
21
+ step "I run it" do
25
22
  run_feature @feature
26
23
  end
27
24
 
28
- Then "I should see the source location of each step of every scenario" do
25
+ step "I should see the source location of each step of every scenario" do
29
26
  @stdout.must_match(
30
27
  /I succeed.*features\/steps\/success_feature\.rb.*3/
31
28
  )
32
29
  end
33
30
 
34
- Given "I have a feature that has no error or failure and use external steps" do
31
+ step "I have a feature that has no error or failure and use external steps" do
35
32
  write_file('features/success_feature.feature', """
36
33
  Feature: A feature that uses external steps
37
34
 
@@ -40,26 +37,26 @@ Feature: A feature that uses external steps
40
37
  """)
41
38
 
42
39
  write_file('features/steps/success_feature.rb',
43
- 'class AFeatureThatUsesExternalSteps < Spinach::FeatureSteps
40
+ 'class Spinach::Features::AFeatureThatUsesExternalSteps < Spinach::FeatureSteps
44
41
  feature "A feature that uses external steps"
45
42
  include ExternalSteps
46
43
  end')
47
44
  write_file('features/support/external_steps.rb',
48
45
  'module ExternalSteps
49
46
  include Spinach::DSL
50
- Given "this is a external step" do
47
+ step "this is a external step" do
51
48
  end
52
49
  end')
53
50
  @feature = "features/success_feature.feature"
54
51
  end
55
52
 
56
- Then "I should see the source location of each step, even external ones" do
53
+ step "I should see the source location of each step, even external ones" do
57
54
  @stdout.must_match(
58
55
  /this is a external step.*features\/support\/external_steps\.rb.*3/
59
56
  )
60
57
  end
61
58
 
62
- Given "I have a feature that has an error" do
59
+ step "I have a feature that has an error" do
63
60
  write_file('features/error_feature.feature', """
64
61
  Feature: An error feature
65
62
 
@@ -68,22 +65,22 @@ Feature: An error feature
68
65
  """)
69
66
 
70
67
  write_file('features/steps/error_feature.rb',
71
- 'class AnErrorFeature < Spinach::FeatureSteps
68
+ 'class Spinach::Features::AnErrorFeature < Spinach::FeatureSteps
72
69
  feature "An error feature"
73
- Then "I do not succeed" do
70
+ step "I do not succeed" do
74
71
  i_do_not_exist.must_be_equal "Your Mumma"
75
72
  end
76
73
  end')
77
74
  @feature = "features/error_feature.feature"
78
75
  end
79
76
 
80
- Then "I should see the source location of each step, even ones with errors" do
77
+ step "I should see the source location of each step, even ones with errors" do
81
78
  @stdout.must_match(
82
79
  /I do not succeed.*features\/steps\/error_feature\.rb.*3/
83
80
  )
84
81
  end
85
82
 
86
- Given "I have a feature that has a failure" do
83
+ step "I have a feature that has a failure" do
87
84
  write_file('features/failure_feature.feature', """
88
85
  Feature: A failure feature
89
86
 
@@ -92,9 +89,9 @@ Feature: A failure feature
92
89
  """)
93
90
 
94
91
  write_file('features/steps/failure_feature.rb',
95
- 'class AFailureFeature < Spinach::FeatureSteps
92
+ 'class Spinach::Features::AFailureFeature < Spinach::FeatureSteps
96
93
  feature "A failure feature"
97
- Then "I do not succeed" do
94
+ step "I do not succeed" do
98
95
  i_exist = "Your Pappa"
99
96
  i_exist.must_be_equal "Your Mumma"
100
97
  end
@@ -102,7 +99,7 @@ Feature: A failure feature
102
99
  @feature = "features/failure_feature.feature"
103
100
  end
104
101
 
105
- Then "I should see the source location of each step, even ones with failures" do
102
+ step "I should see the source location of each step, even ones with failures" do
106
103
  @stdout.must_match(
107
104
  /I do not succeed.*features\/steps\/failure_feature\.rb.*3/
108
105
  )
data/lib/spinach.rb CHANGED
@@ -15,6 +15,7 @@ require_relative 'spinach/generators'
15
15
 
16
16
  require_relative 'spinach/background'
17
17
  require_relative 'spinach/feature'
18
+ require_relative 'spinach/features'
18
19
  require_relative 'spinach/scenario'
19
20
  require_relative 'spinach/step'
20
21
 
@@ -67,9 +68,11 @@ module Spinach
67
68
  # @api public
68
69
  def self.find_step_definitions(name)
69
70
  klass = Spinach::Support.camelize(name)
71
+ scoped_klass = Spinach::Support.scoped_camelize(name)
70
72
  feature_steps.detect do |feature|
71
- feature.feature_name.to_s == name.to_s ||
72
- feature.name == klass
73
+ feature.name == klass ||
74
+ feature.name == scoped_klass ||
75
+ feature.feature_name.to_s == name.to_s
73
76
  end
74
77
  end
75
78
  end
@@ -0,0 +1,6 @@
1
+ module Spinach
2
+ # This module provides scoping to user genereated features, so they won't
3
+ # conflict with the application code.
4
+ module Features
5
+ end
6
+ end
@@ -34,7 +34,7 @@ module Spinach
34
34
  # an example feature steps definition
35
35
  def generate
36
36
  result = StringIO.new
37
- result.puts "class #{Spinach::Support.camelize name} < Spinach::FeatureSteps"
37
+ result.puts "class #{Spinach::Support.scoped_camelize name} < Spinach::FeatureSteps"
38
38
  generated_steps = steps.map do |step|
39
39
  step_generator = Generators::StepGenerator.new(step)
40
40
  step_generator.generate.split("\n").map do |line|
@@ -49,7 +49,7 @@ module Spinach
49
49
  # @return [String]
50
50
  # an example filename for this feature steps
51
51
  def filename
52
- Spinach::Support.underscore (
52
+ Spinach::Support.underscore(
53
53
  Spinach::Support.camelize name
54
54
  ) + ".rb"
55
55
  end
@@ -83,6 +83,5 @@ module Spinach
83
83
  end
84
84
 
85
85
  class FeatureGeneratorException < Exception; end;
86
-
87
86
  end
88
87
  end
@@ -14,7 +14,7 @@ module Spinach
14
14
  # an example step definition
15
15
  def generate
16
16
  result = StringIO.new
17
- result.puts "#{@step.keyword} '#{Spinach::Support.escape_single_commas @step.name}' do"
17
+ result.puts "step '#{Spinach::Support.escape_single_commas @step.name}' do"
18
18
  result.puts " pending 'step not implemented'"
19
19
  result.puts "end"
20
20
  result.string
@@ -17,6 +17,21 @@ module Spinach
17
17
  name.to_s.strip.split(/[^a-z0-9]/i).map{|w| w.capitalize}.join
18
18
  end
19
19
 
20
+ # @param [String] name
21
+ # The name to camelize.
22
+ #
23
+ # @return [String]
24
+ # The +name+ in camel case scoped to Spinach::Features.
25
+ #
26
+ # @example
27
+ # Spinach::Support.scoped_camelize('User authentication')
28
+ # => 'Spinach::Features::UserAuthentication'
29
+ #
30
+ # @api public
31
+ def self.scoped_camelize(name)
32
+ "Spinach::Features::#{camelize(name)}"
33
+ end
34
+
20
35
  # Makes an underscored, lowercase form from the expression in the string.
21
36
  #
22
37
  # Changes '::' to '/' to convert namespaces to paths.
@@ -1,4 +1,4 @@
1
1
  module Spinach
2
2
  # Spinach version.
3
- VERSION = "0.6.1"
3
+ VERSION = "0.7.0"
4
4
  end
data/spinach.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
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', "4.1.0"
21
+ gem.add_development_dependency 'minitest', "4.3.3"
22
22
  gem.add_development_dependency 'turn'
23
23
 
24
24
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -37,8 +37,13 @@ Feature: Cheezburger can I has
37
37
  describe "#generate" do
38
38
  it "generates an entire feature_steps class definition" do
39
39
  result = subject.generate
40
- result.must_match /Given 'I haz a sad' do/
41
- result.must_match /pending 'step not implemented'/
40
+ result.must_match(/step 'I haz a sad' do/)
41
+ result.must_match(/pending 'step not implemented'/)
42
+ end
43
+
44
+ it 'scopes the generated class to prevent conflicts' do
45
+ result = subject.generate
46
+ result.must_match(/class Spinach::Features::CheezburgerCanIHas < Spinach::FeatureSteps/)
42
47
  end
43
48
  end
44
49
 
@@ -13,7 +13,7 @@ module Spinach::Generators
13
13
 
14
14
  describe "#generate" do
15
15
  it "generates a step" do
16
- subject.generate.must_match /Given.*I has a sad/
16
+ subject.generate.must_match /step.*I has a sad/
17
17
  end
18
18
 
19
19
  it "generates a pending step" do
@@ -23,6 +23,12 @@ describe Spinach::Support do
23
23
  end
24
24
  end
25
25
 
26
+ describe '#scoped_camelize' do
27
+ it 'prepends a scope to the class' do
28
+ Spinach::Support.scoped_camelize('feature name').must_equal 'Spinach::Features::FeatureName'
29
+ end
30
+ end
31
+
26
32
  describe '#underscore' do
27
33
  it 'changes dashes to underscores' do
28
34
  Spinach::Support.underscore('feature-name').must_equal 'feature_name'
data/test/spinach_test.rb CHANGED
@@ -6,8 +6,9 @@ describe Spinach do
6
6
  @feature_steps2 = OpenStruct.new(feature_name: 'Slip management')
7
7
  @feature_steps3 = OpenStruct.new(feature_name: 'File attachments')
8
8
  @feature_steps4 = OpenStruct.new(name: 'UserSendsAMessage')
9
+ @feature_steps5 = OpenStruct.new(name: 'Spinach::Features::ScopedFeature')
9
10
  [@feature_steps1, @feature_steps2,
10
- @feature_steps3, @feature_steps4].each do |feature|
11
+ @feature_steps3, @feature_steps4, @feature_steps5].each do |feature|
11
12
  Spinach.feature_steps << feature
12
13
  end
13
14
  end
@@ -41,6 +42,10 @@ describe Spinach do
41
42
  Spinach.find_step_definitions('User sends a message').must_equal @feature_steps4
42
43
  end
43
44
 
45
+ it 'finds scoped features' do
46
+ Spinach.find_step_definitions('Scoped feature').must_equal @feature_steps5
47
+ end
48
+
44
49
  it 'returns nil when it cannot find the class' do
45
50
  Spinach.find_step_definitions('This feature does not exist').must_equal nil
46
51
  end
data/test/test_helper.rb CHANGED
@@ -11,7 +11,7 @@ end
11
11
 
12
12
  require 'minitest/spec'
13
13
  require 'minitest/autorun'
14
- require 'mocha'
14
+ require 'mocha/setup'
15
15
  require 'ostruct'
16
16
  require 'stringio'
17
17
  require 'pry'
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.1
4
+ version: 0.7.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,184 +12,184 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2012-12-16 00:00:00.000000000 Z
15
+ date: 2012-12-18 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: gherkin-ruby
19
+ prerelease: false
19
20
  requirement: !ruby/object:Gem::Requirement
20
- none: false
21
21
  requirements:
22
22
  - - ~>
23
23
  - !ruby/object:Gem::Version
24
24
  version: 0.2.0
25
+ none: false
25
26
  type: :runtime
26
- prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
28
- none: false
29
28
  requirements:
30
29
  - - ~>
31
30
  - !ruby/object:Gem::Version
32
31
  version: 0.2.0
32
+ none: false
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: colorize
35
+ prerelease: false
35
36
  requirement: !ruby/object:Gem::Requirement
36
- none: false
37
37
  requirements:
38
38
  - - ! '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ none: false
41
42
  type: :runtime
42
- prerelease: false
43
43
  version_requirements: !ruby/object:Gem::Requirement
44
- none: false
45
44
  requirements:
46
45
  - - ! '>='
47
46
  - !ruby/object:Gem::Version
48
47
  version: '0'
48
+ none: false
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: rake
51
+ prerelease: false
51
52
  requirement: !ruby/object:Gem::Requirement
52
- none: false
53
53
  requirements:
54
54
  - - ! '>='
55
55
  - !ruby/object:Gem::Version
56
56
  version: '0'
57
+ none: false
57
58
  type: :development
58
- prerelease: false
59
59
  version_requirements: !ruby/object:Gem::Requirement
60
- none: false
61
60
  requirements:
62
61
  - - ! '>='
63
62
  - !ruby/object:Gem::Version
64
63
  version: '0'
64
+ none: false
65
65
  - !ruby/object:Gem::Dependency
66
66
  name: mocha
67
+ prerelease: false
67
68
  requirement: !ruby/object:Gem::Requirement
68
- none: false
69
69
  requirements:
70
70
  - - ! '>='
71
71
  - !ruby/object:Gem::Version
72
72
  version: '0'
73
+ none: false
73
74
  type: :development
74
- prerelease: false
75
75
  version_requirements: !ruby/object:Gem::Requirement
76
- none: false
77
76
  requirements:
78
77
  - - ! '>='
79
78
  - !ruby/object:Gem::Version
80
79
  version: '0'
80
+ none: false
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: sinatra
83
+ prerelease: false
83
84
  requirement: !ruby/object:Gem::Requirement
84
- none: false
85
85
  requirements:
86
86
  - - ! '>='
87
87
  - !ruby/object:Gem::Version
88
88
  version: '0'
89
+ none: false
89
90
  type: :development
90
- prerelease: false
91
91
  version_requirements: !ruby/object:Gem::Requirement
92
- none: false
93
92
  requirements:
94
93
  - - ! '>='
95
94
  - !ruby/object:Gem::Version
96
95
  version: '0'
96
+ none: false
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: capybara
99
+ prerelease: false
99
100
  requirement: !ruby/object:Gem::Requirement
100
- none: false
101
101
  requirements:
102
102
  - - ~>
103
103
  - !ruby/object:Gem::Version
104
104
  version: 2.0.0
105
+ none: false
105
106
  type: :development
106
- prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
- none: false
109
108
  requirements:
110
109
  - - ~>
111
110
  - !ruby/object:Gem::Version
112
111
  version: 2.0.0
112
+ none: false
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: pry
115
+ prerelease: false
115
116
  requirement: !ruby/object:Gem::Requirement
116
- none: false
117
117
  requirements:
118
118
  - - ! '>='
119
119
  - !ruby/object:Gem::Version
120
120
  version: '0'
121
+ none: false
121
122
  type: :development
122
- prerelease: false
123
123
  version_requirements: !ruby/object:Gem::Requirement
124
- none: false
125
124
  requirements:
126
125
  - - ! '>='
127
126
  - !ruby/object:Gem::Version
128
127
  version: '0'
128
+ none: false
129
129
  - !ruby/object:Gem::Dependency
130
130
  name: simplecov
131
+ prerelease: false
131
132
  requirement: !ruby/object:Gem::Requirement
132
- none: false
133
133
  requirements:
134
134
  - - ! '>='
135
135
  - !ruby/object:Gem::Version
136
136
  version: '0'
137
+ none: false
137
138
  type: :development
138
- prerelease: false
139
139
  version_requirements: !ruby/object:Gem::Requirement
140
- none: false
141
140
  requirements:
142
141
  - - ! '>='
143
142
  - !ruby/object:Gem::Version
144
143
  version: '0'
144
+ none: false
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: rspec
147
+ prerelease: false
147
148
  requirement: !ruby/object:Gem::Requirement
148
- none: false
149
149
  requirements:
150
150
  - - ! '>='
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
+ none: false
153
154
  type: :development
154
- prerelease: false
155
155
  version_requirements: !ruby/object:Gem::Requirement
156
- none: false
157
156
  requirements:
158
157
  - - ! '>='
159
158
  - !ruby/object:Gem::Version
160
159
  version: '0'
160
+ none: false
161
161
  - !ruby/object:Gem::Dependency
162
162
  name: minitest
163
+ prerelease: false
163
164
  requirement: !ruby/object:Gem::Requirement
164
- none: false
165
165
  requirements:
166
166
  - - '='
167
167
  - !ruby/object:Gem::Version
168
- version: 4.1.0
168
+ version: 4.3.3
169
+ none: false
169
170
  type: :development
170
- prerelease: false
171
171
  version_requirements: !ruby/object:Gem::Requirement
172
- none: false
173
172
  requirements:
174
173
  - - '='
175
174
  - !ruby/object:Gem::Version
176
- version: 4.1.0
175
+ version: 4.3.3
176
+ none: false
177
177
  - !ruby/object:Gem::Dependency
178
178
  name: turn
179
+ prerelease: false
179
180
  requirement: !ruby/object:Gem::Requirement
180
- none: false
181
181
  requirements:
182
182
  - - ! '>='
183
183
  - !ruby/object:Gem::Version
184
184
  version: '0'
185
+ none: false
185
186
  type: :development
186
- prerelease: false
187
187
  version_requirements: !ruby/object:Gem::Requirement
188
- none: false
189
188
  requirements:
190
189
  - - ! '>='
191
190
  - !ruby/object:Gem::Version
192
191
  version: '0'
192
+ none: false
193
193
  description: Spinach is a BDD framework on top of gherkin
194
194
  email:
195
195
  - info@codegram.com
@@ -250,6 +250,7 @@ files:
250
250
  - lib/spinach/exceptions.rb
251
251
  - lib/spinach/feature.rb
252
252
  - lib/spinach/feature_steps.rb
253
+ - lib/spinach/features.rb
253
254
  - lib/spinach/frameworks.rb
254
255
  - lib/spinach/frameworks/minitest.rb
255
256
  - lib/spinach/frameworks/rspec.rb
@@ -309,26 +310,20 @@ rdoc_options: []
309
310
  require_paths:
310
311
  - lib
311
312
  required_ruby_version: !ruby/object:Gem::Requirement
312
- none: false
313
313
  requirements:
314
314
  - - ! '>='
315
315
  - !ruby/object:Gem::Version
316
316
  version: '0'
317
- segments:
318
- - 0
319
- hash: -2192107922436848750
320
- required_rubygems_version: !ruby/object:Gem::Requirement
321
317
  none: false
318
+ required_rubygems_version: !ruby/object:Gem::Requirement
322
319
  requirements:
323
320
  - - ! '>='
324
321
  - !ruby/object:Gem::Version
325
322
  version: '0'
326
- segments:
327
- - 0
328
- hash: -2192107922436848750
323
+ none: false
329
324
  requirements: []
330
325
  rubyforge_project:
331
- rubygems_version: 1.8.23
326
+ rubygems_version: 1.8.24
332
327
  signing_key:
333
328
  specification_version: 3
334
329
  summary: Spinach is a BDD framework on top of gherkin