paper_trail 3.0.9 → 4.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +1 -2
- data/.travis.yml +5 -0
- data/CHANGELOG.md +37 -23
- data/README.md +170 -63
- data/gemfiles/3.0.gemfile +10 -4
- data/lib/generators/paper_trail/install_generator.rb +19 -3
- data/lib/generators/paper_trail/templates/add_transaction_id_column_to_versions.rb +11 -0
- data/lib/generators/paper_trail/templates/create_version_associations.rb +17 -0
- data/lib/paper_trail.rb +24 -4
- data/lib/paper_trail/cleaner.rb +3 -3
- data/lib/paper_trail/config.rb +17 -0
- data/lib/paper_trail/frameworks/active_record/models/paper_trail/version_association.rb +7 -0
- data/lib/paper_trail/frameworks/rails.rb +1 -0
- data/lib/paper_trail/frameworks/rspec.rb +5 -0
- data/lib/paper_trail/has_paper_trail.rb +112 -38
- data/lib/paper_trail/version_association_concern.rb +13 -0
- data/lib/paper_trail/version_concern.rb +145 -38
- data/lib/paper_trail/version_number.rb +3 -3
- data/paper_trail.gemspec +11 -4
- data/spec/generators/install_generator_spec.rb +4 -4
- data/spec/models/fluxor_spec.rb +19 -0
- data/spec/models/gadget_spec.rb +10 -10
- data/spec/models/joined_version_spec.rb +9 -9
- data/spec/models/post_with_status_spec.rb +3 -3
- data/spec/models/version_spec.rb +49 -71
- data/spec/models/widget_spec.rb +124 -71
- data/spec/modules/version_concern_spec.rb +8 -8
- data/spec/modules/version_number_spec.rb +16 -16
- data/spec/paper_trail_spec.rb +17 -17
- data/spec/rails_helper.rb +34 -0
- data/spec/requests/articles_spec.rb +11 -11
- data/spec/spec_helper.rb +77 -36
- data/test/dummy/app/models/animal.rb +0 -2
- data/test/dummy/app/models/book.rb +4 -0
- data/test/dummy/app/models/customer.rb +4 -0
- data/test/dummy/app/models/editor.rb +4 -0
- data/test/dummy/app/models/editorship.rb +5 -0
- data/test/dummy/app/models/line_item.rb +4 -0
- data/test/dummy/app/models/order.rb +5 -0
- data/test/dummy/app/models/person.rb +1 -1
- data/test/dummy/app/models/post.rb +0 -1
- data/test/dummy/app/models/song.rb +0 -20
- data/test/dummy/app/models/widget.rb +4 -0
- data/test/dummy/config/application.rb +3 -0
- data/test/dummy/config/initializers/paper_trail.rb +1 -1
- data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +41 -0
- data/test/dummy/db/schema.rb +95 -25
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/javascripts/application.js +2 -0
- data/test/dummy/public/javascripts/controls.js +965 -0
- data/test/dummy/public/javascripts/dragdrop.js +974 -0
- data/test/dummy/public/javascripts/effects.js +1123 -0
- data/test/dummy/public/javascripts/rails.js +175 -0
- data/test/dummy/public/stylesheets/.gitkeep +0 -0
- data/test/test_helper.rb +2 -2
- data/test/time_travel_helper.rb +15 -0
- data/test/unit/model_test.rb +613 -185
- data/test/unit/serializer_test.rb +3 -3
- metadata +104 -54
- data/spec/models/animal_spec.rb +0 -19
- data/test/dummy/public/javascripts/prototype.js +0 -6001
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module PaperTrail
|
4
|
+
module VersionAssociationConcern
|
5
|
+
extend ::ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
belongs_to :version
|
9
|
+
|
10
|
+
attr_accessible :version_id, :foreign_key_name, :foreign_key_id if PaperTrail.active_record_protected_attributes?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -6,10 +6,15 @@ module PaperTrail
|
|
6
6
|
|
7
7
|
included do
|
8
8
|
belongs_to :item, :polymorphic => true
|
9
|
+
has_many :version_associations, :dependent => :destroy
|
10
|
+
|
9
11
|
validates_presence_of :event
|
10
|
-
|
12
|
+
|
13
|
+
attr_accessible :item_type, :item_id, :event, :whodunnit, :object, :object_changes, :transaction_id, :created_at if PaperTrail.active_record_protected_attributes?
|
11
14
|
|
12
15
|
after_create :enforce_version_limit!
|
16
|
+
|
17
|
+
scope :within_transaction, lambda { |id| where :transaction_id => id }
|
13
18
|
end
|
14
19
|
|
15
20
|
module ClassMethods
|
@@ -102,21 +107,28 @@ module PaperTrail
|
|
102
107
|
|
103
108
|
# Restore the item from this version.
|
104
109
|
#
|
105
|
-
#
|
106
|
-
# if they are also being versioned by PaperTrail.
|
107
|
-
# to work so you can either change the lookback period (from the default 3 seconds) or
|
108
|
-
# opt out.
|
110
|
+
# Optionally this can also restore all :has_one and :has_many (including has_many :through) associations as
|
111
|
+
# they were "at the time", if they are also being versioned by PaperTrail.
|
109
112
|
#
|
110
113
|
# Options:
|
111
|
-
# :has_one
|
112
|
-
#
|
113
|
-
#
|
114
|
+
# :has_one set to `true` to also reify has_one associations. Default is `false`.
|
115
|
+
# :has_many set to `true` to also reify has_many and has_many :through associations.
|
116
|
+
# Default is `false`.
|
117
|
+
# :mark_for_destruction set to `true` to mark the has_one/has_many associations that did not exist in the
|
118
|
+
# reified version for destruction, instead of remove them. Default is `false`.
|
119
|
+
# This option is handy for people who want to persist the reified version.
|
120
|
+
# :dup `false` default behavior
|
121
|
+
# `true` it always create a new object instance. It is useful for comparing two versions of the same object
|
114
122
|
def reify(options = {})
|
115
123
|
return nil if object.nil?
|
116
124
|
|
117
125
|
without_identity_map do
|
118
|
-
options
|
119
|
-
|
126
|
+
options.reverse_merge!(
|
127
|
+
:version_at => created_at,
|
128
|
+
:mark_for_destruction => false,
|
129
|
+
:has_one => false,
|
130
|
+
:has_many => false
|
131
|
+
)
|
120
132
|
|
121
133
|
attrs = self.class.object_col_is_json? ? object : PaperTrail.serializer.load(object)
|
122
134
|
|
@@ -133,7 +145,7 @@ module PaperTrail
|
|
133
145
|
# `item_type` will be the base class, not the actual subclass.
|
134
146
|
# If `type` is present but empty, the class is the base class.
|
135
147
|
|
136
|
-
if item
|
148
|
+
if item && options[:dup] != true
|
137
149
|
model = item
|
138
150
|
# Look for attributes that exist in the model and not in this version. These attributes should be set to nil.
|
139
151
|
(model.attribute_names - attrs.keys).each { |k| attrs[k] = nil }
|
@@ -144,14 +156,14 @@ module PaperTrail
|
|
144
156
|
model = klass.new
|
145
157
|
end
|
146
158
|
|
147
|
-
|
159
|
+
if PaperTrail.serialized_attributes?
|
160
|
+
model.class.unserialize_attributes_for_paper_trail attrs
|
161
|
+
end
|
148
162
|
|
149
163
|
# Set all the attributes in this version on the model
|
150
164
|
attrs.each do |k, v|
|
151
165
|
if model.has_attribute?(k)
|
152
166
|
model[k.to_sym] = v
|
153
|
-
elsif model.respond_to?("#{k}=")
|
154
|
-
model.send("#{k}=", v)
|
155
167
|
else
|
156
168
|
logger.warn "Attribute #{k} does not exist on #{item_type} (Version id: #{id})."
|
157
169
|
end
|
@@ -160,34 +172,35 @@ module PaperTrail
|
|
160
172
|
model.send "#{model.class.version_association_name}=", self
|
161
173
|
|
162
174
|
unless options[:has_one] == false
|
163
|
-
reify_has_ones model, options
|
175
|
+
reify_has_ones model, options
|
176
|
+
end
|
177
|
+
|
178
|
+
unless options[:has_many] == false
|
179
|
+
reify_has_manys model, options
|
164
180
|
end
|
165
181
|
|
166
182
|
model
|
167
183
|
end
|
168
184
|
end
|
169
185
|
|
170
|
-
# Returns what changed in this version of the item.
|
171
|
-
#
|
186
|
+
# Returns what changed in this version of the item. `ActiveModel::Dirty#changes`.
|
187
|
+
# returns `nil` if your `versions` table does not have an `object_changes` text column.
|
172
188
|
def changeset
|
173
189
|
return nil unless self.class.column_names.include? 'object_changes'
|
174
190
|
|
175
191
|
_changes = self.class.object_changes_col_is_json? ? object_changes : PaperTrail.serializer.load(object_changes)
|
176
192
|
@changeset ||= HashWithIndifferentAccess.new(_changes).tap do |changes|
|
177
|
-
|
193
|
+
if PaperTrail.serialized_attributes?
|
194
|
+
item_type.constantize.unserialize_attribute_changes(changes)
|
195
|
+
end
|
178
196
|
end
|
179
197
|
rescue
|
180
198
|
{}
|
181
199
|
end
|
182
200
|
|
183
201
|
# Returns who put the item into the state stored in this version.
|
184
|
-
def paper_trail_originator
|
185
|
-
@paper_trail_originator ||= previous.whodunnit rescue nil
|
186
|
-
end
|
187
|
-
|
188
202
|
def originator
|
189
|
-
|
190
|
-
self.paper_trail_originator
|
203
|
+
@originator ||= previous.whodunnit rescue nil
|
191
204
|
end
|
192
205
|
|
193
206
|
# Returns who changed the item from the state it had in this version.
|
@@ -236,25 +249,119 @@ module PaperTrail
|
|
236
249
|
# Restore the `model`'s has_one associations as they were when this version was
|
237
250
|
# superseded by the next (because that's what the user was looking at when they
|
238
251
|
# made the change).
|
239
|
-
|
240
|
-
|
241
|
-
def reify_has_ones(model, lookback)
|
252
|
+
def reify_has_ones(model, options = {})
|
253
|
+
version_table_name = model.class.paper_trail_version_class.table_name
|
242
254
|
model.class.reflect_on_all_associations(:has_one).each do |assoc|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
if
|
251
|
-
|
252
|
-
|
255
|
+
if assoc.klass.paper_trail_enabled_for_model?
|
256
|
+
version = model.class.paper_trail_version_class.joins(:version_associations).
|
257
|
+
where("version_associations.foreign_key_name = ?", assoc.foreign_key).
|
258
|
+
where("version_associations.foreign_key_id = ?", model.id).
|
259
|
+
where("#{version_table_name}.item_type = ?", assoc.class_name).
|
260
|
+
where("created_at >= ? OR transaction_id = ?", options[:version_at], transaction_id).
|
261
|
+
order("#{version_table_name}.id ASC").first
|
262
|
+
if version
|
263
|
+
if version.event == 'create'
|
264
|
+
if options[:mark_for_destruction]
|
265
|
+
model.send(assoc.name).mark_for_destruction if model.send(assoc.name, true)
|
266
|
+
else
|
267
|
+
model.appear_as_new_record do
|
268
|
+
model.send "#{assoc.name}=", nil
|
269
|
+
end
|
270
|
+
end
|
271
|
+
else
|
272
|
+
child = version.reify(options.merge(:has_many => false, :has_one => false))
|
273
|
+
model.appear_as_new_record do
|
274
|
+
model.send "#{assoc.name}=", child
|
275
|
+
end
|
253
276
|
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
# Restore the `model`'s has_many associations as they were at version_at timestamp
|
283
|
+
# We lookup the first child versions after version_at timestamp or in same transaction.
|
284
|
+
def reify_has_manys(model, options = {})
|
285
|
+
assoc_has_many_through, assoc_has_many_directly =
|
286
|
+
model.class.reflect_on_all_associations(:has_many).partition { |assoc| assoc.options[:through] }
|
287
|
+
reify_has_many_directly(assoc_has_many_directly, model, options)
|
288
|
+
reify_has_many_through(assoc_has_many_through, model, options)
|
289
|
+
end
|
290
|
+
|
291
|
+
# Restore the `model`'s has_many associations not associated through another association
|
292
|
+
def reify_has_many_directly(associations, model, options = {})
|
293
|
+
version_table_name = model.class.paper_trail_version_class.table_name
|
294
|
+
associations.each do |assoc|
|
295
|
+
next unless assoc.klass.paper_trail_enabled_for_model?
|
296
|
+
version_id_subquery = PaperTrail::VersionAssociation.joins(model.class.version_association_name).
|
297
|
+
select("MIN(version_id)").
|
298
|
+
where("foreign_key_name = ?", assoc.foreign_key).
|
299
|
+
where("foreign_key_id = ?", model.id).
|
300
|
+
where("#{version_table_name}.item_type = ?", assoc.class_name).
|
301
|
+
where("created_at >= ? OR transaction_id = ?", options[:version_at], transaction_id).
|
302
|
+
group("item_id").to_sql
|
303
|
+
versions = model.class.paper_trail_version_class.where("id IN (#{version_id_subquery})").inject({}) do |acc, v|
|
304
|
+
acc.merge!(v.item_id => v)
|
305
|
+
end
|
306
|
+
|
307
|
+
# Pass true to force the model to load
|
308
|
+
collection = Array.new model.send(assoc.name, true)
|
309
|
+
|
310
|
+
# Iterate each child to replace it with the previous value if there is a version after the timestamp
|
311
|
+
collection.map! do |c|
|
312
|
+
if (version = versions.delete(c.id)).nil?
|
313
|
+
c
|
314
|
+
elsif version.event == 'create'
|
315
|
+
options[:mark_for_destruction] ? c.tap { |r| r.mark_for_destruction } : nil
|
316
|
+
else
|
317
|
+
version.reify(options.merge(:has_many => false, :has_one => false))
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
# Reify the rest of the versions and add them to the collection, these versions are for those that
|
322
|
+
# have been removed from the live associations
|
323
|
+
collection += versions.values.map { |version| version.reify(options.merge(:has_many => false, :has_one => false)) }
|
324
|
+
|
325
|
+
model.send(assoc.name).proxy_association.target = collection.compact
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
# Restore the `model`'s has_many associations through another association
|
330
|
+
# This must be called after the direct has_manys have been reified (reify_has_many_directly)
|
331
|
+
def reify_has_many_through(associations, model, options = {})
|
332
|
+
associations.each do |assoc|
|
333
|
+
next unless assoc.klass.paper_trail_enabled_for_model?
|
334
|
+
through_collection = model.send(assoc.options[:through])
|
335
|
+
collection_keys = through_collection.map { |through_model| through_model.send(assoc.foreign_key) }
|
336
|
+
|
337
|
+
version_id_subquery = assoc.klass.paper_trail_version_class.
|
338
|
+
select("MIN(id)").
|
339
|
+
where("item_type = ?", assoc.class_name).
|
340
|
+
where("item_id IN (?)", collection_keys).
|
341
|
+
where("created_at >= ? OR transaction_id = ?", options[:version_at], transaction_id).
|
342
|
+
group("item_id").to_sql
|
343
|
+
versions = assoc.klass.paper_trail_version_class.where("id IN (#{version_id_subquery})").inject({}) do |acc, v|
|
344
|
+
acc.merge!(v.item_id => v)
|
345
|
+
end
|
346
|
+
|
347
|
+
collection = Array.new assoc.klass.where(assoc.klass.primary_key => collection_keys)
|
348
|
+
|
349
|
+
# Iterate each child to replace it with the previous value if there is a version after the timestamp
|
350
|
+
collection.map! do |c|
|
351
|
+
if (version = versions.delete(c.id)).nil?
|
352
|
+
c
|
353
|
+
elsif version.event == 'create'
|
354
|
+
options[:mark_for_destruction] ? c.tap { |r| r.mark_for_destruction } : nil
|
254
355
|
else
|
255
|
-
|
356
|
+
version.reify(options.merge(:has_many => false, :has_one => false))
|
256
357
|
end
|
257
358
|
end
|
359
|
+
|
360
|
+
# Reify the rest of the versions and add them to the collection, these versions are for those that
|
361
|
+
# have been removed from the live associations
|
362
|
+
collection += versions.values.map { |version| version.reify(options.merge(:has_many => false, :has_one => false)) }
|
363
|
+
|
364
|
+
model.send(assoc.name).proxy_association.target = collection.compact
|
258
365
|
end
|
259
366
|
end
|
260
367
|
|
data/paper_trail.gemspec
CHANGED
@@ -19,20 +19,27 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
s.required_rubygems_version = '>= 1.3.6'
|
21
21
|
|
22
|
-
s.add_dependency 'activerecord', ['>= 3.0', '<
|
23
|
-
s.add_dependency 'activesupport', ['>= 3.0', '<
|
22
|
+
s.add_dependency 'activerecord', ['>= 3.0', '< 6.0']
|
23
|
+
s.add_dependency 'activesupport', ['>= 3.0', '< 6.0']
|
24
24
|
|
25
25
|
s.add_development_dependency 'rake', '~> 10.1.1'
|
26
26
|
s.add_development_dependency 'shoulda', '~> 3.5'
|
27
27
|
# s.add_development_dependency 'shoulda-matchers', '~> 1.5' # needed for ActiveRecord < 4
|
28
|
-
s.add_development_dependency 'ffaker',
|
28
|
+
s.add_development_dependency 'ffaker', '>= 1.15'
|
29
29
|
s.add_development_dependency 'railties', ['>= 3.0', '< 5.0']
|
30
30
|
s.add_development_dependency 'sinatra', '~> 1.0'
|
31
31
|
s.add_development_dependency 'rack-test', '>= 0.6'
|
32
|
-
s.add_development_dependency 'rspec-rails', '~>
|
32
|
+
s.add_development_dependency 'rspec-rails', '~> 3.1.0'
|
33
33
|
s.add_development_dependency 'generator_spec'
|
34
34
|
s.add_development_dependency 'database_cleaner', '~> 1.2'
|
35
35
|
|
36
|
+
# Allow time travel in testing. timecop is only supported after 1.9.2 but does a better cleanup at 'return'
|
37
|
+
if RUBY_VERSION < "1.9.2"
|
38
|
+
s.add_development_dependency 'delorean'
|
39
|
+
else
|
40
|
+
s.add_development_dependency 'timecop'
|
41
|
+
end
|
42
|
+
|
36
43
|
# JRuby support for the test ENV
|
37
44
|
unless defined?(JRUBY_VERSION)
|
38
45
|
s.add_development_dependency 'sqlite3', '~> 1.2'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'rails_helper'
|
2
2
|
require 'generator_spec/test_case'
|
3
3
|
require File.expand_path('../../../lib/generators/paper_trail/install_generator', __FILE__)
|
4
4
|
|
@@ -15,7 +15,7 @@ describe PaperTrail::InstallGenerator, :type => :generator do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it "generates a migration for creating the 'versions' table" do
|
18
|
-
destination_root.
|
18
|
+
expect(destination_root).to have_structure {
|
19
19
|
directory 'db' do
|
20
20
|
directory 'migrate' do
|
21
21
|
migration 'create_versions' do
|
@@ -36,7 +36,7 @@ describe PaperTrail::InstallGenerator, :type => :generator do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "generates a migration for creating the 'versions' table" do
|
39
|
-
destination_root.
|
39
|
+
expect(destination_root).to have_structure {
|
40
40
|
directory 'db' do
|
41
41
|
directory 'migrate' do
|
42
42
|
migration 'create_versions' do
|
@@ -50,7 +50,7 @@ describe PaperTrail::InstallGenerator, :type => :generator do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
it "generates a migration for adding the 'object_changes' column to the 'versions' table" do
|
53
|
-
destination_root.
|
53
|
+
expect(destination_root).to have_structure {
|
54
54
|
directory 'db' do
|
55
55
|
directory 'migrate' do
|
56
56
|
migration 'add_object_changes_to_versions' do
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe Fluxor, :type => :model do
|
4
|
+
describe '`be_versioned` matcher' do
|
5
|
+
it { is_expected.to_not be_versioned }
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "Methods" do
|
9
|
+
describe "Class" do
|
10
|
+
subject { Fluxor }
|
11
|
+
|
12
|
+
describe "#paper_trail_enabled_for_model?" do
|
13
|
+
it { is_expected.to respond_to(:paper_trail_enabled_for_model?) }
|
14
|
+
|
15
|
+
it { expect(subject.paper_trail_enabled_for_model?).to be false }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/spec/models/gadget_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require '
|
1
|
+
require 'rails_helper'
|
2
2
|
|
3
|
-
describe Gadget do
|
4
|
-
it {
|
3
|
+
describe Gadget, :type => :model do
|
4
|
+
it { is_expected.to be_versioned }
|
5
5
|
|
6
6
|
let(:gadget) { Gadget.create!(:name => 'Wrench', :brand => 'Acme') }
|
7
7
|
|
@@ -22,16 +22,16 @@ describe Gadget do
|
|
22
22
|
describe "Methods" do
|
23
23
|
describe "Instance", :versioning => true do
|
24
24
|
describe "private" do
|
25
|
-
describe
|
25
|
+
describe '#changed_notably?' do
|
26
26
|
subject { Gadget.new(:created_at => Time.now) }
|
27
27
|
|
28
28
|
# apparently the private methods list in Ruby18 is different than in Ruby19+
|
29
29
|
if RUBY_VERSION.to_f >= 1.9
|
30
|
-
|
30
|
+
it { expect(subject.private_methods).to include(:changed_notably?) }
|
31
31
|
end
|
32
32
|
|
33
33
|
context "create events" do
|
34
|
-
it { subject.send(:changed_notably?).
|
34
|
+
it { expect(subject.send(:changed_notably?)).to be true }
|
35
35
|
end
|
36
36
|
|
37
37
|
context "update events" do
|
@@ -40,24 +40,24 @@ describe Gadget do
|
|
40
40
|
context "without update timestamps" do
|
41
41
|
it "should only acknowledge non-ignored attrs" do
|
42
42
|
subject.name = 'Wrench'
|
43
|
-
subject.send(:changed_notably?).
|
43
|
+
expect(subject.send(:changed_notably?)).to be true
|
44
44
|
end
|
45
45
|
|
46
46
|
it "should not acknowledge ignored attrs and timestamps only" do
|
47
47
|
subject.brand = 'Acme'
|
48
|
-
subject.send(:changed_notably?).
|
48
|
+
expect(subject.send(:changed_notably?)).to be false
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
context "with update timestamps" do
|
53
53
|
it "should only acknowledge non-ignored attrs" do
|
54
54
|
subject.name, subject.updated_at = 'Wrench', Time.now
|
55
|
-
subject.send(:changed_notably?).
|
55
|
+
expect(subject.send(:changed_notably?)).to be true
|
56
56
|
end
|
57
57
|
|
58
58
|
it "should not acknowledge ignored attrs and timestamps only" do
|
59
59
|
subject.brand, subject.updated_at = 'Acme', Time.now
|
60
|
-
subject.send(:changed_notably?).
|
60
|
+
expect(subject.send(:changed_notably?)).to be false
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
@@ -1,32 +1,32 @@
|
|
1
|
-
require '
|
1
|
+
require 'rails_helper'
|
2
2
|
|
3
|
-
describe JoinedVersion, :versioning => true do
|
4
|
-
it { JoinedVersion.superclass.
|
3
|
+
describe JoinedVersion, :type => :model, :versioning => true do
|
4
|
+
it { expect(JoinedVersion.superclass).to be PaperTrail::Version }
|
5
5
|
|
6
6
|
let(:widget) { Widget.create!(:name => Faker::Name.name) }
|
7
7
|
let(:version) { JoinedVersion.first }
|
8
8
|
|
9
9
|
describe "Scopes" do
|
10
10
|
describe "default_scope" do
|
11
|
-
it { JoinedVersion.default_scopes.
|
11
|
+
it { expect(JoinedVersion.default_scopes).not_to be_empty }
|
12
12
|
end
|
13
13
|
|
14
14
|
describe "VersionConcern::ClassMethods" do
|
15
15
|
before { widget } # persist a widget
|
16
16
|
|
17
|
-
describe
|
17
|
+
describe '#subsequent' do
|
18
18
|
it "shouldn't error out when there is a default_scope that joins" do
|
19
19
|
JoinedVersion.subsequent(version).first
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
describe
|
23
|
+
describe '#preceding' do
|
24
24
|
it "shouldn't error out when there is a default scope that joins" do
|
25
25
|
JoinedVersion.preceding(version).first
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
describe
|
29
|
+
describe '#between' do
|
30
30
|
it "shouldn't error out when there is a default scope that joins" do
|
31
31
|
JoinedVersion.between(Time.now, 1.minute.from_now).first
|
32
32
|
end
|
@@ -35,8 +35,8 @@ describe JoinedVersion, :versioning => true do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
describe "Methods" do
|
38
|
-
describe
|
39
|
-
it {
|
38
|
+
describe '#index' do
|
39
|
+
it { is_expected.to respond_to(:index) }
|
40
40
|
|
41
41
|
it "shouldn't error out when there is a default scope that joins" do
|
42
42
|
widget # persist a widget
|