vestal_versions 0.8.3 → 1.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 +20 -2
- data/README.rdoc +110 -8
- data/Rakefile +14 -3
- data/VERSION +1 -1
- data/lib/vestal_versions.rb +93 -143
- data/lib/vestal_versions/changes.rb +125 -0
- data/lib/vestal_versions/conditions.rb +69 -0
- data/lib/vestal_versions/configuration.rb +40 -0
- data/lib/vestal_versions/control.rb +175 -0
- data/lib/vestal_versions/creation.rb +85 -0
- data/lib/vestal_versions/options.rb +42 -0
- data/lib/vestal_versions/reload.rb +23 -0
- data/lib/vestal_versions/reset.rb +56 -0
- data/lib/vestal_versions/reversion.rb +69 -0
- data/lib/vestal_versions/tagging.rb +50 -0
- data/lib/vestal_versions/users.rb +57 -0
- data/lib/vestal_versions/version.rb +32 -0
- data/lib/vestal_versions/versioned.rb +30 -0
- data/lib/vestal_versions/versions.rb +74 -0
- data/rails/init.rb +1 -0
- data/rails_generators/vestal_versions/templates/initializer.rb +9 -0
- data/{generators/vestal_versions_migration → rails_generators/vestal_versions}/templates/migration.rb +9 -2
- data/rails_generators/vestal_versions/vestal_versions_generator.rb +10 -0
- data/test/changes_test.rb +154 -13
- data/test/conditions_test.rb +137 -0
- data/test/configuration_test.rb +39 -0
- data/test/control_test.rb +152 -0
- data/test/creation_test.rb +70 -30
- data/test/options_test.rb +52 -0
- data/test/reload_test.rb +19 -0
- data/test/reset_test.rb +107 -0
- data/test/{revert_test.rb → reversion_test.rb} +8 -22
- data/test/schema.rb +4 -1
- data/test/tagging_test.rb +38 -0
- data/test/test_helper.rb +2 -1
- data/test/users_test.rb +25 -0
- data/test/version_test.rb +43 -0
- data/test/versioned_test.rb +18 -0
- data/test/versions_test.rb +172 -0
- data/vestal_versions.gemspec +61 -21
- metadata +75 -15
- data/generators/vestal_versions_migration/vestal_versions_migration_generator.rb +0 -11
- data/init.rb +0 -1
- data/lib/version.rb +0 -14
- data/test/between_test.rb +0 -58
- data/test/comparable_test.rb +0 -35
- data/test/latest_changes_test.rb +0 -42
data/test/creation_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'test_helper'
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
3
|
class CreationTest < Test::Unit::TestCase
|
4
4
|
context 'The number of versions' do
|
@@ -8,8 +8,8 @@ class CreationTest < Test::Unit::TestCase
|
|
8
8
|
@count = @user.versions.count
|
9
9
|
end
|
10
10
|
|
11
|
-
should 'initially equal
|
12
|
-
assert_equal
|
11
|
+
should 'initially equal zero' do
|
12
|
+
assert_equal 0, @count
|
13
13
|
end
|
14
14
|
|
15
15
|
should 'not increase when no changes are made in an update' do
|
@@ -22,48 +22,88 @@ class CreationTest < Test::Unit::TestCase
|
|
22
22
|
assert_equal @count, @user.versions.count
|
23
23
|
end
|
24
24
|
|
25
|
-
should 'not increase when reverting to the current version' do
|
26
|
-
@user.revert_to!(@user.version)
|
27
|
-
assert_equal @count, @user.versions.count
|
28
|
-
end
|
29
|
-
|
30
25
|
context 'after an update' do
|
31
26
|
setup do
|
32
|
-
@
|
33
|
-
@name = 'Steve Jobs'
|
34
|
-
@user.update_attribute(:name, @name)
|
35
|
-
@count = @user.versions.count
|
27
|
+
@user.update_attribute(:last_name, 'Jobs')
|
36
28
|
end
|
37
29
|
|
38
30
|
should 'increase by one' do
|
39
|
-
assert_equal @
|
31
|
+
assert_equal @count + 1, @user.versions.count
|
40
32
|
end
|
33
|
+
end
|
41
34
|
|
42
|
-
|
43
|
-
|
44
|
-
|
35
|
+
context 'after multiple updates' do
|
36
|
+
setup do
|
37
|
+
@user.update_attribute(:last_name, 'Jobs')
|
38
|
+
@user.update_attribute(:last_name, 'Richert')
|
45
39
|
end
|
46
40
|
|
47
|
-
should '
|
48
|
-
@user.
|
49
|
-
assert_equal @count, @user.versions.count
|
50
|
-
@user.save
|
51
|
-
assert_not_equal @count, @user.versions.count
|
41
|
+
should 'increase multiple times' do
|
42
|
+
assert_operator @count + 1, :<, @user.versions.count
|
52
43
|
end
|
53
44
|
end
|
45
|
+
end
|
54
46
|
|
55
|
-
|
47
|
+
context "A created version's changes" do
|
48
|
+
setup do
|
49
|
+
@user = User.create(:name => 'Steve Richert')
|
50
|
+
@user.update_attribute(:last_name, 'Jobs')
|
51
|
+
end
|
52
|
+
|
53
|
+
should 'not contain Rails timestamps' do
|
54
|
+
%w(created_at created_on updated_at updated_on).each do |timestamp|
|
55
|
+
assert_does_not_contain @user.versions.last.changes.keys, timestamp
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context '(with :only options)' do
|
60
|
+
setup do
|
61
|
+
@only = %w(first_name)
|
62
|
+
User.prepare_versioned_options(:only => @only)
|
63
|
+
@user.update_attribute(:name, 'Steven Tyler')
|
64
|
+
end
|
65
|
+
|
66
|
+
should 'only contain the specified columns' do
|
67
|
+
assert_equal @only, @user.versions.last.changes.keys
|
68
|
+
end
|
69
|
+
|
70
|
+
teardown do
|
71
|
+
User.prepare_versioned_options(:only => nil)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context '(with :except options)' do
|
56
76
|
setup do
|
57
|
-
@
|
58
|
-
|
59
|
-
@user.update_attribute(:name,
|
60
|
-
|
61
|
-
|
77
|
+
@except = %w(first_name)
|
78
|
+
User.prepare_versioned_options(:except => @except)
|
79
|
+
@user.update_attribute(:name, 'Steven Tyler')
|
80
|
+
end
|
81
|
+
|
82
|
+
should 'not contain the specified columns' do
|
83
|
+
@except.each do |column|
|
84
|
+
assert_does_not_contain @user.versions.last.changes.keys, column
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
teardown do
|
89
|
+
User.prepare_versioned_options(:except => nil)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context '(with both :only and :except options)' do
|
94
|
+
setup do
|
95
|
+
@only = %w(first_name)
|
96
|
+
@except = @only
|
97
|
+
User.prepare_versioned_options(:only => @only, :except => @except)
|
98
|
+
@user.update_attribute(:name, 'Steven Tyler')
|
99
|
+
end
|
100
|
+
|
101
|
+
should 'respect only the :only options' do
|
102
|
+
assert_equal @only, @user.versions.last.changes.keys
|
62
103
|
end
|
63
104
|
|
64
|
-
|
65
|
-
|
66
|
-
assert_equal @count, @user.versions.count
|
105
|
+
teardown do
|
106
|
+
User.prepare_versioned_options(:only => nil, :except => nil)
|
67
107
|
end
|
68
108
|
end
|
69
109
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class OptionsTest < Test::Unit::TestCase
|
4
|
+
context 'Configuration options' do
|
5
|
+
setup do
|
6
|
+
@options = {:dependent => :destroy}
|
7
|
+
@configuration = {:class_name => 'MyCustomVersion'}
|
8
|
+
|
9
|
+
VestalVersions::Configuration.options.clear
|
10
|
+
@configuration.each{|k,v| VestalVersions::Configuration.send("#{k}=", v) }
|
11
|
+
|
12
|
+
@prepared_options = User.prepare_versioned_options(@options.dup)
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'have symbolized keys' do
|
16
|
+
assert User.vestal_versions_options.keys.all?{|k| k.is_a?(Symbol) }
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'combine class-level and global configuration options' do
|
20
|
+
combined_keys = (@options.keys + @configuration.keys).map(&:to_sym).uniq
|
21
|
+
combined_options = @configuration.symbolize_keys.merge(@options.symbolize_keys)
|
22
|
+
assert_equal @prepared_options.slice(*combined_keys), combined_options
|
23
|
+
end
|
24
|
+
|
25
|
+
teardown do
|
26
|
+
VestalVersions::Configuration.options.clear
|
27
|
+
User.prepare_versioned_options({})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'Given no options, configuration options' do
|
32
|
+
setup do
|
33
|
+
@prepared_options = User.prepare_versioned_options({})
|
34
|
+
end
|
35
|
+
|
36
|
+
should 'default to "VestalVersions::Version" for :class_name' do
|
37
|
+
assert_equal 'VestalVersions::Version', @prepared_options[:class_name]
|
38
|
+
end
|
39
|
+
|
40
|
+
should 'default to :delete_all for :dependent' do
|
41
|
+
assert_equal :delete_all, @prepared_options[:dependent]
|
42
|
+
end
|
43
|
+
|
44
|
+
should 'force the :as option value to :versioned' do
|
45
|
+
assert_equal :versioned, @prepared_options[:as]
|
46
|
+
end
|
47
|
+
|
48
|
+
should 'default to [VestalVersions::Versions] for :extend' do
|
49
|
+
assert_equal [VestalVersions::Versions], @prepared_options[:extend]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/test/reload_test.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class ReloadTest < Test::Unit::TestCase
|
4
|
+
context 'Reloading a reverted model' do
|
5
|
+
setup do
|
6
|
+
@user = User.create(:name => 'Steve Richert')
|
7
|
+
first_version = @user.version
|
8
|
+
@user.update_attribute(:last_name, 'Jobs')
|
9
|
+
@last_version = @user.version
|
10
|
+
@user.revert_to(first_version)
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'reset the version number to the most recent version' do
|
14
|
+
assert_not_equal @last_version, @user.version
|
15
|
+
@user.reload
|
16
|
+
assert_equal @last_version, @user.version
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/test/reset_test.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class ResetTest < Test::Unit::TestCase
|
4
|
+
context 'Resetting a model' do
|
5
|
+
setup do
|
6
|
+
@user, @versions = User.new, []
|
7
|
+
@names = ['Steve Richert', 'Stephen Richert', 'Stephen Jobs', 'Steve Jobs']
|
8
|
+
@names.each do |name|
|
9
|
+
@user.update_attribute(:name, name)
|
10
|
+
@versions << @user.version
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
should "properly revert the model's attributes" do
|
15
|
+
@versions.reverse.each_with_index do |version, i|
|
16
|
+
@user.reset_to!(version)
|
17
|
+
assert_equal @names.reverse[i], @user.name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
should 'dissociate all versions after the target' do
|
22
|
+
@versions.reverse.each_with_index do |version, i|
|
23
|
+
@user.reset_to!(version)
|
24
|
+
assert_equal 0, @user.versions(true).after(version).count
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with the :dependent option as :delete_all' do
|
29
|
+
setup do
|
30
|
+
User.prepare_versioned_options(:dependent => :delete_all)
|
31
|
+
end
|
32
|
+
|
33
|
+
should 'delete all versions after the target version' do
|
34
|
+
@versions.reverse.each_with_index do |version, i|
|
35
|
+
later_versions = @user.versions.after(version)
|
36
|
+
@user.reset_to!(version)
|
37
|
+
later_versions.each do |later_version|
|
38
|
+
assert_raise ActiveRecord::RecordNotFound do
|
39
|
+
later_version.reload
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
should 'not destroy all versions after the target version' do
|
46
|
+
VestalVersions::Version.any_instance.stubs(:destroy).raises(RuntimeError)
|
47
|
+
@versions.reverse.each_with_index do |version, i|
|
48
|
+
assert_nothing_raised do
|
49
|
+
@user.reset_to!(version)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'with the :dependent option as :destroy' do
|
56
|
+
setup do
|
57
|
+
User.prepare_versioned_options(:dependent => :destroy)
|
58
|
+
end
|
59
|
+
|
60
|
+
should 'delete all versions after the target version' do
|
61
|
+
@versions.reverse.each_with_index do |version, i|
|
62
|
+
later_versions = @user.versions.after(version)
|
63
|
+
@user.reset_to!(version)
|
64
|
+
later_versions.each do |later_version|
|
65
|
+
assert_raise ActiveRecord::RecordNotFound do
|
66
|
+
later_version.reload
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
should 'destroy all versions after the target version' do
|
73
|
+
VestalVersions::Version.any_instance.stubs(:destroy).raises(RuntimeError)
|
74
|
+
@versions.reverse.each_with_index do |version, i|
|
75
|
+
later_versions = @user.versions.after(version)
|
76
|
+
if later_versions.empty?
|
77
|
+
assert_nothing_raised do
|
78
|
+
@user.reset_to!(version)
|
79
|
+
end
|
80
|
+
else
|
81
|
+
assert_raise RuntimeError do
|
82
|
+
@user.reset_to!(version)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'with the :dependent option as :nullify' do
|
90
|
+
setup do
|
91
|
+
User.prepare_versioned_options(:dependent => :nullify)
|
92
|
+
end
|
93
|
+
|
94
|
+
should 'leave all versions after the target version' do
|
95
|
+
@versions.reverse.each_with_index do |version, i|
|
96
|
+
later_versions = @user.versions.after(version)
|
97
|
+
@user.reset_to!(version)
|
98
|
+
later_versions.each do |later_version|
|
99
|
+
assert_nothing_raised do
|
100
|
+
later_version.reload
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'test_helper'
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
-
class
|
3
|
+
class ReversionTest < Test::Unit::TestCase
|
4
4
|
context 'A model reversion' do
|
5
5
|
setup do
|
6
6
|
@user, @attributes, @times = User.new, {}, {}
|
@@ -10,19 +10,13 @@ class RevertTest < Test::Unit::TestCase
|
|
10
10
|
@user.update_attribute(:name, name)
|
11
11
|
@attributes[@user.version] = @user.attributes
|
12
12
|
time += 1.hour
|
13
|
-
@user.versions.last.
|
13
|
+
@user.versions.last.try(:update_attribute, :created_at, time)
|
14
14
|
@times[@user.version] = time
|
15
15
|
end
|
16
16
|
@user.reload.versions.reload
|
17
17
|
@first_version, @last_version = @attributes.keys.min, @attributes.keys.max
|
18
18
|
end
|
19
19
|
|
20
|
-
should 'do nothing for a non-existent version' do
|
21
|
-
attributes = @user.attributes
|
22
|
-
@user.revert_to!(nil)
|
23
|
-
assert_equal attributes, @user.attributes
|
24
|
-
end
|
25
|
-
|
26
20
|
should 'return the new version number' do
|
27
21
|
new_version = @user.revert_to(@first_version)
|
28
22
|
assert_equal @first_version, new_version
|
@@ -34,20 +28,12 @@ class RevertTest < Test::Unit::TestCase
|
|
34
28
|
assert_not_equal current_version, @user.version
|
35
29
|
end
|
36
30
|
|
37
|
-
should '
|
38
|
-
@user.revert_to(:first)
|
39
|
-
assert_equal @first_version, @user.version
|
40
|
-
end
|
41
|
-
|
42
|
-
should 'be able to target the last version' do
|
43
|
-
@user.revert_to(:last)
|
44
|
-
assert_equal @last_version, @user.version
|
45
|
-
end
|
46
|
-
|
47
|
-
should 'do nothing for a non-existent method name' do
|
31
|
+
should 'do nothing for a invalid argument' do
|
48
32
|
current_version = @user.version
|
49
|
-
|
50
|
-
|
33
|
+
[nil, :bogus, 'bogus', (1..2)].each do |invalid|
|
34
|
+
@user.revert_to(invalid)
|
35
|
+
assert_equal current_version, @user.version
|
36
|
+
end
|
51
37
|
end
|
52
38
|
|
53
39
|
should 'be able to target a version number' do
|
data/test/schema.rb
CHANGED
@@ -13,9 +13,12 @@ class CreateSchema < ActiveRecord::Migration
|
|
13
13
|
|
14
14
|
create_table :versions, :force => true do |t|
|
15
15
|
t.belongs_to :versioned, :polymorphic => true
|
16
|
+
t.belongs_to :user, :polymorphic => true
|
17
|
+
t.string :user_name
|
16
18
|
t.text :changes
|
17
19
|
t.integer :number
|
18
|
-
t.
|
20
|
+
t.string :tag
|
21
|
+
t.timestamps
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class TaggingTest < Test::Unit::TestCase
|
4
|
+
context 'Tagging a version' do
|
5
|
+
setup do
|
6
|
+
@user = User.create(:name => 'Steve Richert')
|
7
|
+
@user.update_attribute(:last_name, 'Jobs')
|
8
|
+
end
|
9
|
+
|
10
|
+
should "update the version record's tag column" do
|
11
|
+
tag_name = 'TAG'
|
12
|
+
assert_not_equal tag_name, @user.versions.last.tag
|
13
|
+
@user.tag_version(tag_name)
|
14
|
+
assert_equal tag_name, @user.versions.last.tag
|
15
|
+
end
|
16
|
+
|
17
|
+
should 'create a version record for an initial version' do
|
18
|
+
@user.revert_to(1)
|
19
|
+
assert_nil @user.versions.at(1)
|
20
|
+
@user.tag_version('TAG')
|
21
|
+
assert_not_nil @user.versions.at(1)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'A tagged version' do
|
26
|
+
setup do
|
27
|
+
user = User.create(:name => 'Steve Richert')
|
28
|
+
user.update_attribute(:last_name, 'Jobs')
|
29
|
+
user.tag_version('TAG')
|
30
|
+
@version = user.versions.last
|
31
|
+
end
|
32
|
+
|
33
|
+
should 'return true for the "tagged?" method' do
|
34
|
+
assert @version.respond_to?(:tagged?)
|
35
|
+
assert_equal true, @version.tagged?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/test/test_helper.rb
CHANGED
data/test/users_test.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class UsersTest < Test::Unit::TestCase
|
4
|
+
context 'The user responsible for an update' do
|
5
|
+
setup do
|
6
|
+
@updated_by = User.create(:name => 'Steve Jobs')
|
7
|
+
@user = User.create(:name => 'Steve Richert')
|
8
|
+
end
|
9
|
+
|
10
|
+
should 'default to nil' do
|
11
|
+
@user.update_attributes(:first_name => 'Stephen')
|
12
|
+
assert_nil @user.versions.last.user
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'accept and return an ActiveRecord user' do
|
16
|
+
@user.update_attributes(:first_name => 'Stephen', :updated_by => @updated_by)
|
17
|
+
assert_equal @updated_by, @user.versions.last.user
|
18
|
+
end
|
19
|
+
|
20
|
+
should 'accept and return a string user name' do
|
21
|
+
@user.update_attributes(:first_name => 'Stephen', :updated_by => @updated_by.name)
|
22
|
+
assert_equal @updated_by.name, @user.versions.last.user
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|