mrkurt-mongo_mapper 0.6.8
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 +10 -0
- data/LICENSE +20 -0
- data/README.rdoc +38 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/bin/mmconsole +60 -0
- data/lib/mongo_mapper.rb +139 -0
- data/lib/mongo_mapper/associations.rb +72 -0
- data/lib/mongo_mapper/associations/base.rb +113 -0
- data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +26 -0
- data/lib/mongo_mapper/associations/belongs_to_proxy.rb +21 -0
- data/lib/mongo_mapper/associations/collection.rb +19 -0
- data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +26 -0
- data/lib/mongo_mapper/associations/many_documents_proxy.rb +115 -0
- data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +31 -0
- data/lib/mongo_mapper/associations/many_embedded_proxy.rb +54 -0
- data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +11 -0
- data/lib/mongo_mapper/associations/one_proxy.rb +61 -0
- data/lib/mongo_mapper/associations/proxy.rb +111 -0
- data/lib/mongo_mapper/callbacks.rb +61 -0
- data/lib/mongo_mapper/dirty.rb +117 -0
- data/lib/mongo_mapper/document.rb +496 -0
- data/lib/mongo_mapper/dynamic_finder.rb +74 -0
- data/lib/mongo_mapper/embedded_document.rb +380 -0
- data/lib/mongo_mapper/finder_options.rb +145 -0
- data/lib/mongo_mapper/key.rb +36 -0
- data/lib/mongo_mapper/mongo_mapper.rb +125 -0
- data/lib/mongo_mapper/pagination.rb +66 -0
- data/lib/mongo_mapper/rails_compatibility/document.rb +15 -0
- data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +28 -0
- data/lib/mongo_mapper/serialization.rb +54 -0
- data/lib/mongo_mapper/serializers/json_serializer.rb +48 -0
- data/lib/mongo_mapper/support.rb +192 -0
- data/lib/mongo_mapper/validations.rb +39 -0
- data/mongo_mapper.gemspec +173 -0
- data/specs.watchr +30 -0
- data/test/NOTE_ON_TESTING +1 -0
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +55 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +91 -0
- data/test/functional/associations/test_many_documents_as_proxy.rb +246 -0
- data/test/functional/associations/test_many_documents_proxy.rb +477 -0
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +156 -0
- data/test/functional/associations/test_many_embedded_proxy.rb +192 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +339 -0
- data/test/functional/associations/test_one_proxy.rb +131 -0
- data/test/functional/test_associations.rb +44 -0
- data/test/functional/test_binary.rb +33 -0
- data/test/functional/test_callbacks.rb +85 -0
- data/test/functional/test_dirty.rb +159 -0
- data/test/functional/test_document.rb +1198 -0
- data/test/functional/test_embedded_document.rb +135 -0
- data/test/functional/test_logger.rb +20 -0
- data/test/functional/test_modifiers.rb +242 -0
- data/test/functional/test_pagination.rb +95 -0
- data/test/functional/test_rails_compatibility.rb +25 -0
- data/test/functional/test_string_id_compatibility.rb +72 -0
- data/test/functional/test_validations.rb +361 -0
- data/test/models.rb +271 -0
- data/test/support/custom_matchers.rb +55 -0
- data/test/support/timing.rb +16 -0
- data/test/test_helper.rb +27 -0
- data/test/unit/associations/test_base.rb +182 -0
- data/test/unit/associations/test_proxy.rb +91 -0
- data/test/unit/serializers/test_json_serializer.rb +189 -0
- data/test/unit/test_document.rb +236 -0
- data/test/unit/test_dynamic_finder.rb +125 -0
- data/test/unit/test_embedded_document.rb +709 -0
- data/test/unit/test_finder_options.rb +325 -0
- data/test/unit/test_key.rb +172 -0
- data/test/unit/test_mongo_mapper.rb +65 -0
- data/test/unit/test_pagination.rb +119 -0
- data/test/unit/test_rails_compatibility.rb +52 -0
- data/test/unit/test_serializations.rb +52 -0
- data/test/unit/test_support.rb +346 -0
- data/test/unit/test_time_zones.rb +40 -0
- data/test/unit/test_validations.rb +503 -0
- metadata +239 -0
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class OneProxyTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@post_class = Class.new do
|
6
|
+
include MongoMapper::Document
|
7
|
+
def self.name; 'Post' end
|
8
|
+
end
|
9
|
+
|
10
|
+
@author_class = Class.new do
|
11
|
+
include MongoMapper::Document
|
12
|
+
key :post_id, ObjectId
|
13
|
+
end
|
14
|
+
|
15
|
+
@post_class.collection.remove
|
16
|
+
@author_class.collection.remove
|
17
|
+
end
|
18
|
+
|
19
|
+
should "default to nil" do
|
20
|
+
@post_class.one :author, :class => @author_class
|
21
|
+
@post_class.new.author.nil?.should be_true
|
22
|
+
end
|
23
|
+
|
24
|
+
should "be able to replace the association" do
|
25
|
+
@post_class.one :author, :class => @author_class
|
26
|
+
post = @post_class.new
|
27
|
+
author = @author_class.new
|
28
|
+
post.author = author
|
29
|
+
post.reload
|
30
|
+
|
31
|
+
post.author.should == author
|
32
|
+
post.author.nil?.should be_false
|
33
|
+
end
|
34
|
+
|
35
|
+
should "unset the association" do
|
36
|
+
@post_class.one :author, :class => @author_class
|
37
|
+
post = @post_class.new
|
38
|
+
author = @author_class.new
|
39
|
+
post.author = author
|
40
|
+
post.reload
|
41
|
+
|
42
|
+
post.author = nil
|
43
|
+
post.author.nil?.should be_false
|
44
|
+
end
|
45
|
+
|
46
|
+
should "work with :dependent delete" do
|
47
|
+
@post_class.one :author, :class => @author_class, :dependent => :delete
|
48
|
+
|
49
|
+
post = @post_class.create
|
50
|
+
author = @author_class.new
|
51
|
+
post.author = author
|
52
|
+
post.reload
|
53
|
+
|
54
|
+
@author_class.any_instance.expects(:delete).once
|
55
|
+
post.author = @author_class.new
|
56
|
+
end
|
57
|
+
|
58
|
+
should "work with :dependent destroy" do
|
59
|
+
@post_class.one :author, :class => @author_class, :dependent => :destroy
|
60
|
+
|
61
|
+
post = @post_class.create
|
62
|
+
author = @author_class.new
|
63
|
+
post.author = author
|
64
|
+
post.reload
|
65
|
+
|
66
|
+
@author_class.any_instance.expects(:destroy).once
|
67
|
+
post.author = @author_class.new
|
68
|
+
end
|
69
|
+
|
70
|
+
should "work with :dependent nullify" do
|
71
|
+
@post_class.one :author, :class => @author_class, :dependent => :nullify
|
72
|
+
|
73
|
+
post = @post_class.create
|
74
|
+
author = @author_class.new
|
75
|
+
post.author = author
|
76
|
+
post.reload
|
77
|
+
|
78
|
+
post.author = @author_class.new
|
79
|
+
|
80
|
+
author.reload
|
81
|
+
author.post_id.should be_nil
|
82
|
+
end
|
83
|
+
|
84
|
+
should "be able to build" do
|
85
|
+
@post_class.one :author, :class => @author_class
|
86
|
+
|
87
|
+
post = @post_class.create
|
88
|
+
author = post.author.build(:name => 'John')
|
89
|
+
post.author.should be_instance_of(@author_class)
|
90
|
+
post.author.should be_new
|
91
|
+
post.author.name.should == 'John'
|
92
|
+
post.author.should == author
|
93
|
+
post.author.post_id.should == post.id
|
94
|
+
end
|
95
|
+
|
96
|
+
should "be able to create" do
|
97
|
+
@post_class.one :author, :class => @author_class
|
98
|
+
|
99
|
+
post = @post_class.create
|
100
|
+
author = post.author.create(:name => 'John')
|
101
|
+
post.author.should be_instance_of(@author_class)
|
102
|
+
post.author.should_not be_new
|
103
|
+
post.author.name.should == 'John'
|
104
|
+
post.author.should == author
|
105
|
+
post.author.post_id.should == post.id
|
106
|
+
end
|
107
|
+
|
108
|
+
context "#create!" do
|
109
|
+
setup do
|
110
|
+
@author_class.key :name, String, :required => true
|
111
|
+
@post_class.one :author, :class => @author_class
|
112
|
+
end
|
113
|
+
|
114
|
+
should "raise exception if invalid" do
|
115
|
+
post = @post_class.create
|
116
|
+
assert_raises(MongoMapper::DocumentNotValid) do
|
117
|
+
post.author.create!
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
should "work if valid" do
|
122
|
+
post = @post_class.create
|
123
|
+
author = post.author.create!(:name => 'John')
|
124
|
+
post.author.should be_instance_of(@author_class)
|
125
|
+
post.author.should_not be_new
|
126
|
+
post.author.name.should == 'John'
|
127
|
+
post.author.should == author
|
128
|
+
post.author.post_id.should == post.id
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models'
|
3
|
+
|
4
|
+
class AssociationsTest < Test::Unit::TestCase
|
5
|
+
should "allow changing class names" do
|
6
|
+
class AwesomeUser
|
7
|
+
include MongoMapper::Document
|
8
|
+
|
9
|
+
many :posts, :class_name => 'AssociationsTest::AwesomePost', :foreign_key => :creator_id
|
10
|
+
end
|
11
|
+
AwesomeUser.collection.remove
|
12
|
+
|
13
|
+
class AwesomeTag
|
14
|
+
include MongoMapper::EmbeddedDocument
|
15
|
+
|
16
|
+
key :name, String
|
17
|
+
key :post_id, ObjectId
|
18
|
+
|
19
|
+
belongs_to :post, :class_name => 'AssociationsTest::AwesomeUser'
|
20
|
+
end
|
21
|
+
|
22
|
+
class AwesomePost
|
23
|
+
include MongoMapper::Document
|
24
|
+
|
25
|
+
key :creator_id, ObjectId
|
26
|
+
|
27
|
+
belongs_to :creator, :class_name => 'AssociationsTest::AwesomeUser'
|
28
|
+
many :tags, :class_name => 'AssociationsTest::AwesomeTag', :foreign_key => :post_id
|
29
|
+
end
|
30
|
+
|
31
|
+
AwesomeUser.collection.remove
|
32
|
+
AwesomePost.collection.remove
|
33
|
+
|
34
|
+
user = AwesomeUser.create
|
35
|
+
tag1 = AwesomeTag.new(:name => 'awesome')
|
36
|
+
tag2 = AwesomeTag.new(:name => 'grand')
|
37
|
+
post1 = AwesomePost.create(:creator => user, :tags => [tag1])
|
38
|
+
post2 = AwesomePost.create(:creator => user, :tags => [tag2])
|
39
|
+
user.posts.should == [post1, post2]
|
40
|
+
|
41
|
+
post1 = post1.reload
|
42
|
+
post1.tags.should == [tag1]
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BinaryTest < Test::Unit::TestCase
|
4
|
+
should "serialize and deserialize correctly" do
|
5
|
+
klass = Class.new do
|
6
|
+
include MongoMapper::Document
|
7
|
+
set_collection_name 'test'
|
8
|
+
key :contents, Binary
|
9
|
+
end
|
10
|
+
klass.collection.remove
|
11
|
+
|
12
|
+
doc = klass.new(:contents => '010101')
|
13
|
+
doc.save
|
14
|
+
|
15
|
+
doc = doc.reload
|
16
|
+
doc.contents.to_s.should == ByteBuffer.new('010101').to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
context "Saving a document with a blank binary value" do
|
20
|
+
setup do
|
21
|
+
@document = Class.new do
|
22
|
+
include MongoMapper::Document
|
23
|
+
set_collection_name 'test'
|
24
|
+
key :file, Binary
|
25
|
+
end
|
26
|
+
@document.collection.remove
|
27
|
+
end
|
28
|
+
|
29
|
+
should "not fail" do
|
30
|
+
assert_nothing_raised { @document.new(:file => nil).save }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CallbacksTest < Test::Unit::TestCase
|
4
|
+
context "Defining and running callbacks" do
|
5
|
+
setup do
|
6
|
+
@document = Class.new do
|
7
|
+
include MongoMapper::Document
|
8
|
+
set_collection_name 'test'
|
9
|
+
|
10
|
+
key :name, String
|
11
|
+
|
12
|
+
[ :before_validation_on_create, :before_validation_on_update,
|
13
|
+
:before_validation, :after_validation,
|
14
|
+
:before_create, :after_create,
|
15
|
+
:before_update, :after_update,
|
16
|
+
:before_save, :after_save,
|
17
|
+
:before_destroy, :after_destroy].each do |callback|
|
18
|
+
callback_method = "#{callback}_callback"
|
19
|
+
send(callback, callback_method)
|
20
|
+
define_method(callback_method) do
|
21
|
+
history << callback.to_sym
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def history
|
26
|
+
@history ||= []
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear_history
|
30
|
+
@history = nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
@document.collection.remove
|
34
|
+
end
|
35
|
+
|
36
|
+
should "get the order right for creating documents" do
|
37
|
+
doc = @document.create(:name => 'John Nunemaker')
|
38
|
+
doc.history.should == [:before_validation, :before_validation_on_create, :after_validation, :before_save, :before_create, :after_create, :after_save]
|
39
|
+
end
|
40
|
+
|
41
|
+
should "get the order right for updating documents" do
|
42
|
+
doc = @document.create(:name => 'John Nunemaker')
|
43
|
+
doc.clear_history
|
44
|
+
doc.name = 'John'
|
45
|
+
doc.save
|
46
|
+
doc.history.should == [:before_validation, :before_validation_on_update, :after_validation, :before_save, :before_update, :after_update, :after_save]
|
47
|
+
end
|
48
|
+
|
49
|
+
should "work for before and after validation" do
|
50
|
+
doc = @document.new(:name => 'John Nunemaker')
|
51
|
+
doc.valid?
|
52
|
+
doc.history.should include(:before_validation)
|
53
|
+
doc.history.should include(:after_validation)
|
54
|
+
end
|
55
|
+
|
56
|
+
should "work for before and after create" do
|
57
|
+
doc = @document.create(:name => 'John Nunemaker')
|
58
|
+
doc.history.should include(:before_create)
|
59
|
+
doc.history.should include(:after_create)
|
60
|
+
end
|
61
|
+
|
62
|
+
should "work for before and after update" do
|
63
|
+
doc = @document.create(:name => 'John Nunemaker')
|
64
|
+
doc.name = 'John Doe'
|
65
|
+
doc.save
|
66
|
+
doc.history.should include(:before_update)
|
67
|
+
doc.history.should include(:after_update)
|
68
|
+
end
|
69
|
+
|
70
|
+
should "work for before and after save" do
|
71
|
+
doc = @document.new
|
72
|
+
doc.name = 'John Doe'
|
73
|
+
doc.save
|
74
|
+
doc.history.should include(:before_save)
|
75
|
+
doc.history.should include(:after_save)
|
76
|
+
end
|
77
|
+
|
78
|
+
should "work for before and after destroy" do
|
79
|
+
doc = @document.create(:name => 'John Nunemaker')
|
80
|
+
doc.destroy
|
81
|
+
doc.history.should include(:before_destroy)
|
82
|
+
doc.history.should include(:after_destroy)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models'
|
3
|
+
|
4
|
+
class DirtyTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@document = Class.new do
|
7
|
+
include MongoMapper::Document
|
8
|
+
set_collection_name 'test'
|
9
|
+
key :phrase, String
|
10
|
+
end
|
11
|
+
@document.collection.remove
|
12
|
+
|
13
|
+
Status.collection.remove
|
14
|
+
Project.collection.remove
|
15
|
+
end
|
16
|
+
|
17
|
+
context "marking changes" do
|
18
|
+
should "not happen if there are none" do
|
19
|
+
doc = @document.new
|
20
|
+
doc.phrase_changed?.should be_false
|
21
|
+
doc.phrase_change.should be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
should "happen when change happens" do
|
25
|
+
doc = @document.new
|
26
|
+
doc.phrase = 'Golly Gee Willikers Batman'
|
27
|
+
doc.phrase_changed?.should be_true
|
28
|
+
doc.phrase_was.should be_nil
|
29
|
+
doc.phrase_change.should == [nil, 'Golly Gee Willikers Batman']
|
30
|
+
end
|
31
|
+
|
32
|
+
should "happen when initializing" do
|
33
|
+
doc = @document.new(:phrase => 'Foo')
|
34
|
+
doc.changed?.should be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
should "clear changes on save" do
|
38
|
+
doc = @document.new
|
39
|
+
doc.phrase = 'Golly Gee Willikers Batman'
|
40
|
+
doc.phrase_changed?.should be_true
|
41
|
+
doc.save
|
42
|
+
doc.phrase_changed?.should_not be_true
|
43
|
+
doc.phrase_change.should be_nil
|
44
|
+
end
|
45
|
+
|
46
|
+
should "clear changes on save!" do
|
47
|
+
doc = @document.new
|
48
|
+
doc.phrase = 'Golly Gee Willikers Batman'
|
49
|
+
doc.phrase_changed?.should be_true
|
50
|
+
doc.save!
|
51
|
+
doc.phrase_changed?.should_not be_true
|
52
|
+
doc.phrase_change.should be_nil
|
53
|
+
end
|
54
|
+
|
55
|
+
should "not happen when loading from database" do
|
56
|
+
doc = @document.create(:phrase => 'Foo')
|
57
|
+
doc.phrase = 'Fart'
|
58
|
+
doc.changed?.should be_true
|
59
|
+
doc.reload
|
60
|
+
doc.changed?.should be_false
|
61
|
+
end
|
62
|
+
|
63
|
+
should "happen if changed after loading from database" do
|
64
|
+
doc = @document.create(:phrase => 'Foo')
|
65
|
+
doc.reload
|
66
|
+
doc.changed?.should be_false
|
67
|
+
doc.phrase = 'Bar'
|
68
|
+
doc.changed?.should be_true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "blank new value and type integer" do
|
73
|
+
should "not mark changes" do
|
74
|
+
@document.key :age, Integer
|
75
|
+
|
76
|
+
[nil, ''].each do |value|
|
77
|
+
doc = @document.new
|
78
|
+
doc.age = value
|
79
|
+
doc.age_changed?.should be_false
|
80
|
+
doc.age_change.should be_nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "blank new value and type float" do
|
86
|
+
should "not mark changes" do
|
87
|
+
@document.key :amount, Float
|
88
|
+
|
89
|
+
[nil, ''].each do |value|
|
90
|
+
doc = @document.new
|
91
|
+
doc.amount = value
|
92
|
+
doc.amount_changed?.should be_false
|
93
|
+
doc.amount_change.should be_nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "changed?" do
|
99
|
+
should "be true if key changed" do
|
100
|
+
doc = @document.new
|
101
|
+
doc.phrase = 'A penny saved is a penny earned.'
|
102
|
+
doc.changed?.should be_true
|
103
|
+
end
|
104
|
+
|
105
|
+
should "be false if no keys changed" do
|
106
|
+
@document.new.changed?.should be_false
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "changes" do
|
111
|
+
should "be empty hash if no changes" do
|
112
|
+
@document.new.changes.should == {}
|
113
|
+
end
|
114
|
+
|
115
|
+
should "be hash of keys with values of changes if there are changes" do
|
116
|
+
doc = @document.new
|
117
|
+
doc.phrase = 'A penny saved is a penny earned.'
|
118
|
+
doc.changes.should == {'phrase' => [nil, 'A penny saved is a penny earned.']}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "changed" do
|
123
|
+
should "be empty array if no changes" do
|
124
|
+
@document.new.changed.should == []
|
125
|
+
end
|
126
|
+
|
127
|
+
should "be array of keys that have changed if there are changes" do
|
128
|
+
doc = @document.new
|
129
|
+
doc.phrase = 'A penny saved is a penny earned.'
|
130
|
+
doc.changed.should == ['phrase']
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "will_change!" do
|
135
|
+
should "mark changes" do
|
136
|
+
doc = @document.create(:phrase => 'Foo')
|
137
|
+
|
138
|
+
doc.phrase << 'bar'
|
139
|
+
doc.phrase_changed?.should be_false
|
140
|
+
|
141
|
+
doc.phrase_will_change!
|
142
|
+
doc.phrase_changed?.should be_true
|
143
|
+
doc.phrase_change.should == ['Foobar', 'Foobar']
|
144
|
+
|
145
|
+
doc.phrase << '!'
|
146
|
+
doc.phrase_changed?.should be_true
|
147
|
+
doc.phrase_change.should == ['Foobar', 'Foobar!']
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "changing a foreign key through association" do
|
152
|
+
should "mark changes" do
|
153
|
+
status = Status.create(:name => 'Foo')
|
154
|
+
status.project = Project.create(:name => 'Bar')
|
155
|
+
status.changed?.should be_true
|
156
|
+
status.changed.should == %w(project_id)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|