mongo_mapper_versioned 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1 @@
1
+ WORK IN PROGRESS
@@ -0,0 +1,20 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Versioned
4
+ class Version
5
+
6
+ include MongoMapper::Document
7
+
8
+ # stores id of versioned document
9
+ key :versioned_id, ObjectId
10
+
11
+ # stores version number
12
+ key :version_number, Integer
13
+
14
+ # stores versioned attributes
15
+ key :data, Hash
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Versioned
5
+ Version = '0.1'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,60 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Versioned
4
+
5
+ module ClassMethods
6
+ def versioned(options={})
7
+ configuration = { :ignored_keys => %w(_id version_number created_at updated_at creator_id updater_id) }
8
+ configuration.update(options) if options.is_a?(Hash)
9
+
10
+ key :version_number, Integer, :default => 1, :index => true
11
+ many :versions, :class => MongoMapper::Plugins::Versioned::Version, :foreign_key => :versioned_id, :dependent => :destroy, :order => :version_number.asc
12
+
13
+ after_create :create_version
14
+ before_update :create_version, :if => Proc.new{ |doc| doc.should_create_version? }
15
+
16
+ define_method "ignored_keys" do
17
+ configuration[:ignored_keys]
18
+ end
19
+ end
20
+ end
21
+
22
+
23
+
24
+ module InstanceMethods
25
+
26
+ def create_version
27
+ self.version_number = version_count + 1 if (version_count > 0)
28
+ self.versions << current_version
29
+ end
30
+
31
+ def revert_to(target_version_number)
32
+ if target_version = version_at(target_version_number)
33
+ self.attributes = target_version.data
34
+ self.version_number = target_version.version_number
35
+ end
36
+ end
37
+
38
+ def version_count
39
+ self.versions.count
40
+ end
41
+
42
+ def current_version
43
+ Version.new(:data => self.attributes.slice!(*ignored_keys), :versioned_id => self.id, :version_number => self.version_number)
44
+ end
45
+
46
+ def version_at(target_version_number)
47
+ versions.where(:version_number => target_version_number).first
48
+ end
49
+
50
+ # this method might be overwritten
51
+ # by something more sophisticated (esp. in case of EmbeddedDocuments)
52
+ def should_create_version?
53
+ changes.slice!(*ignored_keys).size > 0
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,152 @@
1
+ require 'test_helper'
2
+
3
+
4
+
5
+ # CLASS SETUP
6
+
7
+ class VersionedDoc
8
+ include MongoMapper::Document
9
+ plugin MongoMapper::Plugins::Versioned
10
+
11
+ key :title, String
12
+ key :body, String
13
+
14
+ versioned :ignored_keys => ['body']
15
+ end
16
+
17
+
18
+ # TESTS
19
+
20
+ class VersionedTest < ActiveSupport::TestCase
21
+
22
+ context "by default" do
23
+ setup do
24
+ @doc = VersionedDoc.new
25
+ end
26
+ should "be on version 1" do
27
+ assert_equal 1, @doc.version_number
28
+ end
29
+ should "have 0 versions" do
30
+ assert_equal 0, @doc.version_count
31
+ end
32
+ end
33
+
34
+ context "when created" do
35
+ setup do
36
+ @doc = VersionedDoc.create(:title => "Famfula")
37
+ end
38
+ should "be on version 1" do
39
+ assert_equal 1, @doc.version_number
40
+ end
41
+ should "have 1 (initial) version" do
42
+ assert_equal 1, @doc.version_count
43
+ end
44
+
45
+ context "when saved with no changes" do
46
+ setup do
47
+ @version_count = @doc.version_count
48
+ @version_number = @doc.version_number
49
+ @doc.save
50
+ end
51
+ should "still be at version 1" do
52
+ assert_equal @version_number, @doc.version_number
53
+ end
54
+ should "not create new version" do
55
+ assert_equal @version_count, @doc.version_count
56
+ end
57
+ end
58
+
59
+ context "after a change" do
60
+ setup do
61
+ @version_count = @doc.version_count
62
+ @version_number = @doc.version_number
63
+ @title = @doc.title
64
+ @doc.update_attributes(:title => "Krabaty")
65
+ end
66
+ should "increase number of versions" do
67
+ assert_equal @version_count+1, @doc.version_count
68
+ end
69
+ should "increase version number" do
70
+ assert_equal @version_number+1, @doc.version_number
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ context "when reverting" do
77
+ setup do
78
+ @doc = VersionedDoc.create(:title => "Vaclav", :body => "Kroupa")
79
+ @doc.update_attributes(:title => "Slavoj", :body => "Zizek")
80
+ @doc.update_attributes(:title => "Karel", :body => "Martens")
81
+ @doc.update_attributes(:title => "Keren", :body => "Cytter")
82
+ @doc.update_attributes(:title => "Jon", :body => "Arnett")
83
+ end
84
+
85
+ context "to first version" do
86
+ setup do
87
+ @doc.revert_to(1)
88
+ end
89
+ should "be at version 1" do
90
+ assert_equal 1, @doc.version_number
91
+ end
92
+ should "have correct attributes" do
93
+ assert_equal "Vaclav", @doc.title
94
+ end
95
+ should "not revert ignored attributes" do
96
+ assert_equal "Arnett", @doc.body
97
+ end
98
+ should "not create new version" do
99
+ assert_equal 5, @doc.version_count
100
+ end
101
+ end
102
+
103
+ context "to version 2" do
104
+ setup do
105
+ @doc.revert_to(2)
106
+ end
107
+ should "be at version 2" do
108
+ assert_equal 2, @doc.version_number
109
+ end
110
+ should "have correct attributes" do
111
+ assert_equal "Slavoj", @doc.title
112
+ end
113
+ should "not revert ignored attributes" do
114
+ assert_equal "Arnett", @doc.body
115
+ end
116
+ should "not create new version" do
117
+ assert_equal 5, @doc.version_count
118
+ end
119
+ context "after save" do
120
+ setup do
121
+ @doc.save
122
+ end
123
+ should "be at version 6" do
124
+ assert_equal 6, @doc.version_number
125
+ end
126
+ should "have 6 versions" do
127
+ assert_equal 6, @doc.version_count
128
+ end
129
+ end
130
+
131
+ end
132
+
133
+ context "to version 5" do
134
+ setup do
135
+ @doc.revert_to(5)
136
+ end
137
+ should "be at version 5" do
138
+ assert_equal 5, @doc.version_number
139
+ end
140
+ should "have correct attributes" do
141
+ assert_equal "Jon", @doc.title
142
+ end
143
+ should "not revert ignored attributes" do
144
+ assert_equal "Arnett", @doc.body
145
+ end
146
+ should "not create new version" do
147
+ assert_equal 5, @doc.version_count
148
+ end
149
+ end
150
+
151
+ end
152
+ end
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
3
+
4
+ require 'mongo_mapper'
5
+ require 'mongo_mapper/plugins/versioned'
6
+ require 'mongo_mapper/plugins/models/version'
7
+ require 'test/unit'
8
+ require 'shoulda'
9
+ require 'ruby-debug'
10
+
11
+
12
+
13
+ class ActiveSupport::TestCase
14
+
15
+ # Drop all collections after each test case.
16
+ def teardown
17
+ MongoMapper.database.collections.each { |coll| coll.remove }
18
+ end
19
+
20
+ # Make sure that each test case has a teardown
21
+ # method to clear the db after each test.
22
+ def inherited(base)
23
+ base.define_method teardown do
24
+ super
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+
31
+
32
+ MongoMapper.connection = Mongo::Connection.new('127.0.0.1', 27017)
33
+ MongoMapper.database = "mongo_mapper_versioned"
34
+ MongoMapper.database.collections.each { |c| c.drop_indexes }
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongo_mapper_versioned
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ version: "0.1"
10
+ platform: ruby
11
+ authors:
12
+ - Tomas Celizna
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-12-22 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ prerelease: false
22
+ version_requirements: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ hash: 3
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ requirement: *id001
32
+ name: mongo_mapper
33
+ type: :runtime
34
+ - !ruby/object:Gem::Dependency
35
+ prerelease: false
36
+ version_requirements: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ hash: 3
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ requirement: *id002
46
+ name: rake
47
+ type: :development
48
+ description:
49
+ email:
50
+ - tomas.celizna@gmail.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - lib/mongo_mapper/plugins/models/version.rb
59
+ - lib/mongo_mapper/plugins/version.rb
60
+ - lib/mongo_mapper/plugins/versioned.rb
61
+ - test/mongo_mapper_versioned_test.rb
62
+ - test/test_helper.rb
63
+ - README.rdoc
64
+ has_rdoc: true
65
+ homepage: http://github.com/tomasc/mongo_mapper_versioned
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options: []
70
+
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ hash: 3
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ hash: 3
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ requirements: []
92
+
93
+ rubyforge_project:
94
+ rubygems_version: 1.3.7
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: Versioned plugin for MongoMapper
98
+ test_files: []
99
+