paper_trail 4.2.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +28 -9
  3. data/.github/ISSUE_TEMPLATE.md +13 -0
  4. data/.gitignore +2 -1
  5. data/.rubocop.yml +100 -0
  6. data/.rubocop_todo.yml +14 -0
  7. data/.travis.yml +8 -9
  8. data/Appraisals +41 -0
  9. data/CHANGELOG.md +49 -9
  10. data/Gemfile +1 -1
  11. data/README.md +130 -109
  12. data/Rakefile +19 -19
  13. data/doc/bug_report_template.rb +20 -14
  14. data/gemfiles/ar3.gemfile +10 -53
  15. data/gemfiles/ar4.gemfile +7 -0
  16. data/gemfiles/ar5.gemfile +13 -0
  17. data/lib/generators/paper_trail/install_generator.rb +26 -18
  18. data/lib/generators/paper_trail/templates/add_object_changes_to_versions.rb +4 -2
  19. data/lib/generators/paper_trail/templates/add_transaction_id_column_to_versions.rb +2 -0
  20. data/lib/generators/paper_trail/templates/create_version_associations.rb +9 -4
  21. data/lib/generators/paper_trail/templates/create_versions.rb +39 -5
  22. data/lib/paper_trail.rb +169 -146
  23. data/lib/paper_trail/attributes_serialization.rb +89 -17
  24. data/lib/paper_trail/cleaner.rb +15 -9
  25. data/lib/paper_trail/config.rb +28 -11
  26. data/lib/paper_trail/frameworks/active_record.rb +4 -0
  27. data/lib/paper_trail/frameworks/active_record/models/paper_trail/version.rb +5 -1
  28. data/lib/paper_trail/frameworks/active_record/models/paper_trail/version_association.rb +6 -2
  29. data/lib/paper_trail/frameworks/cucumber.rb +1 -0
  30. data/lib/paper_trail/frameworks/rails.rb +2 -7
  31. data/lib/paper_trail/frameworks/rails/controller.rb +29 -9
  32. data/lib/paper_trail/frameworks/rails/engine.rb +7 -1
  33. data/lib/paper_trail/frameworks/rspec.rb +5 -5
  34. data/lib/paper_trail/frameworks/rspec/helpers.rb +3 -1
  35. data/lib/paper_trail/frameworks/sinatra.rb +6 -4
  36. data/lib/paper_trail/has_paper_trail.rb +199 -106
  37. data/lib/paper_trail/record_history.rb +1 -3
  38. data/lib/paper_trail/reifier.rb +297 -118
  39. data/lib/paper_trail/serializers/json.rb +3 -3
  40. data/lib/paper_trail/serializers/yaml.rb +27 -8
  41. data/lib/paper_trail/version_association_concern.rb +3 -1
  42. data/lib/paper_trail/version_concern.rb +75 -35
  43. data/lib/paper_trail/version_number.rb +6 -9
  44. data/paper_trail.gemspec +44 -51
  45. data/spec/generators/install_generator_spec.rb +24 -25
  46. data/spec/generators/paper_trail/templates/create_versions_spec.rb +51 -0
  47. data/spec/models/animal_spec.rb +12 -12
  48. data/spec/models/boolit_spec.rb +8 -8
  49. data/spec/models/callback_modifier_spec.rb +47 -47
  50. data/spec/models/car_spec.rb +13 -0
  51. data/spec/models/fluxor_spec.rb +3 -3
  52. data/spec/models/gadget_spec.rb +19 -19
  53. data/spec/models/joined_version_spec.rb +3 -3
  54. data/spec/models/json_version_spec.rb +23 -24
  55. data/spec/models/kitchen/banana_spec.rb +3 -3
  56. data/spec/models/not_on_update_spec.rb +7 -4
  57. data/spec/models/post_with_status_spec.rb +13 -3
  58. data/spec/models/skipper_spec.rb +10 -10
  59. data/spec/models/thing_spec.rb +4 -4
  60. data/spec/models/truck_spec.rb +5 -0
  61. data/spec/models/vehicle_spec.rb +5 -0
  62. data/spec/models/version_spec.rb +103 -59
  63. data/spec/models/widget_spec.rb +82 -52
  64. data/spec/modules/paper_trail_spec.rb +2 -2
  65. data/spec/modules/version_concern_spec.rb +11 -12
  66. data/spec/modules/version_number_spec.rb +2 -4
  67. data/spec/paper_trail/config_spec.rb +10 -29
  68. data/spec/paper_trail_spec.rb +16 -14
  69. data/spec/rails_helper.rb +10 -9
  70. data/spec/requests/articles_spec.rb +11 -7
  71. data/spec/spec_helper.rb +41 -22
  72. data/spec/support/alt_db_init.rb +8 -13
  73. data/test/custom_json_serializer.rb +3 -3
  74. data/test/dummy/Rakefile +2 -2
  75. data/test/dummy/app/controllers/application_controller.rb +21 -8
  76. data/test/dummy/app/controllers/articles_controller.rb +11 -8
  77. data/test/dummy/app/controllers/widgets_controller.rb +13 -12
  78. data/test/dummy/app/models/animal.rb +1 -1
  79. data/test/dummy/app/models/article.rb +19 -11
  80. data/test/dummy/app/models/authorship.rb +1 -1
  81. data/test/dummy/app/models/bar_habtm.rb +4 -0
  82. data/test/dummy/app/models/book.rb +4 -4
  83. data/test/dummy/app/models/boolit.rb +1 -1
  84. data/test/dummy/app/models/callback_modifier.rb +6 -6
  85. data/test/dummy/app/models/car.rb +3 -0
  86. data/test/dummy/app/models/chapter.rb +4 -4
  87. data/test/dummy/app/models/customer.rb +1 -1
  88. data/test/dummy/app/models/document.rb +2 -2
  89. data/test/dummy/app/models/editor.rb +1 -1
  90. data/test/dummy/app/models/foo_habtm.rb +4 -0
  91. data/test/dummy/app/models/fruit.rb +2 -2
  92. data/test/dummy/app/models/gadget.rb +1 -1
  93. data/test/dummy/app/models/kitchen/banana.rb +1 -1
  94. data/test/dummy/app/models/legacy_widget.rb +2 -2
  95. data/test/dummy/app/models/line_item.rb +1 -1
  96. data/test/dummy/app/models/not_on_update.rb +1 -1
  97. data/test/dummy/app/models/person.rb +6 -6
  98. data/test/dummy/app/models/post.rb +1 -1
  99. data/test/dummy/app/models/post_with_status.rb +1 -1
  100. data/test/dummy/app/models/quotation.rb +1 -1
  101. data/test/dummy/app/models/section.rb +1 -1
  102. data/test/dummy/app/models/skipper.rb +2 -2
  103. data/test/dummy/app/models/song.rb +13 -4
  104. data/test/dummy/app/models/thing.rb +2 -2
  105. data/test/dummy/app/models/translation.rb +2 -2
  106. data/test/dummy/app/models/truck.rb +4 -0
  107. data/test/dummy/app/models/vehicle.rb +4 -0
  108. data/test/dummy/app/models/whatchamajigger.rb +1 -1
  109. data/test/dummy/app/models/widget.rb +7 -6
  110. data/test/dummy/app/versions/joined_version.rb +4 -3
  111. data/test/dummy/app/versions/json_version.rb +1 -1
  112. data/test/dummy/app/versions/kitchen/banana_version.rb +1 -1
  113. data/test/dummy/app/versions/post_version.rb +2 -2
  114. data/test/dummy/config.ru +1 -1
  115. data/test/dummy/config/application.rb +20 -9
  116. data/test/dummy/config/boot.rb +5 -5
  117. data/test/dummy/config/environment.rb +1 -1
  118. data/test/dummy/config/environments/development.rb +4 -3
  119. data/test/dummy/config/environments/production.rb +3 -2
  120. data/test/dummy/config/environments/test.rb +15 -5
  121. data/test/dummy/config/initializers/backtrace_silencers.rb +4 -2
  122. data/test/dummy/config/initializers/paper_trail.rb +1 -2
  123. data/test/dummy/config/initializers/secret_token.rb +3 -1
  124. data/test/dummy/config/initializers/session_store.rb +1 -1
  125. data/test/dummy/config/routes.rb +2 -2
  126. data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +120 -74
  127. data/test/dummy/db/schema.rb +29 -6
  128. data/test/dummy/script/rails +6 -4
  129. data/test/functional/controller_test.rb +34 -35
  130. data/test/functional/enabled_for_controller_test.rb +6 -7
  131. data/test/functional/modular_sinatra_test.rb +43 -38
  132. data/test/functional/sinatra_test.rb +49 -40
  133. data/test/functional/thread_safety_test.rb +4 -6
  134. data/test/paper_trail_test.rb +15 -14
  135. data/test/test_helper.rb +68 -44
  136. data/test/time_travel_helper.rb +1 -15
  137. data/test/unit/associations_test.rb +517 -251
  138. data/test/unit/cleaner_test.rb +66 -60
  139. data/test/unit/inheritance_column_test.rb +17 -17
  140. data/test/unit/model_test.rb +611 -504
  141. data/test/unit/protected_attrs_test.rb +16 -12
  142. data/test/unit/serializer_test.rb +44 -43
  143. data/test/unit/serializers/json_test.rb +17 -18
  144. data/test/unit/serializers/mixin_json_test.rb +15 -14
  145. data/test/unit/serializers/mixin_yaml_test.rb +20 -16
  146. data/test/unit/serializers/yaml_test.rb +12 -13
  147. data/test/unit/timestamp_test.rb +10 -12
  148. data/test/unit/version_test.rb +7 -7
  149. metadata +92 -40
@@ -1,10 +1,10 @@
1
- require 'rails_helper'
2
- require 'generator_spec/test_case'
3
- require File.expand_path('../../../lib/generators/paper_trail/install_generator', __FILE__)
1
+ require "rails_helper"
2
+ require "generator_spec/test_case"
3
+ require File.expand_path("../../../lib/generators/paper_trail/install_generator", __FILE__)
4
4
 
5
- describe PaperTrail::InstallGenerator, :type => :generator do
5
+ describe PaperTrail::InstallGenerator, type: :generator do
6
6
  include GeneratorSpec::TestCase
7
- destination File.expand_path('../tmp', __FILE__)
7
+ destination File.expand_path("../tmp", __FILE__)
8
8
 
9
9
  after(:all) { prepare_destination } # cleanup the tmp directory
10
10
 
@@ -13,15 +13,15 @@ describe PaperTrail::InstallGenerator, :type => :generator do
13
13
  prepare_destination
14
14
  run_generator
15
15
  end
16
-
16
+
17
17
  it "generates a migration for creating the 'versions' table" do
18
18
  expect(destination_root).to have_structure {
19
- directory 'db' do
20
- directory 'migrate' do
21
- migration 'create_versions' do
22
- contains 'class CreateVersions'
23
- contains 'def change'
24
- contains 'create_table :versions do |t|'
19
+ directory "db" do
20
+ directory "migrate" do
21
+ migration "create_versions" do
22
+ contains "class CreateVersions"
23
+ contains "def change"
24
+ contains "create_table :versions"
25
25
  end
26
26
  end
27
27
  end
@@ -37,12 +37,12 @@ describe PaperTrail::InstallGenerator, :type => :generator do
37
37
 
38
38
  it "generates a migration for creating the 'versions' table" do
39
39
  expect(destination_root).to have_structure {
40
- directory 'db' do
41
- directory 'migrate' do
42
- migration 'create_versions' do
43
- contains 'class CreateVersions'
44
- contains 'def change'
45
- contains 'create_table :versions do |t|'
40
+ directory "db" do
41
+ directory "migrate" do
42
+ migration "create_versions" do
43
+ contains "class CreateVersions"
44
+ contains "def change"
45
+ contains "create_table :versions"
46
46
  end
47
47
  end
48
48
  end
@@ -51,17 +51,16 @@ describe PaperTrail::InstallGenerator, :type => :generator do
51
51
 
52
52
  it "generates a migration for adding the 'object_changes' column to the 'versions' table" do
53
53
  expect(destination_root).to have_structure {
54
- directory 'db' do
55
- directory 'migrate' do
56
- migration 'add_object_changes_to_versions' do
57
- contains 'class AddObjectChangesToVersions'
58
- contains 'def change'
59
- contains 'add_column :versions, :object_changes, :text'
54
+ directory "db" do
55
+ directory "migrate" do
56
+ migration "add_object_changes_to_versions" do
57
+ contains "class AddObjectChangesToVersions"
58
+ contains "def change"
59
+ contains "add_column :versions, :object_changes, :text"
60
60
  end
61
61
  end
62
62
  end
63
63
  }
64
64
  end
65
65
  end
66
-
67
66
  end
@@ -0,0 +1,51 @@
1
+ require "rails_helper"
2
+ require "generators/paper_trail/templates/create_versions"
3
+
4
+ RSpec.describe CreateVersions do
5
+ describe "#change", verify_stubs: false do
6
+ let(:migration) { described_class.new }
7
+
8
+ before do
9
+ allow(migration).to receive(:add_index)
10
+ allow(migration).to receive(:create_table)
11
+ end
12
+
13
+ it "creates the versions table" do
14
+ migration.change
15
+ expect(migration).to have_received(:create_table) do |arg1|
16
+ expect(arg1).to eq(:versions)
17
+ end
18
+ end
19
+
20
+ case ENV["DB"]
21
+ when "mysql"
22
+ it "uses InnoDB engine" do
23
+ migration.change
24
+ expect(migration).to have_received(:create_table) do |_, arg2|
25
+ expect(arg2[:options]).to match(/ENGINE=InnoDB/)
26
+ end
27
+ end
28
+
29
+ it "uses utf8mb4 character set" do
30
+ migration.change
31
+ expect(migration).to have_received(:create_table) do |_, arg2|
32
+ expect(arg2[:options]).to match(/DEFAULT CHARSET=utf8mb4/)
33
+ end
34
+ end
35
+
36
+ it "uses utf8mb4_col collation" do
37
+ migration.change
38
+ expect(migration).to have_received(:create_table) do |_, arg2|
39
+ expect(arg2[:options]).to match(/COLLATE=utf8mb4_general_ci/)
40
+ end
41
+ end
42
+ else
43
+ it "passes an empty options hash to create_table" do
44
+ migration.change
45
+ expect(migration).to have_received(:create_table) do |_, arg2|
46
+ expect(arg2).to eq({})
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,32 +1,32 @@
1
- require 'rails_helper'
1
+ require "rails_helper"
2
2
 
3
- describe Animal, :type => :model do
3
+ describe Animal, type: :model do
4
4
  it { is_expected.to be_versioned }
5
5
 
6
- describe "STI", :versioning => true do
7
- it { expect(Animal.inheritance_column).to eq('species') }
6
+ describe "STI", versioning: true do
7
+ it { expect(Animal.inheritance_column).to eq("species") }
8
8
 
9
9
  describe "updates to the `inheritance_column`" do
10
- subject { Cat.create!(:name => 'Leo') }
10
+ subject { Cat.create!(name: "Leo") }
11
11
 
12
12
  it "should be allowed" do
13
- subject.update_attributes(:name => 'Spike', :species => 'Dog')
13
+ subject.update_attributes(name: "Spike", species: "Dog")
14
14
  dog = Animal.find(subject.id)
15
15
  expect(dog).to be_instance_of(Dog)
16
16
  end
17
17
  end
18
18
 
19
- context 'with callback-methods' do
20
- context 'when only has_paper_trail set in super class' do
21
- let(:callback_cat) { Cat.create(:name => 'Markus') }
19
+ context "with callback-methods" do
20
+ context "when only has_paper_trail set in super class" do
21
+ let(:callback_cat) { Cat.create(name: "Markus") }
22
22
 
23
- it 'trails all events' do
24
- callback_cat.update_attributes(:name => 'Billie')
23
+ it "trails all events" do
24
+ callback_cat.update_attributes(name: "Billie")
25
25
  callback_cat.destroy
26
26
  expect(callback_cat.versions.collect(&:event)).to eq %w(create update destroy)
27
27
  end
28
28
 
29
- it 'does not break reify' do
29
+ it "does not break reify" do
30
30
  callback_cat.destroy
31
31
  expect { callback_cat.versions.last.reify }.not_to raise_error
32
32
  end
@@ -1,16 +1,16 @@
1
- require 'rails_helper'
2
- require Rails.root.join('..', 'custom_json_serializer')
1
+ require "rails_helper"
2
+ require Rails.root.join("..", "custom_json_serializer")
3
3
 
4
- describe Boolit, :type => :model do
4
+ describe Boolit, type: :model do
5
5
  it { is_expected.to be_versioned }
6
6
 
7
7
  it "has a default scope" do
8
8
  expect(subject.default_scopes).to_not be_empty
9
9
  end
10
10
 
11
- describe "Versioning", :versioning => true do
11
+ describe "Versioning", versioning: true do
12
12
  subject { Boolit.create! }
13
- before { subject.update_attributes!(:name => Faker::Name.name) }
13
+ before { subject.update_attributes!(name: FFaker::Name.name) }
14
14
 
15
15
  it "should have versions" do
16
16
  expect(subject.versions.size).to eq(2)
@@ -21,7 +21,7 @@ describe Boolit, :type => :model do
21
21
  end
22
22
 
23
23
  context "Instance falls out of default scope" do
24
- before { subject.update_attributes!(:scoped => false) }
24
+ before { subject.update_attributes!(scoped: false) }
25
25
 
26
26
  it "is NOT scoped" do
27
27
  expect(Boolit.first).to be_nil
@@ -34,8 +34,8 @@ describe Boolit, :type => :model do
34
34
  context "with `nil` attributes on the live instance" do
35
35
  before do
36
36
  PaperTrail.serializer = CustomJsonSerializer
37
- subject.update_attributes!(:name => nil)
38
- subject.update_attributes!(:name => Faker::Name.name)
37
+ subject.update_attributes!(name: nil)
38
+ subject.update_attributes!(name: FFaker::Name.name)
39
39
  end
40
40
  after { PaperTrail.serializer = PaperTrail::Serializers::YAML }
41
41
 
@@ -1,94 +1,94 @@
1
- require 'rails_helper'
1
+ require "rails_helper"
2
2
 
3
- describe CallbackModifier, :type => :model do
3
+ describe CallbackModifier, type: :model do
4
4
  with_versioning do
5
- describe 'callback-methods', :versioning => true do
6
- describe 'paper_trail_on_destroy' do
7
- it 'should add :destroy to paper_trail_options[:on]' do
8
- modifier = NoArgDestroyModifier.create!(:some_content => Faker::Lorem.sentence)
5
+ describe "callback-methods", versioning: true do
6
+ describe "paper_trail_on_destroy" do
7
+ it "should add :destroy to paper_trail_options[:on]" do
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
- context 'when :before' do
13
- it 'should create the version before destroy' do
14
- modifier = BeforeDestroyModifier.create!(:some_content => Faker::Lorem.sentence)
12
+ context "when :before" do
13
+ it "should create the version before destroy" do
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
17
17
  end
18
18
  end
19
19
 
20
- context 'when :after' do
21
- it 'should create the version after destroy' do
22
- modifier = AfterDestroyModifier.create!(:some_content => Faker::Lorem.sentence)
20
+ context "when :after" do
21
+ it "should create the version after destroy" do
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
25
25
  end
26
26
  end
27
27
 
28
- context 'when no argument' do
29
- it 'should default to after destroy' do
30
- modifier = NoArgDestroyModifier.create!(:some_content => Faker::Lorem.sentence)
28
+ context "when no argument" do
29
+ it "should default to before destroy" do
30
+ modifier = NoArgDestroyModifier.create!(some_content: FFaker::Lorem.sentence)
31
31
  modifier.test_destroy
32
- expect(modifier.versions.last.reify).to be_flagged_deleted
32
+ expect(modifier.versions.last.reify).not_to be_flagged_deleted
33
33
  end
34
34
  end
35
35
  end
36
36
 
37
- describe 'paper_trail_on_update' do
38
- it 'should add :update to paper_trail_options[:on]' do
39
- modifier = UpdateModifier.create!(:some_content => Faker::Lorem.sentence)
37
+ describe "paper_trail_on_update" do
38
+ it "should add :update to paper_trail_options[:on]" do
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 'should create a version' do
44
- modifier = UpdateModifier.create!(:some_content => Faker::Lorem.sentence)
45
- modifier.update_attributes! :some_content => 'modified'
46
- expect(modifier.versions.last.event).to eq 'update'
43
+ it "should create a version" do
44
+ modifier = UpdateModifier.create!(some_content: FFaker::Lorem.sentence)
45
+ modifier.update_attributes! some_content: "modified"
46
+ expect(modifier.versions.last.event).to eq "update"
47
47
  end
48
48
  end
49
49
 
50
- describe 'paper_trail_on_create' do
51
- it 'should add :create to paper_trail_options[:on]' do
52
- modifier = CreateModifier.create!(:some_content => Faker::Lorem.sentence)
50
+ describe "paper_trail_on_create" do
51
+ it "should add :create to paper_trail_options[:on]" do
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 'should create a version' do
57
- modifier = CreateModifier.create!(:some_content => Faker::Lorem.sentence)
58
- expect(modifier.versions.last.event).to eq 'create'
56
+ it "should create a version" do
57
+ modifier = CreateModifier.create!(some_content: FFaker::Lorem.sentence)
58
+ expect(modifier.versions.last.event).to eq "create"
59
59
  end
60
60
  end
61
61
 
62
- context 'when no callback-method used' do
63
- it 'should set paper_trail_options[:on] to [:create, :update, :destroy]' do
64
- modifier = DefaultModifier.create!(:some_content => Faker::Lorem.sentence)
62
+ context "when no callback-method used" do
63
+ it "should set paper_trail_options[:on] to [:create, :update, :destroy]" do
64
+ modifier = DefaultModifier.create!(some_content: FFaker::Lorem.sentence)
65
65
  expect(modifier.paper_trail_options[:on]).to eq [:create, :update, :destroy]
66
66
  end
67
67
 
68
- it 'should default to track destroy' do
69
- modifier = DefaultModifier.create!(:some_content => Faker::Lorem.sentence)
68
+ it "should default to track destroy" do
69
+ modifier = DefaultModifier.create!(some_content: FFaker::Lorem.sentence)
70
70
  modifier.destroy
71
- expect(modifier.versions.last.event).to eq 'destroy'
71
+ expect(modifier.versions.last.event).to eq "destroy"
72
72
  end
73
73
 
74
- it 'should default to track update' do
75
- modifier = DefaultModifier.create!(:some_content => Faker::Lorem.sentence)
76
- modifier.update_attributes! :some_content => 'modified'
77
- expect(modifier.versions.last.event).to eq 'update'
74
+ it "should default to track update" do
75
+ modifier = DefaultModifier.create!(some_content: FFaker::Lorem.sentence)
76
+ modifier.update_attributes! some_content: "modified"
77
+ expect(modifier.versions.last.event).to eq "update"
78
78
  end
79
79
 
80
- it 'should default to track create' do
81
- modifier = DefaultModifier.create!(:some_content => Faker::Lorem.sentence)
82
- expect(modifier.versions.last.event).to eq 'create'
80
+ it "should default to track create" do
81
+ modifier = DefaultModifier.create!(some_content: FFaker::Lorem.sentence)
82
+ expect(modifier.versions.last.event).to eq "create"
83
83
  end
84
84
  end
85
85
 
86
- context 'when only one callback-method' do
87
- it 'does only track the corresponding event' do
88
- modifier = CreateModifier.create!(:some_content => Faker::Lorem.sentence)
89
- modifier.update_attributes!(:some_content => 'modified')
86
+ context "when only one callback-method" do
87
+ it "does only track the corresponding event" do
88
+ modifier = CreateModifier.create!(some_content: FFaker::Lorem.sentence)
89
+ modifier.update_attributes!(some_content: "modified")
90
90
  modifier.test_destroy
91
- expect(modifier.versions.collect(&:event)).to eq ['create']
91
+ expect(modifier.versions.collect(&:event)).to eq ["create"]
92
92
  end
93
93
  end
94
94
  end
@@ -0,0 +1,13 @@
1
+ require "rails_helper"
2
+
3
+ describe Car, type: :model do
4
+ it { is_expected.to be_versioned }
5
+
6
+ describe "changeset", versioning: true do
7
+ it "has the expected keys (see issue 738)" do
8
+ car = Car.create!(name: "Alice")
9
+ car.update_attributes(name: "Bob")
10
+ assert_includes car.versions.last.changeset.keys, "name"
11
+ end
12
+ end
13
+ end
@@ -1,7 +1,7 @@
1
- require 'rails_helper'
1
+ require "rails_helper"
2
2
 
3
- describe Fluxor, :type => :model do
4
- describe '`be_versioned` matcher' do
3
+ describe Fluxor, type: :model do
4
+ describe "`be_versioned` matcher" do
5
5
  it { is_expected.to_not be_versioned }
6
6
  end
7
7
 
@@ -1,36 +1,34 @@
1
- require 'rails_helper'
1
+ require "rails_helper"
2
2
 
3
- describe Gadget, :type => :model do
3
+ describe Gadget, type: :model do
4
4
  it { is_expected.to be_versioned }
5
5
 
6
- let(:gadget) { Gadget.create!(:name => 'Wrench', :brand => 'Acme') }
6
+ let(:gadget) { Gadget.create!(name: "Wrench", brand: "Acme") }
7
7
 
8
- describe "updates", :versioning => true do
8
+ describe "updates", versioning: true do
9
9
  it "should generate a version for updates to `name` attribute" do
10
- expect { gadget.update_attribute(:name, 'Hammer').to change{gadget.versions.size}.by(1) }
10
+ expect { gadget.update_attribute(:name, "Hammer").to change { gadget.versions.size }.by(1) }
11
11
  end
12
12
 
13
13
  it "should ignore for updates to `brand` attribute" do
14
- expect { gadget.update_attribute(:brand, 'Stanley') }.to_not change{gadget.versions.size}
14
+ expect { gadget.update_attribute(:brand, "Stanley") }.to_not change { gadget.versions.size }
15
15
  end
16
16
 
17
17
  it "should still generate a version when only the `updated_at` attribute is updated" do
18
- expect { gadget.update_attribute(:updated_at, Time.now) }.to change{gadget.versions.size}.by(1)
18
+ # Plus 1 second because MySQL lacks sub-second resolution
19
+ expect {
20
+ gadget.update_attribute(:updated_at, Time.now + 1)
21
+ }.to change { gadget.versions.size }.by(1)
19
22
  end
20
23
  end
21
24
 
22
25
  describe "Methods" do
23
- describe "Instance", :versioning => true do
26
+ describe "Instance", versioning: true do
24
27
  describe "private" do
25
28
  describe '#changed_notably?' do
26
- subject { Gadget.new(:created_at => Time.now) }
29
+ subject { Gadget.new(created_at: Time.now) }
27
30
 
28
- # apparently the private methods list in Ruby18 is different than in Ruby19+
29
- if RUBY_VERSION >= '1.9'
30
- it { expect(subject.private_methods).to include(:changed_notably?) }
31
- else
32
- it { expect(subject.private_methods).to include('changed_notably?') }
33
- end
31
+ it { expect(subject.private_methods).to include(:changed_notably?) }
34
32
 
35
33
  context "create events" do
36
34
  it { expect(subject.send(:changed_notably?)).to be true }
@@ -41,24 +39,26 @@ describe Gadget, :type => :model do
41
39
 
42
40
  context "without update timestamps" do
43
41
  it "should only acknowledge non-ignored attrs" do
44
- subject.name = 'Wrench'
42
+ subject.name = "Wrench"
45
43
  expect(subject.send(:changed_notably?)).to be true
46
44
  end
47
45
 
48
46
  it "should not acknowledge ignored attr (brand)" do
49
- subject.brand = 'Acme'
47
+ subject.brand = "Acme"
50
48
  expect(subject.send(:changed_notably?)).to be false
51
49
  end
52
50
  end
53
51
 
54
52
  context "with update timestamps" do
55
53
  it "should only acknowledge non-ignored attrs" do
56
- subject.name, subject.updated_at = 'Wrench', Time.now
54
+ subject.name = "Wrench"
55
+ subject.updated_at = Time.now
57
56
  expect(subject.send(:changed_notably?)).to be true
58
57
  end
59
58
 
60
59
  it "should not acknowledge ignored attrs and timestamps only" do
61
- subject.brand, subject.updated_at = 'Acme', Time.now
60
+ subject.brand = "Acme"
61
+ subject.updated_at = Time.now
62
62
  expect(subject.send(:changed_notably?)).to be false
63
63
  end
64
64
  end