paper_trail 4.0.0 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CONTRIBUTING.md +105 -0
  3. data/.github/ISSUE_TEMPLATE.md +13 -0
  4. data/.gitignore +2 -0
  5. data/.rubocop.yml +100 -0
  6. data/.rubocop_todo.yml +14 -0
  7. data/.travis.yml +11 -10
  8. data/Appraisals +37 -0
  9. data/CHANGELOG.md +173 -8
  10. data/Gemfile +1 -1
  11. data/README.md +641 -470
  12. data/Rakefile +19 -19
  13. data/doc/bug_report_template.rb +71 -0
  14. data/doc/warning_about_not_setting_whodunnit.md +32 -0
  15. data/gemfiles/ar3.gemfile +18 -0
  16. data/gemfiles/ar4.gemfile +7 -0
  17. data/gemfiles/ar5.gemfile +13 -0
  18. data/lib/generators/paper_trail/install_generator.rb +26 -18
  19. data/lib/generators/paper_trail/templates/add_object_changes_to_versions.rb +3 -1
  20. data/lib/generators/paper_trail/templates/add_transaction_id_column_to_versions.rb +2 -0
  21. data/lib/generators/paper_trail/templates/create_version_associations.rb +9 -4
  22. data/lib/generators/paper_trail/templates/create_versions.rb +53 -5
  23. data/lib/paper_trail/attribute_serializers/README.md +10 -0
  24. data/lib/paper_trail/attribute_serializers/cast_attribute_serializer.rb +58 -0
  25. data/lib/paper_trail/attribute_serializers/legacy_active_record_shim.rb +48 -0
  26. data/lib/paper_trail/attribute_serializers/object_attribute.rb +39 -0
  27. data/lib/paper_trail/attribute_serializers/object_changes_attribute.rb +42 -0
  28. data/lib/paper_trail/cleaner.rb +41 -18
  29. data/lib/paper_trail/config.rb +42 -26
  30. data/lib/paper_trail/frameworks/active_record/models/paper_trail/version.rb +5 -1
  31. data/lib/paper_trail/frameworks/active_record/models/paper_trail/version_association.rb +6 -2
  32. data/lib/paper_trail/frameworks/active_record.rb +2 -2
  33. data/lib/paper_trail/frameworks/cucumber.rb +1 -0
  34. data/lib/paper_trail/frameworks/rails/controller.rb +50 -14
  35. data/lib/paper_trail/frameworks/rails/engine.rb +6 -1
  36. data/lib/paper_trail/frameworks/rails.rb +2 -7
  37. data/lib/paper_trail/frameworks/rspec/helpers.rb +3 -1
  38. data/lib/paper_trail/frameworks/rspec.rb +5 -5
  39. data/lib/paper_trail/frameworks/sinatra.rb +8 -5
  40. data/lib/paper_trail/has_paper_trail.rb +381 -221
  41. data/lib/paper_trail/record_history.rb +57 -0
  42. data/lib/paper_trail/reifier.rb +450 -0
  43. data/lib/paper_trail/serializers/json.rb +7 -7
  44. data/lib/paper_trail/serializers/yaml.rb +31 -12
  45. data/lib/paper_trail/version_association_concern.rb +6 -2
  46. data/lib/paper_trail/version_concern.rb +200 -287
  47. data/lib/paper_trail/version_number.rb +6 -9
  48. data/lib/paper_trail.rb +169 -137
  49. data/paper_trail.gemspec +41 -43
  50. data/spec/generators/install_generator_spec.rb +24 -25
  51. data/spec/generators/paper_trail/templates/create_versions_spec.rb +51 -0
  52. data/spec/models/animal_spec.rb +23 -6
  53. data/spec/models/boolit_spec.rb +8 -8
  54. data/spec/models/callback_modifier_spec.rb +96 -0
  55. data/spec/models/car_spec.rb +13 -0
  56. data/spec/models/fluxor_spec.rb +3 -3
  57. data/spec/models/gadget_spec.rb +19 -19
  58. data/spec/models/joined_version_spec.rb +3 -3
  59. data/spec/models/json_version_spec.rb +50 -28
  60. data/spec/models/kitchen/banana_spec.rb +3 -3
  61. data/spec/models/not_on_update_spec.rb +7 -4
  62. data/spec/models/post_with_status_spec.rb +13 -3
  63. data/spec/models/skipper_spec.rb +40 -11
  64. data/spec/models/thing_spec.rb +4 -4
  65. data/spec/models/truck_spec.rb +5 -0
  66. data/spec/models/vehicle_spec.rb +5 -0
  67. data/spec/models/version_spec.rb +103 -59
  68. data/spec/models/widget_spec.rb +86 -55
  69. data/spec/modules/paper_trail_spec.rb +2 -2
  70. data/spec/modules/version_concern_spec.rb +11 -12
  71. data/spec/modules/version_number_spec.rb +3 -4
  72. data/spec/paper_trail/config_spec.rb +33 -0
  73. data/spec/paper_trail_spec.rb +16 -14
  74. data/spec/rails_helper.rb +10 -9
  75. data/spec/requests/articles_spec.rb +11 -7
  76. data/spec/spec_helper.rb +42 -17
  77. data/spec/support/alt_db_init.rb +8 -13
  78. data/test/custom_json_serializer.rb +3 -3
  79. data/test/dummy/Rakefile +2 -2
  80. data/test/dummy/app/controllers/application_controller.rb +21 -8
  81. data/test/dummy/app/controllers/articles_controller.rb +11 -8
  82. data/test/dummy/app/controllers/widgets_controller.rb +13 -12
  83. data/test/dummy/app/models/animal.rb +1 -1
  84. data/test/dummy/app/models/article.rb +19 -11
  85. data/test/dummy/app/models/authorship.rb +1 -1
  86. data/test/dummy/app/models/bar_habtm.rb +4 -0
  87. data/test/dummy/app/models/book.rb +4 -4
  88. data/test/dummy/app/models/boolit.rb +1 -1
  89. data/test/dummy/app/models/callback_modifier.rb +45 -0
  90. data/test/dummy/app/models/car.rb +3 -0
  91. data/test/dummy/app/models/chapter.rb +9 -0
  92. data/test/dummy/app/models/citation.rb +5 -0
  93. data/test/dummy/app/models/customer.rb +1 -1
  94. data/test/dummy/app/models/document.rb +2 -2
  95. data/test/dummy/app/models/editor.rb +1 -1
  96. data/test/dummy/app/models/foo_habtm.rb +5 -0
  97. data/test/dummy/app/models/fruit.rb +2 -2
  98. data/test/dummy/app/models/gadget.rb +1 -1
  99. data/test/dummy/app/models/kitchen/banana.rb +1 -1
  100. data/test/dummy/app/models/legacy_widget.rb +2 -2
  101. data/test/dummy/app/models/line_item.rb +1 -1
  102. data/test/dummy/app/models/not_on_update.rb +1 -1
  103. data/test/dummy/app/models/paragraph.rb +5 -0
  104. data/test/dummy/app/models/person.rb +6 -6
  105. data/test/dummy/app/models/post.rb +1 -1
  106. data/test/dummy/app/models/post_with_status.rb +1 -1
  107. data/test/dummy/app/models/quotation.rb +5 -0
  108. data/test/dummy/app/models/section.rb +6 -0
  109. data/test/dummy/app/models/skipper.rb +2 -2
  110. data/test/dummy/app/models/song.rb +13 -4
  111. data/test/dummy/app/models/thing.rb +2 -2
  112. data/test/dummy/app/models/translation.rb +2 -2
  113. data/test/dummy/app/models/truck.rb +4 -0
  114. data/test/dummy/app/models/vehicle.rb +4 -0
  115. data/test/dummy/app/models/whatchamajigger.rb +1 -1
  116. data/test/dummy/app/models/widget.rb +7 -6
  117. data/test/dummy/app/versions/joined_version.rb +4 -3
  118. data/test/dummy/app/versions/json_version.rb +1 -1
  119. data/test/dummy/app/versions/kitchen/banana_version.rb +1 -1
  120. data/test/dummy/app/versions/post_version.rb +2 -2
  121. data/test/dummy/config/application.rb +20 -9
  122. data/test/dummy/config/boot.rb +5 -5
  123. data/test/dummy/config/database.postgres.yml +1 -1
  124. data/test/dummy/config/environment.rb +1 -1
  125. data/test/dummy/config/environments/development.rb +4 -3
  126. data/test/dummy/config/environments/production.rb +3 -2
  127. data/test/dummy/config/environments/test.rb +15 -5
  128. data/test/dummy/config/initializers/backtrace_silencers.rb +4 -2
  129. data/test/dummy/config/initializers/paper_trail.rb +4 -3
  130. data/test/dummy/config/initializers/secret_token.rb +3 -1
  131. data/test/dummy/config/initializers/session_store.rb +1 -1
  132. data/test/dummy/config/routes.rb +2 -2
  133. data/test/dummy/config.ru +1 -1
  134. data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +148 -68
  135. data/test/dummy/db/schema.rb +119 -31
  136. data/test/dummy/script/rails +6 -4
  137. data/test/functional/controller_test.rb +34 -35
  138. data/test/functional/enabled_for_controller_test.rb +6 -7
  139. data/test/functional/modular_sinatra_test.rb +43 -38
  140. data/test/functional/sinatra_test.rb +49 -40
  141. data/test/functional/thread_safety_test.rb +4 -6
  142. data/test/paper_trail_test.rb +15 -14
  143. data/test/test_helper.rb +78 -18
  144. data/test/time_travel_helper.rb +1 -15
  145. data/test/unit/associations_test.rb +1016 -0
  146. data/test/unit/cleaner_test.rb +66 -60
  147. data/test/unit/inheritance_column_test.rb +19 -19
  148. data/test/unit/model_test.rb +646 -1071
  149. data/test/unit/protected_attrs_test.rb +19 -14
  150. data/test/unit/serializer_test.rb +44 -43
  151. data/test/unit/serializers/json_test.rb +28 -21
  152. data/test/unit/serializers/mixin_json_test.rb +15 -14
  153. data/test/unit/serializers/mixin_yaml_test.rb +20 -16
  154. data/test/unit/serializers/yaml_test.rb +16 -14
  155. data/test/unit/timestamp_test.rb +10 -12
  156. data/test/unit/version_test.rb +88 -70
  157. metadata +166 -72
  158. data/gemfiles/3.0.gemfile +0 -52
data/lib/paper_trail.rb CHANGED
@@ -1,146 +1,178 @@
1
- require 'request_store'
2
-
3
- # Require core library
4
- Dir[File.join(File.dirname(__FILE__), 'paper_trail', '*.rb')].each do |file|
5
- require File.join('paper_trail', File.basename(file, '.rb'))
6
- end
7
-
8
- # Require serializers
9
- Dir[File.join(File.dirname(__FILE__), 'paper_trail', 'serializers', '*.rb')].each do |file|
10
- require File.join('paper_trail', 'serializers', File.basename(file, '.rb'))
11
- end
12
-
1
+ require "request_store"
2
+ require "paper_trail/cleaner"
3
+ require "paper_trail/config"
4
+ require "paper_trail/has_paper_trail"
5
+ require "paper_trail/record_history"
6
+ require "paper_trail/reifier"
7
+ require "paper_trail/version_association_concern"
8
+ require "paper_trail/version_concern"
9
+ require "paper_trail/version_number"
10
+ require "paper_trail/serializers/json"
11
+ require "paper_trail/serializers/yaml"
12
+
13
+ # An ActiveRecord extension that tracks changes to your models, for auditing or
14
+ # versioning.
13
15
  module PaperTrail
14
16
  extend PaperTrail::Cleaner
15
17
 
16
- # Switches PaperTrail on or off.
17
- def self.enabled=(value)
18
- PaperTrail.config.enabled = value
19
- end
20
-
21
- # Returns `true` if PaperTrail is on, `false` otherwise.
22
- # PaperTrail is enabled by default.
23
- def self.enabled?
24
- !!PaperTrail.config.enabled
25
- end
26
-
27
- # ActiveRecord 5 drops support for serialized attributes; for previous
28
- # versions of ActiveRecord it is supported, we have a config option
29
- # to enable it within PaperTrail.
30
- def self.serialized_attributes?
31
- !!PaperTrail.config.serialized_attributes && ::ActiveRecord::VERSION::MAJOR < 5
32
- end
33
-
34
- # Sets whether PaperTrail is enabled or disabled for the current request.
35
- def self.enabled_for_controller=(value)
36
- paper_trail_store[:request_enabled_for_controller] = value
37
- end
38
-
39
- # Returns `true` if PaperTrail is enabled for the request, `false` otherwise.
40
- #
41
- # See `PaperTrail::Rails::Controller#paper_trail_enabled_for_controller`.
42
- def self.enabled_for_controller?
43
- !!paper_trail_store[:request_enabled_for_controller]
44
- end
45
-
46
- # Sets whether PaperTrail is enabled or disabled for this model in the current request.
47
- def self.enabled_for_model(model, value)
48
- paper_trail_store[:"enabled_for_#{model}"] = value
49
- end
50
-
51
- # Returns `true` if PaperTrail is enabled for this model in the current request, `false` otherwise.
52
- def self.enabled_for_model?(model)
53
- !!paper_trail_store.fetch(:"enabled_for_#{model}", true)
54
- end
55
-
56
- # Set the field which records when a version was created.
57
- def self.timestamp_field=(field_name)
58
- PaperTrail.config.timestamp_field = field_name
59
- end
60
-
61
- # Returns the field which records when a version was created.
62
- def self.timestamp_field
63
- PaperTrail.config.timestamp_field
64
- end
65
-
66
- # Sets who is responsible for any changes that occur.
67
- # You would normally use this in a migration or on the console,
68
- # when working with models directly. In a controller it is set
69
- # automatically to the `current_user`.
70
- def self.whodunnit=(value)
71
- paper_trail_store[:whodunnit] = value
72
- end
73
-
74
- # Returns who is reponsible for any changes that occur.
75
- def self.whodunnit
76
- paper_trail_store[:whodunnit]
77
- end
78
-
79
- # Sets any information from the controller that you want PaperTrail
80
- # to store. By default this is set automatically by a before filter.
81
- def self.controller_info=(value)
82
- paper_trail_store[:controller_info] = value
83
- end
84
-
85
- # Returns any information from the controller that you want
86
- # PaperTrail to store.
87
- #
88
- # See `PaperTrail::Rails::Controller#info_for_paper_trail`.
89
- def self.controller_info
90
- paper_trail_store[:controller_info]
91
- end
92
-
93
- # Getter and Setter for PaperTrail Serializer
94
- def self.serializer=(value)
95
- PaperTrail.config.serializer = value
96
- end
97
-
98
- def self.serializer
99
- PaperTrail.config.serializer
100
- end
101
-
102
- def self.active_record_protected_attributes?
103
- @active_record_protected_attributes ||= ::ActiveRecord::VERSION::MAJOR < 4 || !!defined?(ProtectedAttributes)
104
- end
105
-
106
- def self.transaction?
107
- ::ActiveRecord::Base.connection.open_transactions > 0
108
- end
109
-
110
- def self.transaction_id
111
- paper_trail_store[:transaction_id]
112
- end
113
-
114
- def self.transaction_id=(id)
115
- paper_trail_store[:transaction_id] = id
116
- end
117
-
118
- private
119
-
120
- # Thread-safe hash to hold PaperTrail's data.
121
- # Initializing with needed default values.
122
- def self.paper_trail_store
123
- RequestStore.store[:paper_trail] ||= { :request_enabled_for_controller => true }
124
- end
125
-
126
- # Returns PaperTrail's configuration object.
127
- def self.config
128
- @@config ||= PaperTrail::Config.instance
129
- yield @@config if block_given?
130
- @@config
131
- end
132
-
133
18
  class << self
134
- alias_method :configure, :config
19
+ # Switches PaperTrail on or off.
20
+ # @api public
21
+ def enabled=(value)
22
+ PaperTrail.config.enabled = value
23
+ end
24
+
25
+ # Returns `true` if PaperTrail is on, `false` otherwise.
26
+ # PaperTrail is enabled by default.
27
+ # @api public
28
+ def enabled?
29
+ !!PaperTrail.config.enabled
30
+ end
31
+
32
+ def serialized_attributes?
33
+ ActiveSupport::Deprecation.warn(
34
+ "PaperTrail.serialized_attributes? is deprecated without replacement " +
35
+ "and always returns false."
36
+ )
37
+ false
38
+ end
39
+
40
+ # Sets whether PaperTrail is enabled or disabled for the current request.
41
+ # @api public
42
+ def enabled_for_controller=(value)
43
+ paper_trail_store[:request_enabled_for_controller] = value
44
+ end
45
+
46
+ # Returns `true` if PaperTrail is enabled for the request, `false` otherwise.
47
+ #
48
+ # See `PaperTrail::Rails::Controller#paper_trail_enabled_for_controller`.
49
+ # @api public
50
+ def enabled_for_controller?
51
+ !!paper_trail_store[:request_enabled_for_controller]
52
+ end
53
+
54
+ # Sets whether PaperTrail is enabled or disabled for this model in the
55
+ # current request.
56
+ # @api public
57
+ def enabled_for_model(model, value)
58
+ paper_trail_store[:"enabled_for_#{model}"] = value
59
+ end
60
+
61
+ # Returns `true` if PaperTrail is enabled for this model in the current
62
+ # request, `false` otherwise.
63
+ # @api public
64
+ def enabled_for_model?(model)
65
+ !!paper_trail_store.fetch(:"enabled_for_#{model}", true)
66
+ end
67
+
68
+ # Set the field which records when a version was created.
69
+ # @api public
70
+ def timestamp_field=(field_name)
71
+ PaperTrail.config.timestamp_field = field_name
72
+ end
73
+
74
+ # Returns the field which records when a version was created.
75
+ # @api public
76
+ def timestamp_field
77
+ PaperTrail.config.timestamp_field
78
+ end
79
+
80
+ # Sets who is responsible for any changes that occur. You would normally use
81
+ # this in a migration or on the console, when working with models directly.
82
+ # In a controller it is set automatically to the `current_user`.
83
+ # @api public
84
+ def whodunnit=(value)
85
+ paper_trail_store[:whodunnit] = value
86
+ end
87
+
88
+ # Returns who is reponsible for any changes that occur.
89
+ # @api public
90
+ def whodunnit
91
+ paper_trail_store[:whodunnit]
92
+ end
93
+
94
+ # Sets any information from the controller that you want PaperTrail to
95
+ # store. By default this is set automatically by a before filter.
96
+ # @api public
97
+ def controller_info=(value)
98
+ paper_trail_store[:controller_info] = value
99
+ end
100
+
101
+ # Returns any information from the controller that you want
102
+ # PaperTrail to store.
103
+ #
104
+ # See `PaperTrail::Rails::Controller#info_for_paper_trail`.
105
+ # @api public
106
+ def controller_info
107
+ paper_trail_store[:controller_info]
108
+ end
109
+
110
+ # Getter and Setter for PaperTrail Serializer
111
+ # @api public
112
+ def serializer=(value)
113
+ PaperTrail.config.serializer = value
114
+ end
115
+
116
+ # @api public
117
+ def serializer
118
+ PaperTrail.config.serializer
119
+ end
120
+
121
+ # Returns a boolean indicating whether "protected attibutes" should be
122
+ # configured, e.g. attr_accessible, mass_assignment_sanitizer,
123
+ # whitelist_attributes, etc.
124
+ # @api public
125
+ def active_record_protected_attributes?
126
+ @active_record_protected_attributes ||= ::ActiveRecord::VERSION::MAJOR < 4 ||
127
+ !!defined?(ProtectedAttributes)
128
+ end
129
+
130
+ # @api public
131
+ def transaction?
132
+ ::ActiveRecord::Base.connection.open_transactions > 0
133
+ end
134
+
135
+ # @api public
136
+ def transaction_id
137
+ paper_trail_store[:transaction_id]
138
+ end
139
+
140
+ # @api public
141
+ def transaction_id=(id)
142
+ paper_trail_store[:transaction_id] = id
143
+ end
144
+
145
+ # Thread-safe hash to hold PaperTrail's data. Initializing with needed
146
+ # default values.
147
+ # @api private
148
+ def paper_trail_store
149
+ RequestStore.store[:paper_trail] ||= { request_enabled_for_controller: true }
150
+ end
151
+
152
+ # Returns PaperTrail's configuration object.
153
+ # @api private
154
+ def config
155
+ @config ||= PaperTrail::Config.instance
156
+ yield @config if block_given?
157
+ @config
158
+ end
159
+ alias configure config
160
+
161
+ def version
162
+ VERSION::STRING
163
+ end
135
164
  end
136
165
  end
137
166
 
138
- # Ensure `ProtectedAttributes` gem gets required if it is available before the `Version` class gets loaded in
167
+ # If available, ensure that the `protected_attributes` gem is loaded
168
+ # before the `Version` class.
139
169
  unless PaperTrail.active_record_protected_attributes?
140
170
  PaperTrail.send(:remove_instance_variable, :@active_record_protected_attributes)
141
171
  begin
142
- require 'protected_attributes'
143
- rescue LoadError; end # will rescue if `ProtectedAttributes` gem is not available
172
+ require "protected_attributes"
173
+ rescue LoadError # rubocop:disable Lint/HandleExceptions
174
+ # In case `protected_attributes` gem is not available.
175
+ end
144
176
  end
145
177
 
146
178
  ActiveSupport.on_load(:active_record) do
@@ -148,9 +180,9 @@ ActiveSupport.on_load(:active_record) do
148
180
  end
149
181
 
150
182
  # Require frameworks
151
- require 'paper_trail/frameworks/sinatra'
152
- if defined?(::Rails) && ActiveRecord::VERSION::STRING >= '3.2'
153
- require 'paper_trail/frameworks/rails'
183
+ require "paper_trail/frameworks/sinatra"
184
+ if defined?(::Rails) && ActiveRecord::VERSION::STRING >= "3.2"
185
+ require "paper_trail/frameworks/rails"
154
186
  else
155
- require 'paper_trail/frameworks/active_record'
187
+ require "paper_trail/frameworks/active_record"
156
188
  end
data/paper_trail.gemspec CHANGED
@@ -1,54 +1,52 @@
1
- $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
- require 'paper_trail/version_number'
1
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
+ require "paper_trail/version_number"
3
3
 
4
4
  Gem::Specification.new do |s|
5
- s.name = 'paper_trail'
6
- s.version = PaperTrail.version
7
- s.platform = Gem::Platform::RUBY
8
- s.summary = "Track changes to your models' data. Good for auditing or versioning."
9
- s.description = s.summary
10
- s.homepage = 'https://github.com/airblade/paper_trail'
11
- s.authors = ['Andy Stewart', 'Ben Atkins']
12
- s.email = 'batkinz@gmail.com'
13
- s.license = 'MIT'
5
+ s.name = "paper_trail"
6
+ s.version = PaperTrail::VERSION::STRING
7
+ s.platform = Gem::Platform::RUBY
8
+ s.summary = "Track changes to your models' data. Good for auditing or versioning."
9
+ s.description = s.summary
10
+ s.homepage = "https://github.com/airblade/paper_trail"
11
+ s.authors = ["Andy Stewart", "Ben Atkins"]
12
+ s.email = "batkinz@gmail.com"
13
+ s.license = "MIT"
14
14
 
15
- s.files = `git ls-files`.split("\n")
16
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
- s.require_paths = ['lib']
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
19
 
20
- s.required_rubygems_version = '>= 1.3.6'
20
+ s.required_rubygems_version = ">= 1.3.6"
21
+ s.required_ruby_version = ">= 1.9.3"
21
22
 
22
- s.add_dependency 'activerecord', ['>= 3.0', '< 6.0']
23
- s.add_dependency 'activesupport', ['>= 3.0', '< 6.0']
24
- s.add_dependency 'request_store', '~> 1.1'
23
+ s.add_dependency "activerecord", [">= 3.0", "< 6.0"]
24
+ s.add_dependency "activesupport", [">= 3.0", "< 6.0"]
25
+ s.add_dependency "request_store", "~> 1.1"
25
26
 
26
- s.add_development_dependency 'rake', '~> 10.1.1'
27
- s.add_development_dependency 'shoulda', '~> 3.5'
28
- # s.add_development_dependency 'shoulda-matchers', '~> 1.5' # needed for ActiveRecord < 4
29
- s.add_development_dependency 'ffaker', '<= 1.31.0'
30
- s.add_development_dependency 'railties', ['>= 3.0', '< 5.0']
31
- s.add_development_dependency 'sinatra', '~> 1.0'
32
- s.add_development_dependency 'rack-test', '>= 0.6'
33
- s.add_development_dependency 'rspec-rails', '~> 3.1.0'
34
- s.add_development_dependency 'generator_spec'
35
- s.add_development_dependency 'database_cleaner', '~> 1.2'
27
+ s.add_development_dependency "appraisal", "~> 2.1"
28
+ s.add_development_dependency "rake", "~> 10.4.2"
29
+ s.add_development_dependency "shoulda", "~> 3.5.0"
30
+ s.add_development_dependency "ffaker", "~> 2.1.0"
31
+ s.add_development_dependency "railties", [">= 3.0", "< 6.0"]
32
+ s.add_development_dependency "sinatra", "~> 1.4.6"
33
+ s.add_development_dependency "rack-test", "~> 0.6.3"
34
+ s.add_development_dependency "rspec-rails", "~> 3.4.0"
35
+ s.add_development_dependency "generator_spec", "~> 0.9.3"
36
+ s.add_development_dependency "database_cleaner", "~> 1.2"
37
+ s.add_development_dependency "pry-nav", "~> 0.2.4"
38
+ s.add_development_dependency "rubocop", "~> 0.40.0"
39
+ s.add_development_dependency "timecop", "~> 0.8.0"
36
40
 
37
- # Allow time travel in testing. timecop is only supported after 1.9.2 but does a better cleanup at 'return'
38
- if RUBY_VERSION < "1.9.2"
39
- s.add_development_dependency 'delorean'
41
+ if defined?(JRUBY_VERSION)
42
+ s.add_development_dependency "activerecord-jdbcsqlite3-adapter", "~> 1.3.15"
43
+ s.add_development_dependency "activerecord-jdbcpostgresql-adapter", "~> 1.3.15"
44
+ s.add_development_dependency "activerecord-jdbcmysql-adapter", "~> 1.3.15"
40
45
  else
41
- s.add_development_dependency 'timecop'
42
- end
46
+ s.add_development_dependency "sqlite3", "~> 1.2"
47
+ s.add_development_dependency "pg", "~> 0.17"
43
48
 
44
- # JRuby support for the test ENV
45
- unless defined?(JRUBY_VERSION)
46
- s.add_development_dependency 'sqlite3', '~> 1.2'
47
- s.add_development_dependency 'mysql2', '~> 0.3'
48
- s.add_development_dependency 'pg', '~> 0.17'
49
- else
50
- s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.3'
51
- s.add_development_dependency 'activerecord-jdbcpostgresql-adapter', '~> 1.3'
52
- s.add_development_dependency 'activerecord-jdbcmysql-adapter', '~> 1.3'
49
+ # activerecord >= 4.2.5 may use mysql2 >= 0.4
50
+ s.add_development_dependency "mysql2", "~> 0.4.2"
53
51
  end
54
52
  end
@@ -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,19 +1,36 @@
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
+
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
+
23
+ it "trails all events" do
24
+ callback_cat.update_attributes(name: "Billie")
25
+ callback_cat.destroy
26
+ expect(callback_cat.versions.collect(&:event)).to eq %w(create update destroy)
27
+ end
28
+
29
+ it "does not break reify" do
30
+ callback_cat.destroy
31
+ expect { callback_cat.versions.last.reify }.not_to raise_error
32
+ end
33
+ end
34
+ end
18
35
  end
19
36
  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