paper_trail 3.0.6 → 4.2.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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rspec +1 -2
  4. data/.travis.yml +14 -5
  5. data/CHANGELOG.md +215 -8
  6. data/CONTRIBUTING.md +84 -0
  7. data/README.md +922 -502
  8. data/Rakefile +2 -2
  9. data/doc/bug_report_template.rb +65 -0
  10. data/gemfiles/ar3.gemfile +61 -0
  11. data/lib/generators/paper_trail/install_generator.rb +22 -3
  12. data/lib/generators/paper_trail/templates/add_object_changes_to_versions.rb +6 -1
  13. data/lib/generators/paper_trail/templates/add_transaction_id_column_to_versions.rb +11 -0
  14. data/lib/generators/paper_trail/templates/create_version_associations.rb +17 -0
  15. data/lib/generators/paper_trail/templates/create_versions.rb +22 -1
  16. data/lib/paper_trail.rb +52 -22
  17. data/lib/paper_trail/attributes_serialization.rb +89 -0
  18. data/lib/paper_trail/cleaner.rb +32 -15
  19. data/lib/paper_trail/config.rb +35 -2
  20. data/lib/paper_trail/frameworks/active_record.rb +4 -5
  21. data/lib/paper_trail/frameworks/active_record/models/paper_trail/version_association.rb +7 -0
  22. data/lib/paper_trail/frameworks/rails.rb +1 -0
  23. data/lib/paper_trail/frameworks/rails/controller.rb +27 -11
  24. data/lib/paper_trail/frameworks/rspec.rb +5 -0
  25. data/lib/paper_trail/frameworks/sinatra.rb +3 -1
  26. data/lib/paper_trail/has_paper_trail.rb +304 -148
  27. data/lib/paper_trail/record_history.rb +59 -0
  28. data/lib/paper_trail/reifier.rb +270 -0
  29. data/lib/paper_trail/serializers/json.rb +13 -2
  30. data/lib/paper_trail/serializers/yaml.rb +16 -2
  31. data/lib/paper_trail/version_association_concern.rb +15 -0
  32. data/lib/paper_trail/version_concern.rb +160 -122
  33. data/lib/paper_trail/version_number.rb +3 -3
  34. data/paper_trail.gemspec +22 -9
  35. data/spec/generators/install_generator_spec.rb +4 -4
  36. data/spec/models/animal_spec.rb +36 -0
  37. data/spec/models/boolit_spec.rb +48 -0
  38. data/spec/models/callback_modifier_spec.rb +96 -0
  39. data/spec/models/fluxor_spec.rb +19 -0
  40. data/spec/models/gadget_spec.rb +14 -12
  41. data/spec/models/joined_version_spec.rb +9 -9
  42. data/spec/models/json_version_spec.rb +103 -0
  43. data/spec/models/kitchen/banana_spec.rb +14 -0
  44. data/spec/models/not_on_update_spec.rb +19 -0
  45. data/spec/models/post_with_status_spec.rb +3 -3
  46. data/spec/models/skipper_spec.rb +46 -0
  47. data/spec/models/thing_spec.rb +11 -0
  48. data/spec/models/version_spec.rb +195 -44
  49. data/spec/models/widget_spec.rb +136 -76
  50. data/spec/modules/paper_trail_spec.rb +27 -0
  51. data/spec/modules/version_concern_spec.rb +8 -8
  52. data/spec/modules/version_number_spec.rb +16 -16
  53. data/spec/paper_trail/config_spec.rb +52 -0
  54. data/spec/paper_trail_spec.rb +17 -17
  55. data/spec/rails_helper.rb +34 -0
  56. data/spec/requests/articles_spec.rb +10 -14
  57. data/spec/spec_helper.rb +81 -34
  58. data/spec/support/alt_db_init.rb +1 -1
  59. data/test/dummy/app/controllers/application_controller.rb +1 -1
  60. data/test/dummy/app/controllers/articles_controller.rb +4 -1
  61. data/test/dummy/app/models/animal.rb +2 -0
  62. data/test/dummy/app/models/book.rb +4 -0
  63. data/test/dummy/app/models/boolit.rb +4 -0
  64. data/test/dummy/app/models/callback_modifier.rb +45 -0
  65. data/test/dummy/app/models/chapter.rb +9 -0
  66. data/test/dummy/app/models/citation.rb +5 -0
  67. data/test/dummy/app/models/customer.rb +4 -0
  68. data/test/dummy/app/models/editor.rb +4 -0
  69. data/test/dummy/app/models/editorship.rb +5 -0
  70. data/test/dummy/app/models/fruit.rb +5 -0
  71. data/test/dummy/app/models/kitchen/banana.rb +5 -0
  72. data/test/dummy/app/models/line_item.rb +4 -0
  73. data/test/dummy/app/models/not_on_update.rb +4 -0
  74. data/test/dummy/app/models/order.rb +5 -0
  75. data/test/dummy/app/models/paragraph.rb +5 -0
  76. data/test/dummy/app/models/person.rb +13 -3
  77. data/test/dummy/app/models/post.rb +0 -1
  78. data/test/dummy/app/models/quotation.rb +5 -0
  79. data/test/dummy/app/models/section.rb +6 -0
  80. data/test/dummy/app/models/skipper.rb +6 -0
  81. data/test/dummy/app/models/song.rb +20 -0
  82. data/test/dummy/app/models/thing.rb +3 -0
  83. data/test/dummy/app/models/whatchamajigger.rb +4 -0
  84. data/test/dummy/app/models/widget.rb +5 -0
  85. data/test/dummy/app/versions/json_version.rb +3 -0
  86. data/test/dummy/app/versions/kitchen/banana_version.rb +5 -0
  87. data/test/dummy/config/application.rb +6 -0
  88. data/test/dummy/config/database.postgres.yml +1 -1
  89. data/test/dummy/config/environments/test.rb +5 -1
  90. data/test/dummy/config/initializers/paper_trail.rb +6 -1
  91. data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +143 -3
  92. data/test/dummy/db/schema.rb +169 -25
  93. data/test/functional/controller_test.rb +4 -2
  94. data/test/functional/modular_sinatra_test.rb +1 -1
  95. data/test/functional/sinatra_test.rb +1 -1
  96. data/test/paper_trail_test.rb +7 -0
  97. data/test/test_helper.rb +38 -2
  98. data/test/time_travel_helper.rb +15 -0
  99. data/test/unit/associations_test.rb +726 -0
  100. data/test/unit/inheritance_column_test.rb +6 -6
  101. data/test/unit/model_test.rb +109 -125
  102. data/test/unit/protected_attrs_test.rb +4 -3
  103. data/test/unit/serializer_test.rb +6 -6
  104. data/test/unit/serializers/json_test.rb +17 -4
  105. data/test/unit/serializers/yaml_test.rb +5 -1
  106. data/test/unit/version_test.rb +87 -69
  107. metadata +172 -75
  108. data/gemfiles/3.0.gemfile +0 -42
  109. data/test/dummy/public/404.html +0 -26
  110. data/test/dummy/public/422.html +0 -26
  111. data/test/dummy/public/500.html +0 -26
  112. data/test/dummy/public/favicon.ico +0 -0
  113. data/test/dummy/public/javascripts/application.js +0 -2
  114. data/test/dummy/public/javascripts/controls.js +0 -965
  115. data/test/dummy/public/javascripts/dragdrop.js +0 -974
  116. data/test/dummy/public/javascripts/effects.js +0 -1123
  117. data/test/dummy/public/javascripts/prototype.js +0 -6001
  118. data/test/dummy/public/javascripts/rails.js +0 -175
  119. data/test/dummy/public/stylesheets/.gitkeep +0 -0
@@ -1,7 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class InheritanceColumnTest < ActiveSupport::TestCase
4
-
5
4
  context 'STI models' do
6
5
  setup do
7
6
  @animal = Animal.create :name => 'Animal'
@@ -28,16 +27,17 @@ class InheritanceColumnTest < ActiveSupport::TestCase
28
27
 
29
28
  # For some reason `@dog.versions` doesn't include the final `destroy` version.
30
29
  # Neither do `@dog.versions.scoped` nor `@dog.versions(true)` nor `@dog.versions.reload`.
31
- dog_versions = PaperTrail::Version.where(:item_id => @dog.id)
30
+ dog_versions = PaperTrail::Version.where(:item_id => @dog.id).
31
+ order(PaperTrail.timestamp_field)
32
32
  assert_equal 4, dog_versions.count
33
33
  assert_nil dog_versions.first.reify
34
- dog_versions[1..-1].each { |v| assert_equal 'Dog', v.reify.class.name }
34
+ assert_equal %w[NilClass Dog Dog Dog], dog_versions.map { |v| v.reify.class.name }
35
35
 
36
- cat_versions = PaperTrail::Version.where(:item_id => @cat.id)
36
+ cat_versions = PaperTrail::Version.where(:item_id => @cat.id).
37
+ order(PaperTrail.timestamp_field)
37
38
  assert_equal 4, cat_versions.count
38
39
  assert_nil cat_versions.first.reify
39
- cat_versions[1..-1].each { |v| assert_equal 'Cat', v.reify.class.name }
40
+ assert_equal %w[NilClass Cat Cat Cat], cat_versions.map { |v| v.reify.class.name }
40
41
  end
41
42
  end
42
-
43
43
  end
@@ -1,4 +1,5 @@
1
1
  require 'test_helper'
2
+ require 'time_travel_helper'
2
3
 
3
4
  class HasPaperTrailModelTest < ActiveSupport::TestCase
4
5
 
@@ -191,9 +192,8 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
191
192
  assert @widget.live?
192
193
  end
193
194
 
194
-
195
195
  context 'which is then created' do
196
- setup { @widget.update_attributes :name => 'Henry' }
196
+ setup { @widget.update_attributes :name => 'Henry', :created_at => Time.now - 1.day }
197
197
 
198
198
  should 'have one previous version' do
199
199
  assert_equal 1, @widget.versions.length
@@ -212,10 +212,14 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
212
212
  assert @widget.live?
213
213
  end
214
214
 
215
+ should "use the widget `updated_at` as the version's `created_at`" do
216
+ assert_equal @widget.updated_at.to_i, @widget.versions.first.created_at.to_i
217
+ end
218
+
215
219
  should 'have changes' do
216
220
 
217
- #TODO Postgres does not appear to pass back ActiveSupport::TimeWithZone,
218
- # so chosing the lowest common denominator to test.
221
+ #TODO Postgres does not appear to pass back ActiveSupport::TimeWithZone,
222
+ # so chosing the lowest common denominator to test.
219
223
 
220
224
  changes = {
221
225
  'name' => [nil, 'Henry'],
@@ -224,8 +228,8 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
224
228
  'id' => [nil, @widget.id]
225
229
  }
226
230
 
227
- assert_equal Time, @widget.versions.last.changeset['updated_at'][1].class
228
- assert_equal changes, @widget.versions.last.changeset
231
+ assert_kind_of Time, @widget.versions.last.changeset['updated_at'][1]
232
+ assert_changes_equal changes, @widget.versions.last.changeset
229
233
  end
230
234
 
231
235
  context 'and then updated without any changes' do
@@ -301,13 +305,13 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
301
305
  should 'not copy the has_one association by default when reifying' do
302
306
  reified_widget = @widget.versions.last.reify
303
307
  assert_equal @wotsit, reified_widget.wotsit # association hasn't been affected by reifying
304
- assert_equal @wotsit, @widget.wotsit # confirm that the association is correct
308
+ assert_equal @wotsit, @widget.wotsit(true) # confirm that the association is correct
305
309
  end
306
310
 
307
311
  should 'copy the has_one association when reifying with :has_one => true' do
308
312
  reified_widget = @widget.versions.last.reify(:has_one => true)
309
313
  assert_nil reified_widget.wotsit # wotsit wasn't there at the last version
310
- assert_equal @wotsit, @widget.wotsit # wotsit came into being on the live object
314
+ assert_equal @wotsit, @widget.wotsit(true) # wotsit should still exist on live object
311
315
  end
312
316
  end
313
317
 
@@ -328,6 +332,31 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
328
332
  end
329
333
  end
330
334
 
335
+ context 'and has many associated polymorphic objects' do
336
+ setup do
337
+ @f0 = @widget.whatchamajiggers.create :name => 'f-zero'
338
+ @f1 = @widget.whatchamajiggers.create :name => 'f-zero'
339
+ @reified_widget = @widget.versions.last.reify
340
+ end
341
+
342
+ should 'copy the has_many associations when reifying' do
343
+ assert_equal @widget.whatchamajiggers.length, @reified_widget.whatchamajiggers.length
344
+ assert_same_elements @widget.whatchamajiggers, @reified_widget.whatchamajiggers
345
+
346
+ assert_equal @widget.versions.length, @reified_widget.versions.length
347
+ assert_same_elements @widget.versions, @reified_widget.versions
348
+ end
349
+ end
350
+
351
+ context 'polymorphic objects by themselves' do
352
+ setup do
353
+ @widget = Whatchamajigger.new :name => 'f-zero'
354
+ end
355
+
356
+ should 'not fail with a nil pointer on the polymorphic association' do
357
+ @widget.save!
358
+ end
359
+ end
331
360
 
332
361
  context 'and then destroyed' do
333
362
  setup do
@@ -346,7 +375,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
346
375
 
347
376
  should 'be available in its previous version' do
348
377
  assert_equal @widget.id, @reified_widget.id
349
- assert_equal @widget.attributes, @reified_widget.attributes
378
+ assert_attributes_equal @widget.attributes, @reified_widget.attributes
350
379
  end
351
380
 
352
381
  should 'be re-creatable from its previous version' do
@@ -413,7 +442,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
413
442
  end
414
443
 
415
444
  should 'handle decimals' do
416
- assert_in_delta 2.71828, @previous.a_decimal, 0.00001
445
+ assert_in_delta 2.7183, @previous.a_decimal, 0.0001
417
446
  end
418
447
 
419
448
  should 'handle datetimes' do
@@ -442,7 +471,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
442
471
  @last = @widget.versions.last
443
472
  end
444
473
 
445
- teardown do
474
+ teardown do
446
475
  restore_schema
447
476
  end
448
477
 
@@ -455,7 +484,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
455
484
  assert_equal 'The quick brown fox', @last.reify.a_text
456
485
  assert_equal 42, @last.reify.an_integer
457
486
  assert_in_delta 153.01, @last.reify.a_float, 0.001
458
- assert_in_delta 2.71828, @last.reify.a_decimal, 0.00001
487
+ assert_in_delta 2.7183, @last.reify.a_decimal, 0.0001
459
488
  assert_equal @date_time.to_time.utc.to_i, @last.reify.a_datetime.to_time.utc.to_i
460
489
  assert_equal @time.utc.to_i, @last.reify.a_time.utc.to_i
461
490
  assert_equal @date, @last.reify.a_date
@@ -567,9 +596,9 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
567
596
 
568
597
  should 'track who made the change' do
569
598
  assert_equal 'Alice', @version.whodunnit
570
- assert_nil @version.originator
599
+ assert_nil @version.paper_trail_originator
571
600
  assert_equal 'Alice', @version.terminator
572
- assert_equal 'Alice', @widget.originator
601
+ assert_equal 'Alice', @widget.paper_trail_originator
573
602
  end
574
603
 
575
604
  context 'when a record is updated' do
@@ -581,9 +610,9 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
581
610
 
582
611
  should 'track who made the change' do
583
612
  assert_equal 'Bob', @version.whodunnit
584
- assert_equal 'Alice', @version.originator
613
+ assert_equal 'Alice', @version.paper_trail_originator
585
614
  assert_equal 'Bob', @version.terminator
586
- assert_equal 'Bob', @widget.originator
615
+ assert_equal 'Bob', @widget.paper_trail_originator
587
616
  end
588
617
 
589
618
  context 'when a record is destroyed' do
@@ -595,9 +624,9 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
595
624
 
596
625
  should 'track who made the change' do
597
626
  assert_equal 'Charlie', @version.whodunnit
598
- assert_equal 'Bob', @version.originator
627
+ assert_equal 'Bob', @version.paper_trail_originator
599
628
  assert_equal 'Charlie', @version.terminator
600
- assert_equal 'Charlie', @widget.originator
629
+ assert_equal 'Charlie', @widget.paper_trail_originator
601
630
  end
602
631
  end
603
632
  end
@@ -646,7 +675,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
646
675
  should 'should return the correct originator' do
647
676
  PaperTrail.whodunnit = 'Ben'
648
677
  @foo.update_attribute(:name, 'Geoffrey')
649
- assert_equal PaperTrail.whodunnit, @foo.originator
678
+ assert_equal PaperTrail.whodunnit, @foo.paper_trail_originator
650
679
  end
651
680
 
652
681
  context 'when destroyed' do
@@ -731,7 +760,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
731
760
  should 'return versions in the time period' do
732
761
  assert_equal ['Fidget'], @widget.versions_between(20.days.ago, 10.days.ago).map(&:name)
733
762
  assert_equal ['Widget', 'Fidget'], @widget.versions_between(45.days.ago, 10.days.ago).map(&:name)
734
- assert_equal ['Fidget', 'Digit'], @widget.versions_between(16.days.ago, 1.minute.ago).map(&:name)
763
+ assert_equal ['Fidget', 'Digit', 'Digit'], @widget.versions_between(16.days.ago, 1.minute.ago).map(&:name)
735
764
  assert_equal [], @widget.versions_between(60.days.ago, 45.days.ago).map(&:name)
736
765
  end
737
766
  end
@@ -795,8 +824,8 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
795
824
  assert_equal @article.action_data_provider_method, @article.versions.last.action
796
825
  end
797
826
 
798
- should 'store dynamic meta data based on an attribute of the item prior to creation' do
799
- assert_equal nil, @article.versions.last.title
827
+ should 'store dynamic meta data based on an attribute of the item at creation' do
828
+ assert_equal @initial_title, @article.versions.last.title
800
829
  end
801
830
 
802
831
 
@@ -927,7 +956,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
927
956
  count = PaperTrail::Version.count
928
957
  @book.authors.create :name => 'Tolstoy'
929
958
  assert_equal 2, PaperTrail::Version.count - count
930
- assert_same_elements [Person.last, Authorship.last], [PaperTrail::Version.all[-2].item, PaperTrail::Version.last.item]
959
+ assert_same_elements [Person.last, Authorship.last], [PaperTrail::Version.order(:id).to_a[-2].item, PaperTrail::Version.last.item]
931
960
  end
932
961
 
933
962
  should 'store version on join destroy' do
@@ -949,90 +978,10 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
949
978
  end
950
979
  end
951
980
 
952
-
953
- context 'A model with a has_one association' do
954
- setup { @widget = Widget.create :name => 'widget_0' }
955
-
956
- context 'before the associated was created' do
957
- setup do
958
- @widget.update_attributes :name => 'widget_1'
959
- @wotsit = @widget.create_wotsit :name => 'wotsit_0'
960
- end
961
-
962
- context 'when reified' do
963
- setup { @widget_0 = @widget.versions.last.reify(:has_one => 1) }
964
-
965
- should 'see the associated as it was at the time' do
966
- assert_nil @widget_0.wotsit
967
- end
968
- end
969
- end
970
-
971
- context 'where the association is created between model versions' do
972
- setup do
973
- @wotsit = @widget.create_wotsit :name => 'wotsit_0'
974
- make_last_version_earlier @wotsit
975
-
976
- @widget.update_attributes :name => 'widget_1'
977
- end
978
-
979
- context 'when reified' do
980
- setup { @widget_0 = @widget.versions.last.reify(:has_one => 1) }
981
-
982
- should 'see the associated as it was at the time' do
983
- assert_equal 'wotsit_0', @widget_0.wotsit.name
984
- end
985
- end
986
-
987
- context 'and then the associated is updated between model versions' do
988
- setup do
989
- @wotsit.update_attributes :name => 'wotsit_1'
990
- make_last_version_earlier @wotsit
991
- @wotsit.update_attributes :name => 'wotsit_2'
992
- make_last_version_earlier @wotsit
993
-
994
- @widget.update_attributes :name => 'widget_2'
995
- @wotsit.update_attributes :name => 'wotsit_3'
996
- end
997
-
998
- context 'when reified' do
999
- setup { @widget_1 = @widget.versions.last.reify(:has_one => 1) }
1000
-
1001
- should 'see the associated as it was at the time' do
1002
- assert_equal 'wotsit_2', @widget_1.wotsit.name
1003
- end
1004
- end
1005
-
1006
- context 'when reified opting out of has_one reification' do
1007
- setup { @widget_1 = @widget.versions.last.reify(:has_one => false) }
1008
-
1009
- should 'see the associated as it is live' do
1010
- assert_equal 'wotsit_3', @widget_1.wotsit.name
1011
- end
1012
- end
1013
- end
1014
-
1015
- context 'and then the associated is destroyed between model versions' do
1016
- setup do
1017
- @wotsit.destroy
1018
- make_last_version_earlier @wotsit
1019
-
1020
- @widget.update_attributes :name => 'widget_3'
1021
- end
1022
-
1023
- context 'when reified' do
1024
- setup { @widget_2 = @widget.versions.last.reify(:has_one => 1) }
1025
-
1026
- should 'see the associated as it was at the time' do
1027
- assert_nil @widget_2.wotsit
1028
- end
1029
- end
1030
- end
1031
- end
1032
- end
1033
-
1034
981
  context 'When an attribute has a custom serializer' do
1035
- setup { @person = Person.new(:time_zone => "Samoa") }
982
+ setup do
983
+ @person = Person.new(:time_zone => "Samoa")
984
+ end
1036
985
 
1037
986
  should "be an instance of ActiveSupport::TimeZone" do
1038
987
  assert_equal ActiveSupport::TimeZone, @person.time_zone.class
@@ -1052,12 +1001,14 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1052
1001
  should 'version.object_changes attribute should have stored the value returned by the attribute serializer' do
1053
1002
  as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object_changes)]
1054
1003
  assert_equal [nil, 'Samoa'], as_stored_in_version[:time_zone]
1055
- assert_equal @person.instance_variable_get(:@attributes)['time_zone'].serialized_value, as_stored_in_version[:time_zone].last
1004
+ serialized_value = Person::TimeZoneSerializer.dump(@person.time_zone)
1005
+ assert_equal serialized_value, as_stored_in_version[:time_zone].last
1056
1006
  end
1057
1007
 
1058
1008
  # Tests for unserialization:
1059
1009
  should 'version.changeset should convert the attribute value back to its original, unserialized value' do
1060
- assert_equal @person.instance_variable_get(:@attributes)['time_zone'].unserialized_value, @person.versions.last.changeset[:time_zone].last
1010
+ unserialized_value = Person::TimeZoneSerializer.load(@person.time_zone)
1011
+ assert_equal unserialized_value, @person.versions.last.changeset[:time_zone].last
1061
1012
  end
1062
1013
  should "record.changes (before save) returns the original, unserialized values" do
1063
1014
  assert_equal [NilClass, ActiveSupport::TimeZone], @changes_before_save[:time_zone].map(&:class)
@@ -1069,7 +1020,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1069
1020
 
1070
1021
  context 'when that attribute is updated' do
1071
1022
  setup do
1072
- @attribute_value_before_change = @person.instance_variable_get(:@attributes)['time_zone']
1023
+ @attribute_value_before_change = @person.time_zone
1073
1024
  @person.assign_attributes({ :time_zone => 'Pacific Time (US & Canada)' })
1074
1025
  @changes_before_save = @person.changes.dup
1075
1026
  @person.save!
@@ -1078,7 +1029,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1078
1029
  # Tests for serialization:
1079
1030
  # Before the serialized attributes fix, the object/object_changes value that was stored was ridiculously long (58723).
1080
1031
  should 'version.object should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
1081
- assert @person.versions.last.object. length < 105, "object length was #{@person.versions.last.object .length}"
1032
+ assert @person.versions.last.object.length < 105, "object length was #{@person.versions.last.object.length}"
1082
1033
  end
1083
1034
  # Need an additional clause to detect what version of ActiveRecord is being used for this test because AR4 injects the `updated_at` column into the changeset for updates to models
1084
1035
  should 'version.object_changes should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
@@ -1088,20 +1039,24 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1088
1039
  should 'version.object attribute should have stored the value returned by the attribute serializer' do
1089
1040
  as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object)]
1090
1041
  assert_equal 'Samoa', as_stored_in_version[:time_zone]
1091
- assert_equal @attribute_value_before_change.serialized_value, as_stored_in_version[:time_zone]
1042
+ serialized_value = Person::TimeZoneSerializer.dump(@attribute_value_before_change)
1043
+ assert_equal serialized_value, as_stored_in_version[:time_zone]
1092
1044
  end
1093
1045
  should 'version.object_changes attribute should have stored the value returned by the attribute serializer' do
1094
1046
  as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object_changes)]
1095
1047
  assert_equal ['Samoa', 'Pacific Time (US & Canada)'], as_stored_in_version[:time_zone]
1096
- assert_equal @person.instance_variable_get(:@attributes)['time_zone'].serialized_value, as_stored_in_version[:time_zone].last
1048
+ serialized_value = Person::TimeZoneSerializer.dump(@person.time_zone)
1049
+ assert_equal serialized_value, as_stored_in_version[:time_zone].last
1097
1050
  end
1098
1051
 
1099
1052
  # Tests for unserialization:
1100
1053
  should 'version.reify should convert the attribute value back to its original, unserialized value' do
1101
- assert_equal @attribute_value_before_change.unserialized_value, @person.versions.last.reify.time_zone
1054
+ unserialized_value = Person::TimeZoneSerializer.load(@attribute_value_before_change)
1055
+ assert_equal unserialized_value, @person.versions.last.reify.time_zone
1102
1056
  end
1103
1057
  should 'version.changeset should convert the attribute value back to its original, unserialized value' do
1104
- assert_equal @person.instance_variable_get(:@attributes)['time_zone'].unserialized_value, @person.versions.last.changeset[:time_zone].last
1058
+ unserialized_value = Person::TimeZoneSerializer.load(@person.time_zone)
1059
+ assert_equal unserialized_value, @person.versions.last.changeset[:time_zone].last
1105
1060
  end
1106
1061
  should "record.changes (before save) returns the original, unserialized values" do
1107
1062
  assert_equal [ActiveSupport::TimeZone, ActiveSupport::TimeZone], @changes_before_save[:time_zone].map(&:class)
@@ -1165,6 +1120,21 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1165
1120
  should 'return "overwritten" value on reified instance' do
1166
1121
  assert_equal 4, @song.versions.last.reify.length
1167
1122
  end
1123
+
1124
+ context 'Has a virtual attribute injected into the ActiveModel::Dirty changes' do
1125
+ setup do
1126
+ @song.name = 'Good Vibrations'
1127
+ @song.save
1128
+ @song.name = 'Yellow Submarine'
1129
+ end
1130
+
1131
+ should 'return persist the changes on the live instance properly' do
1132
+ assert_equal 'Yellow Submarine', @song.name
1133
+ end
1134
+ should 'return "overwritten" virtual attribute on the reified instance' do
1135
+ assert_equal 'Good Vibrations', @song.versions.last.reify.name
1136
+ end
1137
+ end
1168
1138
  end
1169
1139
 
1170
1140
 
@@ -1252,6 +1222,31 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1252
1222
  assert_equal 'destroy', @fluxor.versions.last.event
1253
1223
  end
1254
1224
  end
1225
+ context 'on []' do
1226
+ setup do
1227
+ Fluxor.reset_callbacks :create
1228
+ Fluxor.reset_callbacks :update
1229
+ Fluxor.reset_callbacks :destroy
1230
+ Fluxor.instance_eval <<-END
1231
+ has_paper_trail :on => []
1232
+ END
1233
+ @fluxor = Fluxor.create
1234
+ @fluxor.update_attributes :name => 'blah'
1235
+ end
1236
+
1237
+ teardown do
1238
+ @fluxor.destroy
1239
+ end
1240
+
1241
+ should 'not have any versions' do
1242
+ assert_equal 0, @fluxor.versions.length
1243
+ end
1244
+
1245
+ should 'still respond to touch_with_version' do
1246
+ @fluxor.touch_with_version
1247
+ assert_equal 1, @fluxor.versions.length
1248
+ end
1249
+ end
1255
1250
  context 'allows a symbol to be passed' do
1256
1251
  setup do
1257
1252
  Fluxor.reset_callbacks :create
@@ -1375,15 +1370,4 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1375
1370
  assert_equal 3, @widget.versions.size
1376
1371
  end
1377
1372
  end
1378
-
1379
- private
1380
-
1381
- # Updates `model`'s last version so it looks like the version was
1382
- # created 2 seconds ago.
1383
- def make_last_version_earlier(model)
1384
- PaperTrail::Version.record_timestamps = false
1385
- model.versions.last.update_attributes :created_at => 2.seconds.ago
1386
- PaperTrail::Version.record_timestamps = true
1387
- end
1388
-
1389
1373
  end
@@ -35,9 +35,10 @@ class ProtectedAttrsTest < ActiveSupport::TestCase
35
35
  end
36
36
 
37
37
  should 'the previous version should contain right attributes' do
38
- # For some reason this test seems to be broken in JRuby 1.9 mode in the test env even though it works in the console. WTF?
39
- unless ActiveRecord::VERSION::MAJOR >= 4 && defined?(JRUBY_VERSION) && RUBY_VERSION.to_f >= 1.9
40
- assert_equal @widget.previous_version.attributes, @initial_attributes
38
+ # For some reason this test seems to be broken in JRuby 1.9 mode in the
39
+ # test env even though it works in the console. WTF?
40
+ unless ActiveRecord::VERSION::MAJOR >= 4 && defined?(JRUBY_VERSION) && RUBY_VERSION >= '1.9'
41
+ assert_attributes_equal @widget.previous_version.attributes, @initial_attributes
41
42
  end
42
43
  end
43
44
  end