paper_trail 6.0.2 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/CONTRIBUTING.md +20 -0
- data/.rubocop.yml +30 -2
- data/.rubocop_todo.yml +20 -0
- data/.travis.yml +3 -5
- data/Appraisals +5 -6
- data/CHANGELOG.md +33 -0
- data/README.md +43 -81
- data/Rakefile +1 -1
- data/doc/bug_report_template.rb +4 -2
- data/gemfiles/ar_4.0.gemfile +7 -0
- data/gemfiles/ar_4.2.gemfile +0 -1
- data/lib/generators/paper_trail/templates/create_version_associations.rb +1 -1
- data/lib/generators/paper_trail/templates/create_versions.rb +1 -1
- data/lib/paper_trail.rb +7 -9
- data/lib/paper_trail/config.rb +0 -15
- data/lib/paper_trail/frameworks/rspec.rb +8 -2
- data/lib/paper_trail/model_config.rb +6 -2
- data/lib/paper_trail/record_trail.rb +3 -1
- data/lib/paper_trail/reifier.rb +43 -354
- data/lib/paper_trail/reifiers/belongs_to.rb +48 -0
- data/lib/paper_trail/reifiers/has_and_belongs_to_many.rb +50 -0
- data/lib/paper_trail/reifiers/has_many.rb +110 -0
- data/lib/paper_trail/reifiers/has_many_through.rb +90 -0
- data/lib/paper_trail/reifiers/has_one.rb +76 -0
- data/lib/paper_trail/serializers/yaml.rb +2 -25
- data/lib/paper_trail/version_concern.rb +5 -5
- data/lib/paper_trail/version_number.rb +7 -3
- data/paper_trail.gemspec +7 -34
- data/spec/controllers/articles_controller_spec.rb +1 -1
- data/spec/generators/install_generator_spec.rb +40 -34
- data/spec/models/animal_spec.rb +50 -25
- data/spec/models/boolit_spec.rb +8 -7
- data/spec/models/callback_modifier_spec.rb +13 -13
- data/spec/models/document_spec.rb +21 -0
- data/spec/models/gadget_spec.rb +35 -39
- data/spec/models/joined_version_spec.rb +4 -4
- data/spec/models/json_version_spec.rb +14 -15
- data/spec/models/not_on_update_spec.rb +1 -1
- data/spec/models/post_with_status_spec.rb +2 -2
- data/spec/models/skipper_spec.rb +4 -4
- data/spec/models/thing_spec.rb +1 -1
- data/spec/models/truck_spec.rb +1 -1
- data/spec/models/vehicle_spec.rb +1 -1
- data/spec/models/version_spec.rb +152 -168
- data/spec/models/widget_spec.rb +170 -196
- data/spec/modules/paper_trail_spec.rb +3 -3
- data/spec/modules/version_concern_spec.rb +5 -8
- data/spec/modules/version_number_spec.rb +11 -36
- data/spec/paper_trail/cleaner_spec.rb +152 -0
- data/spec/paper_trail/config_spec.rb +1 -1
- data/spec/paper_trail/serializers/custom_yaml_serializer_spec.rb +45 -0
- data/spec/paper_trail/serializers/json_spec.rb +57 -0
- data/spec/paper_trail/version_limit_spec.rb +55 -0
- data/spec/paper_trail_spec.rb +45 -32
- data/spec/requests/articles_spec.rb +4 -4
- data/test/dummy/app/models/custom_primary_key_record.rb +4 -2
- data/test/dummy/app/models/document.rb +1 -1
- data/test/dummy/app/models/not_on_update.rb +1 -1
- data/test/dummy/app/models/on/create.rb +6 -0
- data/test/dummy/app/models/on/destroy.rb +6 -0
- data/test/dummy/app/models/on/empty_array.rb +6 -0
- data/test/dummy/app/models/on/update.rb +6 -0
- data/test/dummy/app/models/person.rb +1 -0
- data/test/dummy/app/models/song.rb +19 -28
- data/test/dummy/config/application.rb +10 -43
- data/test/dummy/config/routes.rb +1 -1
- data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +25 -51
- data/test/dummy/db/schema.rb +29 -19
- data/test/test_helper.rb +0 -16
- data/test/unit/associations_test.rb +81 -81
- data/test/unit/model_test.rb +48 -131
- data/test/unit/serializer_test.rb +34 -45
- data/test/unit/serializers/mixin_json_test.rb +3 -1
- data/test/unit/serializers/yaml_test.rb +1 -5
- metadata +44 -19
- data/lib/paper_trail/frameworks/sinatra.rb +0 -40
- data/test/functional/modular_sinatra_test.rb +0 -46
- data/test/functional/sinatra_test.rb +0 -51
- data/test/unit/cleaner_test.rb +0 -151
- data/test/unit/inheritance_column_test.rb +0 -41
- data/test/unit/serializers/json_test.rb +0 -95
- data/test/unit/serializers/mixin_yaml_test.rb +0 -53
@@ -1,9 +1,13 @@
|
|
1
1
|
module PaperTrail
|
2
|
-
#
|
2
|
+
# The version number of the paper_trail gem. Not to be confused with
|
3
|
+
# `PaperTrail::Version`. Ruby constants are case-sensitive, apparently,
|
4
|
+
# and they are two different modules! It would be nice to remove `VERSION`,
|
5
|
+
# because of this confusion, but it's not worth the breaking change.
|
6
|
+
# People are encouraged to use `PaperTrail.gem_version` instead.
|
3
7
|
module VERSION
|
4
|
-
MAJOR =
|
8
|
+
MAJOR = 7
|
5
9
|
MINOR = 0
|
6
|
-
TINY =
|
10
|
+
TINY = 0
|
7
11
|
PRE = nil
|
8
12
|
|
9
13
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".").freeze
|
data/paper_trail.gemspec
CHANGED
@@ -3,7 +3,7 @@ require "paper_trail/version_number"
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "paper_trail"
|
6
|
-
s.version = PaperTrail::VERSION::STRING
|
6
|
+
s.version = PaperTrail::VERSION::STRING
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.summary = "Track changes to your models."
|
9
9
|
s.description = <<-EOS
|
@@ -22,7 +22,7 @@ has been destroyed.
|
|
22
22
|
s.require_paths = ["lib"]
|
23
23
|
|
24
24
|
s.required_rubygems_version = ">= 1.3.6"
|
25
|
-
s.required_ruby_version = ">= 1.
|
25
|
+
s.required_ruby_version = ">= 2.1.0"
|
26
26
|
|
27
27
|
# Rails does not follow semver, makes breaking changes in minor versions.
|
28
28
|
s.add_dependency "activerecord", [">= 4.0", "< 5.2"]
|
@@ -41,37 +41,10 @@ has been destroyed.
|
|
41
41
|
s.add_development_dependency "generator_spec", "~> 0.9.3"
|
42
42
|
s.add_development_dependency "database_cleaner", "~> 1.2"
|
43
43
|
s.add_development_dependency "pry-nav", "~> 0.2.4"
|
44
|
-
|
45
|
-
|
46
|
-
# Rubocop 0.42 requires ruby >= 2.0. We could add a conditional, as we do
|
47
|
-
# below for rack and pg, but that means our config files (e.g. `.rubocop.yml`
|
48
|
-
# would have to simultaneously be valid in two different versions of rubocop.
|
49
|
-
# That is currently possible, but probably won't be in the future, and is
|
50
|
-
# not worth the effort.) Because of pain points like this, I think we'll
|
51
|
-
# have to drop support for ruby 1.9.3 soon.
|
52
|
-
s.add_development_dependency "rubocop", "~> 0.41.1"
|
53
|
-
|
44
|
+
s.add_development_dependency "rubocop", "~> 0.48.0"
|
45
|
+
s.add_development_dependency "rubocop-rspec", "~> 1.15.0"
|
54
46
|
s.add_development_dependency "timecop", "~> 0.8.0"
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
if defined?(JRUBY_VERSION)
|
61
|
-
s.add_development_dependency "activerecord-jdbcsqlite3-adapter", "~> 1.3.15"
|
62
|
-
s.add_development_dependency "activerecord-jdbcpostgresql-adapter", "~> 1.3.15"
|
63
|
-
s.add_development_dependency "activerecord-jdbcmysql-adapter", "~> 1.3.15"
|
64
|
-
else
|
65
|
-
s.add_development_dependency "sqlite3", "~> 1.2"
|
66
|
-
|
67
|
-
# pg 0.19 requires ruby >= 2.0.0
|
68
|
-
if ::Gem.ruby_version >= ::Gem::Version.new("2.0.0")
|
69
|
-
s.add_development_dependency "pg", "~> 0.19.0"
|
70
|
-
else
|
71
|
-
s.add_development_dependency "pg", [">= 0.17", "< 0.19"]
|
72
|
-
end
|
73
|
-
|
74
|
-
# activerecord >= 4.2.5 may use mysql2 >= 0.4
|
75
|
-
s.add_development_dependency "mysql2", "~> 0.4.2"
|
76
|
-
end
|
47
|
+
s.add_development_dependency "sqlite3", "~> 1.2"
|
48
|
+
s.add_development_dependency "pg", "~> 0.19.0"
|
49
|
+
s.add_development_dependency "mysql2", "~> 0.4.2"
|
77
50
|
end
|
@@ -8,7 +8,7 @@ RSpec.describe ArticlesController, type: :controller do
|
|
8
8
|
it "returns true" do
|
9
9
|
assert PaperTrail.enabled?
|
10
10
|
post :create, params_wrapper(article: { title: "Doh", content: FFaker::Lorem.sentence })
|
11
|
-
expect(assigns(:article)).
|
11
|
+
expect(assigns(:article)).not_to be_nil
|
12
12
|
assert PaperTrail.enabled_for_controller?
|
13
13
|
assert_equal 1, assigns(:article).versions.length
|
14
14
|
end
|
@@ -2,7 +2,7 @@ require "rails_helper"
|
|
2
2
|
require "generator_spec/test_case"
|
3
3
|
require File.expand_path("../../../lib/generators/paper_trail/install_generator", __FILE__)
|
4
4
|
|
5
|
-
describe PaperTrail::InstallGenerator, type: :generator do
|
5
|
+
RSpec.describe PaperTrail::InstallGenerator, type: :generator do
|
6
6
|
include GeneratorSpec::TestCase
|
7
7
|
destination File.expand_path("../tmp", __FILE__)
|
8
8
|
|
@@ -15,17 +15,19 @@ describe PaperTrail::InstallGenerator, type: :generator do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it "generates a migration for creating the 'versions' table" do
|
18
|
-
expect(destination_root).to
|
19
|
-
|
20
|
-
directory
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
18
|
+
expect(destination_root).to(
|
19
|
+
have_structure {
|
20
|
+
directory("db") {
|
21
|
+
directory("migrate") {
|
22
|
+
migration("create_versions") {
|
23
|
+
contains "class CreateVersions"
|
24
|
+
contains "def change"
|
25
|
+
contains "create_table :versions"
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
)
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
@@ -36,31 +38,35 @@ describe PaperTrail::InstallGenerator, type: :generator do
|
|
36
38
|
end
|
37
39
|
|
38
40
|
it "generates a migration for creating the 'versions' table" do
|
39
|
-
expect(destination_root).to
|
40
|
-
|
41
|
-
directory
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
41
|
+
expect(destination_root).to(
|
42
|
+
have_structure {
|
43
|
+
directory("db") {
|
44
|
+
directory("migrate") {
|
45
|
+
migration("create_versions") {
|
46
|
+
contains "class CreateVersions"
|
47
|
+
contains "def change"
|
48
|
+
contains "create_table :versions"
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
)
|
50
54
|
end
|
51
55
|
|
52
56
|
it "generates a migration for adding the 'object_changes' column to the 'versions' table" do
|
53
|
-
expect(destination_root).to
|
54
|
-
|
55
|
-
directory
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
expect(destination_root).to(
|
58
|
+
have_structure {
|
59
|
+
directory("db") {
|
60
|
+
directory("migrate") {
|
61
|
+
migration("add_object_changes_to_versions") {
|
62
|
+
contains "class AddObjectChangesToVersions"
|
63
|
+
contains "def change"
|
64
|
+
contains "add_column :versions, :object_changes, :text"
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
)
|
64
70
|
end
|
65
71
|
end
|
66
72
|
end
|
data/spec/models/animal_spec.rb
CHANGED
@@ -1,35 +1,60 @@
|
|
1
1
|
require "rails_helper"
|
2
2
|
|
3
|
-
describe Animal, type: :model do
|
4
|
-
it
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
describe "updates to the `inheritance_column`" do
|
10
|
-
subject { Cat.create!(name: "Leo") }
|
3
|
+
describe Animal, type: :model, versioning: true do
|
4
|
+
it "baseline test setup" do
|
5
|
+
expect(Animal.new).to be_versioned
|
6
|
+
expect(Animal.inheritance_column).to eq("species")
|
7
|
+
end
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
it "works with custom STI inheritance column" do
|
10
|
+
animal = Animal.create(name: "Animal")
|
11
|
+
animal.update_attributes(name: "Animal from the Muppets")
|
12
|
+
animal.update_attributes(name: "Animal Muppet")
|
13
|
+
animal.destroy
|
14
|
+
dog = Dog.create(name: "Snoopy")
|
15
|
+
dog.update_attributes(name: "Scooby")
|
16
|
+
dog.update_attributes(name: "Scooby Doo")
|
17
|
+
dog.destroy
|
18
|
+
cat = Cat.create(name: "Garfield")
|
19
|
+
cat.update_attributes(name: "Garfield (I hate Mondays)")
|
20
|
+
cat.update_attributes(name: "Garfield The Cat")
|
21
|
+
cat.destroy
|
22
|
+
expect(PaperTrail::Version.count).to(eq(12))
|
23
|
+
expect(animal.versions.count).to(eq(4))
|
24
|
+
expect(animal.versions.first.reify).to(be_nil)
|
25
|
+
animal.versions[(1..-1)].each do |v|
|
26
|
+
expect(v.reify.class.name).to(eq("Animal"))
|
17
27
|
end
|
28
|
+
dog_versions = PaperTrail::Version.where(item_id: dog.id).order(:created_at)
|
29
|
+
expect(dog_versions.count).to(eq(4))
|
30
|
+
expect(dog_versions.first.reify).to(be_nil)
|
31
|
+
expect(dog_versions.map { |v| v.reify.class.name }).to eq(%w(NilClass Dog Dog Dog))
|
32
|
+
cat_versions = PaperTrail::Version.where(item_id: cat.id).order(:created_at)
|
33
|
+
expect(cat_versions.count).to(eq(4))
|
34
|
+
expect(cat_versions.first.reify).to(be_nil)
|
35
|
+
expect(cat_versions.map { |v| v.reify.class.name }).to eq(%w(NilClass Cat Cat Cat))
|
36
|
+
end
|
37
|
+
|
38
|
+
it "allows the inheritance_column (species) to be updated" do
|
39
|
+
cat = Cat.create!(name: "Leo")
|
40
|
+
cat.update_attributes(name: "Spike", species: "Dog")
|
41
|
+
dog = Animal.find(cat.id)
|
42
|
+
expect(dog).to be_instance_of(Dog)
|
43
|
+
end
|
18
44
|
|
19
|
-
|
20
|
-
|
21
|
-
|
45
|
+
context "with callback-methods" do
|
46
|
+
context "when only has_paper_trail set in super class" do
|
47
|
+
let(:callback_cat) { Cat.create(name: "Markus") }
|
22
48
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
49
|
+
it "trails all events" do
|
50
|
+
callback_cat.update_attributes(name: "Billie")
|
51
|
+
callback_cat.destroy
|
52
|
+
expect(callback_cat.versions.collect(&:event)).to eq %w(create update destroy)
|
53
|
+
end
|
28
54
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
55
|
+
it "does not break reify" do
|
56
|
+
callback_cat.destroy
|
57
|
+
expect { callback_cat.versions.last.reify }.not_to raise_error
|
33
58
|
end
|
34
59
|
end
|
35
60
|
end
|
data/spec/models/boolit_spec.rb
CHANGED
@@ -5,19 +5,20 @@ describe Boolit, type: :model do
|
|
5
5
|
it { is_expected.to be_versioned }
|
6
6
|
|
7
7
|
it "has a default scope" do
|
8
|
-
expect(subject.default_scopes).
|
8
|
+
expect(subject.default_scopes).not_to be_empty
|
9
9
|
end
|
10
10
|
|
11
11
|
describe "Versioning", versioning: true do
|
12
12
|
subject { Boolit.create! }
|
13
|
+
|
13
14
|
before { subject.update_attributes!(name: FFaker::Name.name) }
|
14
15
|
|
15
|
-
it "
|
16
|
+
it "has two versions" do
|
16
17
|
expect(subject.versions.size).to eq(2)
|
17
18
|
end
|
18
19
|
|
19
|
-
it "
|
20
|
-
expect { subject.versions.last.reify.save! }.
|
20
|
+
it "can be reified and persisted" do
|
21
|
+
expect { subject.versions.last.reify.save! }.not_to raise_error
|
21
22
|
end
|
22
23
|
|
23
24
|
context "Instance falls out of default scope" do
|
@@ -27,8 +28,8 @@ describe Boolit, type: :model do
|
|
27
28
|
expect(Boolit.first).to be_nil
|
28
29
|
end
|
29
30
|
|
30
|
-
it "
|
31
|
-
expect { subject.paper_trail.previous_version.save! }.
|
31
|
+
it "still can be reified and persisted" do
|
32
|
+
expect { subject.paper_trail.previous_version.save! }.not_to raise_error
|
32
33
|
end
|
33
34
|
|
34
35
|
context "with `nil` attributes on the live instance" do
|
@@ -39,7 +40,7 @@ describe Boolit, type: :model do
|
|
39
40
|
end
|
40
41
|
after { PaperTrail.serializer = PaperTrail::Serializers::YAML }
|
41
42
|
|
42
|
-
it "
|
43
|
+
it "does not overwrite that attribute during the reification process" do
|
43
44
|
expect(subject.paper_trail.previous_version.name).to be_nil
|
44
45
|
end
|
45
46
|
end
|
@@ -4,13 +4,13 @@ describe CallbackModifier, type: :model do
|
|
4
4
|
with_versioning do
|
5
5
|
describe "callback-methods", versioning: true do
|
6
6
|
describe "paper_trail_on_destroy" do
|
7
|
-
it "
|
7
|
+
it "adds :destroy to paper_trail_options[:on]" do
|
8
8
|
modifier = NoArgDestroyModifier.create!(some_content: FFaker::Lorem.sentence)
|
9
9
|
expect(modifier.paper_trail_options[:on]).to eq [:destroy]
|
10
10
|
end
|
11
11
|
|
12
12
|
context "when :before" do
|
13
|
-
it "
|
13
|
+
it "creates the version before destroy" do
|
14
14
|
modifier = BeforeDestroyModifier.create!(some_content: FFaker::Lorem.sentence)
|
15
15
|
modifier.test_destroy
|
16
16
|
expect(modifier.versions.last.reify).not_to be_flagged_deleted
|
@@ -18,7 +18,7 @@ describe CallbackModifier, type: :model do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
context "when :after" do
|
21
|
-
it "
|
21
|
+
it "creates the version after destroy" do
|
22
22
|
modifier = AfterDestroyModifier.create!(some_content: FFaker::Lorem.sentence)
|
23
23
|
modifier.test_destroy
|
24
24
|
expect(modifier.versions.last.reify).to be_flagged_deleted
|
@@ -26,7 +26,7 @@ describe CallbackModifier, type: :model do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
context "when no argument" do
|
29
|
-
it "
|
29
|
+
it "defaults to before destroy" do
|
30
30
|
modifier = NoArgDestroyModifier.create!(some_content: FFaker::Lorem.sentence)
|
31
31
|
modifier.test_destroy
|
32
32
|
expect(modifier.versions.last.reify).not_to be_flagged_deleted
|
@@ -35,12 +35,12 @@ describe CallbackModifier, type: :model do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
describe "paper_trail_on_update" do
|
38
|
-
it "
|
38
|
+
it "adds :update to paper_trail_options[:on]" do
|
39
39
|
modifier = UpdateModifier.create!(some_content: FFaker::Lorem.sentence)
|
40
40
|
expect(modifier.paper_trail_options[:on]).to eq [:update]
|
41
41
|
end
|
42
42
|
|
43
|
-
it "
|
43
|
+
it "creates a version" do
|
44
44
|
modifier = UpdateModifier.create!(some_content: FFaker::Lorem.sentence)
|
45
45
|
modifier.update_attributes! some_content: "modified"
|
46
46
|
expect(modifier.versions.last.event).to eq "update"
|
@@ -48,36 +48,36 @@ describe CallbackModifier, type: :model do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
describe "paper_trail_on_create" do
|
51
|
-
it "
|
51
|
+
it "adds :create to paper_trail_options[:on]" do
|
52
52
|
modifier = CreateModifier.create!(some_content: FFaker::Lorem.sentence)
|
53
53
|
expect(modifier.paper_trail_options[:on]).to eq [:create]
|
54
54
|
end
|
55
55
|
|
56
|
-
it "
|
56
|
+
it "creates a version" do
|
57
57
|
modifier = CreateModifier.create!(some_content: FFaker::Lorem.sentence)
|
58
58
|
expect(modifier.versions.last.event).to eq "create"
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
62
|
context "when no callback-method used" do
|
63
|
-
it "
|
63
|
+
it "sets paper_trail_options[:on] to [:create, :update, :destroy]" do
|
64
64
|
modifier = DefaultModifier.create!(some_content: FFaker::Lorem.sentence)
|
65
|
-
expect(modifier.paper_trail_options[:on]).to eq
|
65
|
+
expect(modifier.paper_trail_options[:on]).to eq %i(create update destroy)
|
66
66
|
end
|
67
67
|
|
68
|
-
it "
|
68
|
+
it "tracks destroy" do
|
69
69
|
modifier = DefaultModifier.create!(some_content: FFaker::Lorem.sentence)
|
70
70
|
modifier.destroy
|
71
71
|
expect(modifier.versions.last.event).to eq "destroy"
|
72
72
|
end
|
73
73
|
|
74
|
-
it "
|
74
|
+
it "tracks update" do
|
75
75
|
modifier = DefaultModifier.create!(some_content: FFaker::Lorem.sentence)
|
76
76
|
modifier.update_attributes! some_content: "modified"
|
77
77
|
expect(modifier.versions.last.event).to eq "update"
|
78
78
|
end
|
79
79
|
|
80
|
-
it "
|
80
|
+
it "tracks create" do
|
81
81
|
modifier = DefaultModifier.create!(some_content: FFaker::Lorem.sentence)
|
82
82
|
expect(modifier.versions.last.event).to eq "create"
|
83
83
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "rails_helper"
|
2
|
+
|
3
|
+
describe Document, type: :model do
|
4
|
+
describe "`have_a_version_with` matcher", versioning: true do
|
5
|
+
it "works with custom versions association" do
|
6
|
+
document = Document.create!(name: "Foo")
|
7
|
+
document.update_attributes!(name: "Bar")
|
8
|
+
|
9
|
+
expect(document).to have_a_version_with(name: "Foo")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "`have_a_version_with_changes` matcher", versioning: true do
|
14
|
+
it "works with custom versions association" do
|
15
|
+
document = Document.create!(name: "Foo")
|
16
|
+
document.update_attributes!(name: "Bar")
|
17
|
+
|
18
|
+
expect(document).to have_a_version_with_changes(name: "Bar")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/spec/models/gadget_spec.rb
CHANGED
@@ -6,61 +6,57 @@ describe Gadget, type: :model do
|
|
6
6
|
let(:gadget) { Gadget.create!(name: "Wrench", brand: "Acme") }
|
7
7
|
|
8
8
|
describe "updates", versioning: true do
|
9
|
-
it "
|
10
|
-
expect { gadget.update_attribute(:name, "Hammer").to
|
9
|
+
it "generates a version for updates to `name` attribute" do
|
10
|
+
expect { gadget.update_attribute(:name, "Hammer") }.to(change { gadget.versions.size }.by(1))
|
11
11
|
end
|
12
12
|
|
13
|
-
it "
|
14
|
-
expect { gadget.update_attribute(:brand, "Stanley") }.
|
13
|
+
it "ignores for updates to `brand` attribute" do
|
14
|
+
expect { gadget.update_attribute(:brand, "Stanley") }.not_to(change { gadget.versions.size })
|
15
15
|
end
|
16
16
|
|
17
|
-
it "
|
17
|
+
it "still generates a version when only the `updated_at` attribute is updated" do
|
18
18
|
# Plus 1 second because MySQL lacks sub-second resolution
|
19
19
|
expect {
|
20
20
|
gadget.update_attribute(:updated_at, Time.now + 1)
|
21
|
-
}.to
|
21
|
+
}.to(change { gadget.versions.size }.by(1))
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
describe "
|
26
|
-
|
27
|
-
describe "private" do
|
28
|
-
describe "#changed_notably?" do
|
29
|
-
subject { Gadget.new(created_at: Time.now) }
|
25
|
+
describe "#changed_notably?", versioning: true do
|
26
|
+
subject { Gadget.new(created_at: Time.now) }
|
30
27
|
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
context "create events" do
|
29
|
+
it "returns true" do
|
30
|
+
expect(subject.paper_trail.changed_notably?).to eq(true)
|
31
|
+
end
|
32
|
+
end
|
34
33
|
|
35
|
-
|
36
|
-
|
34
|
+
context "update events" do
|
35
|
+
before { subject.save! }
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
context "without update timestamps" do
|
38
|
+
it "only acknowledges non-ignored attrs" do
|
39
|
+
subject.name = "Wrench"
|
40
|
+
expect(subject.paper_trail.changed_notably?).to be true
|
41
|
+
end
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
43
|
+
it "does not acknowledge ignored attr (brand)" do
|
44
|
+
subject.brand = "Acme"
|
45
|
+
expect(subject.paper_trail.changed_notably?).to be false
|
46
|
+
end
|
47
|
+
end
|
49
48
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
49
|
+
context "with update timestamps" do
|
50
|
+
it "only acknowledges non-ignored attrs" do
|
51
|
+
subject.name = "Wrench"
|
52
|
+
subject.updated_at = Time.now
|
53
|
+
expect(subject.paper_trail.changed_notably?).to be true
|
54
|
+
end
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
56
|
+
it "does not acknowledge ignored attrs and timestamps only" do
|
57
|
+
subject.brand = "Acme"
|
58
|
+
subject.updated_at = Time.now
|
59
|
+
expect(subject.paper_trail.changed_notably?).to be false
|
64
60
|
end
|
65
61
|
end
|
66
62
|
end
|