rutabaga 1.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 547b7485f528f7252565c2bec92ffe22494f08c9
4
- data.tar.gz: 6584d74700984a895c43316e4b51ae863cc6f4ac
3
+ metadata.gz: 23d4ee4fca4ba9cc50f66acd809b29a67241567e
4
+ data.tar.gz: f35a01a98cc5df69b2207bb5d35d35f75ab1fb71
5
5
  SHA512:
6
- metadata.gz: 4583d3ed0b60b7cb05f6ed17894ec833cb1b8dde9671880be2dc44cb8075c948dfa119112a282ef85b75c93927195daaac64b407afbb456b5ee591159c41dbae
7
- data.tar.gz: 5fe7c7f08763cf41a28eff3a78937cc2caac4d8344fbe5415b87b7e99174afdef47b81b447503ee48c1188b6af76c3a948a39267937c4cbc7fc160651b0c7d70
6
+ metadata.gz: a0f89ac99d40a51f25b51d35a7a4313aa24804fc7e0a6fadb5160370392e134039220e56c9385373497f1cc9f120304f8e756b7ccf4a2c0b82087995ddb7ba58
7
+ data.tar.gz: 3fc0d2e7d30939fd5e44a2890ffa431f98f05e9481bfe11ded7bae5e9030247f480b48872ce6bfc5724a6f7196b19fd30d095fe93d734b68193e7627bd7b6bab
data/.travis.yml CHANGED
@@ -3,9 +3,9 @@ rvm:
3
3
  - 2.0.0
4
4
  - 2.1.7
5
5
  - 2.2.3
6
- - jruby-19mode
6
+ - jruby-9.0.5.0
7
7
 
8
8
  gemfile:
9
9
  - Gemfile
10
10
 
11
- script: bundle exec rspec spec
11
+ script: bundle exec rspec spec
data/CHANGELOG.md CHANGED
@@ -1,6 +1,38 @@
1
1
  # Changes
2
2
 
3
+ ## Version 2.0.0
4
+
5
+ - Features should now be called directly in the describe block rather than inside an `it` block. This allows specific scenarios to be run without having to run the entire feature.
6
+
7
+ Old:
8
+
9
+ ```ruby
10
+ describe "the feature" do
11
+ it "runs the feature" do
12
+ feature
13
+ end
14
+
15
+ step "first step" do
16
+ ...
17
+ end
18
+ end
19
+ ```
20
+
21
+ New:
22
+
23
+ ```ruby
24
+ feature "the feature" do
25
+ step "first step" do
26
+ ...
27
+ end
28
+ end
29
+ ```
30
+
31
+ The old way is deprecated.
32
+ - Refactor of Turnip and RSpec integration to simplify
33
+ - Improved feature finding, allowing features in the current directory to be found without specifying full path
34
+
3
35
  ## Version 1.0.0
4
36
 
5
37
  - Drop support for turnip versions less than 2.
6
- - Drop support (because of turnip) for rspec versions less than 3.
38
+ - Drop support (because of turnip) for rspec versions less than 3.
data/Gemfile CHANGED
@@ -3,3 +3,9 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in rutabaga.gemspec
4
4
  gemspec
5
5
 
6
+ unless RUBY_PLATFORM
7
+ gem 'pry-byebug'
8
+ gem 'pry-doc'
9
+ gem 'pry-stack_explorer'
10
+ gem 'pry-rescue'
11
+ end
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Rutabaga
2
2
 
3
+ ![image](rutabaga-vs-turnip.jpg)
4
+
3
5
  [Turnip](https://github.com/jnicklas/turnip) hacks to enable running turnips from inside spec files, rather than outside.
4
6
 
5
7
  Rutabaga allows you to invert the control of feature files, so that features are called from your `_spec.rb` files rather than the other way around. Step definitions are then put into the `_spec.rb` files as well. The steps are then scoped to that particular test.
@@ -7,6 +9,7 @@ Rutabaga allows you to invert the control of feature files, so that features are
7
9
  This means that it is simple to create tests that are described by a class (such as controller tests in rspec-rails).
8
10
 
9
11
  [![Build Status](https://travis-ci.org/simplybusiness/rutabaga.svg?branch=master)](https://travis-ci.org/simplybusiness/rutabaga)
12
+ [![Gem Version](https://badge.fury.io/rb/rutabaga.svg)](https://badge.fury.io/rb/rutabaga)
10
13
 
11
14
  ## Installation
12
15
 
@@ -53,19 +56,17 @@ end
53
56
 
54
57
  ### Running a feature file from a spec file
55
58
 
56
- Please look in `spec/controllers/feature_test_spec.rb` and `spec/controllers/feature_test.feature` for more.
57
-
58
- For file `spec/controllers/test_feature_spec.rb`
59
+ If you create a file `spec/controllers/test_feature_spec.rb` and add:
59
60
 
60
61
  ```ruby
61
- it "should run feature" do
62
- feature
62
+ feature "should run feature" do
63
+
63
64
  end
64
65
  ```
65
66
 
66
- Will run `spec/controllers/test_feature.feature`.
67
+ Rutabaga will run `spec/controllers/test_feature.feature`.
67
68
 
68
- Features are found either with the same name as the spec file, or as specified in the example name `it "relative_from_root/path/to/feature/file.feature"`. So, if you have:
69
+ Features are found either with the same name as the spec file, or as specified by the feature `feature "relative_from_root/path/to/feature/file.feature"`. So, if you have:
69
70
 
70
71
  `spec/controllers/feature_test_spec.rb`
71
72
 
@@ -73,45 +74,41 @@ Then the feature will be:
73
74
 
74
75
  `spec/controllers/feature_test.feature`
75
76
 
76
- Alternatively, if the feature is specified in the `it`, that takes precedence:
77
+ Alternatively, if the feature is specified in the `feature`, that takes precedence:
77
78
 
78
79
  ```ruby
79
- it "spec/features/test.feature" do
80
- feature
80
+ feature "spec/features/test.feature" do
81
+
81
82
  end
82
83
  ```
83
84
 
84
- Will run `spec/features/test.feature`.
85
-
86
- Second alternative, is specifying the feature file in the `feature` command:
85
+ Path can also be relative to the spec location so:
87
86
 
88
87
  ```ruby
89
- it "should run the feature" do
90
- feature "spec/features/test.feature"
88
+ feature "test.feature" do
89
+
91
90
  end
92
91
  ```
93
92
 
94
- Will run `spec/features/test.feature`.
93
+ Will run `spec/controllers/test.feature`.
94
+
95
+ **Note** Anywhere that a `.feature` extension can be used, a `.rutabaga` extension is also valid.
95
96
 
96
97
  ### Definining steps
97
98
 
98
99
  Steps are defined in the same way as in Turnip, however, steps can be defined within the rspec context and are scoped to only be available there.
99
100
 
100
101
  ```ruby
101
- describe "step will only be in this context" do
102
- it "should run feature" do
103
- feature
104
- end
102
+ feature "step will only be in this context" do
105
103
 
106
104
  step "action :named" do |named| do
107
105
  expect(named).to eq("a name")
108
106
  end
109
107
  end
110
108
 
111
- describe "step 'action :named' is not available here" do
112
- it "cannot run feature due to missing step" do
113
- expect(feature).to raise_error
114
- end
109
+ feature "step 'action :named' is not available here" do
110
+
111
+ # missing step will cause tests to be marked as pending"
115
112
  end
116
113
  ```
117
114
 
@@ -127,15 +124,18 @@ Other than these differences, Rutabaga is a tiny shim over Turnip and all featur
127
124
  * Test those rules whereever/however appropriate (not just through Capybara/black box)
128
125
  * Use the full power of RSpec (so being able to describe a class and then test it)
129
126
 
130
- From my point of view, the fundamental purpose of Turnip/Cucumber is to document the system in end-user readable form. It is not just to do integration tests.
131
-
132
127
  The most important functionality in a system is the business rules. These range from what appears on a page, to complex rules around when emails should be sent to who. For example, we've written Gherkin tests to test premium changes when a customer changes their insurance coverage.
133
128
 
134
129
  These rules are often implemented in a Model, a lib class, or some other specific class in the system, especially if the application is well modularized.
135
130
 
136
- In any case, business rules are usually implemented somewhere inside a class tested by a unit test. I want to get those business rules tested in Cucumber/Turnip without having to go through the whole system, and without having to have duplicate tests, one inside my rspec and another inside my features.
131
+ In any case, business rules are usually implemented somewhere inside a class tested by a unit test. Those business rules should be tested in Cucumber/Turnip without having to go through the whole system, and without having to have duplicate tests, one inside rspec and another inside features.
132
+
133
+ The goal is to test just the business rule, in Rutabaga, and not the login, the html, the steps to get there, etc. That way, when the rule changes, only the feature, the test code and the class in question need to change. The test is not affected by wider ranging changes, and is therefore less brittle. The features run at the unit code level, but are acceptance tests.
134
+
135
+ ## Notes/Issues
137
136
 
138
- My goal is to test just the business rule, in Turnip, and not the login, the html, the steps to get there, etc. That way, when the rule changes, I change the Turnip, the test code and the class in question. My test is not affected by wider ranging changes, and therefore less brittle. I guess, in that sense, the code runs at the unit code level, but is an acceptance test.
137
+ 1. Capybara's rspec extension also redefines feature, so rutabaga will block capaybara's feature example groups
138
+ from working.
139
139
 
140
140
  ## Contributing
141
141
 
@@ -157,9 +157,9 @@ Put the following (example in a `Gemfile_for_xxx`) to test other versions of gem
157
157
  # Use global Gemfile and customize
158
158
  eval(IO.read('Gemfile'), binding)
159
159
 
160
- gem 'turnip', '1.2.4'
160
+ gem 'turnip', '1.3.1'
161
161
  ```
162
162
 
163
163
  ## Copyright
164
164
 
165
- Copyright © 2012-2015 Simply Business. See LICENSE for details.
165
+ Copyright © 2012-2016 Simply Business. See LICENSE for details.
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'capybara/rspec'
3
+
4
+ describe "capaybara rails does not overwrite the feature command" do
5
+ feature '../test2.feature' do
6
+ step "that :first + :second is calculated" do |first, second|
7
+ @first = first
8
+ @second = second
9
+ end
10
+
11
+ step "my result is :result" do |result|
12
+ expect(@first.to_i + @second.to_i - 1).to eq(result.to_i)
13
+ end
14
+ end
15
+ end
16
+
17
+ describe "turnip doesn't overwrite the type", type: :parent_group do
18
+ feature '../test2.feature' do
19
+ step "that :first + :second is calculated" do |first, second|
20
+ metadata_type = RSpec.current_example.example_group.metadata[:type]
21
+
22
+ puts "feature metadata type is preserved as #{metadata_type}"
23
+
24
+ expect(metadata_type).to eq(:parent_group)
25
+ end
26
+
27
+ step "my result is :result" do |result|
28
+ end
29
+ end
30
+ end
@@ -3,3 +3,13 @@ Feature: Test that rspec will call the feature
3
3
  Scenario: ensures the feature is called
4
4
  Given that 2 + 2 is calculated
5
5
  Then my result is 4
6
+
7
+ Scenario Outline: ensures the outline feature is called
8
+ Given that <a> + <b> is calculated
9
+ Then my result is <c>
10
+
11
+ Examples:
12
+ | a | b | c |
13
+ | 1 | 1 | 2 |
14
+ | 2 | 2 | 4 |
15
+ | 3 | 3 | 5 |
@@ -0,0 +1,15 @@
1
+ Feature: Test that rspec will call the feature
2
+
3
+ Scenario: ensures the feature is called
4
+ Given that 2 + 2 is calculated
5
+ Then my result is 4
6
+
7
+ Scenario Outline: ensures the outline feature is called with one failing example which can be called individually
8
+ Given that <a> + <b> is calculated
9
+ Then my result is <c>
10
+
11
+ Examples:
12
+ | a | b | c |
13
+ | 1 | 1 | 2 |
14
+ | 2 | 2 | 4 |
15
+ | 3 | 3 | 5 |
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ describe "test feature argument" do
4
+ feature
5
+
6
+ step "that :first + :second is calculated" do |first, second|
7
+ @first = first
8
+ @second = second
9
+ end
10
+
11
+ step "my result is :result" do |result|
12
+ expect(@first.to_i + @second.to_i).to eq(result.to_i)
13
+ end
14
+ end
15
+
16
+ feature "feature block" do
17
+ step "that :first + :second is calculated" do |first, second|
18
+ @first = first
19
+ @second = second
20
+ end
21
+
22
+ step "my result is :result" do |result|
23
+ expect(@first.to_i + @second.to_i).to eq(result.to_i)
24
+ end
25
+ end
26
+
27
+ describe "feature block inside a describe block" do
28
+ feature do
29
+
30
+ step "that :first + :second is calculated" do |first, second|
31
+ @first = first
32
+ @second = second
33
+ end
34
+
35
+ step "my result is :result" do |result|
36
+ expect(@first.to_i + @second.to_i).to eq(result.to_i)
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "should find the feature file using the root (and monkey patching the result)" do
42
+ feature "examples/test2.feature"
43
+
44
+ step "that :first + :second is calculated" do |first, second|
45
+ @first = first
46
+ @second = second
47
+ end
48
+
49
+ step "my result is :result" do |result|
50
+ expect(@first.to_i + @second.to_i - 1).to eq(result.to_i)
51
+ end
52
+ end
53
+
54
+ describe "causes a failing test" do
55
+ feature "examples/test2.feature"
56
+
57
+ step "that :first + :second is calculated" do |first, second|
58
+ @first = first
59
+ @second = second
60
+ end
61
+
62
+ step "my result is :result" do |result|
63
+ expect(@first.to_i + @second.to_i).to eq(result.to_i)
64
+ end
65
+ end
66
+
67
+ describe "finds a feature file given as parameter to the 'feature' method" do
68
+ feature "examples/test3.feature"
69
+
70
+ step "that :first * :second is calculated" do |first, second|
71
+ @first = first
72
+ @second = second
73
+ end
74
+
75
+ step "my result is :result" do |result|
76
+ expect(@first.to_i * @second.to_i).to eq(result.to_i)
77
+ end
78
+ end
79
+
80
+ describe "finds a feature file with a different name in the same directory" do
81
+ feature "test3.feature"
82
+
83
+ step "that :first * :second is calculated" do |first, second|
84
+ @first = first
85
+ @second = second
86
+ end
87
+
88
+ step "my result is :result" do |result|
89
+ expect(@first.to_i * @second.to_i).to eq(result.to_i)
90
+ end
91
+ end
92
+
93
+ describe "backgrounds are properly called" do
94
+ feature "examples/test_background.feature"
95
+
96
+ step "we add :initial" do |initial|
97
+ @initial = 10
98
+ end
99
+
100
+ step "that :first * :second is calculated" do |first, second|
101
+ @first = first
102
+ @second = second
103
+ end
104
+
105
+ step "my result is :result" do |result|
106
+ expect(@initial.to_i + @first.to_i * @second.to_i).to eq(result.to_i)
107
+ end
108
+
109
+ end
@@ -1,20 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "test" do
4
- it "should run feature" do
5
- feature
6
- end
7
-
8
- step "that :first + :second is calculated" do |first, second|
9
- @first = first
10
- @second = second
11
- end
12
-
13
- step "my result is :result" do |result|
14
- expect(@first.to_i + @second.to_i).to eq(result.to_i)
15
- end
16
- end
17
-
18
3
  describe "should find the feature file using the root (and monkey patching the result)" do
19
4
  it "examples/test2.feature" do
20
5
  feature
@@ -30,55 +15,3 @@ describe "should find the feature file using the root (and monkey patching the r
30
15
  end
31
16
 
32
17
  end
33
-
34
- describe "causes a failing test" do
35
- it "examples/test2.feature" do
36
- feature
37
- end
38
-
39
- step "that :first + :second is calculated" do |first, second|
40
- @first = first
41
- @second = second
42
- end
43
-
44
- step "my result is :result" do |result|
45
- expect(@first.to_i + @second.to_i).to eq(result.to_i)
46
- end
47
-
48
- end
49
-
50
- describe "finds a feature file given as parameter to the 'feature' method" do
51
- it "implements the named feature" do
52
- feature "examples/test3.feature"
53
- end
54
-
55
- step "that :first * :second is calculated" do |first, second|
56
- @first = first
57
- @second = second
58
- end
59
-
60
- step "my result is :result" do |result|
61
- expect(@first.to_i * @second.to_i).to eq(result.to_i)
62
- end
63
-
64
- end
65
-
66
- describe "backgrounds are properly called" do
67
- it "implements the named feature" do
68
- feature "examples/test_background.feature"
69
- end
70
-
71
- step "we add :initial" do |initial|
72
- @initial = 10
73
- end
74
-
75
- step "that :first * :second is calculated" do |first, second|
76
- @first = first
77
- @second = second
78
- end
79
-
80
- step "my result is :result" do |result|
81
- expect(@initial.to_i + @first.to_i * @second.to_i).to eq(result.to_i)
82
- end
83
-
84
- end
data/lib/rutabaga.rb CHANGED
@@ -1,3 +1,6 @@
1
1
  require 'rutabaga/version'
2
+ require 'active_support/concern'
2
3
  require 'turnip'
3
4
  require 'rutabaga/feature'
5
+ require 'rutabaga/example_group/feature'
6
+ require 'rutabaga/util'
@@ -0,0 +1,45 @@
1
+ require 'turnip/rspec'
2
+ require 'rspec'
3
+
4
+ # Monkey patch rspec to block capybara from using feature
5
+ class RSpec::Core::Configuration
6
+ alias_method :orig_alias_example_group_to, :alias_example_group_to
7
+
8
+ def alias_example_group_to(new_name, *args)
9
+ return if [:feature, :xfeature, :ffeature].include?(new_name)
10
+ orig_alias_example_group_to(new_name, *args)
11
+ end
12
+ end
13
+
14
+ # Monkey patch RSpec to add the feature method in example groups
15
+ class RSpec::Core::ExampleGroup
16
+ class << self
17
+ alias_method :orig_subclass, :subclass
18
+
19
+ def subclass(parent, description, args, &example_group_block)
20
+ self.orig_subclass(parent, description, args, &example_group_block).tap do |describe|
21
+
22
+ if args.any? { |arg| arg.kind_of?(Hash) && arg[:rutabaga] }
23
+ Rutabaga::ExampleGroup::Feature.feature(describe, description, args)
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+
30
+ define_example_group_method :feature, :rutabaga => true
31
+ end
32
+
33
+ module Rutabaga
34
+ module ExampleGroup
35
+ module Feature
36
+ class << self
37
+ def feature(example_group_class, description, args)
38
+ Util.require_if_exists 'turnip_helper'
39
+
40
+ Turnip::RSpec.rutabaga_run(Util.find_feature(description), example_group_class)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -3,8 +3,15 @@ require 'rspec'
3
3
 
4
4
  module Rutabaga
5
5
  module Feature
6
- def feature(feature_file = find_feature)
7
-
6
+ def feature(feature_file = nil)
7
+ RSpec.deprecate(
8
+ "Calling `feature` from an `it` block",
9
+ :message => "Calling `feature` from an `it` block " \
10
+ "is deprecated.\nIt should now be called directly in the " \
11
+ "`describe` block."
12
+ )
13
+
14
+ feature_file = Util.find_feature(feature_file || RSpec.current_example.description)
8
15
  example_group_class = self.class
9
16
 
10
17
  # Hack turnip into the rspec only when needed
@@ -14,20 +21,7 @@ module Rutabaga
14
21
  run(feature_file, example_group_class)
15
22
  end
16
23
 
17
- def find_feature
18
- return get_example.description if File.exists?(get_example.description)
19
-
20
- feature_file = caller(0).find do |call|
21
- call =~ /_spec.rb:/
22
- end.gsub(/_spec.rb:.*\Z/, '.feature')
23
- return feature_file if File.exists?(feature_file)
24
-
25
- raise "Feature file not found. Tried: #{get_example.description} and #{feature_file}"
26
- end
27
-
28
- private
29
-
30
- # Adapted from jnicklas/turnip v1.3.1
24
+ # Adapted from jnicklas/turnip v2.0.0
31
25
  def run(feature_file, example_group_class)
32
26
  Turnip::Builder.build(feature_file).features.each do |feature|
33
27
  describe = example_group_class.describe feature.name, feature.metadata_hash
@@ -38,7 +32,7 @@ module Rutabaga
38
32
  def run_feature(describe, feature, filename, example_group_class)
39
33
  example_group_class.before do
40
34
  # This is kind of a hack, but it will make RSpec throw way nicer exceptions
41
- get_example.metadata[:file_path] = filename
35
+ RSpec.current_example.metadata[:file_path] = filename
42
36
 
43
37
  feature.backgrounds.map(&:steps).flatten.each do |step|
44
38
  run_step(filename, step)
@@ -55,15 +49,5 @@ module Rutabaga
55
49
  end
56
50
  end
57
51
  end
58
-
59
- def get_example
60
- @example ||= RSpec.current_example
61
- end
62
52
  end
63
53
  end
64
-
65
- ::RSpec.configure do |c|
66
- c.include Rutabaga::Feature
67
- # Blow away turnip's pattern, and focus just on features directory
68
- c.pattern.gsub!(",**/*.feature", ",features/**/*.feature")
69
- end
@@ -0,0 +1,68 @@
1
+ # Utils and monkey patches for both versions of feature
2
+
3
+ # Monkey patch for Turnip to not have to copy loads of code
4
+ module Turnip::RSpec
5
+ def self.rutabaga_run(feature_file, example_group_class)
6
+ Turnip::Builder.build(feature_file).features.each do |feature|
7
+ instance_eval <<-EOS, feature_file, feature.line
8
+ describe = example_group_class.describe feature.name, feature.metadata_hash.reject { |key, _| key == :type }
9
+ run_feature(describe, feature, feature_file)
10
+ EOS
11
+ end
12
+ end
13
+ end
14
+
15
+ module Rutabaga
16
+ class Util
17
+ class << self
18
+ def find_feature(description)
19
+ tried = []
20
+
21
+ if description =~ /.*\.(feature|rutabaga)\Z/
22
+ return description if File.exists?(description)
23
+ tried << description
24
+
25
+ candidate = File.join(extract_directory, description)
26
+ return candidate if File.exists?(candidate)
27
+ tried << candidate
28
+ else
29
+ feature_files = extract_features
30
+ feature_files.each do |feature_file|
31
+ return feature_file if File.exists?(feature_file)
32
+ end
33
+ tried += feature_files
34
+ end
35
+
36
+ raise "Feature file not found. Tried: #{tried.join(', ')}"
37
+ end
38
+
39
+ def require_if_exists(filename)
40
+ require filename
41
+ rescue LoadError => e
42
+ # Don't hide LoadErrors raised in the spec helper.
43
+ raise unless e.message.include?(filename)
44
+ end
45
+
46
+ private
47
+
48
+ def extract_directory
49
+ caller(0).find do |call|
50
+ call =~ /_spec.rb:/
51
+ end.gsub(/\/[^\/]+_spec.rb:.*\Z/, '')
52
+ end
53
+
54
+ def extract_features
55
+ base = caller(0).find do |call|
56
+ call =~ /_spec.rb:/
57
+ end.gsub(/_spec.rb:.*\Z/, '')
58
+ [base+'.feature', base+'.rutabaga']
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ ::RSpec.configure do |c|
65
+ c.include Rutabaga::Feature
66
+ # Blow away turnip's pattern, and focus just on features directory
67
+ c.pattern.gsub!(",**/*.feature", ",features/**/*.feature")
68
+ end
@@ -1,3 +1,3 @@
1
1
  module Rutabaga
2
- VERSION = '1.0.0'
2
+ VERSION = '2.0.1'
3
3
  end
Binary file
data/rutabaga.gemspec CHANGED
@@ -16,6 +16,11 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Rutabaga::VERSION
17
17
  gem.license = 'MIT'
18
18
 
19
- gem.add_runtime_dependency 'turnip', ['>= 2.0']
20
- gem.add_development_dependency "pry", '~> 0'
19
+ gem.add_runtime_dependency 'turnip', ['~> 2.0.0']
20
+ gem.add_runtime_dependency 'gherkin', ['~> 2.0']
21
+ gem.add_runtime_dependency 'activesupport'
22
+ # There is a bug in 3.4.1 with turnip 2.0.x
23
+ gem.add_runtime_dependency 'rspec-mocks', ['<= 3.4.0']
24
+ gem.add_development_dependency 'capybara'
25
+ gem.add_development_dependency 'pry', '~> 0'
21
26
  end
data/spec/feature_spec.rb CHANGED
@@ -1,36 +1,76 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'integration', :type => :integration do
4
- before do
5
- @result = %x(rspec -r rutabaga -fd examples/*_spec.rb)
6
- end
4
+ describe 'functionality' do
5
+ before(:all) do
6
+ @result = %x(rspec -r rutabaga -fd examples/*_spec.rb 2>&1)
7
+ end
7
8
 
8
- it "shows the correct description" do
9
- expect(@result).to include('ensures the feature is called')
10
- expect(@result).to include('that 2 + 2 is calculated')
11
- expect(@result).to include('my result is 4')
12
- end
9
+ it "shows the correct description" do
10
+ expect(@result).to include('ensures the feature is called')
11
+ expect(@result).to include('that 2 + 2 is calculated')
12
+ expect(@result).to include('my result is 4')
13
+ end
13
14
 
14
- it "should not show any pending steps" do
15
- expect(@result).not_to include('PENDING')
16
- expect(@result).not_to include('No such step')
17
- end
15
+ it "executes features as an argument" do
16
+ expect(@result).to include('test feature argument')
17
+ end
18
18
 
19
- it "prints out failures and successes" do
20
- expect(@result).to include('10 examples, 1 failure')
21
- end
19
+ it "executes features as blocks/example groups" do
20
+ expect(@result).to include('feature block')
21
+ end
22
22
 
23
- it "should find features relative to the root" do
24
- expect(@result).not_to include('Feature file not found')
25
- end
23
+ it "executes features as blocks inside example groups" do
24
+ expect(@result).to include('feature block inside a describe block')
25
+ end
26
26
 
27
- it "finds the .feature file given as parameter to the 'feature' method" do
28
- expect(@result).to include('that 2 * 4 is calculated')
29
- expect(@result).to include('my result is 8')
30
- end
27
+ it "should not show any pending steps" do
28
+ expect(@result).not_to include('PENDING')
29
+ expect(@result).not_to include('No such step')
30
+ end
31
+
32
+ it "prints out failures and successes" do
33
+ expect(@result).to include('19 examples, 4 failures')
34
+ end
35
+
36
+ it "should find features relative to the root" do
37
+ expect(@result).not_to include('Feature file not found')
38
+ end
31
39
 
32
- it "should scope steps to describe blocks" do
33
- expect(@result).not_to include('Turnip::Ambiguous')
40
+ it "finds the .feature file given as parameter to the 'feature' method" do
41
+ expect(@result).to include('that 2 * 4 is calculated')
42
+ expect(@result).to include('my result is 8')
43
+ end
44
+
45
+ it "should scope steps to describe blocks" do
46
+ expect(@result).not_to include('Turnip::Ambiguous')
47
+ end
48
+
49
+ it "should provide failure messages that allow a specific scenario to be run" do
50
+ expect(@result).to include("rspec ./examples/test_feature_example_group_spec.rb[1:1:1:4:1]")
51
+ end
52
+
53
+ it "should have a feature deprecation warning" do
54
+ expect(@result).to include("Calling `feature` from an `it` block is deprecated.")
55
+ end
34
56
  end
35
57
 
58
+ describe 'compatibility' do
59
+ before(:all) do
60
+ @result = %x(rspec -r rutabaga -fd examples/compatibility/*_spec.rb 2>&1)
61
+ end
62
+
63
+ it "passes all tests" do
64
+ expect(@result).to include('2 examples, 0 failures')
65
+ end
66
+
67
+ it "runs feature blocks even if capybara/rspec is installed" do
68
+ expect(@result).to include("capaybara rails does not overwrite the feature command")
69
+ end
70
+
71
+ it "preserves the type from the surrounding describe blocks (for example rspec rails example groups)" do
72
+ expect(@result).to include("feature metadata type is preserved as parent_group")
73
+ end
74
+
75
+ end
36
76
  end
@@ -0,0 +1,130 @@
1
+ require 'spec_helper'
2
+ require 'rutabaga'
3
+
4
+ describe Rutabaga::Util do
5
+ describe "location of test from stack track" do
6
+ it "finds the directory" do
7
+ expect(subject.class.send(:extract_directory)).to match(/\/rutabaga\/spec\/rutabaga\Z/)
8
+ end
9
+
10
+ it "finds the feature" do
11
+ features = subject.class.send(:extract_features)
12
+ expect(features[0]).to match(/\/rutabaga\/spec\/rutabaga\/util\.feature\Z/)
13
+ expect(features[1]).to match(/\/rutabaga\/spec\/rutabaga\/util\.rutabaga\Z/)
14
+ end
15
+ end
16
+
17
+ describe ".find_feature" do
18
+ let(:subject) { Rutabaga::Util.find_feature(@description) }
19
+ before do
20
+ allow(File).to receive(:exists?).with('spec/rutabaga/existing.feature').and_return(true)
21
+ allow(File).to receive(:exists?).with('spec/rutabaga/missing.feature').and_return(false)
22
+ allow(File).to receive(:exists?).with(nil).and_return(false)
23
+ end
24
+
25
+ it "returns the file if it exists" do
26
+ @description = 'spec/rutabaga/existing.feature'
27
+ expect(subject).to eq('spec/rutabaga/existing.feature')
28
+ end
29
+
30
+ describe "looks for the feature in the spec's directory" do
31
+ before do
32
+ allow(File).to receive(:exists?).with('different.feature').and_return(false)
33
+ end
34
+
35
+ it "looks directly in the directory" do
36
+ @description = 'different.feature'
37
+ expect(File).to receive(:exists?).with(/spec\/rutabaga\/different\.feature\Z/).and_return(true)
38
+
39
+ expect(subject).to match(/spec\/rutabaga\/different\.feature\Z/)
40
+ end
41
+
42
+ it "allows sub-directories" do
43
+ allow(File).to receive(:exists?).with('subdirectory/different.feature').and_return(false)
44
+
45
+ @description = 'subdirectory/different.feature'
46
+ expect(File).to receive(:exists?).with(/spec\/rutabaga\/subdirectory\/different\.feature\Z/).and_return(true)
47
+
48
+ expect(subject).to match(/spec\/rutabaga\/subdirectory\/different\.feature\Z/)
49
+ end
50
+ end
51
+
52
+ describe "figures out the feature name from the spec name" do
53
+ it "description is nil" do
54
+ @description = nil
55
+ allow(File).to receive(:exists?).with(/spec\/rutabaga\/util\.feature\Z/).and_return(true)
56
+ expect(subject).to match(/spec\/rutabaga\/util\.feature\Z/)
57
+ end
58
+
59
+ it "description does not match a feature file" do
60
+ @description = 'this is not a feature file'
61
+ allow(File).to receive(:exists?).with(/this is not a feature file/).and_return(false)
62
+
63
+ allow(File).to receive(:exists?).with(/spec\/rutabaga\/util\.feature\Z/).and_return(true)
64
+ expect(subject).to match(/spec\/rutabaga\/util\.feature\Z/)
65
+ end
66
+
67
+ it "description does not match a feature file" do
68
+ @description = 'this is not a feature file'
69
+ allow(File).to receive(:exists?).with(/this is not a feature file/).and_return(false)
70
+
71
+ allow(File).to receive(:exists?).with(/spec\/rutabaga\/util\.feature\Z/).and_return(false)
72
+ allow(File).to receive(:exists?).with(/spec\/rutabaga\/util\.rutabaga\Z/).and_return(true)
73
+ expect(subject).to match(/spec\/rutabaga\/util\.rutabaga\Z/)
74
+ end
75
+
76
+ it "handles paths with spaces" do
77
+ @description = '/User/person/Internet plugins/feature.feature'
78
+ allow(File).to receive(:exists?).with(@description).and_return(true)
79
+
80
+ expect(subject).to eq(@description)
81
+ end
82
+
83
+ it "allows the .feature extension" do
84
+ @description = "example.feature"
85
+ allow(File).to receive(:exists?).with(@description).and_return(true)
86
+
87
+ expect(subject).to include(@description)
88
+ end
89
+
90
+ it "allows the .rutabaga extension" do
91
+ @description = "example.rutabaga"
92
+ allow(File).to receive(:exists?).with(@description).and_return(true)
93
+
94
+ expect(subject).to include(@description)
95
+ end
96
+
97
+ end
98
+
99
+ describe "raises an error if the feature cannot be found" do
100
+ before do
101
+ allow(File).to receive(:exists?).and_return(false)
102
+ end
103
+
104
+ it "has a nil description" do
105
+ @description = nil
106
+
107
+ expect{subject}.to raise_error(/Feature file not found\. Tried: [\\\/\w]*\/spec\/rutabaga\/util\.feature/)
108
+ end
109
+
110
+ it "has a sentance description" do
111
+ @description = "my life as a dog"
112
+
113
+ expect{subject}.to raise_error(/Feature file not found\. Tried: [\\\/\w]*\/spec\/rutabaga\/util\.feature/)
114
+ end
115
+
116
+ it "has a filename description but the file doesn't exist" do
117
+ @description = "example.feature"
118
+
119
+ expect{subject}.to raise_error(/Feature file not found\. Tried: example\.feature, [\\\/\w]*example\.feature/)
120
+ end
121
+
122
+ it "raises an error if the filename does not end in feature" do
123
+ @description = "example.other"
124
+ allow(File).to receive(:exists?).with(@description).and_return(true)
125
+
126
+ expect{subject}.to raise_error(/Feature file not found\. Tried: [\\\/\w]*\/spec\/rutabaga\/util\.feature/)
127
+ end
128
+ end
129
+ end
130
+ end
metadata CHANGED
@@ -1,29 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rutabaga
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukas Oberhuber
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-07 00:00:00.000000000 Z
11
+ date: 2016-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: turnip
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: gherkin
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
18
32
  - !ruby/object:Gem::Version
19
33
  version: '2.0'
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - ">="
38
+ - - "~>"
25
39
  - !ruby/object:Gem::Version
26
40
  version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-mocks
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "<="
60
+ - !ruby/object:Gem::Version
61
+ version: 3.4.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "<="
67
+ - !ruby/object:Gem::Version
68
+ version: 3.4.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: capybara
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
27
83
  - !ruby/object:Gem::Dependency
28
84
  name: pry
29
85
  requirement: !ruby/object:Gem::Requirement
@@ -52,17 +108,24 @@ files:
52
108
  - LICENSE
53
109
  - README.md
54
110
  - Rakefile
111
+ - examples/compatibility/compatibility_spec.rb
55
112
  - examples/spec_helper.rb
56
113
  - examples/test.feature
57
114
  - examples/test2.feature
58
115
  - examples/test3.feature
59
116
  - examples/test_background.feature
117
+ - examples/test_feature_example_group.feature
118
+ - examples/test_feature_example_group_spec.rb
60
119
  - examples/test_spec.rb
61
120
  - lib/rutabaga.rb
121
+ - lib/rutabaga/example_group/feature.rb
62
122
  - lib/rutabaga/feature.rb
123
+ - lib/rutabaga/util.rb
63
124
  - lib/rutabaga/version.rb
125
+ - rutabaga-vs-turnip.jpg
64
126
  - rutabaga.gemspec
65
127
  - spec/feature_spec.rb
128
+ - spec/rutabaga/util_spec.rb
66
129
  - spec/spec_helper.rb
67
130
  homepage: https://github.com/simplybusiness/rutabaga
68
131
  licenses:
@@ -84,12 +147,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
147
  version: '0'
85
148
  requirements: []
86
149
  rubyforge_project:
87
- rubygems_version: 2.4.5
150
+ rubygems_version: 2.4.5.1
88
151
  signing_key:
89
152
  specification_version: 4
90
153
  summary: Calling Turnip feature files from RSpec, which allows encapsulating a feature
91
154
  inside a describe block
92
155
  test_files:
93
156
  - spec/feature_spec.rb
157
+ - spec/rutabaga/util_spec.rb
94
158
  - spec/spec_helper.rb
95
159
  has_rdoc: