vestal_versions 1.0.2 → 2.0.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.
- data/.gitignore +19 -20
- data/.travis.yml +22 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +10 -0
- data/README.rdoc +63 -36
- data/Rakefile +4 -43
- data/gemfiles/activerecord_3_0.gemfile +10 -0
- data/gemfiles/activerecord_3_1.gemfile +10 -0
- data/gemfiles/activerecord_3_2.gemfile +10 -0
- data/gemfiles/activerecord_4_0.gemfile +10 -0
- data/lib/generators/vestal_versions.rb +11 -0
- data/lib/generators/vestal_versions/migration/migration_generator.rb +17 -0
- data/{generators/vestal_versions → lib/generators/vestal_versions/migration}/templates/initializer.rb +0 -0
- data/{generators/vestal_versions → lib/generators/vestal_versions/migration}/templates/migration.rb +4 -3
- data/lib/vestal_versions.rb +39 -12
- data/lib/vestal_versions/changes.rb +43 -47
- data/lib/vestal_versions/conditions.rb +31 -43
- data/lib/vestal_versions/control.rb +162 -138
- data/lib/vestal_versions/creation.rb +67 -59
- data/lib/vestal_versions/deletion.rb +37 -0
- data/lib/vestal_versions/options.rb +6 -10
- data/lib/vestal_versions/reload.rb +7 -14
- data/lib/vestal_versions/reset.rb +15 -19
- data/lib/vestal_versions/reversion.rb +64 -52
- data/lib/vestal_versions/users.rb +36 -39
- data/lib/vestal_versions/version.rb +57 -2
- data/lib/vestal_versions/version_tagging.rb +51 -0
- data/lib/vestal_versions/versioned.rb +14 -17
- data/lib/vestal_versions/versions.rb +22 -7
- data/spec/spec_helper.rb +28 -0
- data/spec/support/models.rb +19 -0
- data/spec/support/schema.rb +25 -0
- data/spec/vestal_versions/changes_spec.rb +134 -0
- data/spec/vestal_versions/conditions_spec.rb +103 -0
- data/spec/vestal_versions/control_spec.rb +120 -0
- data/spec/vestal_versions/creation_spec.rb +90 -0
- data/spec/vestal_versions/deletion_spec.rb +86 -0
- data/spec/vestal_versions/options_spec.rb +45 -0
- data/spec/vestal_versions/reload_spec.rb +18 -0
- data/spec/vestal_versions/reset_spec.rb +111 -0
- data/spec/vestal_versions/reversion_spec.rb +103 -0
- data/spec/vestal_versions/users_spec.rb +21 -0
- data/spec/vestal_versions/version_spec.rb +61 -0
- data/spec/vestal_versions/version_tagging_spec.rb +39 -0
- data/spec/vestal_versions/versioned_spec.rb +16 -0
- data/spec/vestal_versions/versions_spec.rb +176 -0
- data/vestal_versions.gemspec +18 -100
- metadata +153 -102
- data/VERSION +0 -1
- data/generators/vestal_versions/vestal_versions_generator.rb +0 -10
- data/init.rb +0 -1
- data/lib/vestal_versions/configuration.rb +0 -40
- data/lib/vestal_versions/tagging.rb +0 -50
- data/test/changes_test.rb +0 -169
- data/test/conditions_test.rb +0 -137
- data/test/configuration_test.rb +0 -39
- data/test/control_test.rb +0 -152
- data/test/creation_test.rb +0 -110
- data/test/options_test.rb +0 -52
- data/test/reload_test.rb +0 -19
- data/test/reset_test.rb +0 -112
- data/test/reversion_test.rb +0 -68
- data/test/schema.rb +0 -43
- data/test/tagging_test.rb +0 -39
- data/test/test_helper.rb +0 -11
- data/test/users_test.rb +0 -25
- data/test/version_test.rb +0 -43
- data/test/versioned_test.rb +0 -18
- data/test/versions_test.rb +0 -172
@@ -1,17 +1,28 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'active_support/configurable'
|
3
|
+
|
1
4
|
module VestalVersions
|
2
5
|
# The ActiveRecord model representing versions.
|
3
6
|
class Version < ActiveRecord::Base
|
4
7
|
include Comparable
|
8
|
+
include ActiveSupport::Configurable
|
5
9
|
|
6
10
|
# Associate polymorphically with the parent record.
|
7
11
|
belongs_to :versioned, :polymorphic => true
|
8
12
|
|
13
|
+
if ActiveRecord::VERSION::MAJOR == 3
|
14
|
+
attr_accessible :modifications, :number, :user, :tag, :reverted_from
|
15
|
+
end
|
16
|
+
|
9
17
|
# ActiveRecord::Base#changes is an existing method, so before serializing the +changes+ column,
|
10
|
-
# the existing +changes+ method is undefined. The overridden +changes+ method pertained to
|
18
|
+
# the existing +changes+ method is undefined. The overridden +changes+ method pertained to
|
11
19
|
# dirty attributes, but will not affect the partial updates functionality as that's based on
|
12
20
|
# an underlying +changed_attributes+ method, not +changes+ itself.
|
13
21
|
undef_method :changes
|
14
|
-
|
22
|
+
def changes
|
23
|
+
self[:modifications]
|
24
|
+
end
|
25
|
+
serialize :modifications, Hash
|
15
26
|
|
16
27
|
# In conjunction with the included Comparable module, allows comparison of version records
|
17
28
|
# based on their corresponding version numbers, creation timestamps and IDs.
|
@@ -25,5 +36,49 @@ module VestalVersions
|
|
25
36
|
def initial?
|
26
37
|
number == 1
|
27
38
|
end
|
39
|
+
|
40
|
+
# Returns the original version number that this version was.
|
41
|
+
def original_number
|
42
|
+
if reverted_from.nil?
|
43
|
+
number
|
44
|
+
else
|
45
|
+
version = versioned.versions.at(reverted_from)
|
46
|
+
version.nil? ? 1 : version.original_number
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def restore!
|
51
|
+
model = restore
|
52
|
+
|
53
|
+
if model
|
54
|
+
model.save!
|
55
|
+
destroy
|
56
|
+
end
|
57
|
+
|
58
|
+
model
|
59
|
+
end
|
60
|
+
|
61
|
+
def restore
|
62
|
+
if tag == 'deleted'
|
63
|
+
attrs = modifications
|
64
|
+
|
65
|
+
class_name = attrs['type'].blank? ? versioned_type : attrs['type']
|
66
|
+
klass = class_name.constantize
|
67
|
+
model = klass.new
|
68
|
+
|
69
|
+
attrs.each do |k, v|
|
70
|
+
begin
|
71
|
+
model.send "#{k}=", v
|
72
|
+
rescue NoMethodError
|
73
|
+
logger.warn "Attribute #{k} does not exist on #{class_name} (Version id: #{id})." rescue nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
model
|
78
|
+
else
|
79
|
+
latest_version = self.class.where(:versioned_id => versioned_id, :versioned_type => versioned_type, :tag => 'deleted').first
|
80
|
+
latest_version.nil? ? nil : latest_version.restore
|
81
|
+
end
|
82
|
+
end
|
28
83
|
end
|
29
84
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module VestalVersions
|
2
|
+
# Allows specific versions to be tagged with a custom string. Useful for assigning a more
|
3
|
+
# meaningful value to a version for the purpose of reversion.
|
4
|
+
module VersionTagging
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
# Adds an instance method which allows version tagging through the parent object.
|
8
|
+
|
9
|
+
# Accepts a single string argument which is attached to the version record associated with
|
10
|
+
# the current version number of the parent object.
|
11
|
+
#
|
12
|
+
# Returns the given tag if successful, nil if not. Tags must be unique within the scope of
|
13
|
+
# the parent object. Tag creation will fail if non-unique.
|
14
|
+
#
|
15
|
+
# Version records corresponding to version number 1 are not typically created, but one will
|
16
|
+
# be built to house the given tag if the parent object's current version number is 1.
|
17
|
+
def tag_version(tag)
|
18
|
+
v = versions.at(version) || versions.build(:number => 1)
|
19
|
+
t = v.tag!(tag)
|
20
|
+
versions.reload
|
21
|
+
t
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Instance methods included into VestalVersions::Version to enable version tagging.
|
26
|
+
module VersionMethods
|
27
|
+
extend ActiveSupport::Concern
|
28
|
+
|
29
|
+
included do
|
30
|
+
validates_uniqueness_of :tag, :scope => [:versioned_id, :versioned_type], :if => :validate_tags?
|
31
|
+
end
|
32
|
+
|
33
|
+
# Attaches the given string to the version tag column. If the uniqueness validation fails,
|
34
|
+
# nil is returned. Otherwise, the given string is returned.
|
35
|
+
def tag!(tag)
|
36
|
+
write_attribute(:tag, tag)
|
37
|
+
save ? tag : nil
|
38
|
+
end
|
39
|
+
|
40
|
+
# Simply returns a boolean signifying whether the version instance has a tag value attached.
|
41
|
+
def tagged?
|
42
|
+
!tag.nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
def validate_tags?
|
46
|
+
tagged? && tag != 'deleted'
|
47
|
+
end
|
48
|
+
|
49
|
+
Version.class_eval{ include VersionMethods }
|
50
|
+
end
|
51
|
+
end
|
@@ -1,30 +1,27 @@
|
|
1
1
|
module VestalVersions
|
2
2
|
# Simply adds a flag to determine whether a model class if versioned.
|
3
3
|
module Versioned
|
4
|
-
|
5
|
-
base.class_eval do
|
6
|
-
class << self
|
7
|
-
alias_method_chain :versioned, :flag
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
4
|
+
extend ActiveSupport::Concern
|
11
5
|
|
12
6
|
# Overrides the +versioned+ method to first define the +versioned?+ class method before
|
13
7
|
# deferring to the original +versioned+.
|
14
|
-
|
15
|
-
|
8
|
+
module ClassMethods
|
9
|
+
def versioned(*args)
|
10
|
+
super(*args)
|
16
11
|
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
class << self
|
13
|
+
def versioned?
|
14
|
+
true
|
15
|
+
end
|
20
16
|
end
|
21
17
|
end
|
22
|
-
end
|
23
18
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
19
|
+
# For all ActiveRecord::Base models that do not call the +versioned+ method, the +versioned?+
|
20
|
+
# method will return false.
|
21
|
+
def versioned?
|
22
|
+
false
|
23
|
+
end
|
28
24
|
end
|
25
|
+
|
29
26
|
end
|
30
27
|
end
|
@@ -1,3 +1,21 @@
|
|
1
|
+
# See: https://github.com/rails/rails/issues/11026
|
2
|
+
if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0 && RUBY_VERSION >= "2.0.0"
|
3
|
+
module ActiveRecord
|
4
|
+
module Associations
|
5
|
+
class AssociationProxy
|
6
|
+
def send(method, *args)
|
7
|
+
if proxy_respond_to?(method, true)
|
8
|
+
super
|
9
|
+
else
|
10
|
+
load_target
|
11
|
+
@target.send(method, *args)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
1
19
|
module VestalVersions
|
2
20
|
# An extension module for the +has_many+ association with versions.
|
3
21
|
module Versions
|
@@ -13,16 +31,13 @@ module VestalVersions
|
|
13
31
|
return [] if from_number.nil? || to_number.nil?
|
14
32
|
|
15
33
|
condition = (from_number == to_number) ? to_number : Range.new(*[from_number, to_number].sort)
|
16
|
-
|
17
|
-
:conditions => {:number => condition},
|
18
|
-
:order => "#{aliased_table_name}.number #{(from_number > to_number) ? 'DESC' : 'ASC'}"
|
19
|
-
)
|
34
|
+
where(:number => condition).order("#{table_name}.#{connection.quote_column_name('number')} #{(from_number > to_number) ? 'DESC' : 'ASC'}").to_a
|
20
35
|
end
|
21
36
|
|
22
37
|
# Returns all version records created before the version associated with the given value.
|
23
38
|
def before(value)
|
24
39
|
return [] if (number = number_at(value)).nil?
|
25
|
-
|
40
|
+
where("#{table_name}.#{connection.quote_column_name('number')} < #{number}").to_a
|
26
41
|
end
|
27
42
|
|
28
43
|
# Returns all version records created after the version associated with the given value.
|
@@ -30,7 +45,7 @@ module VestalVersions
|
|
30
45
|
# This is useful for dissociating records during use of the +reset_to!+ method.
|
31
46
|
def after(value)
|
32
47
|
return [] if (number = number_at(value)).nil?
|
33
|
-
|
48
|
+
where("#{table_name}.#{connection.quote_column_name('number')} > #{number}").to_a
|
34
49
|
end
|
35
50
|
|
36
51
|
# Returns a single version associated with the given value. The following formats are valid:
|
@@ -49,7 +64,7 @@ module VestalVersions
|
|
49
64
|
# untouched.
|
50
65
|
def at(value)
|
51
66
|
case value
|
52
|
-
when Date, Time then
|
67
|
+
when Date, Time then where("#{table_name}.created_at <= ?", value.to_time).last
|
53
68
|
when Numeric then find_by_number(value.floor)
|
54
69
|
when String then find_by_tag(value)
|
55
70
|
when Symbol then respond_to?(value) ? send(value) : nil
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
if ENV['COVERAGE']
|
2
|
+
require 'coveralls'
|
3
|
+
Coveralls.wear!
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'vestal_versions'
|
7
|
+
|
8
|
+
require 'bundler'
|
9
|
+
Bundler.require(:test)
|
10
|
+
|
11
|
+
RSpec.configure do |c|
|
12
|
+
c.before(:suite) do
|
13
|
+
CreateSchema.suppress_messages{ CreateSchema.migrate(:up) }
|
14
|
+
end
|
15
|
+
|
16
|
+
c.after(:suite) do
|
17
|
+
FileUtils.rm_rf(File.expand_path('../test.db', __FILE__))
|
18
|
+
end
|
19
|
+
|
20
|
+
c.after(:each) do
|
21
|
+
VestalVersions::Version.config.clear
|
22
|
+
User.prepare_versioned_options({})
|
23
|
+
end
|
24
|
+
|
25
|
+
c.order = 'random'
|
26
|
+
end
|
27
|
+
|
28
|
+
Dir[File.expand_path('../support/*.rb', __FILE__)].each{|f| require f }
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
versioned
|
3
|
+
|
4
|
+
def name
|
5
|
+
[first_name, last_name].compact.join(' ')
|
6
|
+
end
|
7
|
+
|
8
|
+
def name= names
|
9
|
+
self[:first_name], self[:last_name] = names.split(' ', 2)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class DeletedUser < ActiveRecord::Base
|
14
|
+
self.table_name = 'users'
|
15
|
+
versioned :dependent => :tracking
|
16
|
+
end
|
17
|
+
|
18
|
+
class MyCustomVersion < VestalVersions::Version
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
ActiveRecord::Base.establish_connection(
|
2
|
+
:adapter => 'sqlite3',
|
3
|
+
:database => File.expand_path('../../test.db', __FILE__)
|
4
|
+
)
|
5
|
+
|
6
|
+
class CreateSchema < ActiveRecord::Migration
|
7
|
+
def self.up
|
8
|
+
create_table :users, :force => true do |t|
|
9
|
+
t.string :first_name
|
10
|
+
t.string :last_name
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
create_table :versions, :force => true do |t|
|
15
|
+
t.belongs_to :versioned, :polymorphic => true
|
16
|
+
t.belongs_to :user, :polymorphic => true
|
17
|
+
t.string :user_name
|
18
|
+
t.text :modifications
|
19
|
+
t.integer :number
|
20
|
+
t.integer :reverted_from
|
21
|
+
t.string :tag
|
22
|
+
t.timestamps
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VestalVersions::Changes do
|
4
|
+
context "a version's changes" do
|
5
|
+
let(:user){ User.create(:name => 'Steve Richert') }
|
6
|
+
subject{ user.versions.last.changes }
|
7
|
+
|
8
|
+
before do
|
9
|
+
user.update_attribute(:last_name, 'Jobs')
|
10
|
+
end
|
11
|
+
|
12
|
+
it { should be_a(Hash) }
|
13
|
+
it { should_not be_empty }
|
14
|
+
|
15
|
+
it 'has string keys' do
|
16
|
+
subject.keys.each{ |key| key.should be_a(String) }
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'has two-element array values' do
|
20
|
+
subject.values.each do |key|
|
21
|
+
key.should be_a(Array)
|
22
|
+
key.size.should == 2
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'has unique-element values' do
|
27
|
+
subject.values.each{ |v| v.uniq.should == v }
|
28
|
+
end
|
29
|
+
|
30
|
+
it "equals the model's changes" do
|
31
|
+
user.first_name = 'Stephen'
|
32
|
+
model_changes = user.changes
|
33
|
+
user.save
|
34
|
+
changes = user.versions.last.changes
|
35
|
+
|
36
|
+
model_changes.should == changes
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'a hash of changes' do
|
41
|
+
let(:changes){ {'first_name' => ['Steve', 'Stephen']} }
|
42
|
+
let(:other){ {'first_name' => ['Catie', 'Catherine']} }
|
43
|
+
|
44
|
+
it 'properly appends other changes' do
|
45
|
+
expected = {'first_name' => ['Steve', 'Catherine']}
|
46
|
+
|
47
|
+
changes.append_changes(other).should == expected
|
48
|
+
|
49
|
+
changes.append_changes!(other)
|
50
|
+
changes.should == expected
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'properly prepends other changes' do
|
54
|
+
expected = {'first_name' => ['Catie', 'Stephen']}
|
55
|
+
|
56
|
+
changes.prepend_changes(other).should == expected
|
57
|
+
|
58
|
+
changes.prepend_changes!(other)
|
59
|
+
changes.should == expected
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'is reversible' do
|
63
|
+
expected = {'first_name' => ['Stephen', 'Steve']}
|
64
|
+
|
65
|
+
changes.reverse_changes.should == expected
|
66
|
+
|
67
|
+
changes.reverse_changes!
|
68
|
+
changes.should == expected
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'the changes between two versions' do
|
73
|
+
let(:name){ 'Steve Richert' }
|
74
|
+
let(:user){ User.create(:name => name) } # 1
|
75
|
+
let(:version){ user.version }
|
76
|
+
|
77
|
+
before do
|
78
|
+
user.update_attribute(:last_name, 'Jobs') # 2
|
79
|
+
user.update_attribute(:first_name, 'Stephen') # 3
|
80
|
+
user.update_attribute(:last_name, 'Richert') # 4
|
81
|
+
user.update_attribute(:name, name) # 5
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'is a hash' do
|
85
|
+
1.upto(version) do |i|
|
86
|
+
1.upto(version) do |j|
|
87
|
+
user.changes_between(i, j).should be_a(Hash)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'has string keys' do
|
93
|
+
1.upto(version) do |i|
|
94
|
+
1.upto(version) do |j|
|
95
|
+
user.changes_between(i, j).keys.each{ |key| key.should be_a(String) }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'has two-element arrays with unique values' do
|
101
|
+
1.upto(version) do |i|
|
102
|
+
1.upto(version) do |j|
|
103
|
+
user.changes_between(i, j).values.each do |value|
|
104
|
+
value.should be_a(Array)
|
105
|
+
value.size.should == 2
|
106
|
+
value.uniq.should == value
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'is empty between identical versions' do
|
113
|
+
user.changes_between(1, version).should be_empty
|
114
|
+
user.changes_between(version, 1).should be_empty
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'is should reverse with direction' do
|
118
|
+
1.upto(version) do |i|
|
119
|
+
i.upto(version) do |j|
|
120
|
+
up = user.changes_between(i, j)
|
121
|
+
down = user.changes_between(j, i)
|
122
|
+
up.should == down.reverse_changes
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'is empty with invalid arguments' do
|
128
|
+
1.upto(version) do |i|
|
129
|
+
user.changes_between(i, nil).should be_blank
|
130
|
+
user.changes_between(nil, i).should be_blank
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VestalVersions::Conditions do
|
4
|
+
shared_examples_for 'a conditional option' do |option|
|
5
|
+
before do
|
6
|
+
User.class_eval do
|
7
|
+
def true; true; end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'is an array' do
|
12
|
+
User.vestal_versions_options[option].should be_a(Array)
|
13
|
+
User.prepare_versioned_options(option => :true)
|
14
|
+
User.vestal_versions_options[option].should be_a(Array)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'has proc values' do
|
18
|
+
User.prepare_versioned_options(option => :true)
|
19
|
+
User.vestal_versions_options[option].each{|i| i.should be_a(Proc) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it_should_behave_like 'a conditional option', :if
|
24
|
+
it_should_behave_like 'a conditional option', :unless
|
25
|
+
|
26
|
+
context 'a new version' do
|
27
|
+
subject{ User.create(:name => 'Steve Richert') }
|
28
|
+
let(:count){ subject.versions.count }
|
29
|
+
|
30
|
+
before do
|
31
|
+
User.class_eval do
|
32
|
+
def true; true; end
|
33
|
+
def false; false; end
|
34
|
+
end
|
35
|
+
count # memoize this value
|
36
|
+
end
|
37
|
+
|
38
|
+
after do
|
39
|
+
User.prepare_versioned_options(:if => [], :unless => [])
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'with :if conditions' do
|
43
|
+
context 'that pass' do
|
44
|
+
before do
|
45
|
+
User.prepare_versioned_options(:if => [:true])
|
46
|
+
subject.update_attribute(:last_name, 'Jobs')
|
47
|
+
end
|
48
|
+
|
49
|
+
its('versions.count'){ should == count + 1 }
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'that fail' do
|
53
|
+
before do
|
54
|
+
User.prepare_versioned_options(:if => [:false])
|
55
|
+
subject.update_attribute(:last_name, 'Jobs')
|
56
|
+
end
|
57
|
+
|
58
|
+
its('versions.count'){ should == count }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with :unless conditions' do
|
63
|
+
context 'that pass' do
|
64
|
+
before do
|
65
|
+
User.prepare_versioned_options(:unless => [:true])
|
66
|
+
subject.update_attribute(:last_name, 'Jobs')
|
67
|
+
end
|
68
|
+
|
69
|
+
its('versions.count'){ should == count }
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'that fail' do
|
73
|
+
before do
|
74
|
+
User.prepare_versioned_options(:unless => [:false])
|
75
|
+
subject.update_attribute(:last_name, 'Jobs')
|
76
|
+
end
|
77
|
+
|
78
|
+
its('versions.count'){ should == count + 1 }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'with :if and :unless conditions' do
|
83
|
+
context 'that pass' do
|
84
|
+
before do
|
85
|
+
User.prepare_versioned_options(:if => [:true], :unless => [:true])
|
86
|
+
subject.update_attribute(:last_name, 'Jobs')
|
87
|
+
end
|
88
|
+
|
89
|
+
its('versions.count'){ should == count }
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'that fail' do
|
93
|
+
before do
|
94
|
+
User.prepare_versioned_options(:if => [:false], :unless => [:false])
|
95
|
+
subject.update_attribute(:last_name, 'Jobs')
|
96
|
+
end
|
97
|
+
|
98
|
+
its('versions.count'){ should == count }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|