Avoid changing schema during test run

Sean's approach to dropping/re-adding the column during the test run
worked, but it had a few disadvantages:

1. it required a `before(:all)` callback, which is frowned upon by rubocop-rspec
2. more importantly, it could have prevented us from using test parallelization
  in the future
3. least importantly, it produced annoying output in the middle of the test run
This commit is contained in:
Jared Beck 2018-08-13 00:58:25 -04:00
parent d7a51edc24
commit dadba10f18
5 changed files with 89 additions and 51 deletions

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
# Demonstrates a table that omits the `object` column.
class NoObject < ActiveRecord::Base
has_paper_trail(
class_name: "NoObjectVersion",
meta: { metadatum: 42 }
)
validates :letter, length: { is: 1 }, presence: true
end

View File

@ -0,0 +1,6 @@
# frozen_string_literal: true
# Demonstrates a table that omits the `object` column.
class NoObjectVersion < ::PaperTrail::Version
self.table_name = "no_object_versions"
end

View File

@ -124,6 +124,24 @@ class SetUpTestTables < (
end
add_index :post_versions, %i[item_type item_id]
# Uses custom versions table `no_object_versions`.
create_table :no_objects, force: true do |t|
t.string :letter, null: false, limit: 1
t.timestamps null: false, limit: 6
end
# This table omits the `object` column.
create_table :no_object_versions, force: true do |t|
t.string :item_type, null: false
t.integer :item_id, null: false
t.string :event, null: false
t.string :whodunnit
t.datetime :created_at, limit: 6
t.text :object_changes, limit: TEXT_BYTES
t.integer :metadatum
end
add_index :no_object_versions, %i[item_type item_id]
if ENV["DB"] == "postgres"
create_table :json_versions, force: true do |t|
t.string :item_type, null: false

View File

@ -0,0 +1,55 @@
# frozen_string_literal: true
require "spec_helper"
RSpec.describe NoObject, versioning: true do
it "still creates version records" do
n = described_class.create!(letter: "A")
a = n.versions.last.attributes
expect(a).not_to include "object"
expect(a["event"]).to eq "create"
expect(a["object_changes"]).to start_with("---")
expect(a["metadatum"]).to eq(42)
n.update!(letter: "B")
a = n.versions.last.attributes
expect(a).not_to include "object"
expect(a["event"]).to eq "update"
expect(a["object_changes"]).to start_with("---")
expect(a["metadatum"]).to eq(42)
n.destroy!
a = n.versions.last.attributes
expect(a).not_to include "object"
expect(a["event"]).to eq "destroy"
expect(a["object_changes"]).to be_nil
expect(a["metadatum"]).to eq(42)
end
describe "reify" do
it "raises error" do
n = NoObject.create!(letter: "A")
v = n.versions.last
expect { v.reify }.to(
raise_error(
::RuntimeError,
"reify can't be called without an object column"
)
)
end
end
describe "where_object" do
it "raises error" do
n = NoObject.create!(letter: "A")
expect {
n.versions.where_object(foo: "bar")
}.to(
raise_error(
::RuntimeError,
"where_object can't be called without an object column"
)
)
end
end
end

View File

@ -877,55 +877,4 @@ RSpec.describe(::PaperTrail, versioning: true) do
expect(widget.versions.empty?).to(eq(true))
end
end
context "without the object column" do
# rubocop:disable RSpec/BeforeAfterAll
before :all do
ActiveRecord::Migration.remove_column :versions, :object
PaperTrail::Version.reset_column_information
end
after :all do
ActiveRecord::Migration.add_column :versions, :object, :text
PaperTrail::Version.reset_column_information
end
# rubocop:enable RSpec/BeforeAfterAll
it "versions are created" do
song = Song.create length: 4
version = song.versions.last.attributes
expect(version).not_to include "object"
expect(version["event"]).to eq "create"
expect(version["object_changes"]).to start_with("---")
song.update length: 5
version = song.versions.last.attributes
expect(version).not_to include "object"
expect(version["event"]).to eq "update"
expect(version["object_changes"]).to start_with("---")
song.destroy
version = song.versions.last.attributes
expect(version).not_to include "object"
expect(version["event"]).to eq "destroy"
expect(version["object_changes"]).to eq nil
end
it "reify doesn't work" do
song = Song.create length: 4
song.update length: 5
expect do
song.versions.first.reify
end.to raise_error "reify can't be called without an object column"
end
it "where_object doesn't work" do
song = Song.create length: 4
song.update length: 5
expect do
song.versions.where_object length: 4
end.to raise_error "where_object can't be called without an object column"
end
end
end