From fd4a3158fdd7926e77fdea7436f5bd79d6578d00 Mon Sep 17 00:00:00 2001 From: Sean Doyle Date: Mon, 25 Sep 2023 11:24:10 -0400 Subject: [PATCH] Support `file_fixture` in Factory definitions Related to [factory_bot#1282][] [rails/rails#45606][] has been merged and is likely to be released as part of Rails 7.1. With that addition, the path toward resolving [factory_bot#1282][] becomes more clear. If factories can pass along [Pathname][] instances to attachment attributes, Active Support will handle the rest. Instances of `ActiveSupport::TestCase` provide a [file_fixture][] helper to construct a `Pathname` instance based on the path defined by `ActiveSupport::TestCase.file_fixture_path` (relative to the Rails root directory). [factory_bot#1282]: https://github.com/thoughtbot/factory_bot/issues/1282#issuecomment-1733796049 [rails/rails#45606]: https://github.com/rails/rails/pull/45606 [Pathname]: https://docs.ruby-lang.org/en/master/Pathname.html [file_fixture]: https://api.rubyonrails.org/classes/ActiveSupport/Testing/FileFixtures.html#method-i-file_fixture --- Gemfile.lock | 242 ++++++++++-------- README.md | 13 + Rakefile | 5 +- factory_bot_rails.gemspec | 1 + lib/factory_bot_rails/file_fixture_support.rb | 9 + lib/factory_bot_rails/railtie.rb | 18 ++ spec/factory_bot_rails/factory_spec.rb | 40 +++ spec/fake_app.rb | 20 +- spec/fixtures/files/file.txt | 0 spec/spec_helper.rb | 6 + spec/support/macros/define_constant.rb | 67 ----- test/factory_bot_rails/factory_test.rb | 40 +++ test/fixtures/files/file.txt | 0 test/test_helper.rb | 17 ++ 14 files changed, 307 insertions(+), 171 deletions(-) create mode 100644 lib/factory_bot_rails/file_fixture_support.rb create mode 100644 spec/factory_bot_rails/factory_spec.rb create mode 100644 spec/fixtures/files/file.txt delete mode 100644 spec/support/macros/define_constant.rb create mode 100644 test/factory_bot_rails/factory_test.rb create mode 100644 test/fixtures/files/file.txt create mode 100644 test/test_helper.rb diff --git a/Gemfile.lock b/Gemfile.lock index a229f840..e57a86b0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,128 +8,148 @@ PATH GEM remote: https://rubygems.org/ specs: - actionpack (7.1.2) - actionview (= 7.1.2) - activesupport (= 7.1.2) + actionpack (7.2.2) + actionview (= 7.2.2) + activesupport (= 7.2.2) nokogiri (>= 1.8.5) racc - rack (>= 2.2.4) + rack (>= 2.2.4, < 3.2) rack-session (>= 1.0.1) rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actionview (7.1.2) - activesupport (= 7.1.2) + useragent (~> 0.16) + actionview (7.2.2) + activesupport (= 7.2.2) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activemodel (7.1.2) - activesupport (= 7.1.2) - activerecord (7.1.2) - activemodel (= 7.1.2) - activesupport (= 7.1.2) + activejob (7.2.2) + activesupport (= 7.2.2) + globalid (>= 0.3.6) + activemodel (7.2.2) + activesupport (= 7.2.2) + activerecord (7.2.2) + activemodel (= 7.2.2) + activesupport (= 7.2.2) timeout (>= 0.4.0) - activesupport (7.1.2) + activestorage (7.2.2) + actionpack (= 7.2.2) + activejob (= 7.2.2) + activerecord (= 7.2.2) + activesupport (= 7.2.2) + marcel (~> 1.0) + activesupport (7.2.2) base64 + benchmark (>= 0.3) bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) + concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) - mutex_m - tzinfo (~> 2.0) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) appraisal (2.5.0) bundler rake thor (>= 0.14.0) - aruba (2.1.0) + aruba (2.2.0) bundler (>= 1.17, < 3.0) - childprocess (>= 2.0, < 5.0) contracts (>= 0.16.0, < 0.18.0) - cucumber (>= 4.0, < 9.0) + cucumber (>= 8.0, < 10.0) rspec-expectations (~> 3.4) thor (~> 1.0) ast (2.4.2) base64 (0.2.0) + benchmark (0.3.0) bigdecimal (3.1.8) - bigdecimal (3.1.8-java) builder (3.3.0) - childprocess (4.1.0) concurrent-ruby (1.3.4) connection_pool (2.4.1) - contracts (0.17) + contracts (0.17.2) crass (1.0.6) - cucumber (8.0.0) - builder (~> 3.2, >= 3.2.4) - cucumber-ci-environment (~> 9.0, >= 9.0.4) - cucumber-core (~> 11.0, >= 11.0.0) - cucumber-cucumber-expressions (~> 15.1, >= 15.1.1) - cucumber-gherkin (~> 23.0, >= 23.0.1) - cucumber-html-formatter (~> 19.1, >= 19.1.0) - cucumber-messages (~> 18.0, >= 18.0.0) - diff-lcs (~> 1.5, >= 1.5.0) - mime-types (~> 3.4, >= 3.4.1) - multi_test (~> 1.1, >= 1.1.0) - sys-uname (~> 1.2, >= 1.2.2) - cucumber-ci-environment (9.1.0) - cucumber-core (11.0.0) - cucumber-gherkin (~> 23.0, >= 23.0.1) - cucumber-messages (~> 18.0, >= 18.0.0) - cucumber-tag-expressions (~> 4.1, >= 4.1.0) - cucumber-cucumber-expressions (15.2.0) - cucumber-gherkin (23.0.1) - cucumber-messages (~> 18.0, >= 18.0.0) - cucumber-html-formatter (19.2.0) - cucumber-messages (~> 18.0, >= 18.0.0) - cucumber-messages (18.0.0) - cucumber-tag-expressions (4.1.0) + cucumber (9.2.0) + builder (~> 3.2) + cucumber-ci-environment (> 9, < 11) + cucumber-core (> 13, < 14) + cucumber-cucumber-expressions (~> 17.0) + cucumber-gherkin (> 24, < 28) + cucumber-html-formatter (> 20.3, < 22) + cucumber-messages (> 19, < 25) + diff-lcs (~> 1.5) + mini_mime (~> 1.1) + multi_test (~> 1.1) + sys-uname (~> 1.2) + cucumber-ci-environment (10.0.1) + cucumber-core (13.0.3) + cucumber-gherkin (>= 27, < 28) + cucumber-messages (>= 20, < 23) + cucumber-tag-expressions (> 5, < 7) + cucumber-cucumber-expressions (17.1.0) + bigdecimal + cucumber-gherkin (27.0.0) + cucumber-messages (>= 19.1.4, < 23) + cucumber-html-formatter (21.7.0) + cucumber-messages (> 19, < 27) + cucumber-messages (22.0.0) + cucumber-tag-expressions (6.1.1) diff-lcs (1.5.1) drb (2.2.1) erubi (1.13.0) factory_bot (6.5.0) activesupport (>= 5.0.0) - ffi (1.15.5) - ffi (1.15.5-java) - i18n (1.14.5) + ffi (1.17.0-aarch64-linux-gnu) + ffi (1.17.0-aarch64-linux-musl) + ffi (1.17.0-arm-linux-gnu) + ffi (1.17.0-arm-linux-musl) + ffi (1.17.0-arm64-darwin) + ffi (1.17.0-x86-linux-gnu) + ffi (1.17.0-x86-linux-musl) + ffi (1.17.0-x86_64-darwin) + ffi (1.17.0-x86_64-linux-gnu) + ffi (1.17.0-x86_64-linux-musl) + globalid (1.2.1) + activesupport (>= 6.1) + i18n (1.14.6) concurrent-ruby (~> 1.0) io-console (0.7.2) - io-console (0.7.2-java) - irb (1.14.0) + irb (1.14.1) rdoc (>= 4.0.0) reline (>= 0.4.2) - jar-dependencies (0.4.1) - json (2.7.2) - json (2.7.2-java) + json (2.7.5) language_server-protocol (3.17.0.3) lint_roller (1.1.0) - loofah (2.22.0) + logger (1.6.1) + loofah (2.23.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) - mime-types (3.4.1) - mime-types-data (~> 3.2015) - mime-types-data (3.2023.0218.1) - mini_portile2 (2.8.7) + marcel (1.0.4) + mini_mime (1.1.5) minitest (5.25.1) multi_test (1.1.0) - mutex_m (0.2.0) - nokogiri (1.16.7) - mini_portile2 (~> 2.8.2) + nokogiri (1.16.7-aarch64-linux) + racc (~> 1.4) + nokogiri (1.16.7-arm-linux) + racc (~> 1.4) + nokogiri (1.16.7-arm64-darwin) racc (~> 1.4) - nokogiri (1.16.7-java) + nokogiri (1.16.7-x86-linux) + racc (~> 1.4) + nokogiri (1.16.7-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.16.7-x86_64-linux) racc (~> 1.4) parallel (1.26.3) - parser (3.3.4.2) + parser (3.3.5.1) ast (~> 2.4.1) racc psych (5.1.2) stringio - psych (5.1.2-java) - jar-dependencies (>= 0.1.7) racc (1.8.1) - racc (1.8.1-java) - rack (3.1.7) + rack (3.1.8) rack-session (2.0.0) rack (>= 3.0.0) rack-test (2.1.0) @@ -144,10 +164,10 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (7.1.2) - actionpack (= 7.1.2) - activesupport (= 7.1.2) - irb + railties (7.2.2) + actionpack (= 7.2.2) + activesupport (= 7.2.2) + irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) @@ -157,77 +177,95 @@ GEM rdoc (6.7.0) psych (>= 4.0.0) regexp_parser (2.9.2) - reline (0.5.9) + reline (0.5.10) io-console (~> 0.5) - rexml (3.3.6) - strscan - rspec-core (3.13.0) + rspec-core (3.13.2) rspec-support (~> 3.13.0) - rspec-expectations (3.13.2) + rspec-expectations (3.13.3) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-mocks (3.13.1) + rspec-mocks (3.13.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (6.1.4) - actionpack (>= 6.1) - activesupport (>= 6.1) - railties (>= 6.1) + rspec-rails (7.0.1) + actionpack (>= 7.0) + activesupport (>= 7.0) + railties (>= 7.0) rspec-core (~> 3.13) rspec-expectations (~> 3.13) rspec-mocks (~> 3.13) rspec-support (~> 3.13) rspec-support (3.13.1) - rubocop (1.65.1) + rubocop (1.66.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.4, < 3.0) - rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.31.1, < 2.0) + rubocop-ast (>= 1.32.2, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.32.1) + rubocop-ast (1.33.0) parser (>= 3.3.1.0) - rubocop-performance (1.21.1) + rubocop-performance (1.22.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (1.13.0) - sqlite3 (1.6.2) - mini_portile2 (~> 2.8.0) - standard (1.40.0) + securerandom (0.3.1) + sqlite3 (2.2.0-aarch64-linux-gnu) + sqlite3 (2.2.0-aarch64-linux-musl) + sqlite3 (2.2.0-arm-linux-gnu) + sqlite3 (2.2.0-arm-linux-musl) + sqlite3 (2.2.0-arm64-darwin) + sqlite3 (2.2.0-x86-linux-gnu) + sqlite3 (2.2.0-x86-linux-musl) + sqlite3 (2.2.0-x86_64-darwin) + sqlite3 (2.2.0-x86_64-linux-gnu) + sqlite3 (2.2.0-x86_64-linux-musl) + standard (1.41.1) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.65.0) + rubocop (~> 1.66.0) standard-custom (~> 1.0.0) - standard-performance (~> 1.4) + standard-performance (~> 1.5) standard-custom (1.0.2) lint_roller (~> 1.0) rubocop (~> 1.50) - standard-performance (1.4.0) + standard-performance (1.5.0) lint_roller (~> 1.1) - rubocop-performance (~> 1.21.0) + rubocop-performance (~> 1.22.0) stringio (3.1.1) - strscan (3.1.0) - strscan (3.1.0-java) - sys-uname (1.2.3) + sys-uname (1.3.0) ffi (~> 1.1) thor (1.3.2) - timeout (0.4.1) + timeout (0.4.2) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (2.5.0) - webrick (1.8.1) - zeitwerk (2.6.17) + unicode-display_width (2.6.0) + useragent (0.16.10) + webrick (1.8.2) + zeitwerk (2.7.1) PLATFORMS - java - ruby + aarch64-linux + aarch64-linux-gnu + aarch64-linux-musl + arm-linux + arm-linux-gnu + arm-linux-musl + arm64-darwin + x86-linux + x86-linux-gnu + x86-linux-musl + x86_64-darwin + x86_64-linux + x86_64-linux-gnu + x86_64-linux-musl DEPENDENCIES activerecord (>= 5.0.0) + activestorage (>= 5.0.0) appraisal aruba cucumber diff --git a/README.md b/README.md index 6aef3130..a1191086 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,19 @@ using an empty array: config.factory_bot.definition_file_paths = [] ``` +### File Fixture Support + +Factories have access to [ActiveSupport::Testing::FileFixtures#file_fixture][] +helper to read files from tests. + +To disable file fixture support, set `file_fixture_support = false`: + +```rb +config.factory_bot.file_fixture_support = false +``` + +[ActiveSupport::Testing::FileFixtures#file_fixture]: https://api.rubyonrails.org/classes/ActiveSupport/Testing/FileFixtures.html#method-i-file_fixture + ### Generators Including factory\_bot\_rails in the development group of your Gemfile diff --git a/Rakefile b/Rakefile index 1b8ba844..ee1006f8 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,7 @@ require "bundler/setup" require "cucumber/rake/task" require "rspec/core/rake_task" +require "minitest/test_task" require "standard/rake" Bundler::GemHelper.install_tasks name: "factory_bot_rails" @@ -12,5 +13,7 @@ end RSpec::Core::RakeTask.new(:spec) +Minitest::TestTask.create + desc "Run the test suite and standard" -task default: %w[spec cucumber standard] +task default: %w[spec test cucumber standard] diff --git a/factory_bot_rails.gemspec b/factory_bot_rails.gemspec index d86dae01..3f58232f 100644 --- a/factory_bot_rails.gemspec +++ b/factory_bot_rails.gemspec @@ -24,4 +24,5 @@ Gem::Specification.new do |s| s.add_development_dependency("sqlite3") s.add_development_dependency("activerecord", ">= 5.0.0") + s.add_development_dependency("activestorage", ">= 5.0.0") end diff --git a/lib/factory_bot_rails/file_fixture_support.rb b/lib/factory_bot_rails/file_fixture_support.rb new file mode 100644 index 00000000..ef2044a9 --- /dev/null +++ b/lib/factory_bot_rails/file_fixture_support.rb @@ -0,0 +1,9 @@ +module FactoryBotRails + module FileFixtureSupport + def self.included(klass) + klass.class_attribute :file_fixture_support, instance_accessor: false + + klass.delegate :file_fixture, to: "self.class.file_fixture_support" + end + end +end diff --git a/lib/factory_bot_rails/railtie.rb b/lib/factory_bot_rails/railtie.rb index 0e7dfdb8..2b122370 100644 --- a/lib/factory_bot_rails/railtie.rb +++ b/lib/factory_bot_rails/railtie.rb @@ -4,6 +4,7 @@ require "factory_bot_rails/generator" require "factory_bot_rails/reloader" require "factory_bot_rails/factory_validator" +require "factory_bot_rails/file_fixture_support" require "rails" module FactoryBotRails @@ -11,6 +12,7 @@ class Railtie < Rails::Railtie config.factory_bot = ActiveSupport::OrderedOptions.new config.factory_bot.definition_file_paths = FactoryBot.definition_file_paths config.factory_bot.validator = FactoryBotRails::FactoryValidator.new + config.factory_bot.file_fixture_support = true initializer "factory_bot.set_fixture_replacement" do Generator.new(config).run @@ -20,6 +22,22 @@ class Railtie < Rails::Railtie FactoryBot.definition_file_paths = definition_file_paths end + config.after_initialize do + if config.factory_bot.file_fixture_support + FactoryBot::SyntaxRunner.include FactoryBotRails::FileFixtureSupport + + ActiveSupport.on_load :active_support_test_case do + setup { FactoryBot::SyntaxRunner.file_fixture_support = self } + end + + if defined?(RSpec) && RSpec.respond_to?(:configure) + RSpec.configure do |config| + config.before { FactoryBot::SyntaxRunner.file_fixture_support = self } + end + end + end + end + config.after_initialize do |app| FactoryBot.find_definitions Reloader.new(app).run diff --git a/spec/factory_bot_rails/factory_spec.rb b/spec/factory_bot_rails/factory_spec.rb new file mode 100644 index 00000000..479ff1f9 --- /dev/null +++ b/spec/factory_bot_rails/factory_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "factory extensions" do + describe "#file_fixture" do + it "delegates to the test harness" do + FactoryBot.define do + factory :upload, class: Struct.new(:filename) do + filename { file_fixture("file.txt") } + end + end + + upload = FactoryBot.build(:upload) + + expect(Pathname(upload.filename)).to eq(file_fixture("file.txt")) + end + + it "uploads an ActiveStorage::Blob" do + FactoryBot.define do + factory :active_storage_blob, class: ActiveStorage::Blob do + filename { pathname.basename } + + transient do + pathname { file_fixture("file.txt") } + end + + after :build do |model, factory| + model.upload factory.pathname.open + end + end + end + + blob = FactoryBot.create(:active_storage_blob) + + expect(blob.filename.to_s).to eq("file.txt") + expect(blob.download).to eq(file_fixture("file.txt").read) + end + end +end diff --git a/spec/fake_app.rb b/spec/fake_app.rb index 958850a1..681344cc 100644 --- a/spec/fake_app.rb +++ b/spec/fake_app.rb @@ -1,5 +1,11 @@ # frozen_string_literal: true +require "rails" +require "active_record/railtie" +require "active_storage/engine" + +ENV["DATABASE_URL"] = "sqlite3::memory:" + module Dummy class Application < Rails::Application config.eager_load = false @@ -8,9 +14,21 @@ class Application < Rails::Application if Rails.gem_version >= Gem::Version.new("7.1") config.active_support.cache_format_version = 7 end + + config.active_storage.service = :local + config.active_storage.service_configurations = { + local: { + root: root.join("tmp/storage"), + service: "Disk" + } + } end end -Rails.logger = Logger.new("/dev/null") +Rails.logger = Logger.new(File::NULL) + +ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:") + +ActiveStorage::Engine.root.glob("db/migrate/*.rb").each { |file| require file } Rails.application.initialize! diff --git a/spec/fixtures/files/file.txt b/spec/fixtures/files/file.txt new file mode 100644 index 00000000..e69de29b diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1c77212d..3a3adf85 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,6 +4,7 @@ require "factory_bot_rails" require "fake_app" +require "rspec/rails" Dir["spec/support/**/*.rb"].each { |f| require File.expand_path(f) } @@ -11,4 +12,9 @@ config.run_all_when_everything_filtered = true config.filter_run :focus config.order = "random" + + config.before do + CreateActiveStorageTables.new.change + rescue ActiveRecord::StatementInvalid + end end diff --git a/spec/support/macros/define_constant.rb b/spec/support/macros/define_constant.rb deleted file mode 100644 index 5184f29f..00000000 --- a/spec/support/macros/define_constant.rb +++ /dev/null @@ -1,67 +0,0 @@ -require "active_record" - -module DefineConstantMacros - def define_class(path, base = Object, &block) - const = stub_const(path, Class.new(base)) - const.class_eval(&block) if block - const - end - - def define_model(name, columns = {}, &) - model = define_class(name, ActiveRecord::Base, &) - create_table(model.table_name) do |table| - columns.each do |column_name, type| - table.column column_name, type - end - end - model - end - - def create_table(table_name, &) - connection = ActiveRecord::Base.connection - - begin - connection.execute("DROP TABLE IF EXISTS #{table_name}") - connection.create_table(table_name, &) - created_tables << table_name - connection - rescue Exception => e # rubocop:disable Lint/RescueException - connection.execute("DROP TABLE IF EXISTS #{table_name}") - raise e - end - end - - def clear_generated_tables - created_tables.each do |table_name| - clear_generated_table(table_name) - end - created_tables.clear - end - - def clear_generated_table(table_name) - ActiveRecord::Base - .connection - .execute("DROP TABLE IF EXISTS #{table_name}") - end - - private - - def created_tables - @created_tables ||= [] - end -end - -RSpec.configure do |config| - config.include DefineConstantMacros - - config.before(:all) do - ActiveRecord::Base.establish_connection( - adapter: "sqlite3", - database: ":memory:" - ) - end - - config.after do - clear_generated_tables - end -end diff --git a/test/factory_bot_rails/factory_test.rb b/test/factory_bot_rails/factory_test.rb new file mode 100644 index 00000000..0c657ef7 --- /dev/null +++ b/test/factory_bot_rails/factory_test.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "test_helper" + +class FactoryBotRails::FactoryTest < ActiveSupport::TestCase + self.file_fixture_path = "test/fixtures/files" + + test "delegates #file_fixture to the test harness" do + FactoryBot.define do + factory :upload, class: Struct.new(:filename) do + filename { file_fixture("file.txt") } + end + end + + upload = FactoryBot.build(:upload) + + assert_equal file_fixture("file.txt"), upload.filename + end + + test "uploads an ActiveStorage::Blob" do + FactoryBot.define do + factory :active_storage_blob, class: ActiveStorage::Blob do + filename { pathname.basename } + + transient do + pathname { file_fixture("file.txt") } + end + + after :build do |model, factory| + model.upload factory.pathname.open + end + end + end + + blob = FactoryBot.create(:active_storage_blob) + + assert_equal "file.txt", blob.filename.to_s + assert_equal file_fixture("file.txt").read, blob.download + end +end diff --git a/test/fixtures/files/file.txt b/test/fixtures/files/file.txt new file mode 100644 index 00000000..e69de29b diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 00000000..8258e92a --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +# Configure Rails Environment +ENV["RAILS_ENV"] = "test" + +require_relative "../spec/fake_app" +require "rails/test_help" +require "factory_bot_rails" + +Dir["spec/support/**/*.rb"].each { |f| require File.expand_path(f) } + +ActiveSupport.on_load :active_support_test_case do + setup do + CreateActiveStorageTables.new.change + rescue ActiveRecord::StatementInvalid + end +end