1
0
Fork 0
mirror of https://github.com/thoughtbot/factory_bot_rails.git synced 2022-11-09 11:49:18 -05:00
thoughtbot--factory_bot_rails/features/reloading.feature

104 lines
3.1 KiB
Gherkin
Raw Normal View History

Feature:
When using factory_bot_rails together with Spring
I want changes to my application to trigger the factory_bot_rails reloader
So that factory_bot_rails doesn't hold onto stale class references
Scenario: Editing a model without editing the factory
When I create a new rails application
And I add "factory_bot_rails" from this project as a dependency
And I run `bundle install` with a clean environment
And I write to "db/migrate/1_create_users.rb" with:
"""
migration_class =
if ActiveRecord::Migration.respond_to?(:[])
ActiveRecord::Migration[4.2]
else
ActiveRecord::Migration
end
class CreateUsers < migration_class
def self.up
create_table :users do |t|
t.string :name
end
end
end
"""
And I run `bundle exec rake db:migrate` with a clean environment
And I write to "app/models/user.rb" with:
"""
class User < ActiveRecord::Base
end
"""
And I write to "test/factories.rb" with:
"""
FactoryBot.define do
factory :author, class: User do
name { "Frank" }
end
end
"""
And I write to "test/unit/user_test.rb" with:
"""
require 'test_helper'
class UserTest < ActiveSupport::TestCase
test "use factory" do
author = FactoryBot.create(:author)
assert_equal author.class.object_id, User.object_id
end
end
"""
And I run `bundle binstubs bundler rake spring --force` with a clean environment
And I run `bin/spring binstub --all` with a clean environment
And I run `bin/rake test` with Spring enabled
And I append to "app/models/user.rb" with:
"""
# User model edited
"""
And I run `bin/rake test` with Spring enabled
And I run `spring stop` with a clean environment
Then the output should contain "1 runs, 1 assertions"
And the output should not contain "Failure:"
Ensure factory_bot only loads after initialization Fixes #336 Alternate solution to #343 The initialization process looks like this: Rails runs all of the initializers 1. Run the ["factory_bot.set_factory_paths"][set_factory_paths] initializer 2. Run the ["factory_bot.register_reloader"][register_reloader] initializer, which sets up a [prepare callback][] 3. Run the [`:run_prepare_callbacks`][] initializer 4. This triggers the factory_bot [prepare callback][], which causes factory\_bot to [reload][] Rails runs `after_initialize` callbacks 1. [I18n initializes] 2. factory\_bot [reloads again][] as described in #334 The double reloading of factory_bot in this initialization is not ideal, but also shouldn't generally cause any problems on its own. The problems people are having in #336 come from the fact that I18n gets set up in an `after_initialize` callback, but factory_bot gets reloaded before the `after_initialize` callbacks are triggered. If the `FactoryBot.define` block references any code that uses I18n translations as it loads, that code will raise an error (references inside other factory_bot methods, or code that uses I18n translations inside of methods still works fine, since the whole Rails initialization process would be complete by the time any of that code runs). This commit changes step 4 above to avoid reloading factory_bot before the application has initialized. [set_factory_paths]: https://github.com/thoughtbot/factory_bot_rails/blob/3815aae2b9e4a5c5c3027a2ee8851f44b7c6a4da/lib/factory_bot_rails/railtie.rb#L17-L19 [register_reloader]: https://github.com/thoughtbot/factory_bot_rails/blob/3815aae2b9e4a5c5c3027a2ee8851f44b7c6a4da/lib/factory_bot_rails/railtie.rb#L21-L23 [prepare callback]: https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/factory_bot_rails/reloader.rb#L34-L36 [`:run_prepare_callbacks`]: https://github.com/rails/rails/blob/5-2-stable/railties/lib/rails/application/finisher.rb#L62-L64 [reload]: https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/factory_bot_rails/reloader.rb#L24-L26 [I18n initializes]: https://github.com/rails/rails/blob/13e2102517fafc8f8736fce5d57de901067202d0/activesupport/lib/active_support/i18n_railtie.rb#L16-L20 [reloads again]: https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/factory_bot_rails/railtie.rb#L25-L27 Co-authored-by: Danny Garcia <dannygarcia.me@gmail.com>
2019-09-20 15:59:39 -04:00
Scenario: Initializing the reloader with I18n support
When I create a new rails application
Ensure factory_bot only loads after initialization Fixes #336 Alternate solution to #343 The initialization process looks like this: Rails runs all of the initializers 1. Run the ["factory_bot.set_factory_paths"][set_factory_paths] initializer 2. Run the ["factory_bot.register_reloader"][register_reloader] initializer, which sets up a [prepare callback][] 3. Run the [`:run_prepare_callbacks`][] initializer 4. This triggers the factory_bot [prepare callback][], which causes factory\_bot to [reload][] Rails runs `after_initialize` callbacks 1. [I18n initializes] 2. factory\_bot [reloads again][] as described in #334 The double reloading of factory_bot in this initialization is not ideal, but also shouldn't generally cause any problems on its own. The problems people are having in #336 come from the fact that I18n gets set up in an `after_initialize` callback, but factory_bot gets reloaded before the `after_initialize` callbacks are triggered. If the `FactoryBot.define` block references any code that uses I18n translations as it loads, that code will raise an error (references inside other factory_bot methods, or code that uses I18n translations inside of methods still works fine, since the whole Rails initialization process would be complete by the time any of that code runs). This commit changes step 4 above to avoid reloading factory_bot before the application has initialized. [set_factory_paths]: https://github.com/thoughtbot/factory_bot_rails/blob/3815aae2b9e4a5c5c3027a2ee8851f44b7c6a4da/lib/factory_bot_rails/railtie.rb#L17-L19 [register_reloader]: https://github.com/thoughtbot/factory_bot_rails/blob/3815aae2b9e4a5c5c3027a2ee8851f44b7c6a4da/lib/factory_bot_rails/railtie.rb#L21-L23 [prepare callback]: https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/factory_bot_rails/reloader.rb#L34-L36 [`:run_prepare_callbacks`]: https://github.com/rails/rails/blob/5-2-stable/railties/lib/rails/application/finisher.rb#L62-L64 [reload]: https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/factory_bot_rails/reloader.rb#L24-L26 [I18n initializes]: https://github.com/rails/rails/blob/13e2102517fafc8f8736fce5d57de901067202d0/activesupport/lib/active_support/i18n_railtie.rb#L16-L20 [reloads again]: https://github.com/thoughtbot/factory_bot_rails/blob/master/lib/factory_bot_rails/railtie.rb#L25-L27 Co-authored-by: Danny Garcia <dannygarcia.me@gmail.com>
2019-09-20 15:59:39 -04:00
And I add "factory_bot_rails" from this project as a dependency
And I run `bundle install` with a clean environment
And I run `bundle exec rake db:migrate` with a clean environment
And I write to "app/models/user.rb" with:
"""
class User
TRANSLATION = I18n.translate("translation_key")
end
"""
And I write to "config/locales/en.yml" with:
"""
en:
translation_key: "translation_value"
"""
And I write to "test/factories.rb" with:
"""
FactoryBot.define do
factory :user do
User::TRANSLATION
end
end
"""
And I write to "test/unit/user_test.rb" with:
"""
require 'test_helper'
class UserTest < ActiveSupport::TestCase
test "use factory" do
user = FactoryBot.build(:user)
assert_equal "translation_value", User::TRANSLATION
end
end
"""
And I run `bundle exec rake test` with a clean environment
Then the output should contain "1 runs, 1 assertions"
And the output should not contain "Failure:"