Merge pull request #1277 from paper-trail-gem/release-11.1.0

Release 11.1.0
This commit is contained in:
Jared Beck 2020-12-16 11:00:13 -05:00 committed by GitHub
commit 3f2e6f0b66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 302 additions and 258 deletions

View File

@ -51,26 +51,36 @@ Testing is a little awkward because the test suite:
### Test sqlite, AR 6
```
DB=sqlite bundle exec appraisal ar-6.0 rake
DB=sqlite bundle exec appraisal rails-6.0 rake
```
### Test sqlite, AR 5
```
DB=sqlite bundle exec appraisal ar-5.2 rake
DB=sqlite bundle exec appraisal rails-5.2 rake
```
### Test mysql, AR 5
```
DB=mysql bundle exec appraisal ar-5.2 rake
DB=mysql bundle exec appraisal rails-5.2 rake
```
### Test postgres, AR 5
```
createuser --superuser postgres
DB=postgres bundle exec appraisal ar-5.2 rake
DB=postgres bundle exec appraisal rails-5.2 rake
```
## The dummy_app
In the rare event you need a `console` in the `dummy_app`:
```
cd spec/dummy_app
cp config/database.mysql.yml config/database.yml
BUNDLE_GEMFILE='../../gemfiles/rails_5.2.gemfile' bin/rails console -e test
```
## Adding new schema

131
.github/workflows/test.yml vendored Normal file
View File

@ -0,0 +1,131 @@
name: gha-workflow-pt-test
on: [push, pull_request]
jobs:
# Linting is a separate job, primary because it only needs to be done once,
# and secondarily because jobs are performed concurrently.
gha-job-pt-lint:
name: Lint
runs-on: ubuntu-18.04
steps:
- name: Checkout source
uses: actions/checkout@v2
- name: Setup ruby
uses: actions/setup-ruby@v1
with:
# Set to `TargetRubyVersion` in `.rubocopy.yml`
ruby-version: 2.4
- name: Bundle
run: |
gem install bundler
bundle install --jobs 4 --retry 3
- name: Lint
run: bundle exec rubocop
# The test job is a matrix of ruby/rails versions.
gha-job-pt-test:
name: Ruby ${{ matrix.ruby }}, ${{ matrix.gemfile }}.gemfile
runs-on: ubuntu-18.04
services:
gha-service-pt-mysql:
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: paper_trail_test
image: mysql:8.0
options: >-
--health-cmd="mysqladmin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
ports:
- 3306:3306
gha-service-pt-postgres:
env:
POSTGRES_PASSWORD: asdfasdf
image: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
strategy:
# Unlike TravisCI, the database will not be part of the matrix. Each
# sub-job in the matrix tests all three databases. Alternatively, we could
# have set this up with each database as a separate job, but then we'd be
# duplicating the matrix configuration three times.
matrix:
gemfile: [ 'rails_5.2', 'rails_6.0', 'rails_6.1' ]
# To keep matrix size down, only test highest and lowest rubies. In
# `.rubocopy.yml`, set `TargetRubyVersion`, to the lowest ruby version
# tested here.
ruby: [ '2.4', '2.7' ]
exclude:
# rails 6 requires ruby >= 2.5.0
- ruby: '2.4'
gemfile: 'rails_6.0'
- ruby: '2.4'
gemfile: 'rails_6.1'
steps:
- name: Checkout source
uses: actions/checkout@v2
- name: Setup ruby
uses: actions/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
- name: Bundle
run: |
gem install bundler
bundle install --jobs 4 --retry 3
env:
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
# MySQL db was created above, sqlite will be created during test suite,
# when migrations occur, so we only need to create the postgres db. I
# tried something like `cd .....dummy_app && ....db:create`, but couldn't
# get that to work.
- name: Create postgres database
run: |
createdb \
--host=$POSTGRES_HOST \
--port=$POSTGRES_PORT \
--username=postgres \
paper_trail_test
env:
PGPASSWORD: asdfasdf
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
# The following three steps finally run the tests. We use `rake
# install_database_yml spec` instead of `rake` (default) because the
# default includes rubocop, which we run (once) as a separate job. See
# above.
- name: Test, sqlite
run: bundle exec rake install_database_yml spec
env:
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
DB: sqlite
- name: Test, mysql
run: bundle exec rake install_database_yml spec
env:
BACKTRACE: 1
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
DB: mysql
PT_CI_DATABASE: paper_trail
PT_CI_DB_USER: root
PT_CI_DB_HOST: 127.0.0.1
PT_CI_DB_PORT: 3306
- name: Test, postgres
run: bundle exec rake install_database_yml spec
env:
BACKTRACE: 1
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
DB: postgres
PT_CI_DATABASE: paper_trail
PT_CI_DB_USER: postgres
PT_CI_DB_PASSWORD: asdfasdf
PT_CI_DB_HOST: 127.0.0.1
PT_CI_DB_PORT: 5432

1
.rspec
View File

@ -1,2 +1,3 @@
--backtrace
--color
--require spec_helper

View File

@ -18,7 +18,7 @@ AllCops:
# Enable pending cops so we can adopt the code before they are switched on.
NewCops: enable
# Set to lowest supported version
# Set to lowest supported version of ruby
TargetRubyVersion: 2.4
Bundler/OrderedGems:

View File

@ -1,40 +0,0 @@
language: ruby
cache: bundler
# For ruby, we test the highest and lowest minor versions only.
rvm:
- 2.4
- 2.7
env:
global:
- TRAVIS=true
matrix:
- DB=mysql
- DB=postgres
- DB=sqlite
# We want to use `sudo: false` because the container infrastructure is supposed
# to be faster, but Travis is having issues with containers lately ..
#
# > No output has been received in the last 10m0s
#
# .. and they recommend we use the VM infrastructure (`sudo: required`) in
# the meantime.
sudo: required
before_install:
- gem update bundler
gemfile:
- gemfiles/ar_5.2.gemfile
- gemfiles/ar_6.0.gemfile
matrix:
exclude:
# rails 6 requires ruby >= 2.5.0
- rvm: 2.4
gemfile: gemfiles/ar_6.0.gemfile
fast_finish: true
services:
- mysql
- postgresql

View File

@ -8,13 +8,19 @@
# > appraisal. If something is specified in both the Gemfile and an appraisal,
# > the version from the appraisal takes precedence.
# > https://github.com/thoughtbot/appraisal
appraise "ar-5.2" do
gem "activerecord", "~> 5.2.4"
#
#
appraise "rails-5.2" do
gem "rails", "~> 5.2.4"
gem "rails-controller-testing", "~> 1.0.2"
end
appraise "ar-6.0" do
gem "activerecord", "~> 6.0.3"
appraise "rails-6.0" do
gem "rails", "~> 6.0.3"
gem "rails-controller-testing", "~> 1.0.3"
end
appraise "rails-6.1" do
gem "rails", "~> 6.1.0"
gem "rails-controller-testing", "~> 1.0.5"
end

View File

@ -17,6 +17,21 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/).
- None
## 11.1.0 (2020-12-16)
### Breaking Changes
- None
### Added
- [#1272](https://github.com/paper-trail-gem/paper_trail/issues/1272) -
Rails 6.1 compatibility
### Fixed
- None
## 11.0.0 (2020-08-24)
### Breaking Changes

View File

@ -13,7 +13,7 @@ has been destroyed.
| Version | Documentation |
| -------------- | ------------- |
| Unreleased | https://github.com/paper-trail-gem/paper_trail/blob/master/README.md |
| 11.0.0 | https://github.com/paper-trail-gem/paper_trail/blob/v11.0.0/README.md |
| 11.1.0 | https://github.com/paper-trail-gem/paper_trail/blob/v11.1.0/README.md |
| 10.3.1 | https://github.com/paper-trail-gem/paper_trail/blob/v10.3.1/README.md |
| 9.2.0 | https://github.com/paper-trail-gem/paper_trail/blob/v9.2.0/README.md |
| 8.1.2 | https://github.com/paper-trail-gem/paper_trail/blob/v8.1.2/README.md |
@ -83,8 +83,8 @@ has been destroyed.
| paper_trail | branch | ruby | activerecord |
| -------------- | ---------- | -------- | ------------- |
| unreleased | master | >= 2.4.0 | >= 5.2, < 6.1 |
| 11 | master | >= 2.4.0 | >= 5.2, < 6.1 |
| unreleased | master | >= 2.4.0 | >= 5.2, < 6.2 |
| 11 | master | >= 2.4.0 | >= 5.2, < 6.2 |
| 10 | 10-stable | >= 2.3.0 | >= 4.2, < 6.1 |
| 9 | 9-stable | >= 2.3.0 | >= 4.2, < 5.3 |
| 8 | 8-stable | >= 2.2.0 | >= 4.2, < 5.2 |
@ -703,9 +703,9 @@ it came instead from a previous version -- with `live?`:
```ruby
widget = Widget.find 42
widget.live? # true
widget.paper_trail.live? # true
widget = widget.paper_trail.previous_version
widget.live? # false
widget.paper_trail.live? # false
```
And you can perform `WHERE` queries for object versions based on attributes:
@ -753,8 +753,8 @@ widget.versions.last.changeset
# {}
```
The `object_changes` are only stored for creation and updates, not when an
object is destroyed.
Prior to 10.0.0, the `object_changes` were only stored for create and update
events. As of 10.0.0, they are stored for all three events.
Please be aware that PaperTrail doesn't use diffs internally. When I designed
PaperTrail I wanted simplicity and robustness so I decided to make each version

View File

@ -1,24 +1,36 @@
# frozen_string_literal: true
ENV["DB"] ||= "sqlite"
require "fileutils"
require "bundler"
Bundler::GemHelper.install_tasks
desc "Delete generated files and databases"
task :clean do
desc "Copy the database.DB.yml per ENV['DB']"
task :install_database_yml do
puts format("installing database.yml for %s", ENV["DB"])
# It's tempting to use `git clean` here, but this rake task will be run by
# people working on changes that haven't been committed yet, so we have to
# be more selective with what we delete.
::FileUtils.rm("spec/dummy_app/db/database.yml", force: true)
FileUtils.cp(
"spec/dummy_app/config/database.#{ENV['DB']}.yml",
"spec/dummy_app/config/database.yml"
)
end
desc "Delete generated files and databases"
task :clean do
puts format("dropping %s database", ENV["DB"])
case ENV["DB"]
when "mysql"
%w[test foo bar].each do |db|
system("mysqladmin drop -f paper_trail_#{db} > /dev/null 2>&1")
end
# TODO: only works locally. doesn't respect database.yml
system "mysqladmin drop -f paper_trail_test > /dev/null 2>&1"
when "postgres"
%w[test foo bar].each do |db|
system("dropdb --if-exists paper_trail_#{db} > /dev/null 2>&1")
end
# TODO: only works locally. doesn't respect database.yml
system "dropdb --if-exists paper_trail_test > /dev/null 2>&1"
when nil, "sqlite"
::FileUtils.rm(::Dir.glob("spec/dummy_app/db/*.sqlite3"))
else
@ -26,28 +38,21 @@ task :clean do
end
end
desc "Write a database.yml for the specified RDBMS"
task prepare: [:clean] do
ENV["DB"] ||= "sqlite"
FileUtils.cp(
"spec/dummy_app/config/database.#{ENV['DB']}.yml",
"spec/dummy_app/config/database.yml"
)
desc <<~EOS
Write a database.yml for the specified RDBMS, and create database. Does not
migrate. Migration happens later in spec_helper.
EOS
task prepare: %i[clean install_database_yml] do
puts format("creating %s database", ENV["DB"])
case ENV["DB"]
when "mysql"
%w[test foo bar].each do |db|
system("mysqladmin create paper_trail_#{db}")
# Migration happens later in spec_helper.
end
# TODO: only works locally. doesn't respect database.yml
system "mysqladmin create paper_trail_test"
when "postgres"
%w[test foo bar].each do |db|
system("createdb paper_trail_#{db}")
# Migration happens later in spec_helper.
end
# TODO: only works locally. doesn't respect database.yml
system "createdb paper_trail_test"
when nil, "sqlite"
# noop. test.sqlite3 will be created when migration happens in spec_helper.
# Shortly thereafter, foo and bar.sqlite3 are created when
# spec/support/alt_db_init.rb is `require`d.
# noop. test.sqlite3 will be created when migration happens
nil
else
raise "Don't know how to create specified DB: #{ENV['DB']}"

View File

@ -2,7 +2,7 @@
source "https://rubygems.org"
gem "activerecord", "~> 5.2.4"
gem "rails", "~> 5.2.4"
gem "rails-controller-testing", "~> 1.0.2"
gemspec path: "../"

View File

@ -2,7 +2,7 @@
source "https://rubygems.org"
gem "activerecord", "~> 6.0.3"
gem "rails", "~> 6.0.3"
gem "rails-controller-testing", "~> 1.0.3"
gemspec path: "../"

View File

@ -0,0 +1,8 @@
# This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", "~> 6.1.0"
gem "rails-controller-testing", "~> 1.0.5"
gemspec path: "../"

View File

@ -18,7 +18,7 @@ module PaperTrail
# versions.
module Compatibility
ACTIVERECORD_GTE = ">= 5.2" # enforced in gemspec
ACTIVERECORD_LT = "< 6.1" # not enforced in gemspec
ACTIVERECORD_LT = "< 6.2" # not enforced in gemspec
E_INCOMPATIBLE_AR = <<-EOS
PaperTrail %s is not compatible with ActiveRecord %s. We allow PT

View File

@ -12,7 +12,7 @@ module PaperTrail
# `.paper_trail` and `#paper_trail`.
module Model
def self.included(base)
base.send :extend, ClassMethods
base.extend ClassMethods
end
# :nodoc:

View File

@ -8,7 +8,7 @@ module PaperTrail
# People are encouraged to use `PaperTrail.gem_version` instead.
module VERSION
MAJOR = 11
MINOR = 0
MINOR = 1
TINY = 0
# Set PRE to nil unless it's a pre-release (beta, rc, etc.)

View File

@ -20,7 +20,7 @@ has been destroyed.
s.license = "MIT"
s.files = `git ls-files -z`.split("\x0").select { |f|
f.match(%r{^(Gemfile|LICENSE|lib|paper_trail.gemspec)/})
f.match(%r{^(Gemfile|LICENSE|lib/|paper_trail.gemspec)})
}
s.executables = []
s.require_paths = ["lib"]
@ -31,7 +31,7 @@ has been destroyed.
# https://www.ruby-lang.org/en/news/2019/10/02/ruby-2-4-9-released/
s.required_ruby_version = ">= 2.4.0"
# We no longer specify a maximum rails version.
# We no longer specify a maximum activerecord version.
# See discussion in paper_trail/compatibility.rb
s.add_dependency "activerecord", ::PaperTrail::Compatibility::ACTIVERECORD_GTE
s.add_dependency "request_store", "~> 1.1"
@ -41,6 +41,12 @@ has been destroyed.
s.add_development_dependency "ffaker", "~> 2.11"
s.add_development_dependency "generator_spec", "~> 0.9.4"
s.add_development_dependency "memory_profiler", "~> 0.9.14"
# For `spec/dummy_app`. Technically, we only need `actionpack` (as of 2020).
# However, that might change in the future, and the advantages of specifying a
# subset (e.g. actionpack only) are unclear.
s.add_development_dependency "rails", ::PaperTrail::Compatibility::ACTIVERECORD_GTE
s.add_development_dependency "rake", "~> 13.0"
s.add_development_dependency "rspec-rails", "~> 4.0"
s.add_development_dependency "rubocop", "~> 0.89.1"

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
module Family
class CelebrityFamily < Family::Family
class CelebrityFamily < ::Family::Family
end
end

6
spec/dummy_app/bin/rails Executable file
View File

@ -0,0 +1,6 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
APP_PATH = File.expand_path("../config/application", __dir__)
require_relative "../config/boot"
require "rails/commands"

View File

@ -11,38 +11,14 @@ require "paper_trail"
module Dummy
class Application < Rails::Application
config.load_defaults(::Rails.gem_version.segments.take(2).join("."))
config.encoding = "utf-8"
config.filter_parameters += [:password]
config.active_support.escape_html_entities_in_json = true
config.active_support.test_order = :sorted
# Disable assets in rails 4.2. In rails 5, config does not respond to
# assets, probably because it was moved out of railties to some other gem,
# and we only have dev. dependencies on railties, not all of rails. When
# we drop support for rails 4.2, we can remove this whole conditional.
if config.respond_to?(:assets)
config.assets.enabled = false
end
config.secret_key_base = "A fox regularly kicked the screaming pile of biscuits."
# `raise_in_transactional_callbacks` was added in rails 4, then deprecated
# in rails 5. Oh, how fickle are the gods.
if ActiveRecord.respond_to?(:gem_version)
v = ActiveRecord.gem_version
if v >= Gem::Version.new("4.2") && v < Gem::Version.new("5.0.0.beta1")
config.active_record.raise_in_transactional_callbacks = true
end
if v >= Gem::Version.new("5.0.0.beta1") && v < Gem::Version.new("5.1")
config.active_record.belongs_to_required_by_default = true
config.active_record.time_zone_aware_types = [:datetime]
end
if v >= Gem::Version.new("5.1")
config.load_defaults "5.1"
config.active_record.time_zone_aware_types = [:datetime]
end
end
# In rails >= 6.0, "`.represent_boolean_as_integer=` is now always true,
# so setting this is deprecated and will be removed in Rails 6.1."
if ::ENV["DB"] == "sqlite" &&

View File

@ -1,19 +1,12 @@
test: &test
adapter: mysql2
encoding: utf8
database: paper_trail_test
database: <%= ENV.fetch('PT_CI_DATABASE', 'paper_trail') %>_test
pool: 5
username: root
username: <%= ENV.fetch('PT_CI_DB_USER', 'root') %>
host: <%= ENV.fetch('PT_CI_DB_HOST', 'localhost') %>
port: <%= ENV.fetch('PT_CI_DB_PORT', 3306) %>
protocol: TCP
# password deliberately blank
password:
host: localhost
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
foo:
<<: *test
database: paper_trail_foo
bar:
<<: *test
database: paper_trail_bar

View File

@ -1,15 +1,8 @@
test: &test
adapter: postgresql
database: paper_trail_test
username: postgres
password:
host: localhost
port: 5432
foo:
<<: *test
database: paper_trail_foo
bar:
<<: *test
database: paper_trail_bar
database: <%= ENV.fetch('PT_CI_DATABASE', 'paper_trail') %>_test
username: <%= ENV.fetch('PT_CI_DB_USER', 'postgres') %>
password: <%= ENV.fetch('PT_CI_DB_PASSWORD', '') %>
host: <%= ENV.fetch('PT_CI_DB_HOST', 'localhost') %>
port: <%= ENV.fetch('PT_CI_DB_PORT', 5432) %>
protocol: TCP

View File

@ -5,11 +5,3 @@ test: &test
pool: 5
timeout: 5000
database: db/test.sqlite3
foo:
<<: *test
database: db/test-foo.sqlite3
bar:
<<: *test
database: db/test-bar.sqlite3

View File

@ -35,7 +35,7 @@ RSpec.describe Gadget, type: :model do
gadget.update_attribute(:updated_at, Time.now + 1)
}.to(change { gadget.versions.size }.by(1))
expect(
YAML.safe_load(gadget.versions.last.object_changes, [::Time]).keys
YAML.load(gadget.versions.last.object_changes).keys
).to eq(["updated_at"])
end
end

View File

@ -27,7 +27,7 @@ RSpec.describe NoObject, versioning: true do
# New feature: destroy populates object_changes
# https://github.com/paper-trail-gem/paper_trail/pull/1123
h = YAML.safe_load(a["object_changes"], [::Time])
h = YAML.load a["object_changes"]
expect(h["id"]).to eq([n.id, nil])
expect(h["letter"]).to eq([n.letter, nil])
expect(h["created_at"][0]).to be_present

View File

@ -14,7 +14,7 @@ module PaperTrail
context "when incompatible" do
it "writes a warning to stderr" do
ar_version = ::Gem::Version.new("6.1.0")
ar_version = ::Gem::Version.new("6.2.0")
expect {
described_class.check_activerecord(ar_version)
}.to output(/not compatible/).to_stderr

View File

@ -335,8 +335,9 @@ RSpec.describe(::PaperTrail, versioning: true) do
expect(previous_widget.a_datetime.to_time.utc.to_i).to(eq(t0.to_time.utc.to_i))
end
it "handle times" do
expect(previous_widget.a_time.utc.to_i).to(eq(t0.utc.to_i))
it "handle times (time only, no date)" do
format = ->(t) { t.utc.strftime "%H:%M:%S" }
expect(format[previous_widget.a_time]).to eq(format[t0])
end
it "handle dates" do
@ -362,7 +363,8 @@ RSpec.describe(::PaperTrail, versioning: true) do
assert_in_delta(153.01, reified.a_float, 0.001)
assert_in_delta(2.7183, reified.a_decimal, 0.0001)
expect(reified.a_datetime.to_time.utc.to_i).to(eq(t0.to_time.utc.to_i))
expect(reified.a_time.utc.to_i).to(eq(t0.utc.to_i))
format = ->(t) { t.utc.strftime "%H:%M:%S" }
expect(format[reified.a_time]).to eq(format[t0])
expect(reified.a_date).to(eq(d0))
expect(reified.a_boolean).to(be_truthy)
end

View File

@ -30,7 +30,7 @@ module PaperTrail
matches = described_class.
where_object_condition(PaperTrail::Version.arel_table[:object], :arg1, "Val 1")
expect(matches.instance_of?(Arel::Nodes::Matches)).to(eq(true))
expect(matches.right.val).to eq("%\"arg1\":\"Val 1\"%")
expect(arel_value(matches.right)).to eq("%\"arg1\":\"Val 1\"%")
end
end
@ -39,7 +39,7 @@ module PaperTrail
matches = described_class.
where_object_condition(PaperTrail::Version.arel_table[:object], :arg1, nil)
expect(matches.instance_of?(Arel::Nodes::Matches)).to(eq(true))
expect(matches.right.val).to(eq("%\"arg1\":null%"))
expect(arel_value(matches.right)).to(eq("%\"arg1\":null%"))
end
end
@ -48,9 +48,14 @@ module PaperTrail
grouping = described_class.
where_object_condition(PaperTrail::Version.arel_table[:object], :arg1, -3.5)
expect(grouping.instance_of?(Arel::Nodes::Grouping)).to(eq(true))
matches = grouping.select { |v| v.instance_of?(Arel::Nodes::Matches) }
expect(matches.first.right.val).to eq("%\"arg1\":-3.5,%")
expect(matches.last.right.val).to eq("%\"arg1\":-3.5}%")
disjunction = grouping.expr
expect(disjunction).to be_an(Arel::Nodes::Or)
dj_left = disjunction.left
expect(dj_left).to be_an(Arel::Nodes::Matches)
expect(arel_value(dj_left.right)).to eq("%\"arg1\":-3.5,%")
dj_right = disjunction.right
expect(dj_right).to be_an(Arel::Nodes::Matches)
expect(arel_value(dj_right.right)).to eq("%\"arg1\":-3.5}%")
end
end
end

View File

@ -39,7 +39,7 @@ module PaperTrail
::PaperTrail::Version.arel_table[:object], :arg1, "Val 1"
)
expect(matches.instance_of?(Arel::Nodes::Matches)).to(eq(true))
expect(matches.right.val).to eq("%\narg1: Val 1\n%")
expect(arel_value(matches.right)).to eq("%\narg1: Val 1\n%")
end
end
end

View File

@ -1,29 +0,0 @@
# frozen_string_literal: true
require "spec_helper"
require "support/alt_db_init"
RSpec.describe PaperTrail::VersionConcern do
it "allows included class to have different connections" do
expect(Foo::Version.connection).not_to eq(Bar::Version.connection)
end
it "allows custom version class to share connection with superclass" do
expect(Foo::Version.connection).to eq(Foo::Document.connection)
expect(Bar::Version.connection).to eq(Bar::Document.connection)
end
it "can be used with class_name option" do
expect(Foo::Document.version_class_name).to eq("Foo::Version")
expect(Bar::Document.version_class_name).to eq("Bar::Version")
end
describe "persistence", versioning: true do
it "stores versions in the correct corresponding db location" do
foo_doc = Foo::Document.create!(name: "foobar")
bar_doc = Bar::Document.create!(name: "raboof")
expect(foo_doc.versions.first).to be_instance_of(Foo::Version)
expect(bar_doc.versions.first).to be_instance_of(Bar::Version)
end
end
end

View File

@ -4,6 +4,7 @@ ENV["RAILS_ENV"] ||= "test"
ENV["DB"] ||= "sqlite"
require "byebug"
require_relative "support/pt_arel_helpers"
unless File.exist?(File.expand_path("dummy_app/config/database.yml", __dir__))
warn "No database.yml detected for the dummy app, please run `rake prepare` first"
@ -25,6 +26,7 @@ RSpec.configure do |config|
config.default_formatter = "doc"
end
config.order = :random
config.include PTArelHelpers
Kernel.srand config.seed
end

View File

@ -1,62 +0,0 @@
# frozen_string_literal: true
require_relative "paper_trail_spec_migrator"
# This file copies the test database into locations for the `Foo` and `Bar`
# namespace, then defines those namespaces, then establishes the sqlite3
# connection for the namespaces to simulate an application with multiple
# database connections.
# This is all going to change in rails 6. See "RailsConf 2018: Keynote: The
# Future of Rails 6: Scalable by Default by Eileen Uchitelle"
# https://www.youtube.com/watch?v=8evXWvM4oXM
# Load database yaml to use
configs = YAML.load_file("#{Rails.root}/config/database.yml")
# If we are testing with sqlite make it quick
db_directory = "#{Rails.root}/db"
# Set up alternate databases
if ENV["DB"] == "sqlite"
FileUtils.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-foo.sqlite3"
FileUtils.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-bar.sqlite3"
end
module Foo
class Base < ActiveRecord::Base
self.abstract_class = true
end
class Version < Base
include PaperTrail::VersionConcern
end
class Document < Base
has_paper_trail versions: { class_name: "Foo::Version" }
end
end
Foo::Base.configurations = configs
Foo::Base.establish_connection(:foo)
ActiveRecord::Base.establish_connection(:foo)
::PaperTrailSpecMigrator.new.migrate
module Bar
class Base < ActiveRecord::Base
self.abstract_class = true
end
class Version < Base
include PaperTrail::VersionConcern
end
class Document < Base
has_paper_trail versions: { class_name: "Bar::Version" }
end
end
Bar::Base.configurations = configs
Bar::Base.establish_connection(:bar)
ActiveRecord::Base.establish_connection(:bar)
::PaperTrailSpecMigrator.new.migrate

View File

@ -1,5 +1,17 @@
# frozen_string_literal: true
# AR 6.1 does not autoload MigrationContext, so we must `require` it.
#
# ```
# # lib/active_record.rb
# autoload :Migration
# autoload :Migrator, "active_record/migration"
# ```
#
# The above may indicate that we should use `Migrator` instead of
# MigrationContext.
require "active_record/migration"
# Manage migrations including running generators to build them, and cleaning up strays
class PaperTrailSpecMigrator
def initialize
@ -31,12 +43,13 @@ class PaperTrailSpecMigrator
# - generator [String] - name of generator, eg. "paper_trail:update_sti"
# - generator_invoke_args [Array] - arguments to `Generators#invoke`
def generate_and_migrate(generator, generator_invoke_args)
files = generate(generator, generator_invoke_args)
generate(generator, generator_invoke_args)
begin
migrate
ensure
files.each do |file|
File.delete(Rails.root.join(file))
cmd = "git clean -x --force --quiet " + dummy_app_migrations_dir.to_s
unless system(cmd)
raise "Unable to clean up after PT migration generator test"
end
end
end

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
module PTArelHelpers
def arel_value(node)
if node.respond_to?(:val) # rails < 6.1
node.val
else
node.value
end
end
end