Skip to content

Update fixture support #1372

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 25, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .rspec
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
--color
--warnings
--color
--require spec_helper
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Enhancements:
* Add support for `ActiveJob` specs as standard `RSpec::Rails::RailsExampleGoup`s
via both `:type => :job` and inferring type from spec directory `spec/jobs`.
(Gabe Martin-Dempesy, #1361)
* Include `RSpec::Rails::FixtureSupport` into example groups using metadata
`:use_fixtures => true`. (Aaron Kromer, #1372)

Bug Fixes:

Expand All @@ -16,6 +18,8 @@ Bug Fixes:
* Remove pre-loading of ActionMailer in the Railtie (Aaron Kromer, #1327)
* Fix undefined method `need_auto_run=` error when using Ruby 2.1 and Rails 3.2
without the test-unit gem (Orien Madgwick, #1350)
* Fix load order issued which causes an undefined method `fixture_path` error
when loading rspec-rails after a spec has been created. (Aaron Kromer, #1372)

### 3.2.1 / 2015-02-23
[Full Changelog](http://github.com/rspec/rspec-rails/compare/v3.2.0...v3.2.1)
Expand Down
4 changes: 4 additions & 0 deletions example_app_generator/generate_stuff.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ def using_source_path(path)

# Use the absolute path so we can load it without active record too
apply File.join(DEFAULT_SOURCE_PATH, 'generate_action_mailer_specs.rb')
using_source_path(File.expand_path('..', __FILE__)) do
# rspec-core loads files alphabetically, so we want this to be the first one
copy_file 'spec/__verify_fixture_load_order_spec.rb'
end

gsub_file 'spec/spec_helper.rb', /^=(begin|end)/, ''

Expand Down
4 changes: 4 additions & 0 deletions example_app_generator/run_specs.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
run('bin/rspec spec -cfdoc') || abort
# Ensure we test the issue in-case this isn't the first spec file loaded
run(
'bin/rspec --backtrace -cfdoc spec/__verify_fixture_load_order_spec.rb'
) || abort
run('bin/rake --backtrace spec') || abort
run('bin/rake --backtrace spec:requests') || abort
run('bin/rake --backtrace spec:models') || abort
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This spec needs to be run before `rails_helper` is loaded to check the issue
RSpec.describe "Verify issue rspec/rspec-rails#1355" do
it "passes" do
expect(1).to eq 1
end
end
require 'rails_helper'
11 changes: 10 additions & 1 deletion lib/rspec/rails/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,20 @@ def self.initialize_configuration(config)
config.add_setting :infer_base_class_for_anonymous_controllers, :default => true

# fixture support
config.include RSpec::Rails::FixtureSupport
config.add_setting :use_transactional_fixtures, :alias_with => :use_transactional_examples
config.add_setting :use_instantiated_fixtures
config.add_setting :global_fixtures
config.add_setting :fixture_path
config.include RSpec::Rails::FixtureSupport, :use_fixtures

# We'll need to create a deprecated module in order to properly report to
# gems / projects which are relying on this being loaded globally.
#
# See rspec/rspec-rails#1355 for history
#
# @deprecated Include `RSpec::Rails::RailsExampleGroup` or
# `RSpec::Rails::FixtureSupport` directly instead
config.include RSpec::Rails::FixtureSupport
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does it mean to tag a line of code as deprecated rather than a method or class? Will users see this deprecation in the YARD docs? And why are you including the module above and here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was mostly a note for myself and others for 3.99. Line 72 is us globally patching fixture support onto all specs. Due to semver we can't just remove it. So this was a reminder that we need to warn users in 3.99.

I've added fixture support to the RSpec::Rails:RailsExampleGroup base module. So all Rails related specs which people expect fixtures to be available for will have it. Line 63 above provides an option for people to selectively include fixture support onto any example/group via metadata.


# This allows us to expose `render_views` as a config option even though it
# breaks the convention of other options by using `render_views` as a
Expand Down
1 change: 1 addition & 0 deletions lib/rspec/rails/example/rails_example_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module RailsExampleGroup
include RSpec::Rails::MinitestLifecycleAdapter if ::Rails::VERSION::STRING >= '4'
include RSpec::Rails::MinitestAssertionAdapter
include RSpec::Rails::Matchers
include RSpec::Rails::FixtureSupport
end
end
end
231 changes: 219 additions & 12 deletions spec/rspec/rails/configuration_spec.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,233 @@
require "spec_helper"
require 'rspec/support/spec/in_sub_process'

RSpec.describe "Configuration" do

include RSpec::Support::InSubProcess

subject(:config) { RSpec::Core::Configuration.new }

describe "configuration" do
before do
@orig_render_views = RSpec.configuration.render_views?
RSpec::Rails.initialize_configuration(config)
end

it "adds 'vendor/' to the backtrace exclusions" do
expect(config.backtrace_exclusion_patterns).to include(/vendor\//)
end

it "adds 'lib/rspec/rails' to the backtrace exclusions" do
expect(
config.backtrace_exclusion_patterns
).to include(%r{ lib/rspec/rails })
end

shared_examples_for "adds setting" do |accessor, opts|
opts ||= {}
default_value = opts[:default]
alias_setting = opts[:alias_with]
query_method = "#{accessor}?".to_sym
command_method = "#{accessor}=".to_sym

specify "`##{query_method}` is `#{default_value.inspect}` by default" do
expect(config.send(query_method)).to be(default_value)
end

describe "`##{command_method}`" do
it "changes `#{query_method}` to the provided value" do
expect {
config.send(command_method, :a_value)
}.to change { config.send(query_method) }.to(:a_value)
end

it "sets `#{accessor}` to the provided value" do
expect {
config.send(command_method, :a_value)
}.to change {
config.send(accessor)
}.from(default_value).to(:a_value)
end
end

if alias_setting
specify "`##{alias_setting}` is an alias for `#{accessor}`" do
expect {
config.send(command_method, :a_value)
}.to change { config.send(alias_setting) }.to(:a_value)
end
end
end

after do
RSpec.configuration.render_views = @orig_render_views
context "adds settings" do
include_examples "adds setting",
:infer_base_class_for_anonymous_controllers,
:default => true

include_examples "adds setting",
:use_transactional_fixtures,
:alias_with => :use_transactional_examples

include_examples "adds setting", :use_instantiated_fixtures

include_examples "adds setting", :global_fixtures

include_examples "adds setting", :fixture_path

include_examples "adds setting", :rendering_views

specify "`#render_views?` is falsey by default" do
expect(config.render_views?).to be_falsey
end

specify "`#render_views` sets `render_views?` to `true`" do
expect {
config.render_views
}.to change { config.render_views? }.to be(true)
end

describe "`#render_views=`" do
it "sets `render_views?` to the provided value" do
expect {
config.render_views = false
}.to change { config.render_views? }.from(nil).to(false)
end

it "sets `render_views` to the provided value" do
expect {
config.render_views = :a_value
}.to change { config.render_views? }.to(:a_value)
end
end
end

describe "#infer_spec_type_from_file_location!" do
def in_inferring_type_from_location_environment
in_sub_process do
RSpec.configuration.infer_spec_type_from_file_location!
yield
end
end

shared_examples_for "infers type from location" do |type, location|
it "sets the type to `#{type.inspect}` for file path `#{location}`" do
in_inferring_type_from_location_environment do
allow(RSpec::Core::Metadata).to receive(:relative_path).and_return(
"./#{location}/foos_spec.rb"
)
group = RSpec.describe("Arbitrary Description")
expect(group.metadata).to include(:type => type)
end
end
end

include_examples "infers type from location",
:controller,
"spec/controllers"
include_examples "infers type from location", :helper, "spec/helpers"
include_examples "infers type from location", :mailer, "spec/mailers"
include_examples "infers type from location", :model, "spec/models"
include_examples "infers type from location", :request, "spec/requests"
include_examples "infers type from location", :request, "spec/integration"
include_examples "infers type from location", :request, "spec/api"
include_examples "infers type from location", :routing, "spec/routing"
include_examples "infers type from location", :view, "spec/views"
include_examples "infers type from location", :feature, "spec/features"
end

describe "#render_views?" do
it "is false by default" do
expect(RSpec.configuration.render_views?).to be_falsey
it "fixture support is included with metadata `:use_fixtures`" do
in_sub_process do
RSpec.configuration.global_fixtures = [:foo]
RSpec.configuration.fixture_path = "custom/path"

group = RSpec.describe("Arbitrary Description", :use_fixtures)

expect(group).to respond_to(:fixture_path)
expect(group.fixture_path).to eq("custom/path")
expect(group.new.respond_to?(:foo, true)).to be(true)
end
end

describe "#render_views" do
it "sets render_views? to return true" do
RSpec.configuration.render_views = false
RSpec.configuration.render_views
it "metadata `:type => :controller` sets up controller example groups" do
a_controller_class = Class.new
stub_const "SomeController", a_controller_class

group = RSpec.describe(SomeController, :type => :controller)

expect(group.controller_class).to be(a_controller_class)
expect(group.new).to be_a(RSpec::Rails::ControllerExampleGroup)
end

it "metadata `:type => :helper` sets up helper example groups" do
a_helper_module = Module.new
stub_const "SomeHelper", a_helper_module

group = RSpec.describe(SomeHelper, :type => :helper)

expect(
group.determine_default_helper_class(:ignored)
).to be(a_helper_module)
expect(group.new).to be_a(RSpec::Rails::HelperExampleGroup)
end

it "metadata `:type => :model` sets up model example groups" do
a_model_class = Class.new
stub_const "SomeModel", a_model_class

group = RSpec.describe(SomeModel, :type => :model)

expect(group.new).to be_a(RSpec::Rails::ModelExampleGroup)
end

it "metadata `:type => :request` sets up request example groups" do
a_rails_app = double("Rails application")
the_rails_module = double("Rails module", :application => a_rails_app)
stub_const "Rails", the_rails_module

expect(RSpec.configuration.render_views?).to be_truthy
group = RSpec.describe("Some Request API", :type => :request)

expect(group.new.app).to be(a_rails_app)
expect(group.new).to be_a(RSpec::Rails::RequestExampleGroup)
end

it "metadata `:type => :routing` sets up routing example groups" do
a_controller_class = Class.new
stub_const "SomeController", a_controller_class

group = RSpec.describe(SomeController, :type => :routing)

expect(group).to respond_to(:routes)
expect(group.new).to be_a(RSpec::Rails::RoutingExampleGroup)
end

it "metadata `:type => :view` sets up view example groups" do
a_helper_module = Module.new
stub_const "SomeControllerHelper", a_helper_module

group = RSpec.describe("some_controller/action.html.erb", :type => :view)

expect(group._default_helper).to be(a_helper_module)
expect(group.new).to be_a(RSpec::Rails::ViewExampleGroup)
end

it "metadata `:type => :feature` sets up feature example groups" do
a_rails_app = double("Rails application")
the_rails_module = double("Rails module", :application => a_rails_app)
stub_const "Rails", the_rails_module

group = RSpec.describe("Some feature description", :type => :feature)
example = group.new

expect(example).to respond_to(:visit)
expect(example).to be_a(RSpec::Rails::FeatureExampleGroup)
end

if defined?(ActionMailer)
it "metadata `:type => :mailer` sets up mailer example groups" do
a_mailer_class = Class.new
stub_const "SomeMailer", a_mailer_class
group = RSpec.describe(SomeMailer, :type => :mailer)
expect(group.mailer_class).to be(a_mailer_class)
expect(group.new).to be_a(RSpec::Rails::MailerExampleGroup)
end
end

end