Skip to content
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

Add fixture_paths configuration setting #2673

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions lib/generators/rspec/install/templates/spec/rails_helper.rb
Expand Up @@ -34,7 +34,17 @@
RSpec.configure do |config|
<% if RSpec::Rails::FeatureCheck.has_active_record? -%>
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
<% if ::Rails::VERSION::STRING < "7.1.0" -%>
config.fixture_path = Rails.root.join('spec/fixtures')
jguecaimburu marked this conversation as resolved.
Show resolved Hide resolved
# Starting with Rails 7.1, use this instead:
# config.fixture_paths = [
# Rails.root.join('spec/fixtures')
# ]
<% else -%>
config.fixture_paths = [
Rails.root.join('spec/fixtures')
]
<% end -%>

# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
Expand Down
22 changes: 20 additions & 2 deletions lib/rspec/rails/configuration.rb
Expand Up @@ -57,7 +57,7 @@ def self.add_test_type_configurations(config)
end

# @private
def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity
def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/AbcSize,Metrics/PerceivedComplexity
config.backtrace_exclusion_patterns << /vendor\//
config.backtrace_exclusion_patterns << %r{lib/rspec/rails}

Expand All @@ -69,7 +69,13 @@ def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength
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

if ::Rails::VERSION::STRING < "7.1.0"
config.add_setting :fixture_path
else
config.add_setting :fixture_paths
end

config.include RSpec::Rails::FixtureSupport, :use_fixtures

# We'll need to create a deprecated module in order to properly report to
Expand Down Expand Up @@ -157,6 +163,18 @@ def filter_rails_from_backtrace!
filter_gems_from_backtrace "activemodel", "activerecord",
"activesupport", "activejob"
end

# @deprecated TestFixtures#fixture_path is deprecated and will be removed in Rails 7.2
if ::Rails::VERSION::STRING >= "7.1.0"
def fixture_path=(path)
RSpec.deprecate(
"config.fixture_path = #{path.inspect}",
replacement: "config.fixture_paths = [#{path.inspect}]",
message: "Rails 7.1 has deprecated the singular fixture_path in favour of an array"
benoittgt marked this conversation as resolved.
Show resolved Hide resolved
)
self.fixture_paths = Array(path)
end
end
end

add_test_type_configurations(config)
Expand Down
8 changes: 7 additions & 1 deletion lib/rspec/rails/fixture_file_upload_support.rb
Expand Up @@ -14,6 +14,8 @@ def rails_fixture_file_wrapper
resolved_fixture_path =
if respond_to?(:file_fixture_path) && !file_fixture_path.nil?
file_fixture_path.to_s
elsif respond_to?(:fixture_paths)
(RSpec.configuration.fixture_paths&.first || '').to_s
Comment on lines +17 to +18
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible that respond_to?(:file_fixture_path) is false in Rails 7.1+?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so. This module is included in TestCase: https://github.com/rails/rails/blob/b72b7c35dd9506b08ed040594bbd4536139e6d3f/activesupport/lib/active_support/testing/file_fixtures.rb#L16

But it could be set to nil explicitly if somebody decides to do Rspec.configure { |config| config.file_fixture_path = nil } or self.file_fixture_path = nil in a test case. But in that case, I'm not sure why the wrapper should return a default value. Maybe I'm missing something here.

Copy link
Member

Choose a reason for hiding this comment

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

Does Rails not support multiple paths here? Seems odd they would allow multiple paths for fixtures but not for files?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is weird indeed, but I could not find any reference to a plural method in their codebase. Here the author of the change mentions that it is something that they might wanna do in the future.

Copy link
Member

Choose a reason for hiding this comment

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

Does Rails solely configure this with file_fixture_path directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think so: https://github.com/search?q=repo%3Arails%2Frails%20file_fixture_path&type=code

It defaults to "#{Rails.root}/test/fixtures/files" most of the time and you can overwrite that config. Rails does not use any of the configured fixture_paths to build the file_fixture_path. Althought the first of the fixture paths is "#{Rails.root}/test/fixtures" by default, I think that relation is not enforced.

else
(RSpec.configuration.fixture_path || '').to_s
end
Expand All @@ -26,7 +28,11 @@ class RailsFixtureFileWrapper
include ActiveSupport::Testing::FileFixtures

class << self
attr_accessor :fixture_path
if ::Rails::VERSION::STRING < "7.1.0"
attr_accessor :fixture_path
else
attr_accessor :fixture_paths
end

# Get instance of wrapper
def instance
Expand Down
3 changes: 2 additions & 1 deletion lib/rspec/rails/fixture_support.rb
Expand Up @@ -23,10 +23,11 @@ def run_in_transaction?

# TestFixtures#fixture_path is deprecated and will be removed in Rails 7.2
if respond_to?(:fixture_paths=)
fixture_paths << RSpec.configuration.fixture_path
self.fixture_paths = RSpec.configuration.fixture_paths
else
self.fixture_path = RSpec.configuration.fixture_path
end

self.use_transactional_tests = RSpec.configuration.use_transactional_fixtures
self.use_instantiated_fixtures = RSpec.configuration.use_instantiated_fixtures

Expand Down
11 changes: 10 additions & 1 deletion spec/generators/rspec/install/install_generator_spec.rb
Expand Up @@ -15,6 +15,10 @@ def have_a_fixture_path
match(/^ config\.fixture_path = /m)
end

def have_fixture_paths
match(/^ config\.fixture_paths = /m)
end

def maintain_test_schema
match(/ActiveRecord::Migration\.maintain_test_schema!/m)
end
Expand Down Expand Up @@ -84,7 +88,11 @@ def filter_rails_from_backtrace

specify "with default fixture path" do
run_generator
expect(rails_helper).to have_a_fixture_path
if ::Rails::VERSION::STRING < "7.1.0"
expect(rails_helper).to have_a_fixture_path
else
expect(rails_helper).to have_fixture_paths
end
end

specify "with transactional fixtures" do
Expand Down Expand Up @@ -127,6 +135,7 @@ def filter_rails_from_backtrace
specify "without fixture path" do
run_generator
expect(rails_helper).not_to have_a_fixture_path
expect(rails_helper).not_to have_fixture_paths
end

specify "without transactional fixtures" do
Expand Down
51 changes: 41 additions & 10 deletions spec/rspec/rails/configuration_spec.rb
Expand Up @@ -78,7 +78,11 @@

include_examples "adds setting", :global_fixtures

include_examples "adds setting", :fixture_path
if ::Rails::VERSION::STRING < "7.1.0"
include_examples "adds setting", :fixture_path
else
include_examples "adds setting", :fixture_paths
end

include_examples "adds setting", :rendering_views

Expand Down Expand Up @@ -157,22 +161,49 @@ def in_inferring_type_from_location_environment
include_examples "infers type from location", :feature, "spec/features"
end

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"
if ::Rails::VERSION::STRING < "7.1.0"
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)
group = RSpec.describe("Arbitrary Description", :use_fixtures)

if ::Rails::VERSION::STRING < '7.1.0'
expect(group).to respond_to(:fixture_path)
expect(group.fixture_path).to eq("custom/path")
else

expect(group.new.respond_to?(:foo, true)).to be(true)
end
end
else
it "fixture support is included with metadata `:use_fixtures` and fixture_paths configured" do
in_sub_process do
RSpec.configuration.global_fixtures = [:foo]
RSpec.configuration.fixture_paths = ["custom/path", "other/custom/path"]

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

expect(group).to respond_to(:fixture_paths)
expect(group.fixture_paths).to include("custom/path")
expect(group.fixture_paths).to eq(["custom/path", "other/custom/path"])

expect(group.new.respond_to?(:foo, true)).to be(true)
end
end

it "fixture support is included with metadata `:use_fixtures` and deprecated fixture_path configured" do
in_sub_process do
expect(RSpec).to receive(:deprecate)

RSpec.configuration.global_fixtures = [:foo]
RSpec.configuration.fixture_path = "custom/path"

expect(group.new.respond_to?(:foo, true)).to be(true)
group = RSpec.describe("Arbitrary Description", :use_fixtures)

expect(group).to respond_to(:fixture_paths)
expect(group.fixture_paths).to eq(["custom/path"])

expect(group.new.respond_to?(:foo, true)).to be(true)
end
end
end

Expand Down
63 changes: 45 additions & 18 deletions spec/rspec/rails/fixture_file_upload_support_spec.rb
@@ -1,27 +1,54 @@
module RSpec::Rails
RSpec.describe FixtureFileUploadSupport do
context 'with fixture path set in config' do
it 'resolves fixture file' do
RSpec.configuration.fixture_path = File.dirname(__FILE__)
expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb')
if ::Rails::VERSION::STRING < "7.1.0"
context 'with fixture path set in config' do
it 'resolves fixture file' do
RSpec.configuration.fixture_path = File.dirname(__FILE__)
expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb')
end

it 'resolves supports `Pathname` objects' do
RSpec.configuration.fixture_path = Pathname(File.dirname(__FILE__))
expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb')
end
end

it 'resolves supports `Pathname` objects' do
RSpec.configuration.fixture_path = Pathname(File.dirname(__FILE__))
expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb')
context 'with fixture path set in spec' do
it 'resolves fixture file' do
expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb', File.dirname(__FILE__))
end
end
end

context 'with fixture path set in spec' do
it 'resolves fixture file' do
expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb', File.dirname(__FILE__))
context 'with fixture path not set' do
it 'resolves fixture using relative path' do
RSpec.configuration.fixture_path = nil
expect_to_pass fixture_file_upload_resolved('spec/rspec/rails/fixture_file_upload_support_spec.rb')
end
end
end
else
context 'with fixture paths set in config' do
it 'resolves fixture file' do
RSpec.configuration.fixture_paths = [File.dirname(__FILE__)]
expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb')
end

context 'with fixture path not set' do
it 'resolves fixture using relative path' do
RSpec.configuration.fixture_path = nil
expect_to_pass fixture_file_upload_resolved('spec/rspec/rails/fixture_file_upload_support_spec.rb')
it 'resolves supports `Pathname` objects' do
RSpec.configuration.fixture_paths = [Pathname(File.dirname(__FILE__))]
expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb')
end
end

context 'with fixture path set in spec' do
it 'resolves fixture file' do
expect_to_pass fixture_file_upload_resolved('fixture_file_upload_support_spec.rb', File.dirname(__FILE__))
end
end

context 'with fixture path not set' do
it 'resolves fixture using relative path' do
RSpec.configuration.fixture_path = nil
expect_to_pass fixture_file_upload_resolved('spec/rspec/rails/fixture_file_upload_support_spec.rb')
end
end
end

Expand All @@ -31,11 +58,11 @@ def expect_to_pass(group)
expect(result).to be true
end

def fixture_file_upload_resolved(fixture_name, fixture_path = nil)
def fixture_file_upload_resolved(fixture_name, file_fixture_path = nil)
RSpec::Core::ExampleGroup.describe do
include RSpec::Rails::FixtureFileUploadSupport

self.file_fixture_path = fixture_path
self.file_fixture_path = file_fixture_path

it 'supports fixture file upload' do
file = fixture_file_upload(fixture_name)
Expand Down
11 changes: 8 additions & 3 deletions spec/rspec/rails/fixture_support_spec.rb
@@ -1,14 +1,19 @@
module RSpec::Rails
RSpec.describe FixtureSupport do
context "with use_transactional_fixtures set to false" do
it "still supports fixture_path" do
it "still supports fixture_path/fixture_paths" do
allow(RSpec.configuration).to receive(:use_transactional_fixtures) { false }
group = RSpec::Core::ExampleGroup.describe do
include FixtureSupport
end

expect(group).to respond_to(:fixture_path)
expect(group).to respond_to(:fixture_path=)
if ::Rails::VERSION::STRING < "7.1.0"
expect(group).to respond_to(:fixture_path)
expect(group).to respond_to(:fixture_path=)
else
expect(group).to respond_to(:fixture_paths)
expect(group).to respond_to(:fixture_paths=)
end
end
end

Expand Down