Skip to content

Support file_fixture in Factory definitions #427

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 1 commit into from
Jan 17, 2025
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
6 changes: 4 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ jobs:
ruby-version: ${{ matrix.ruby }}
- name: Setup project
run: bundle install
- name: Run test
run: bundle exec rake
- name: RSpec specs
run: bundle exec rake spec
- name: Minitest tests
run: bundle exec rake test

standard:
name: Run standard
Expand Down
13 changes: 13 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,21 @@ GEM
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (7.1.2)
activesupport (= 7.1.2)
globalid (>= 0.3.6)
activemodel (7.1.2)
activesupport (= 7.1.2)
activerecord (7.1.2)
activemodel (= 7.1.2)
activesupport (= 7.1.2)
timeout (>= 0.4.0)
activestorage (7.1.2)
actionpack (= 7.1.2)
activejob (= 7.1.2)
activerecord (= 7.1.2)
activesupport (= 7.1.2)
marcel (~> 1.0)
activesupport (7.1.2)
base64
bigdecimal
Expand Down Expand Up @@ -92,6 +101,8 @@ GEM
activesupport (>= 5.0.0)
ffi (1.15.5)
ffi (1.15.5-java)
globalid (1.2.1)
activesupport (>= 6.1)
i18n (1.14.5)
concurrent-ruby (~> 1.0)
io-console (0.7.2)
Expand All @@ -107,6 +118,7 @@ GEM
loofah (2.22.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
marcel (1.0.4)
mime-types (3.4.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2023.0218.1)
Expand Down Expand Up @@ -228,6 +240,7 @@ PLATFORMS

DEPENDENCIES
activerecord (>= 5.0.0)
activestorage (>= 5.0.0)
appraisal
aruba
cucumber
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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]
1 change: 1 addition & 0 deletions factory_bot_rails.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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
9 changes: 9 additions & 0 deletions lib/factory_bot_rails/file_fixture_support.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module FactoryBotRails
module FileFixtureSupport
def self.included(klass)
klass.cattr_accessor :file_fixture_support

klass.delegate :file_fixture, to: "self.class.file_fixture_support"
end
end
end
18 changes: 18 additions & 0 deletions lib/factory_bot_rails/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
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
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
Expand All @@ -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
Expand Down
40 changes: 40 additions & 0 deletions spec/factory_bot_rails/factory_spec.rb
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions spec/fake_app.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# frozen_string_literal: true

ENV["DATABASE_URL"] = "sqlite3::memory:"

require "active_record/railtie"
require "active_storage/engine"

module Dummy
class Application < Rails::Application
config.eager_load = false
Expand All @@ -8,6 +13,14 @@ 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

Expand Down
Empty file added spec/fixtures/files/file.txt
Empty file.
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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) }

Expand Down
27 changes: 27 additions & 0 deletions spec/support/active_record/migrations.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

ActiveStorage::Engine.root.glob("db/migrate/*.rb").each { |file| require file }

ActiveSupport.on_load :active_support_test_case do
setup do
CreateActiveStorageTables.migrate :up
end

teardown do
CreateActiveStorageTables.migrate :down
rescue ActiveRecord::StatementInvalid
# no-op
end
end

defined?(RSpec) && RSpec.configure do |config|
config.before do
CreateActiveStorageTables.migrate :up
end

config.after do
CreateActiveStorageTables.migrate :down
rescue ActiveRecord::StatementInvalid
# no-op
end
end
67 changes: 0 additions & 67 deletions spec/support/macros/define_constant.rb

This file was deleted.

40 changes: 40 additions & 0 deletions test/factory_bot_rails/factory_test.rb
Original file line number Diff line number Diff line change
@@ -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
Empty file added test/fixtures/files/file.txt
Empty file.
11 changes: 11 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 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) }
Loading