Skip to content

Commit 052d847

Browse files
committed
Allows metadata to override the type of Rails spec
[Fixes #801]
1 parent e207d0a commit 052d847

File tree

3 files changed

+119
-24
lines changed

3 files changed

+119
-24
lines changed

features/.nav

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- Changelog.md
55
- Upgrade.md
66
- RailsVersions.md (Rails versions)
7+
- directory_structure.feature
78
- model_specs:
89
- errors_on.feature
910
- records.feature

features/directory_structure.feature

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
Feature: Directory Structure
2+
3+
Specs are usually placed in a canonical directory structure that describes
4+
their purpose.
5+
6+
* Model specs reside in the `spec/models` directory
7+
* Controller specs reside in the `spec/controllers` directory
8+
* Request specs reside in the `spec/requests` directory
9+
* Feature specs reside in the `spec/features` directory
10+
* View specs reside in the `spec/views` directory
11+
* Helper specs reside in the `spec/helpers` directory
12+
* Mailer specs reside in the `spec/mailers` directory
13+
* Routing specs reside in the `spec/routing` directory
14+
15+
If you follow this directory structure, RSpec will automatically include the
16+
correct test support functions for each type of test.
17+
18+
Application developers are free to use a different directory structure, but
19+
will need to specify the types manually by adding a `:type` metadata key (for
20+
example, `describe WidgetsController, :type => :controller`)
21+
22+
Scenario: Specs in the `spec/controllers` directory automatically tagged as controller specs
23+
Given a file named "spec/controllers/widgets_controller_spec.rb" with:
24+
"""ruby
25+
require "spec_helper"
26+
27+
describe WidgetsController do
28+
it "responds successfully" do
29+
get :index
30+
expect(response.status).to eq(200)
31+
end
32+
end
33+
"""
34+
When I run `rspec spec`
35+
Then the example should pass
36+
37+
Scenario: Specs in other directories must have their types specified manually
38+
Given a file named "spec/functional/widgets_controller_spec.rb" with:
39+
"""ruby
40+
require "spec_helper"
41+
42+
describe WidgetsController, :type => :controller do
43+
it "responds successfully" do
44+
get :index
45+
expect(response.status).to eq(200)
46+
end
47+
end
48+
"""
49+
When I run `rspec spec`
50+
Then the example should pass
51+
52+
Scenario: Specs in canonical directories can override their types
53+
Given a file named "spec/routing/duckduck_routing_spec.rb" with:
54+
"""ruby
55+
require "spec_helper"
56+
57+
Rails.application.routes.draw do
58+
get "/example" => redirect("http://example.com")
59+
end
60+
61+
# Due to limitations in the Rails routing test framework, routes that
62+
# perform redirects must actually be tested via request specs
63+
describe "/example", :type => :request do
64+
it "redirects to example.com" do
65+
get "/example"
66+
expect(response).to redirect_to("http://example.com")
67+
end
68+
end
69+
"""
70+
When I run `rspec spec`
71+
Then the example should pass

lib/rspec/rails/example.rb

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,53 @@ def c.escaped_path(*parts)
1313
Regexp.compile(parts.join('[\\\/]') + '[\\\/]')
1414
end
1515

16-
c.include RSpec::Rails::ControllerExampleGroup, :type => :controller, :example_group => {
17-
:file_path => c.escaped_path(%w[spec controllers])
18-
}
19-
c.include RSpec::Rails::HelperExampleGroup, :type => :helper, :example_group => {
20-
:file_path => c.escaped_path(%w[spec helpers])
21-
}
22-
if defined?(RSpec::Rails::MailerExampleGroup)
23-
c.include RSpec::Rails::MailerExampleGroup, :type => :mailer, :example_group => {
24-
:file_path => c.escaped_path(%w[spec mailers])
16+
c.include RSpec::Rails::ControllerExampleGroup,
17+
:type => :controller,
18+
:example_group => lambda { |example_group, metadata|
19+
metadata[:type].nil? && c.escaped_path(%w[spec controllers]) =~ example_group[:file_path]
20+
}
21+
22+
c.include RSpec::Rails::HelperExampleGroup,
23+
:type => :helper,
24+
:example_group => lambda { |example_group, metadata|
25+
metadata[:type].nil? && c.escaped_path(%w[spec helpers]) =~ example_group[:file_path]
2526
}
27+
28+
if defined?(RSpec::Rails::MailerExampleGroup)
29+
c.include RSpec::Rails::MailerExampleGroup,
30+
:type => :mailer,
31+
:example_group => lambda { |example_group, metadata|
32+
metadata[:type].nil? && c.escaped_path(%w[spec mailers]) =~ example_group[:file_path]
33+
}
2634
end
27-
c.include RSpec::Rails::ModelExampleGroup, :type => :model, :example_group => {
28-
:file_path => c.escaped_path(%w[spec models])
29-
}
30-
c.include RSpec::Rails::RequestExampleGroup, :type => :request, :example_group => {
31-
:file_path => c.escaped_path(%w[spec (requests|integration|api)])
32-
}
33-
c.include RSpec::Rails::RoutingExampleGroup, :type => :routing, :example_group => {
34-
:file_path => c.escaped_path(%w[spec routing])
35-
}
36-
c.include RSpec::Rails::ViewExampleGroup, :type => :view, :example_group => {
37-
:file_path => c.escaped_path(%w[spec views])
38-
}
39-
c.include RSpec::Rails::FeatureExampleGroup, :type => :feature, :example_group => {
40-
:file_path => c.escaped_path(%w[spec features])
41-
}
35+
36+
c.include RSpec::Rails::ModelExampleGroup,
37+
:type => :model,
38+
:example_group => lambda { |example_group, metadata|
39+
metadata[:type].nil? && c.escaped_path(%w[spec models]) =~ example_group[:file_path]
40+
}
41+
42+
c.include RSpec::Rails::RequestExampleGroup,
43+
:type => :request,
44+
:example_group => lambda { |example_group, metadata|
45+
metadata[:type].nil? && c.escaped_path(%w[spec (requests|integration|api)]) =~ example_group[:file_path]
46+
}
47+
48+
c.include RSpec::Rails::RoutingExampleGroup,
49+
:type => :routing,
50+
:example_group => lambda { |example_group, metadata|
51+
metadata[:type].nil? && c.escaped_path(%w[spec routing]) =~ example_group[:file_path]
52+
}
53+
54+
c.include RSpec::Rails::ViewExampleGroup,
55+
:type => :view,
56+
:example_group => lambda { |example_group, metadata|
57+
metadata[:type].nil? && c.escaped_path(%w[spec views]) =~ example_group[:file_path]
58+
}
59+
60+
c.include RSpec::Rails::FeatureExampleGroup,
61+
:type => :feature,
62+
:example_group => lambda { |example_group, metadata|
63+
metadata[:type].nil? && c.escaped_path(%w[spec features]) =~ example_group[:file_path]
64+
}
4265
end

0 commit comments

Comments
 (0)