paper_trail_without_deprecated 3.0.0.beta1

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 (105) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +21 -0
  5. data/CHANGELOG.md +68 -0
  6. data/Gemfile +2 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +979 -0
  9. data/Rakefile +18 -0
  10. data/gemfiles/3.0.gemfile +31 -0
  11. data/lib/generators/paper_trail/USAGE +2 -0
  12. data/lib/generators/paper_trail/install_generator.rb +23 -0
  13. data/lib/generators/paper_trail/templates/add_object_changes_column_to_versions.rb +9 -0
  14. data/lib/generators/paper_trail/templates/create_versions.rb +18 -0
  15. data/lib/paper_trail.rb +115 -0
  16. data/lib/paper_trail/cleaner.rb +34 -0
  17. data/lib/paper_trail/config.rb +14 -0
  18. data/lib/paper_trail/frameworks/cucumber.rb +31 -0
  19. data/lib/paper_trail/frameworks/rails.rb +79 -0
  20. data/lib/paper_trail/frameworks/rspec.rb +24 -0
  21. data/lib/paper_trail/frameworks/rspec/extensions.rb +20 -0
  22. data/lib/paper_trail/frameworks/sinatra.rb +31 -0
  23. data/lib/paper_trail/has_paper_trail.rb +308 -0
  24. data/lib/paper_trail/serializers/json.rb +17 -0
  25. data/lib/paper_trail/serializers/yaml.rb +17 -0
  26. data/lib/paper_trail/version.rb +200 -0
  27. data/lib/paper_trail/version_number.rb +3 -0
  28. data/paper_trail.gemspec +36 -0
  29. data/spec/models/widget_spec.rb +13 -0
  30. data/spec/paper_trail_spec.rb +47 -0
  31. data/spec/spec_helper.rb +41 -0
  32. data/test/custom_json_serializer.rb +13 -0
  33. data/test/dummy/Rakefile +7 -0
  34. data/test/dummy/app/controllers/application_controller.rb +17 -0
  35. data/test/dummy/app/controllers/test_controller.rb +5 -0
  36. data/test/dummy/app/controllers/widgets_controller.rb +31 -0
  37. data/test/dummy/app/helpers/application_helper.rb +2 -0
  38. data/test/dummy/app/models/animal.rb +4 -0
  39. data/test/dummy/app/models/article.rb +16 -0
  40. data/test/dummy/app/models/authorship.rb +5 -0
  41. data/test/dummy/app/models/book.rb +5 -0
  42. data/test/dummy/app/models/cat.rb +2 -0
  43. data/test/dummy/app/models/document.rb +4 -0
  44. data/test/dummy/app/models/dog.rb +2 -0
  45. data/test/dummy/app/models/elephant.rb +3 -0
  46. data/test/dummy/app/models/fluxor.rb +3 -0
  47. data/test/dummy/app/models/foo_widget.rb +2 -0
  48. data/test/dummy/app/models/legacy_widget.rb +4 -0
  49. data/test/dummy/app/models/person.rb +28 -0
  50. data/test/dummy/app/models/post.rb +4 -0
  51. data/test/dummy/app/models/protected_widget.rb +3 -0
  52. data/test/dummy/app/models/song.rb +12 -0
  53. data/test/dummy/app/models/translation.rb +4 -0
  54. data/test/dummy/app/models/widget.rb +10 -0
  55. data/test/dummy/app/models/wotsit.rb +4 -0
  56. data/test/dummy/app/versions/post_version.rb +3 -0
  57. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  58. data/test/dummy/config.ru +4 -0
  59. data/test/dummy/config/application.rb +63 -0
  60. data/test/dummy/config/boot.rb +10 -0
  61. data/test/dummy/config/database.yml +22 -0
  62. data/test/dummy/config/environment.rb +5 -0
  63. data/test/dummy/config/environments/development.rb +40 -0
  64. data/test/dummy/config/environments/production.rb +73 -0
  65. data/test/dummy/config/environments/test.rb +37 -0
  66. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  67. data/test/dummy/config/initializers/inflections.rb +10 -0
  68. data/test/dummy/config/initializers/mime_types.rb +5 -0
  69. data/test/dummy/config/initializers/paper_trail.rb +5 -0
  70. data/test/dummy/config/initializers/secret_token.rb +7 -0
  71. data/test/dummy/config/initializers/session_store.rb +8 -0
  72. data/test/dummy/config/locales/en.yml +5 -0
  73. data/test/dummy/config/routes.rb +3 -0
  74. data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +136 -0
  75. data/test/dummy/db/schema.rb +101 -0
  76. data/test/dummy/public/404.html +26 -0
  77. data/test/dummy/public/422.html +26 -0
  78. data/test/dummy/public/500.html +26 -0
  79. data/test/dummy/public/favicon.ico +0 -0
  80. data/test/dummy/public/javascripts/application.js +2 -0
  81. data/test/dummy/public/javascripts/controls.js +965 -0
  82. data/test/dummy/public/javascripts/dragdrop.js +974 -0
  83. data/test/dummy/public/javascripts/effects.js +1123 -0
  84. data/test/dummy/public/javascripts/prototype.js +6001 -0
  85. data/test/dummy/public/javascripts/rails.js +175 -0
  86. data/test/dummy/public/stylesheets/.gitkeep +0 -0
  87. data/test/dummy/script/rails +6 -0
  88. data/test/functional/controller_test.rb +90 -0
  89. data/test/functional/modular_sinatra_test.rb +44 -0
  90. data/test/functional/sinatra_test.rb +45 -0
  91. data/test/functional/thread_safety_test.rb +26 -0
  92. data/test/paper_trail_test.rb +27 -0
  93. data/test/test_helper.rb +40 -0
  94. data/test/unit/cleaner_test.rb +143 -0
  95. data/test/unit/inheritance_column_test.rb +43 -0
  96. data/test/unit/model_test.rb +1314 -0
  97. data/test/unit/protected_attrs_test.rb +46 -0
  98. data/test/unit/serializer_test.rb +117 -0
  99. data/test/unit/serializers/json_test.rb +40 -0
  100. data/test/unit/serializers/mixin_json_test.rb +36 -0
  101. data/test/unit/serializers/mixin_yaml_test.rb +49 -0
  102. data/test/unit/serializers/yaml_test.rb +40 -0
  103. data/test/unit/timestamp_test.rb +44 -0
  104. data/test/unit/version_test.rb +74 -0
  105. metadata +286 -0
@@ -0,0 +1,46 @@
1
+ require 'test_helper'
2
+
3
+ class ProtectedAttrsTest < ActiveSupport::TestCase
4
+ subject { ProtectedWidget.new }
5
+
6
+ if ActiveRecord::VERSION::STRING.to_f < 4.0 # these ActiveModel matchers (provided by shoulda-matchers) only work for Rails 3
7
+ accessible_attrs = ProtectedWidget.accessible_attributes.to_a
8
+ accessible_attrs.each do |attr_name|
9
+ should allow_mass_assignment_of(attr_name.to_sym)
10
+ end
11
+ ProtectedWidget.column_names.reject { |column_name| accessible_attrs.include?(column_name) }.each do |attr_name|
12
+ should_not allow_mass_assignment_of(attr_name.to_sym)
13
+ end
14
+ end
15
+
16
+ context 'A model with `attr_accessible` created' do
17
+ setup do
18
+ @widget = ProtectedWidget.create! :name => 'Henry'
19
+ @initial_attributes = @widget.attributes
20
+ end
21
+
22
+ should 'be `nil` in its previous version' do
23
+ assert_nil @widget.previous_version
24
+ end
25
+
26
+ context 'which is then updated' do
27
+ setup do
28
+ @widget.assign_attributes(:name => 'Jeff', :a_text => 'Short statement')
29
+ @widget.an_integer = 42
30
+ @widget.save!
31
+ end
32
+
33
+ should 'not be `nil` in its previous version' do
34
+ assert_not_nil @widget.previous_version
35
+ end
36
+
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::STRING.to_f >= 4.0 && defined?(JRUBY_VERSION) && RUBY_VERSION.to_f >= 1.9
40
+ assert_equal @widget.previous_version.attributes, @initial_attributes
41
+ end
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,117 @@
1
+ require 'test_helper'
2
+ require 'custom_json_serializer'
3
+
4
+ class SerializerTest < ActiveSupport::TestCase
5
+
6
+ context 'YAML Serializer' do
7
+ setup do
8
+ Fluxor.instance_eval <<-END
9
+ has_paper_trail
10
+ END
11
+
12
+ @fluxor = Fluxor.create :name => 'Some text.'
13
+ @original_fluxor_attributes = @fluxor.send(:item_before_change).attributes # this is exactly what PaperTrail serializes
14
+ @fluxor.update_attributes :name => 'Some more text.'
15
+ end
16
+
17
+ should 'work with the default yaml serializer' do
18
+ # Normal behaviour
19
+ assert_equal 2, @fluxor.versions.length
20
+ assert_nil @fluxor.versions[0].reify
21
+ assert_equal 'Some text.', @fluxor.versions[1].reify.name
22
+
23
+ # Check values are stored as YAML.
24
+ assert_equal @original_fluxor_attributes, YAML.load(@fluxor.versions[1].object)
25
+ # This test can't consistently pass in Ruby1.8 because hashes do no preserve order, which means the order of the
26
+ # attributes in the YAML can't be ensured.
27
+ if RUBY_VERSION.to_f >= 1.9
28
+ assert_equal YAML.dump(@original_fluxor_attributes), @fluxor.versions[1].object
29
+ end
30
+ end
31
+ end
32
+
33
+ context 'JSON Serializer' do
34
+ setup do
35
+ PaperTrail.configure do |config|
36
+ config.serializer = PaperTrail::Serializers::Json
37
+ end
38
+
39
+ Fluxor.instance_eval <<-END
40
+ has_paper_trail
41
+ END
42
+
43
+ @fluxor = Fluxor.create :name => 'Some text.'
44
+ @original_fluxor_attributes = @fluxor.send(:item_before_change).attributes # this is exactly what PaperTrail serializes
45
+ @fluxor.update_attributes :name => 'Some more text.'
46
+ end
47
+
48
+ teardown do
49
+ PaperTrail.config.serializer = PaperTrail::Serializers::Yaml
50
+ end
51
+
52
+ should 'reify with JSON serializer' do
53
+ # Normal behaviour
54
+ assert_equal 2, @fluxor.versions.length
55
+ assert_nil @fluxor.versions[0].reify
56
+ assert_equal 'Some text.', @fluxor.versions[1].reify.name
57
+
58
+ # Check values are stored as JSON.
59
+ assert_equal @original_fluxor_attributes, ActiveSupport::JSON.decode(@fluxor.versions[1].object)
60
+ # This test can't consistently pass in Ruby1.8 because hashes do no preserve order, which means the order of the
61
+ # attributes in the JSON can't be ensured.
62
+ if RUBY_VERSION.to_f >= 1.9
63
+ assert_equal ActiveSupport::JSON.encode(@original_fluxor_attributes), @fluxor.versions[1].object
64
+ end
65
+ end
66
+
67
+ should 'store object_changes' do
68
+ initial_changeset = {"name" => [nil, "Some text."], "id" => [nil, 1]}
69
+ second_changeset = {"name"=>["Some text.", "Some more text."]}
70
+ assert_equal initial_changeset, @fluxor.versions[0].changeset
71
+ assert_equal second_changeset, @fluxor.versions[1].changeset
72
+ end
73
+ end
74
+
75
+ context 'Custom Serializer' do
76
+ setup do
77
+ PaperTrail.configure do |config|
78
+ config.serializer = CustomJsonSerializer
79
+ end
80
+
81
+ Fluxor.instance_eval <<-END
82
+ has_paper_trail
83
+ END
84
+
85
+ @fluxor = Fluxor.create
86
+ @original_fluxor_attributes = @fluxor.send(:item_before_change).attributes.reject { |k,v| v.nil? } # this is exactly what PaperTrail serializes
87
+ @fluxor.update_attributes :name => 'Some more text.'
88
+ end
89
+
90
+ teardown do
91
+ PaperTrail.config.serializer = PaperTrail::Serializers::Yaml
92
+ end
93
+
94
+ should 'reify with custom serializer' do
95
+ # Normal behaviour
96
+ assert_equal 2, @fluxor.versions.length
97
+ assert_nil @fluxor.versions[0].reify
98
+ assert_nil @fluxor.versions[1].reify.name
99
+
100
+ # Check values are stored as JSON.
101
+ assert_equal @original_fluxor_attributes, ActiveSupport::JSON.decode(@fluxor.versions[1].object)
102
+ # This test can't consistently pass in Ruby1.8 because hashes do no preserve order, which means the order of the
103
+ # attributes in the JSON can't be ensured.
104
+ if RUBY_VERSION.to_f >= 1.9
105
+ assert_equal ActiveSupport::JSON.encode(@original_fluxor_attributes), @fluxor.versions[1].object
106
+ end
107
+ end
108
+
109
+ should 'store object_changes' do
110
+ initial_changeset = {"id" => [nil, 1]}
111
+ second_changeset = {"name"=>[nil, "Some more text."]}
112
+ assert_equal initial_changeset, @fluxor.versions[0].changeset
113
+ assert_equal second_changeset, @fluxor.versions[1].changeset
114
+ end
115
+ end
116
+
117
+ end
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ class JsonTest < ActiveSupport::TestCase
4
+
5
+ setup do
6
+ # Setup a hash with random values
7
+ @hash = {}
8
+ (1..4).each do |i|
9
+ @hash["key#{i}"] = Faker::Lorem.word
10
+ end
11
+ @hash_as_json = @hash.to_json
12
+ # Setup an array of random words
13
+ @array = []
14
+ (rand(5) + 4).times { @array << Faker::Lorem.word }
15
+ @array_as_json = @array.to_json
16
+ end
17
+
18
+ context '`load` class method' do
19
+ should 'exist' do
20
+ assert PaperTrail::Serializers::Json.respond_to?(:load)
21
+ end
22
+
23
+ should '`deserialize` JSON to Ruby' do
24
+ assert_equal @hash, PaperTrail::Serializers::Json.load(@hash_as_json)
25
+ assert_equal @array, PaperTrail::Serializers::Json.load(@array_as_json)
26
+ end
27
+ end
28
+
29
+ context '`dump` class method' do
30
+ should 'exist' do
31
+ assert PaperTrail::Serializers::Json.respond_to?(:dump)
32
+ end
33
+
34
+ should '`serialize` Ruby to JSON' do
35
+ assert_equal @hash_as_json, PaperTrail::Serializers::Json.dump(@hash)
36
+ assert_equal @array_as_json, PaperTrail::Serializers::Json.dump(@array)
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+ require 'custom_json_serializer'
3
+
4
+ class MixinJsonTest < ActiveSupport::TestCase
5
+
6
+ setup do
7
+ # Setup a hash with random values, ensuring some values are nil
8
+ @hash = {}
9
+ (1..4).each do |i|
10
+ @hash["key#{i}"] = [Faker::Lorem.word, nil].sample
11
+ end
12
+ @hash['tkey'] = nil
13
+ @hash[''] = 'foo'
14
+ @hash_as_json = @hash.to_json
15
+ end
16
+
17
+ context '`load` class method' do
18
+ should 'exist' do
19
+ assert CustomJsonSerializer.respond_to?(:load)
20
+ end
21
+
22
+ should '`deserialize` JSON to Ruby, removing pairs with `blank` keys or values' do
23
+ assert_equal @hash.reject { |k,v| k.blank? || v.blank? }, CustomJsonSerializer.load(@hash_as_json)
24
+ end
25
+ end
26
+
27
+ context '`dump` class method' do
28
+ should 'exist' do
29
+ assert CustomJsonSerializer.respond_to?(:dump)
30
+ end
31
+
32
+ should '`serialize` Ruby to JSON, removing pairs with `nil` values' do
33
+ assert_equal @hash.reject { |k,v| v.nil? }.to_json, CustomJsonSerializer.dump(@hash)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+
3
+ module CustomYamlSerializer
4
+ extend PaperTrail::Serializers::Yaml
5
+
6
+ def self.load(string)
7
+ parsed_value = super(string)
8
+ parsed_value.is_a?(Hash) ? parsed_value.reject { |k,v| k.blank? || v.blank? } : parsed_value
9
+ end
10
+
11
+ def self.dump(object)
12
+ object.is_a?(Hash) ? super(object.reject { |k,v| v.nil? }) : super
13
+ end
14
+ end
15
+
16
+ class MixinYamlTest < ActiveSupport::TestCase
17
+
18
+ setup do
19
+ # Setup a hash with random values, ensuring some values are nil
20
+ @hash = {}
21
+ (1..4).each do |i|
22
+ @hash["key#{i}"] = [Faker::Lorem.word, nil].sample
23
+ end
24
+ @hash['tkey'] = nil
25
+ @hash[''] = 'foo'
26
+ @hash_as_yaml = @hash.to_yaml
27
+ end
28
+
29
+ context '`load` class method' do
30
+ should 'exist' do
31
+ assert CustomYamlSerializer.respond_to?(:load)
32
+ end
33
+
34
+ should '`deserialize` YAML to Ruby, removing pairs with `blank` keys or values' do
35
+ assert_equal @hash.reject { |k,v| k.blank? || v.blank? }, CustomYamlSerializer.load(@hash_as_yaml)
36
+ end
37
+ end
38
+
39
+ context '`dump` class method' do
40
+ should 'exist' do
41
+ assert CustomYamlSerializer.respond_to?(:dump)
42
+ end
43
+
44
+ should '`serialize` Ruby to YAML, removing pairs with `nil` values' do
45
+ assert_equal @hash.reject { |k,v| v.nil? }.to_yaml, CustomYamlSerializer.dump(@hash)
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ class YamlTest < ActiveSupport::TestCase
4
+
5
+ setup do
6
+ # Setup a hash with random values
7
+ @hash = {}
8
+ (1..4).each do |i|
9
+ @hash["key#{i}".to_sym] = Faker::Lorem.word
10
+ end
11
+ @hash_as_yaml = @hash.to_yaml
12
+ # Setup an array of random words
13
+ @array = []
14
+ (rand(5) + 4).times { @array << Faker::Lorem.word }
15
+ @array_as_yaml = @array.to_yaml
16
+ end
17
+
18
+ context '`load` class method' do
19
+ should 'exist' do
20
+ assert PaperTrail::Serializers::Yaml.respond_to?(:load)
21
+ end
22
+
23
+ should '`deserialize` YAML to Ruby' do
24
+ assert_equal @hash, PaperTrail::Serializers::Yaml.load(@hash_as_yaml)
25
+ assert_equal @array, PaperTrail::Serializers::Yaml.load(@array_as_yaml)
26
+ end
27
+ end
28
+
29
+ context '`dump` class method' do
30
+ should 'exist' do
31
+ assert PaperTrail::Serializers::Yaml.respond_to?(:dump)
32
+ end
33
+
34
+ should '`serialize` Ruby to YAML' do
35
+ assert_equal @hash_as_yaml, PaperTrail::Serializers::Yaml.dump(@hash)
36
+ assert_equal @array_as_yaml, PaperTrail::Serializers::Yaml.dump(@array)
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,44 @@
1
+ require 'test_helper'
2
+
3
+ class TimestampTest < ActiveSupport::TestCase
4
+
5
+ setup do
6
+ PaperTrail.timestamp_field = :custom_created_at
7
+ change_schema
8
+ PaperTrail::Version.connection.schema_cache.clear!
9
+ PaperTrail::Version.reset_column_information
10
+
11
+ Fluxor.instance_eval <<-END
12
+ has_paper_trail
13
+ END
14
+
15
+ @fluxor = Fluxor.create :name => 'Some text.'
16
+ @fluxor.update_attributes :name => 'Some more text.'
17
+ @fluxor.update_attributes :name => 'Even more text.'
18
+ end
19
+
20
+ teardown do
21
+ PaperTrail.timestamp_field = :created_at
22
+ end
23
+
24
+ test 'versions works with custom timestamp field' do
25
+ # Normal behaviour
26
+ assert_equal 3, @fluxor.versions.length
27
+ assert_nil @fluxor.versions[0].reify
28
+ assert_equal 'Some text.', @fluxor.versions[1].reify.name
29
+ assert_equal 'Some more text.', @fluxor.versions[2].reify.name
30
+
31
+ # Tinker with custom timestamps.
32
+ now = Time.now.utc
33
+ @fluxor.versions.reverse.each_with_index do |version, index|
34
+ version.update_attribute :custom_created_at, (now + index.seconds)
35
+ end
36
+
37
+ # Test we are ordering by custom timestamps.
38
+ @fluxor.versions true # reload association
39
+ assert_nil @fluxor.versions[2].reify
40
+ assert_equal 'Some text.', @fluxor.versions[1].reify.name
41
+ assert_equal 'Some more text.', @fluxor.versions[0].reify.name
42
+ end
43
+
44
+ end
@@ -0,0 +1,74 @@
1
+ require 'test_helper'
2
+
3
+ class PaperTrail::VersionTest < ActiveSupport::TestCase
4
+ setup do
5
+ change_schema
6
+ @animal = Animal.create
7
+ assert PaperTrail::Version.creates.present?
8
+ end
9
+
10
+ context "PaperTrail::Version.creates" do
11
+ should "return only create events" do
12
+ PaperTrail::Version.creates.each do |version|
13
+ assert_equal "create", version.event
14
+ end
15
+ end
16
+ end
17
+
18
+ context "PaperTrail::Version.updates" do
19
+ setup {
20
+ @animal.update_attributes(:name => 'Animal')
21
+ assert PaperTrail::Version.updates.present?
22
+ }
23
+
24
+ should "return only update events" do
25
+ PaperTrail::Version.updates.each do |version|
26
+ assert_equal "update", version.event
27
+ end
28
+ end
29
+ end
30
+
31
+ context "PaperTrail::Version.destroys" do
32
+ setup {
33
+ @animal.destroy
34
+ assert PaperTrail::Version.destroys.present?
35
+ }
36
+
37
+ should "return only destroy events" do
38
+ PaperTrail::Version.destroys.each do |version|
39
+ assert_equal "destroy", version.event
40
+ end
41
+ end
42
+ end
43
+
44
+ context "PaperTrail::Version.not_creates" do
45
+ setup {
46
+ @animal.update_attributes(:name => 'Animal')
47
+ @animal.destroy
48
+ assert PaperTrail::Version.not_creates.present?
49
+ }
50
+
51
+ should "return all items except create events" do
52
+ PaperTrail::Version.not_creates.each do |version|
53
+ assert_not_equal "create", version.event
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ class VersionTest < ActiveSupport::TestCase
60
+ # without this, it sometimes picks up the changed schema from the previous test and gets confused
61
+ setup { PaperTrail::Version.reset_column_information }
62
+
63
+ context "Version class" do
64
+ should "be a subclass of the `PaperTrail::Version` class" do
65
+ assert Version < PaperTrail::Version
66
+ end
67
+
68
+ should "act like a `PaperTrail::Version` while warning the user" do
69
+ widget = Widget.create! :name => Faker::Name.name
70
+ widget.update_attributes! :name => Faker::Name.name
71
+ assert_equal Version.last.reify.name, widget.versions.last.reify.name
72
+ end
73
+ end
74
+ end