mongoid_versioning 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1541712ab768cbdfe3e5feff620d363e15f26c36
4
+ data.tar.gz: 502a9f2582215937f32dc231a1bfe92bebe4d68f
5
+ SHA512:
6
+ metadata.gz: b36237f72a53a2d07d660c65a3bcfa67e41c9d665b6a4e8616795f070f44be2c06cdc41f6306b02650612afd5407ecc179c615a8e43cfe5f8b6eada0744794f6
7
+ data.tar.gz: 73460dbb43b06e4235288c944ac2d1d62411d726bab2afedeb7fd5136528018f6aaf2b6a4bce9f2ab8201075b507339da1cc13a93c42983c88ff3f4c84d80439
data/.gitignore ADDED
@@ -0,0 +1,34 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ # Gemfile.lock
30
+ # .ruby-version
31
+ # .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ sudo: false
2
+ language: ruby
3
+ cache: bundler
4
+ script: 'bundle exec rake'
5
+ rvm:
6
+ - 2.1.2
7
+ services:
8
+ - mongodb
9
+
10
+ notifications:
11
+ email:
12
+ recipients:
13
+ - tomas.celizna@gmail.com
14
+ on_failure: change
15
+ on_success: never
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongoid_permalink_extension.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,106 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mongoid_versioning (0.0.1)
5
+ mongoid (~> 4.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (4.1.6)
11
+ activesupport (= 4.1.6)
12
+ builder (~> 3.1)
13
+ activesupport (4.1.6)
14
+ i18n (~> 0.6, >= 0.6.9)
15
+ json (~> 1.7, >= 1.7.7)
16
+ minitest (~> 5.1)
17
+ thread_safe (~> 0.1)
18
+ tzinfo (~> 1.1)
19
+ bson (2.3.0)
20
+ builder (3.2.2)
21
+ celluloid (0.16.0)
22
+ timers (~> 4.0.0)
23
+ coderay (1.1.0)
24
+ connection_pool (2.0.0)
25
+ coveralls (0.7.1)
26
+ multi_json (~> 1.3)
27
+ rest-client
28
+ simplecov (>= 0.7)
29
+ term-ansicolor
30
+ thor
31
+ database_cleaner (1.3.0)
32
+ docile (1.1.5)
33
+ ffi (1.9.5)
34
+ formatador (0.2.5)
35
+ guard (2.6.1)
36
+ formatador (>= 0.2.4)
37
+ listen (~> 2.7)
38
+ lumberjack (~> 1.0)
39
+ pry (>= 0.9.12)
40
+ thor (>= 0.18.1)
41
+ guard-minitest (2.3.2)
42
+ guard (~> 2.0)
43
+ minitest (>= 3.0)
44
+ hitimes (1.2.2)
45
+ i18n (0.6.11)
46
+ json (1.8.1)
47
+ listen (2.7.11)
48
+ celluloid (>= 0.15.2)
49
+ rb-fsevent (>= 0.9.3)
50
+ rb-inotify (>= 0.9)
51
+ lumberjack (1.0.9)
52
+ method_source (0.8.2)
53
+ mime-types (2.4.1)
54
+ minitest (5.4.2)
55
+ mongoid (4.0.0)
56
+ activemodel (~> 4.0)
57
+ moped (~> 2.0.0)
58
+ origin (~> 2.1)
59
+ tzinfo (>= 0.3.37)
60
+ moped (2.0.0)
61
+ bson (~> 2.2)
62
+ connection_pool (~> 2.0)
63
+ optionable (~> 0.2.0)
64
+ multi_json (1.10.1)
65
+ netrc (0.7.7)
66
+ optionable (0.2.0)
67
+ origin (2.1.1)
68
+ pry (0.10.1)
69
+ coderay (~> 1.1.0)
70
+ method_source (~> 0.8.1)
71
+ slop (~> 3.4)
72
+ rake (10.3.2)
73
+ rb-fsevent (0.9.4)
74
+ rb-inotify (0.9.5)
75
+ ffi (>= 0.5.0)
76
+ rest-client (1.7.2)
77
+ mime-types (>= 1.16, < 3.0)
78
+ netrc (~> 0.7)
79
+ simplecov (0.9.1)
80
+ docile (~> 1.1.0)
81
+ multi_json (~> 1.0)
82
+ simplecov-html (~> 0.8.0)
83
+ simplecov-html (0.8.0)
84
+ slop (3.6.0)
85
+ term-ansicolor (1.3.0)
86
+ tins (~> 1.0)
87
+ thor (0.19.1)
88
+ thread_safe (0.3.4)
89
+ timers (4.0.1)
90
+ hitimes
91
+ tins (1.3.3)
92
+ tzinfo (1.2.2)
93
+ thread_safe (~> 0.1)
94
+
95
+ PLATFORMS
96
+ ruby
97
+
98
+ DEPENDENCIES
99
+ bundler (~> 1.3)
100
+ coveralls
101
+ database_cleaner
102
+ guard
103
+ guard-minitest
104
+ minitest
105
+ mongoid_versioning!
106
+ rake
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :minitest do
5
+ watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
6
+ watch(%r{^test/.+_test\.rb$})
7
+ watch(%r{^test/test_helper\.rb$}) { 'test' }
8
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Tomas Celizna
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # Mongoid Versioning
2
+
3
+ [![Build Status](https://travis-ci.org/tomasc/mongoid_versioning.svg)](https://travis-ci.org/tomasc/mongoid_versioning) [![Gem Version](https://badge.fury.io/rb/mongoid_versioning.svg)](http://badge.fury.io/rb/mongoid_versioning) [![Coverage Status](https://img.shields.io/coveralls/tomasc/mongoid_versioning.svg)](https://coveralls.io/r/tomasc/mongoid_versioning)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'mongoid_versioning'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```
22
+ $ gem install mongoid_versioning
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ Include the `MongoidVersioning::Versioned` module into your model:
28
+
29
+ ```ruby
30
+ class MyVersionedDocument
31
+ include Mongoid::Document
32
+ include MongoidVersioning::Versioned
33
+ end
34
+ ```
35
+
36
+ Your class will then have:
37
+
38
+ ```ruby
39
+ field :_version, type: Integer
40
+ field :_based_on_version, type: Integer
41
+ ```
42
+
43
+ ### Creating versions
44
+
45
+ To create new version of your document:
46
+
47
+ ```ruby
48
+ doc = MyVersionedDocument.new
49
+ doc.revise # => true
50
+ doc._version # => 1
51
+ doc._based_on_version # => nil
52
+ ```
53
+
54
+ The `#revise` method validates the document and runs `:revise`, `:save` and `:update` callbacks (resp. `:revise`, `:save` and `:create` for new record).
55
+
56
+ ### Retrieving versions
57
+
58
+ To access all previous versions:
59
+
60
+ ```ruby
61
+ doc.previous_versions # => Mongoid::Criteria
62
+ ```
63
+
64
+ These versions are stored in separate collection, by default named by appending `.versions` to name of the source collection. In the above example it is `my_versioned_documents.versions`.
65
+
66
+ To access latest version (as stored in the db):
67
+
68
+ ```ruby
69
+ doc.latest_version # => MyVersionedDocument
70
+ ```
71
+
72
+ To retrieve all versions of a document:
73
+
74
+ ```ruby
75
+ doc.versions # => Array
76
+ ```
77
+
78
+ To retrieve specific version:
79
+
80
+ ```ruby
81
+ doc.version(2) # => MyVersionedDocument
82
+ ```
83
+
84
+ ## Further Reading
85
+
86
+ See [Further Thoughts on How to Track Versions with MongoDB](http://askasya.com/post/revisitversions).
87
+
88
+ ## Contributing
89
+
90
+ 1. Fork it ( https://github.com/tomasc/mongoid_versioning/fork )
91
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
92
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
93
+ 4. Push to the branch (`git push origin my-new-feature`)
94
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ t.pattern = 'test/**/*_test.rb'
7
+ end
8
+
9
+ task :default => :test
@@ -0,0 +1,3 @@
1
+ module MongoidVersioning
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,123 @@
1
+ module MongoidVersioning
2
+ module Versioned
3
+
4
+ def self.included base
5
+ base.extend ClassMethods
6
+ base.class_eval do
7
+ define_model_callbacks :revise, only: [:before, :after]
8
+
9
+ field :_version, type: Integer
10
+ field :_based_on_version, type: Integer
11
+
12
+ collection.database[versions_collection_name].indexes.create(
13
+ { _orig_id: 1, _version: 1 }, { unique: true }
14
+ )
15
+
16
+ after_initialize :revert_id
17
+ end
18
+ end
19
+
20
+ # =====================================================================
21
+
22
+ module ClassMethods
23
+ def versions_collection_name
24
+ [collection.name, 'versions'].join('.')
25
+ end
26
+ end
27
+
28
+ # =====================================================================
29
+
30
+ def revise options={}
31
+ if new_record?
32
+ !_create_revised(options).new_record?
33
+ else
34
+ _update_revised(options)
35
+ end
36
+ end
37
+
38
+ # ---------------------------------------------------------------------
39
+
40
+ def versions
41
+ [latest_version].concat(previous_versions)
42
+ end
43
+
44
+ def latest_version
45
+ self.class.where(_id: id).first
46
+ end
47
+
48
+ def previous_versions
49
+ self.class.with(collection: self.class.versions_collection_name).
50
+ where(_orig_id: id).
51
+ lt(_version: _version).
52
+ desc(:_version)
53
+ end
54
+
55
+ def version v
56
+ return latest_version if v == _version
57
+ previous_versions.where(_version: v).first
58
+ end
59
+
60
+ private # =============================================================
61
+
62
+ def revert_id
63
+ return unless self['_orig_id']
64
+ self._id = self['_orig_id']
65
+ end
66
+
67
+ # these mirror the #create and #save methods from Mongoid
68
+ def _create_revised options={}
69
+ return self if performing_validations?(options) && invalid?(:create)
70
+ result = run_callbacks(:revise) do
71
+ run_callbacks(:save) do
72
+ run_callbacks(:create) do
73
+ _revise
74
+ true
75
+ end
76
+ end
77
+ end
78
+ post_process_persist(result, options) and self
79
+ end
80
+
81
+ def _update_revised options={}
82
+ return false if performing_validations?(options) && invalid?(:update)
83
+ process_flagged_destroys
84
+ result = run_callbacks(:revise) do
85
+ run_callbacks(:save) do
86
+ run_callbacks(:update) do
87
+ _revise
88
+ true
89
+ end
90
+ end
91
+ end
92
+ post_process_persist(result, options) and self
93
+ end
94
+
95
+ def _revise
96
+ previous_version = nil
97
+
98
+ # 1. get the latest version as stored in the db
99
+ if previous_doc = self.class.collection.find({ _id: id }).first
100
+
101
+ previous_version = previous_doc["_version"] || 1
102
+
103
+ previous_doc['_orig_id'] = previous_doc['_id']
104
+ previous_doc['_id'] = BSON::ObjectId.new
105
+ previous_doc['_version'] = previous_version
106
+
107
+ # 2. upsert the latest version into the .versions collection
108
+ self.class.collection.database[self.class.versions_collection_name].where(_orig_id: id, _version: previous_version).upsert(previous_doc)
109
+ end
110
+
111
+ # 3. insert new version
112
+ self._based_on_version = _version || previous_version
113
+ self._version = previous_version.to_i+1
114
+
115
+ self.class.collection.where(_id: id).upsert(self.as_document)
116
+
117
+ # TODO
118
+ # if (result.nModified != 1) {
119
+ # print("Someone got there first, replay flow to try again");
120
+ # }
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,5 @@
1
+ # http://askasya.com/post/revisitversions
2
+
3
+ require "mongoid_versioning/version"
4
+
5
+ require "mongoid_versioning/versioned"
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mongoid_versioning/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mongoid_versioning"
8
+ spec.version = MongoidVersioning::VERSION
9
+ spec.authors = ["Tomas Celizna"]
10
+ spec.email = ["tomas.celizna@gmail.com"]
11
+ spec.description = %q{Versioning Mongoid documents by means of separate collection.}
12
+ spec.summary = %q{Versioning Mongoid documents by means of separate collection.}
13
+ spec.homepage = "https://github.com/tomasc/mongoid_versioning"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "mongoid", "~> 4.0"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "coveralls"
25
+ spec.add_development_dependency "database_cleaner"
26
+ spec.add_development_dependency "guard"
27
+ spec.add_development_dependency "guard-minitest"
28
+ spec.add_development_dependency "minitest"
29
+ spec.add_development_dependency "rake"
30
+ end
@@ -0,0 +1,299 @@
1
+ require 'test_helper'
2
+
3
+ class TestDocument
4
+ include Mongoid::Document
5
+ include MongoidVersioning::Versioned
6
+
7
+ attr_accessor :callbacks
8
+
9
+ field :name, type: String
10
+
11
+ validates :name, presence: true
12
+
13
+ before_revise -> i { i.callbacks = i.callbacks << 'before_revise' }
14
+ after_revise -> i { i.callbacks = i.callbacks << 'after_revise' }
15
+ before_save -> i { i.callbacks = i.callbacks << 'before_save' }
16
+ after_save -> i { i.callbacks = i.callbacks << 'after_save' }
17
+ before_update -> i { i.callbacks = i.callbacks << 'before_update' }
18
+ after_update -> i { i.callbacks = i.callbacks << 'after_update' }
19
+ before_create -> i { i.callbacks = i.callbacks << 'before_create' }
20
+ after_create -> i { i.callbacks = i.callbacks << 'after_create' }
21
+
22
+ def callbacks
23
+ @callbacks ||= []
24
+ end
25
+ end
26
+
27
+ module MongoidVersioning
28
+ describe Versioned do
29
+
30
+ subject { TestDocument.new(name: 'Init') }
31
+
32
+ # =====================================================================
33
+
34
+ describe 'fields' do
35
+ it 'has :_version' do
36
+ subject.must_respond_to :_version
37
+ end
38
+
39
+ it 'has :_based_on_version' do
40
+ subject.must_respond_to :_based_on_version
41
+ end
42
+ end
43
+
44
+ # =====================================================================
45
+
46
+ describe 'class methods' do
47
+ describe '.versions_collection_name' do
48
+ it 'infers name for version collection' do
49
+ subject.class.versions_collection_name.must_equal "#{subject.collection.name}.versions"
50
+ end
51
+ end
52
+ end
53
+
54
+ # =====================================================================
55
+
56
+ describe 'instance methods' do
57
+ describe '#revise' do
58
+
59
+ describe 'when invalid' do
60
+ let(:invalid_document) { TestDocument.new }
61
+
62
+ it 'returns false' do
63
+ invalid_document.revise.must_equal false
64
+ end
65
+ end
66
+
67
+ describe 'new record' do
68
+ before do
69
+ subject.callbacks = []
70
+ subject.revise
71
+
72
+ @current_docs = TestDocument.collection.where({ _id: subject.id })
73
+ @version_docs = TestDocument.collection.database[TestDocument.versions_collection_name].where(_orig_id: subject.id)
74
+ end
75
+
76
+ describe 'callbacks' do
77
+ it 'runs :revise, :save, :create' do
78
+ subject.callbacks.must_equal %w(before_revise before_save before_create after_create after_save after_revise)
79
+ end
80
+ end
81
+
82
+ describe 'default collection' do
83
+ it 'stores the document' do
84
+ @current_docs.first.must_be :present?
85
+ end
86
+ it '_version to 1' do
87
+ @current_docs.first['_version'].must_equal 1
88
+ end
89
+ it '_based_on_version at nil' do
90
+ @current_docs.first['_based_on_version'].must_be_nil
91
+ end
92
+ it 'maintains only one current doc' do
93
+ @current_docs.count.must_equal 1
94
+ end
95
+ end
96
+
97
+ describe 'versions' do
98
+ it 'does not create any versions' do
99
+ @version_docs.count.must_equal 0
100
+ end
101
+ end
102
+ end
103
+
104
+ # ---------------------------------------------------------------------
105
+
106
+ describe 'existing record' do
107
+ let(:existing_document) { TestDocument.create(name: 'Init') }
108
+
109
+ before do
110
+ existing_document.callbacks = []
111
+ existing_document.name = 'Foo'
112
+ existing_document.revise
113
+
114
+ @current_docs = TestDocument.collection.where(_id: existing_document.id)
115
+ @version_docs = TestDocument.collection.database[TestDocument.versions_collection_name].where(_orig_id: existing_document.id)
116
+ end
117
+
118
+ describe 'callbacks' do
119
+ it 'runs :revise, :save, :update' do
120
+ existing_document.callbacks.must_equal %w(before_revise before_save before_update after_update after_save after_revise)
121
+ end
122
+ end
123
+
124
+ describe 'default collection' do
125
+ it 'updates the document' do
126
+ @current_docs.first['name'].must_equal 'Foo'
127
+ end
128
+ it '_version to 2' do
129
+ @current_docs.first['_version'].must_equal 2
130
+ end
131
+ it 'sets the _based_on_version to 1' do
132
+ @current_docs.first['_based_on_version'].must_equal 1
133
+ end
134
+ it 'maintains only one current doc' do
135
+ @current_docs.count.must_equal 1
136
+ end
137
+ end
138
+
139
+ describe 'previous versions' do
140
+ it 'copies the latest version to .versions' do
141
+ @version_docs.first.must_be :present?
142
+ end
143
+
144
+ it '_version to 1' do
145
+ @version_docs.first['_version'].must_equal 1
146
+ end
147
+ it '_version to 1' do
148
+ @version_docs.first['_based_on_version'].must_equal nil
149
+ end
150
+ it 'is not updated' do
151
+ @version_docs.first['name'].wont_equal 'Foo'
152
+ end
153
+ it 'creates only one version' do
154
+ @version_docs.count.must_equal 1
155
+ end
156
+ end
157
+ end
158
+
159
+ # ---------------------------------------------------------------------
160
+
161
+ describe 'subsequent revision' do
162
+ before do
163
+ subject.name = 'v1'
164
+ subject.revise
165
+ subject.name = 'v2'
166
+ subject.revise
167
+ subject.name = 'v3'
168
+ subject.revise
169
+
170
+ @current_docs = TestDocument.collection.where(_id: subject.id)
171
+ @version_docs = TestDocument.collection.database[TestDocument.versions_collection_name].where(_orig_id: subject.id)
172
+ end
173
+
174
+ describe 'default collection' do
175
+ it 'updates the current document in the db' do
176
+ @current_docs.first['name'].must_equal 'v3'
177
+ @current_docs.first['_version'].must_equal 3
178
+ @current_docs.first['_based_on_version'].must_equal 2
179
+ @current_docs.count.must_equal 1
180
+ end
181
+ end
182
+
183
+ describe 'versions' do
184
+ it 'has 2 previous versions' do
185
+ @version_docs.count.must_equal 2
186
+ @version_docs.collect{ |i| i['_version'] }.must_equal [1,2]
187
+ @version_docs.collect{ |i| i['_based_on_version'] }.must_equal [nil,1]
188
+ end
189
+ end
190
+ end
191
+
192
+ # ---------------------------------------------------------------------
193
+
194
+ describe 'revise on previous version' do
195
+ before do
196
+ subject.name = 'v1'
197
+ subject.revise
198
+ subject.name = 'v2'
199
+ subject.revise
200
+ subject.name = 'v3'
201
+ subject.revise
202
+
203
+ @new_version = subject.version(1)
204
+ @new_version.revise
205
+ end
206
+
207
+ it 'saves reverted attribute' do
208
+ @new_version.name.must_equal 'v1'
209
+ end
210
+ it 'updates :_version' do
211
+ @new_version._version.must_equal 4
212
+ end
213
+ it 'updates :_based_on_version' do
214
+ @new_version._based_on_version.must_equal 1
215
+ end
216
+ end
217
+ end
218
+
219
+ # =====================================================================
220
+
221
+ describe 'versions' do
222
+ before do
223
+ subject.name = 'v1'
224
+ subject.revise
225
+ subject.name = 'v2'
226
+ subject.revise
227
+ subject.name = 'v3'
228
+ subject.revise
229
+ subject.name = 'Foo'
230
+ end
231
+
232
+ it 'returns an Array' do
233
+ subject.versions.must_be_kind_of Array
234
+ end
235
+
236
+ # ---------------------------------------------------------------------
237
+
238
+ describe '#previous_versions' do
239
+ it 'returns everything but the latest' do
240
+ subject.previous_versions.map(&:_version).must_equal [2,1]
241
+ end
242
+ it 'correctly reverts document _ids' do
243
+ subject.previous_versions.map(&:id).uniq.must_equal [subject.id]
244
+ end
245
+ end
246
+
247
+ # ---------------------------------------------------------------------
248
+
249
+ describe '#latest_version' do
250
+ it 'includes the latest version as in the database' do
251
+ subject.latest_version.name.wont_equal 'Foo'
252
+ end
253
+ end
254
+
255
+ # ---------------------------------------------------------------------
256
+
257
+ describe '#versions' do
258
+ it 'returns all versions including the latest one' do
259
+ subject.versions.map(&:_version).must_equal [3,2,1]
260
+ end
261
+ end
262
+
263
+
264
+ # ---------------------------------------------------------------------
265
+
266
+ describe '#version' do
267
+ before do
268
+ subject.name = 'v1'
269
+ subject.revise
270
+ subject.name = 'v2'
271
+ subject.revise
272
+ subject.name = 'v3'
273
+ subject.revise
274
+ subject.name = 'Foo'
275
+ end
276
+
277
+ describe 'when latest version' do
278
+ it 'returns the version from db' do
279
+ subject.version(3)._version.must_equal 3
280
+ end
281
+ end
282
+
283
+ describe 'when previous version' do
284
+ it 'returns the version from db' do
285
+ subject.version(1)._version.must_equal 1
286
+ end
287
+ end
288
+
289
+ describe 'when version does not exist' do
290
+ it 'returns nil' do
291
+ subject.version(10).must_be_nil
292
+ end
293
+ end
294
+ end
295
+ end
296
+ end
297
+
298
+ end
299
+ end
@@ -0,0 +1,45 @@
1
+ require 'bundler/setup'
2
+ require 'database_cleaner'
3
+ require 'minitest'
4
+ require 'minitest/autorun'
5
+ require 'minitest/spec'
6
+ require 'mongoid'
7
+
8
+ require 'mongoid_versioning'
9
+
10
+ # ---------------------------------------------------------------------
11
+
12
+ if ENV["CI"]
13
+ require "coveralls"
14
+ Coveralls.wear!
15
+ end
16
+
17
+ ENV["MONGOID_TEST_HOST"] ||= "localhost"
18
+ ENV["MONGOID_TEST_PORT"] ||= "27017"
19
+
20
+ HOST = ENV["MONGOID_TEST_HOST"]
21
+ PORT = ENV["MONGOID_TEST_PORT"].to_i
22
+
23
+ def database_id
24
+ "mongoid_versioning_test"
25
+ end
26
+
27
+ CONFIG = {
28
+ sessions: {
29
+ default: {
30
+ database: database_id,
31
+ hosts: [ "#{HOST}:#{PORT}" ]
32
+ }
33
+ }
34
+ }
35
+
36
+ Mongoid.configure do |config|
37
+ config.load_configuration(CONFIG)
38
+ end
39
+
40
+ DatabaseCleaner.orm = :mongoid
41
+ DatabaseCleaner.strategy = :truncation
42
+
43
+ class MiniTest::Spec
44
+ before(:each) { DatabaseCleaner.clean }
45
+ end
metadata ADDED
@@ -0,0 +1,172 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid_versioning
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tomas Celizna
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mongoid
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: coveralls
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: database_cleaner
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: guard-minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: Versioning Mongoid documents by means of separate collection.
126
+ email:
127
+ - tomas.celizna@gmail.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".travis.yml"
134
+ - Gemfile
135
+ - Gemfile.lock
136
+ - Guardfile
137
+ - LICENSE
138
+ - README.md
139
+ - Rakefile
140
+ - lib/mongoid_versioning.rb
141
+ - lib/mongoid_versioning/version.rb
142
+ - lib/mongoid_versioning/versioned.rb
143
+ - mongoid_versioning.gemspec
144
+ - test/mongoid_versioning/versioned_test.rb
145
+ - test/test_helper.rb
146
+ homepage: https://github.com/tomasc/mongoid_versioning
147
+ licenses:
148
+ - MIT
149
+ metadata: {}
150
+ post_install_message:
151
+ rdoc_options: []
152
+ require_paths:
153
+ - lib
154
+ required_ruby_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ requirements: []
165
+ rubyforge_project:
166
+ rubygems_version: 2.2.2
167
+ signing_key:
168
+ specification_version: 4
169
+ summary: Versioning Mongoid documents by means of separate collection.
170
+ test_files:
171
+ - test/mongoid_versioning/versioned_test.rb
172
+ - test/test_helper.rb