Document and make explicit certain "boot" order

- Ensure that the "paper_trail" initializer happens before the
end-user's initializers (in their app's config/initializers)
- Document the boot process of dummy_app and how it differs
from a conventional app.

This is a direct continuation of fc6c5f6, which was a collaboration
between Eric and myself, but I choose to make this a separate
commit, partly for vanity, and partly on the faint hope that it
might make review easier.
This commit is contained in:
Jared Beck 2021-03-18 01:18:32 -04:00
parent fc6c5f6941
commit 6616e13023
4 changed files with 50 additions and 32 deletions

View File

@ -2,13 +2,15 @@
module PaperTrail
# Represents code to load within Rails framework. See documentation in
# `rails/railtie.rb`.
# `railties/lib/rails/railtie.rb`.
# @api private
class Railtie < ::Rails::Railtie
# PaperTrail only has one initializer. The `initializer` method can take a
# `before:` or `after:` argument, but that's only relevant for railties with
# more than one initializer.
initializer "paper_trail" do
# PaperTrail only has one initializer.
#
# We specify `before: "load_config_initializers"` to ensure that the PT
# initializer happens before "app initializers" (those defined in
# the app's `config/initalizers`).
initializer "paper_trail", before: "load_config_initializers" do
# `on_load` is a "lazy load hook". It "declares a block that will be
# executed when a Rails component is fully loaded". (See
# `active_support/lazy_load_hooks.rb`)

View File

@ -2,12 +2,14 @@
require File.expand_path("boot", __dir__)
# Pick the frameworks you want:
require "active_record/railtie"
require "action_controller/railtie"
# Here a conventional app would load the Rails components it needs, but we have
# already loaded these in our spec_helper.
# require "active_record/railtie"
# require "action_controller/railtie"
Bundler.require(:default, Rails.env)
require "paper_trail"
# Here a conventional app would require gems, but again, we have already loaded
# these in our spec_helper.
# Bundler.require(:default, Rails.env)
module Dummy
class Application < Rails::Application

View File

@ -1,18 +1,3 @@
# frozen_string_literal: true
require "rubygems"
# When you run rake locally (not on travis) in this dummy app, set the
# BUNDLE_GEMFILE env. variable to ensure that the correct version of AR is used
# for e.g. migrations. See examples in CONTRIBUTING.md.
unless ENV.key?("BUNDLE_GEMFILE")
gemfile = File.expand_path("../../../Gemfile", __dir__)
if File.exist?(gemfile)
puts "Booting PT test dummy app: Using gemfile: #{gemfile}"
ENV["BUNDLE_GEMFILE"] = gemfile
end
end
require "bundler"
Bundler.setup
$LOAD_PATH.unshift(File.expand_path("../../../lib", __dir__))
# Unlike a conventional Rails app, our "dummy" app is booted by our spec_helper.

View File

@ -30,16 +30,45 @@ RSpec.configure do |config|
Kernel.srand config.seed
end
require File.expand_path("dummy_app/config/environment", __dir__)
require "rspec/rails"
require "paper_trail/frameworks/rspec"
require "ffaker"
# At this point, totally isolated unit tests could be run. But the PT test suite
# also has "integration" tests, via a "dummy" Rails app. Here, we boot that
# "dummy" app. The following process follows the same order, roughly, as a
# conventional Rails app.
#
# In the past, this boot process was partially implemented here, and partially
# in `dummy_app/config/*`. By consolidating it here,
#
# - It can better be understood, and documented in one place
# - It can more closely resememble a conventional app boot. For example, loading
# gems (like rspec-rails) _before_ loading the app.
# Migrate
# First, `config/boot.rb` would add gems to $LOAD_PATH.
Bundler.setup
# Then, the chosen components of Rails would be loaded. In our case, we only
# test with AR and AC.
require "active_record/railtie"
require "action_controller/railtie"
# Then, gems are loaded. In a conventional Rails app, this would be done with
# by the `Bundler.require` in `config/application.rb`.
require "paper_trail"
require "ffaker"
require "rspec/rails"
require "rails-controller-testing"
# Now we can load our dummy app. Its boot process does not perfectly match a
# conventional Rails app, but it's what we were able to fit in our test suite.
require File.expand_path("dummy_app/config/environment", __dir__)
# Now that AR has a connection pool, we can migrate the database.
require_relative "support/paper_trail_spec_migrator"
::PaperTrailSpecMigrator.new.migrate
# This final section reselmbles what might be dummy_app's spec_helper, if it
# had one.
require "paper_trail/frameworks/rspec"
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.fixture_path = nil # we use factories, not fixtures
config.use_transactional_fixtures = true
end