paper_trail 6.0.2 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|