versioned 0.1.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/README.rdoc ADDED
@@ -0,0 +1,51 @@
1
+ = versioned
2
+
3
+ Simple versioning for MongoMapper
4
+
5
+ = installation
6
+
7
+ The versioned gem is hosted on gemcutter.org:
8
+
9
+ * gem install versioned
10
+
11
+ = usage
12
+
13
+ class Doc
14
+ include MongoMapper::Document
15
+ include Versioned
16
+ key :title, String
17
+ end
18
+
19
+ @doc = Doc.create(:title=>"v1")
20
+ @doc.title = "v2"
21
+ @doc.save
22
+
23
+ @doc.revert
24
+
25
+ puts @doc.title
26
+ => v1
27
+
28
+ @doc.title = "v3"
29
+ @doc.save
30
+ @doc.version
31
+ => 3
32
+
33
+ @doc.retrieve_version 2
34
+ puts @doc.title
35
+ => "v2"
36
+
37
+ @doc = Doc.find(@doc.id)
38
+ @doc.title
39
+ => "v3"
40
+ @doc.version
41
+ => 3
42
+
43
+ == Note on Patches/Pull Requests
44
+
45
+ * Fork the project.
46
+ * Make your feature addition or bug fix.
47
+ * Add tests for it. This is important so I don't break it in a
48
+ future version unintentionally.
49
+ * Commit, do not mess with rakefile, version, or history.
50
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
51
+ * Send me a pull request. Bonus points for topic branches.
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |g|
9
+ g.name = 'versioned'
10
+ g.summary = %(Versioning for MongoMapper)
11
+ g.description = %(Versioning for MongoMapper)
12
+ g.email = 'signalstatic@gmail.com'
13
+ g.homepage = 'http://github.com/twoism/versioned'
14
+ g.authors = %w(twoism toastyapps jacqui)
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts 'Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com'
19
+ end
20
+
21
+ Rake::TestTask.new do |t|
22
+ t.libs = %w(test)
23
+ t.pattern = 'test/**/*_test.rb'
24
+ end
25
+
26
+ task :default => :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/version.rb ADDED
@@ -0,0 +1,20 @@
1
+ class Version
2
+ include MongoMapper::Document
3
+ include Comparable
4
+
5
+ key :number, Integer
6
+ key :versioned_type, String
7
+ key :versioned_id, ObjectId
8
+ key :changes, Hash
9
+ timestamps!
10
+
11
+ belongs_to :versioned, :polymorphic => true
12
+ def changes
13
+ read_attribute(:changes)
14
+ end
15
+ alias_attribute :version, :number
16
+
17
+ def <=>(other)
18
+ number <=> other.number
19
+ end
20
+ end
data/lib/versioned.rb ADDED
@@ -0,0 +1,163 @@
1
+ require 'version'
2
+
3
+ module Versioned
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ base.class_eval do
7
+ versioned
8
+ end
9
+ end
10
+
11
+ module ClassMethods
12
+ def versioned(options = {})
13
+ class_inheritable_accessor :version_only_columns
14
+ self.version_only_columns = Array(options[:only]).map(&:to_s).uniq if options[:only]
15
+ class_inheritable_accessor :version_except_columns
16
+ self.version_except_columns = Array(options[:except]).map(&:to_s).uniq if options[:except]
17
+
18
+ many :versions, :as => :versioned, :order => 'number ASC', :dependent => :delete_all do
19
+ def between(from, to)
20
+ from_number, to_number = number_at(from), number_at(to)
21
+ return [] if from_number.nil? || to_number.nil?
22
+ condition = (from_number == to_number) ? to_number : Range.new(*[from_number, to_number].sort)
23
+ if condition.is_a?(Range)
24
+ conditions = {'$gte' => condition.first, '$lte' => condition.last}
25
+ else
26
+ conditions = condition
27
+ end
28
+ find(:all,
29
+ :number => conditions,
30
+ :order => "number #{(from_number > to_number) ? 'DESC' : 'ASC'}"
31
+ )
32
+ end
33
+
34
+ def at(value)
35
+ case value
36
+ when Version then value
37
+ when Numeric then find_by_number(value.floor)
38
+ when Symbol then respond_to?(value) ? send(value) : nil
39
+ when Date, Time then last(:created_at => {'$lte' => value.to_time})
40
+ end
41
+ end
42
+
43
+ def number_at(value)
44
+ case value
45
+ when Version then value.number
46
+ when Numeric then value.floor
47
+ when Symbol, Date, Time then at(value).try(:number)
48
+ end
49
+ end
50
+ end
51
+
52
+ after_create :create_initial_version
53
+ after_update :create_initial_version, :if => :needs_initial_version?
54
+ after_update :create_version, :if => :needs_version?
55
+
56
+ include InstanceMethods
57
+ alias_method_chain :reload, :versions
58
+ end
59
+ end
60
+
61
+ module InstanceMethods
62
+ private
63
+ def versioned_columns
64
+ case
65
+ when version_only_columns then self.class.keys.keys & version_only_columns
66
+ when version_except_columns then self.class.keys.keys - version_except_columns
67
+ else self.class.keys.keys
68
+ end - %w(created_at created_on updated_at updated_on)
69
+ end
70
+
71
+ def needs_initial_version?
72
+ versions.empty?
73
+ end
74
+
75
+ def needs_version?
76
+ !(versioned_columns & changed).empty?
77
+ end
78
+
79
+ def reset_version(new_version = nil)
80
+ @last_version = nil if new_version.nil?
81
+ @version = new_version
82
+ end
83
+
84
+ def create_initial_version
85
+ versions.create(:changes => nil, :number => 1)
86
+ end
87
+
88
+ def create_version
89
+ versions << Version.create(:changes => changes.slice(*versioned_columns), :number => (last_version + 1))
90
+ reset_version
91
+ end
92
+
93
+ public
94
+ def version
95
+ @version ||= last_version
96
+ end
97
+
98
+ def last_version
99
+ @last_version ||= versions.inject(1){|max, version| version.number > max ? version.number : max}
100
+ end
101
+
102
+ def reverted?
103
+ version != last_version
104
+ end
105
+
106
+ def reload_with_versions(*args)
107
+ reset_version
108
+ reload_without_versions(*args)
109
+ end
110
+
111
+ def changes_between(from, to)
112
+ from_number, to_number = versions.number_at(from), versions.number_at(to)
113
+ return {} if from_number == to_number
114
+ chain = versions.between(from_number, to_number)
115
+ return {} if chain.empty?
116
+
117
+ backward = chain.first > chain.last
118
+ backward ? chain.pop : chain.shift
119
+
120
+ chain.inject({}) do |changes, version|
121
+ version.changes.each do |attribute, change|
122
+ change.reverse! if backward
123
+ new_change = [changes.fetch(attribute, change).first, change.last]
124
+ changes.update(attribute => new_change)
125
+ end
126
+ changes
127
+ end
128
+ end
129
+
130
+ def revert
131
+ revert_to self.version -1
132
+ end
133
+
134
+ def retrieve_version n
135
+ versions.find_by_number(n).changes.each do |n,v|
136
+ self.send("#{n.to_sym}=",v.first)
137
+ end
138
+ end
139
+
140
+ def revert_to(value)
141
+ to_number = versions.number_at(value)
142
+ changes = changes_between(version, to_number)
143
+ return version if changes.empty?
144
+
145
+ changes.each do |attribute, change|
146
+ write_attribute(attribute, change.last)
147
+ end
148
+
149
+ reset_version(to_number)
150
+ end
151
+
152
+ def revert_to!(value)
153
+ revert_to(value)
154
+ reset_version if saved = save
155
+ saved
156
+ end
157
+
158
+ def latest_changes
159
+ return {} if version.nil? || version == 1
160
+ versions.at(version).changes
161
+ end
162
+ end
163
+ end
Binary file
@@ -0,0 +1,58 @@
1
+ require 'test_helper'
2
+
3
+ class BetweenTest < Test::Unit::TestCase
4
+ context 'The number of versions between' do
5
+ setup do
6
+ @user = User.create(:name => 'Steve Richert')
7
+ @version = @user.version
8
+ @valid = [@version, 0, 1_000_000, :first, :last, 1.day.since(@user.created_at), @user.versions.first]
9
+ @invalid = [nil, :bogus, 'bogus', Date.parse('0001-12-25')]
10
+ end
11
+
12
+ context 'the current version and the current version' do
13
+ should 'equal one' do
14
+ assert_equal 1, @user.versions.between(@version, @version).size
15
+ end
16
+ end
17
+
18
+ context 'the current version and a valid value' do
19
+ should 'not equal zero' do
20
+ @valid.each do |valid|
21
+ assert_not_equal 0, @user.versions.between(@version, valid).size
22
+ assert_not_equal 0, @user.versions.between(valid, @version).size
23
+ end
24
+ end
25
+ end
26
+
27
+ context 'the current version and an invalid value' do
28
+ should 'equal zero' do
29
+ @invalid.each do |invalid|
30
+ assert_equal 0, @user.versions.between(@version, invalid).size
31
+ assert_equal 0, @user.versions.between(invalid, @version).size
32
+ end
33
+ end
34
+ end
35
+
36
+ context 'two invalid values' do
37
+ should 'equal zero' do
38
+ @invalid.each do |first|
39
+ @invalid.each do |second|
40
+ assert_equal 0, @user.versions.between(first, second).size
41
+ assert_equal 0, @user.versions.between(second, first).size
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ context 'a valid value and an invalid value' do
48
+ should 'equal zero' do
49
+ @valid.each do |valid|
50
+ @invalid.each do |invalid|
51
+ assert_equal 0, @user.versions.between(valid, invalid).size
52
+ assert_equal 0, @user.versions.between(invalid, valid).size
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+
3
+ class ChangesTest < Test::Unit::TestCase
4
+ context "A version's changes" do
5
+ setup do
6
+ @user = User.create(:name => 'Steve Richert')
7
+ end
8
+
9
+ should "initially be blank" do
10
+ assert @user.versions.first.changes.blank?
11
+ end
12
+
13
+ should 'contain all changed attributes' do
14
+ @user.name = 'Steve Jobs'
15
+ changes = @user.changes
16
+ @user.save
17
+ assert_equal changes, @user.versions.last.changes.slice(*changes.keys)
18
+ end
19
+
20
+ should 'contain no more than the changed attributes and timestamps' do
21
+ timestamps = %w(created_at created_on updated_at updated_on)
22
+ @user.name = 'Steve Jobs'
23
+ changes = @user.changes
24
+ @user.save
25
+ assert_equal changes, @user.versions.last.changes.except(*timestamps)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+
3
+ class ComparableTest < Test::Unit::TestCase
4
+ context 'A comparable version' do
5
+ setup do
6
+ @version_1 = Version.new(:number => 1)
7
+ @version_2 = Version.new(:number => 2)
8
+ end
9
+
10
+ should 'equal itself' do
11
+ assert @version_1 == @version_1
12
+ assert @version_2 == @version_2
13
+ end
14
+
15
+ context 'with version number 1' do
16
+ should 'not equal a version with version number 2' do
17
+ assert @version_1 != @version_2
18
+ end
19
+
20
+ should 'be less than a version with version number 2' do
21
+ assert @version_1 < @version_2
22
+ end
23
+ end
24
+
25
+ context 'with version number 2' do
26
+ should 'not equal a version with version number 1' do
27
+ assert @version_2 != @version_1
28
+ end
29
+
30
+ should 'be greater than a version with version number 1' do
31
+ assert @version_2 > @version_1
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,79 @@
1
+ require 'test_helper'
2
+
3
+ class CreationTest < Test::Unit::TestCase
4
+ context 'The number of versions' do
5
+ setup do
6
+ @name = 'Steve Richert'
7
+ @user = User.create(:name => @name)
8
+ @count = @user.versions.count
9
+ end
10
+
11
+ should 'initially equal one' do
12
+ assert_equal 1, @count
13
+ end
14
+
15
+ should 'not increase when no changes are made in an update' do
16
+ @user.name = @name
17
+ assert_equal @count, @user.versions.count
18
+ end
19
+
20
+ should 'not increase when no changes are made before a save' do
21
+ @user.save
22
+ assert_equal @count, @user.versions.count
23
+ end
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
+ context 'after an update' do
31
+ setup do
32
+ @initial_count = @count
33
+ @name = 'Steve Jobs'
34
+ @user.name = @name
35
+ @user.save
36
+ @count = @user.versions.count
37
+ end
38
+
39
+ should 'increase by one' do
40
+ assert_equal @initial_count + 1, @count
41
+ end
42
+
43
+ should 'increase by one when reverted' do
44
+ @user.revert_to!(:first)
45
+ assert_equal @count + 1, @user.versions.count
46
+ end
47
+
48
+ should 'not increase until a revert is saved' do
49
+ @user.revert_to(:first)
50
+ assert_equal @count, @user.versions.count
51
+ @user.save
52
+ assert_not_equal @count, @user.versions.count
53
+ end
54
+ end
55
+
56
+ should "retrieve a specific version without reverting it" do
57
+ @user.name = "Hoge"
58
+ @user.save
59
+ version_count = @user.versions.size
60
+ @user.retrieve_version 2
61
+ assert_equal version_count, @user.versions.size
62
+ end
63
+
64
+ context 'after multiple updates' do
65
+ setup do
66
+ @initial_count = @count
67
+ @new_name = 'Steve Jobs'
68
+ @user.name = @new_name
69
+ @user.name = @name
70
+ @count = @user.versions.count
71
+ end
72
+
73
+ should 'not increase when reverting to an identical version' do
74
+ @user.revert_to!(:first)
75
+ assert_equal @count, @user.versions.count
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,42 @@
1
+ require 'test_helper'
2
+
3
+ class LatestChangesTest < Test::Unit::TestCase
4
+ context "A created model's last changes" do
5
+ setup do
6
+ @user = User.create(:name => 'Steve Richert')
7
+ end
8
+
9
+ should 'be blank' do
10
+ assert @user.latest_changes.blank?
11
+ end
12
+ end
13
+
14
+ context "An updated model's last changes" do
15
+ setup do
16
+ @user = User.create(:name => 'Steve Richert')
17
+ @previous_attributes = @user.attributes
18
+ @user.name = 'Steve Jobs'
19
+ @current_attributes = @user.attributes
20
+ end
21
+
22
+ should 'values of two-element arrays with unique values' do
23
+ @user.latest_changes.values.each do |value|
24
+ assert_kind_of Array, value
25
+ assert_equal 2, value.size
26
+ assert_equal value, value.uniq
27
+ end
28
+ end
29
+
30
+ should 'begin with the previous attribute values' do
31
+ changes = @user.latest_changes.inject({}){|h,(k,v)| h.update(k => v.first) }
32
+ previous = @previous_attributes.slice(*@user.latest_changes.keys)
33
+ assert_equal previous, changes
34
+ end
35
+
36
+ should 'end with the current attribute values' do
37
+ changes = @user.latest_changes.inject({}){|h,(k,v)| h.update(k => v.last) }
38
+ current = @current_attributes.slice(*@user.latest_changes.keys)
39
+ assert_equal current, changes
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,79 @@
1
+ require 'test_helper'
2
+
3
+ class RevertTest < Test::Unit::TestCase
4
+ context 'A model reversion' do
5
+ setup do
6
+ @user, @attributes, @times = User.new, {}, {}
7
+ names = ['Steve Richert', 'Stephen Richert', 'Stephen Jobs', 'Steve Jobs']
8
+ time = names.size.hours.ago
9
+ names.each do |name|
10
+ @user.update_attributes({:name => name})
11
+ @attributes[@user.version] = @user.attributes
12
+ time += 1.hour
13
+ @user.versions.last.update_attributes({:created_at => time})
14
+ @times[@user.version] = time
15
+ end
16
+ @first_version, @last_version = @attributes.keys.min, @attributes.keys.max
17
+ end
18
+
19
+ should 'do nothing for a non-existent version' do
20
+ attributes = @user.attributes
21
+ @user.revert_to!(nil)
22
+ assert_equal attributes, @user.attributes
23
+ end
24
+
25
+ should 'return the new version number' do
26
+ new_version = @user.revert_to(@first_version)
27
+ assert_equal @first_version, new_version
28
+ end
29
+
30
+ should 'change the version number when saved' do
31
+ current_version = @user.version
32
+ @user.revert_to!(@first_version)
33
+ assert_not_equal current_version, @user.version
34
+ end
35
+
36
+ should 'be able to target the first version' do
37
+ @user.revert_to(:first)
38
+ assert_equal @first_version, @user.version
39
+ end
40
+
41
+ should 'be able to target the last version' do
42
+ @user.revert_to(:last)
43
+ assert_equal @last_version, @user.version
44
+ end
45
+
46
+ should 'do nothing for a non-existent method name' do
47
+ current_version = @user.version
48
+ @user.revert_to(:bogus)
49
+ assert_equal current_version, @user.version
50
+ end
51
+
52
+ should 'be able to target a version number' do
53
+ @user.revert_to(1)
54
+ assert 1, @user.version
55
+ end
56
+
57
+ should 'be able to target a date and time' do
58
+ @times.each do |version, time|
59
+ @user.revert_to(time + 1.second)
60
+ assert_equal version, @user.version
61
+ end
62
+ end
63
+
64
+ should 'be able to target a version object' do
65
+ @user.versions.each do |version|
66
+ @user.revert_to(version)
67
+ assert_equal version.number, @user.version
68
+ end
69
+ end
70
+
71
+ should "correctly roll back the model's attributes" do
72
+ timestamps = %w(created_at created_on updated_at updated_on)
73
+ @attributes.each do |version, attributes|
74
+ @user.revert_to!(version)
75
+ assert_equal attributes.except(*timestamps), @user.attributes.except(*timestamps)
76
+ end
77
+ end
78
+ end
79
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,21 @@
1
+ MongoMapper.connection = Mongo::Connection.new('127.0.0.1')
2
+ MongoMapper.database = "testing_versioned"
3
+
4
+ class User
5
+ include MongoMapper::Document
6
+ include Versioned
7
+ key :first_name, String
8
+ key :last_name, String
9
+ timestamps!
10
+
11
+ def name
12
+ [first_name, last_name].compact.join(' ')
13
+ end
14
+
15
+ def name=(names)
16
+ self[:first_name], self[:last_name] = names.split(' ', 2)
17
+ end
18
+ end
19
+
20
+ User.destroy_all
21
+ Version.destroy_all
@@ -0,0 +1,10 @@
1
+ $: << File.join(File.dirname(__FILE__), '..', 'lib')
2
+ $: << File.dirname(__FILE__)
3
+
4
+ require 'rubygems'
5
+ require 'test/unit'
6
+ require 'shoulda'
7
+ require 'mongo_mapper'
8
+ require 'versioned'
9
+ require 'schema'
10
+ begin; require 'redgreen'; rescue LoadError; end
data/versioned.gemspec ADDED
@@ -0,0 +1,61 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{versioned}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["twoism", "toastyapps", "jacqui"]
12
+ s.date = %q{2009-12-17}
13
+ s.description = %q{Versioning for MongoMapper}
14
+ s.email = %q{signalstatic@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ "README.rdoc",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "lib/version.rb",
23
+ "lib/versioned.rb",
24
+ "pkg/versioned-0.1.0.gem",
25
+ "test/between_test.rb",
26
+ "test/changes_test.rb",
27
+ "test/comparable_test.rb",
28
+ "test/creation_test.rb",
29
+ "test/latest_changes_test.rb",
30
+ "test/revert_test.rb",
31
+ "test/schema.rb",
32
+ "test/test_helper.rb",
33
+ "versioned.gemspec"
34
+ ]
35
+ s.homepage = %q{http://github.com/twoism/versioned}
36
+ s.rdoc_options = ["--charset=UTF-8"]
37
+ s.require_paths = ["lib"]
38
+ s.rubygems_version = %q{1.3.5}
39
+ s.summary = %q{Versioning for MongoMapper}
40
+ s.test_files = [
41
+ "test/between_test.rb",
42
+ "test/changes_test.rb",
43
+ "test/comparable_test.rb",
44
+ "test/creation_test.rb",
45
+ "test/latest_changes_test.rb",
46
+ "test/revert_test.rb",
47
+ "test/schema.rb",
48
+ "test/test_helper.rb"
49
+ ]
50
+
51
+ if s.respond_to? :specification_version then
52
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
53
+ s.specification_version = 3
54
+
55
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
56
+ else
57
+ end
58
+ else
59
+ end
60
+ end
61
+
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: versioned
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - twoism
8
+ - toastyapps
9
+ - jacqui
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2009-12-17 00:00:00 -05:00
15
+ default_executable:
16
+ dependencies: []
17
+
18
+ description: Versioning for MongoMapper
19
+ email: signalstatic@gmail.com
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files:
25
+ - README.rdoc
26
+ files:
27
+ - README.rdoc
28
+ - Rakefile
29
+ - VERSION
30
+ - lib/version.rb
31
+ - lib/versioned.rb
32
+ - pkg/versioned-0.1.0.gem
33
+ - test/between_test.rb
34
+ - test/changes_test.rb
35
+ - test/comparable_test.rb
36
+ - test/creation_test.rb
37
+ - test/latest_changes_test.rb
38
+ - test/revert_test.rb
39
+ - test/schema.rb
40
+ - test/test_helper.rb
41
+ - versioned.gemspec
42
+ has_rdoc: true
43
+ homepage: http://github.com/twoism/versioned
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --charset=UTF-8
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.3.5
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Versioning for MongoMapper
70
+ test_files:
71
+ - test/between_test.rb
72
+ - test/changes_test.rb
73
+ - test/comparable_test.rb
74
+ - test/creation_test.rb
75
+ - test/latest_changes_test.rb
76
+ - test/revert_test.rb
77
+ - test/schema.rb
78
+ - test/test_helper.rb