drogus-mongo_mapper 0.6.10
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 +29 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/bin/mmconsole +60 -0
- data/lib/mongo_mapper.rb +131 -0
- data/lib/mongo_mapper/document.rb +417 -0
- data/lib/mongo_mapper/embedded_document.rb +55 -0
- data/lib/mongo_mapper/finder_options.rb +127 -0
- data/lib/mongo_mapper/plugins.rb +30 -0
- data/lib/mongo_mapper/plugins/associations.rb +104 -0
- data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +30 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +25 -0
- data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +50 -0
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
- data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
- data/lib/mongo_mapper/plugins/callbacks.rb +134 -0
- data/lib/mongo_mapper/plugins/clone.rb +13 -0
- data/lib/mongo_mapper/plugins/descendants.rb +16 -0
- data/lib/mongo_mapper/plugins/dirty.rb +119 -0
- data/lib/mongo_mapper/plugins/equality.rb +23 -0
- data/lib/mongo_mapper/plugins/identity_map.rb +122 -0
- data/lib/mongo_mapper/plugins/inspect.rb +14 -0
- data/lib/mongo_mapper/plugins/keys.rb +324 -0
- data/lib/mongo_mapper/plugins/logger.rb +17 -0
- data/lib/mongo_mapper/plugins/pagination.rb +85 -0
- data/lib/mongo_mapper/plugins/protected.rb +45 -0
- data/lib/mongo_mapper/plugins/rails.rb +45 -0
- data/lib/mongo_mapper/plugins/serialization.rb +105 -0
- data/lib/mongo_mapper/plugins/validations.rb +57 -0
- data/lib/mongo_mapper/support.rb +217 -0
- data/lib/mongo_mapper/support/descendant_appends.rb +46 -0
- data/lib/mongo_mapper/support/find.rb +77 -0
- data/mongo_mapper.gemspec +195 -0
- data/performance/read_write.rb +52 -0
- data/specs.watchr +51 -0
- data/test/NOTE_ON_TESTING +1 -0
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +63 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +101 -0
- data/test/functional/associations/test_in_array_proxy.rb +309 -0
- data/test/functional/associations/test_many_documents_as_proxy.rb +229 -0
- data/test/functional/associations/test_many_documents_proxy.rb +431 -0
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +176 -0
- data/test/functional/associations/test_many_embedded_proxy.rb +256 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +302 -0
- data/test/functional/associations/test_one_proxy.rb +161 -0
- data/test/functional/test_associations.rb +44 -0
- data/test/functional/test_binary.rb +27 -0
- data/test/functional/test_callbacks.rb +81 -0
- data/test/functional/test_dirty.rb +163 -0
- data/test/functional/test_document.rb +1264 -0
- data/test/functional/test_embedded_document.rb +125 -0
- data/test/functional/test_identity_map.rb +508 -0
- data/test/functional/test_logger.rb +20 -0
- data/test/functional/test_modifiers.rb +252 -0
- data/test/functional/test_pagination.rb +93 -0
- data/test/functional/test_protected.rb +155 -0
- data/test/functional/test_string_id_compatibility.rb +67 -0
- data/test/functional/test_validations.rb +329 -0
- data/test/models.rb +232 -0
- data/test/support/custom_matchers.rb +55 -0
- data/test/support/timing.rb +16 -0
- data/test/test_helper.rb +60 -0
- data/test/unit/associations/test_base.rb +207 -0
- data/test/unit/associations/test_proxy.rb +105 -0
- data/test/unit/serializers/test_json_serializer.rb +189 -0
- data/test/unit/test_descendant_appends.rb +71 -0
- data/test/unit/test_document.rb +231 -0
- data/test/unit/test_dynamic_finder.rb +123 -0
- data/test/unit/test_embedded_document.rb +663 -0
- data/test/unit/test_finder_options.rb +329 -0
- data/test/unit/test_keys.rb +169 -0
- data/test/unit/test_mongo_mapper.rb +65 -0
- data/test/unit/test_pagination.rb +127 -0
- data/test/unit/test_plugins.rb +50 -0
- data/test/unit/test_rails.rb +123 -0
- data/test/unit/test_rails_compatibility.rb +52 -0
- data/test/unit/test_serialization.rb +51 -0
- data/test/unit/test_support.rb +354 -0
- data/test/unit/test_time_zones.rb +39 -0
- data/test/unit/test_validations.rb +544 -0
- metadata +290 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models'
|
3
|
+
|
4
|
+
class EmbeddedDocumentTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@klass = Doc do
|
7
|
+
key :first_name, String
|
8
|
+
key :last_name, String
|
9
|
+
end
|
10
|
+
|
11
|
+
@pet_klass = EDoc do
|
12
|
+
key :name, String
|
13
|
+
end
|
14
|
+
|
15
|
+
@klass.many :pets, :class => @pet_klass
|
16
|
+
|
17
|
+
@address_class = EDoc do
|
18
|
+
key :city, String
|
19
|
+
key :state, String
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "Saving a document with an embedded document" do
|
24
|
+
setup do
|
25
|
+
@klass.key :foo, @address_class
|
26
|
+
|
27
|
+
@address = @address_class.new(:city => 'South Bend', :state => 'IN')
|
28
|
+
@doc = @klass.new(:foo => @address)
|
29
|
+
end
|
30
|
+
|
31
|
+
should "embed embedded document" do
|
32
|
+
@doc.save
|
33
|
+
@doc.foo.city.should == 'South Bend'
|
34
|
+
@doc.foo.state.should == 'IN'
|
35
|
+
|
36
|
+
doc = @doc.reload
|
37
|
+
doc.foo.city.should == 'South Bend'
|
38
|
+
doc.foo.state.should == 'IN'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
should "correctly instantiate single collection inherited embedded documents" do
|
43
|
+
document = Doc('Foo') do
|
44
|
+
key :message, Message
|
45
|
+
end
|
46
|
+
|
47
|
+
doc1 = document.create(:message => Enter.new)
|
48
|
+
doc1.reload.message.class.should be(Enter)
|
49
|
+
end
|
50
|
+
|
51
|
+
context "new?" do
|
52
|
+
setup do
|
53
|
+
@klass.key :foo, @address_class
|
54
|
+
end
|
55
|
+
|
56
|
+
should "be new until document is saved" do
|
57
|
+
address = @address_class.new(:city => 'South Bend', :state => 'IN')
|
58
|
+
doc = @klass.new(:foo => address)
|
59
|
+
address.new?.should == true
|
60
|
+
end
|
61
|
+
|
62
|
+
should "not be new after document is saved" do
|
63
|
+
address = @address_class.new(:city => 'South Bend', :state => 'IN')
|
64
|
+
doc = @klass.new(:foo => address)
|
65
|
+
doc.save
|
66
|
+
doc.foo.new?.should == false
|
67
|
+
end
|
68
|
+
|
69
|
+
should "not be new when document is read back" do
|
70
|
+
address = @address_class.new(:city => 'South Bend', :state => 'IN')
|
71
|
+
doc = @klass.new(:foo => address)
|
72
|
+
doc.save
|
73
|
+
|
74
|
+
doc = doc.reload
|
75
|
+
doc.foo.new?.should == false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
should "be able to save" do
|
80
|
+
person = @klass.create
|
81
|
+
|
82
|
+
pet = @pet_klass.new(:name => 'sparky')
|
83
|
+
person.pets << pet
|
84
|
+
pet.should be_new
|
85
|
+
pet.save
|
86
|
+
pet.should_not be_new
|
87
|
+
|
88
|
+
person.reload
|
89
|
+
person.pets.first.should == pet
|
90
|
+
end
|
91
|
+
|
92
|
+
should "be able to dynamically add new keys and save" do
|
93
|
+
person = @klass.create
|
94
|
+
|
95
|
+
pet = @pet_klass.new(:name => 'sparky', :crazy_key => 'crazy')
|
96
|
+
person.pets << pet
|
97
|
+
pet.save
|
98
|
+
|
99
|
+
person.reload
|
100
|
+
person.pets.first.crazy_key.should == 'crazy'
|
101
|
+
end
|
102
|
+
|
103
|
+
should "be able to update_attributes" do
|
104
|
+
pet = @pet_klass.new(:name => 'sparky')
|
105
|
+
person = @klass.create(:pets => [pet])
|
106
|
+
person.reload
|
107
|
+
pet = person.pets.first
|
108
|
+
|
109
|
+
pet.update_attributes(:name => 'koda').should be_true
|
110
|
+
person.reload
|
111
|
+
person.pets.first._id.should == pet._id
|
112
|
+
person.pets.first.name.should == 'koda'
|
113
|
+
end
|
114
|
+
|
115
|
+
should "be able to update_attributes!" do
|
116
|
+
person = @klass.create(:pets => [@pet_klass.new(:name => 'sparky')])
|
117
|
+
person.reload
|
118
|
+
pet = person.pets.first
|
119
|
+
|
120
|
+
attributes = {:name => 'koda'}
|
121
|
+
pet.expects(:attributes=).with(attributes)
|
122
|
+
pet.expects(:save!)
|
123
|
+
pet.update_attributes!(attributes)
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,508 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class IdentityMapTest < Test::Unit::TestCase
|
4
|
+
def assert_in_map(*resources)
|
5
|
+
[resources].flatten.each do |resource|
|
6
|
+
resource.identity_map.keys.should include(resource._id)
|
7
|
+
mapped_resource = resource.identity_map[resource._id]
|
8
|
+
resource.should equal(mapped_resource)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def assert_not_in_map(*resources)
|
13
|
+
[resources].flatten.each do |resource|
|
14
|
+
resource.identity_map.keys.should_not include(resource._id)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def expect_no_queries
|
19
|
+
Mongo::Collection.any_instance.expects(:find_one).never
|
20
|
+
Mongo::Collection.any_instance.expects(:find).never
|
21
|
+
end
|
22
|
+
|
23
|
+
def expects_one_query
|
24
|
+
Mongo::Collection.any_instance.expects(:find_one).once.returns({})
|
25
|
+
end
|
26
|
+
|
27
|
+
context "Document" do
|
28
|
+
setup do
|
29
|
+
MongoMapper::Plugins::IdentityMap.models.clear
|
30
|
+
|
31
|
+
@person_class = Doc('Person') do
|
32
|
+
set_collection_name 'people'
|
33
|
+
plugin MongoMapper::Plugins::IdentityMap
|
34
|
+
|
35
|
+
key :name, String
|
36
|
+
end
|
37
|
+
|
38
|
+
@post_class = Doc('Post') do
|
39
|
+
set_collection_name 'posts'
|
40
|
+
plugin MongoMapper::Plugins::IdentityMap
|
41
|
+
|
42
|
+
key :title, String
|
43
|
+
key :person_id, ObjectId
|
44
|
+
end
|
45
|
+
|
46
|
+
@post_class.belongs_to :person, :class => @person_class
|
47
|
+
@person_class.many :posts, :class => @post_class
|
48
|
+
|
49
|
+
@post_class.identity_map_on
|
50
|
+
@person_class.identity_map_on
|
51
|
+
MongoMapper::Plugins::IdentityMap.clear
|
52
|
+
end
|
53
|
+
|
54
|
+
should "track identity mapped models" do
|
55
|
+
MongoMapper::Plugins::IdentityMap.models.should == [@person_class, @post_class].to_set
|
56
|
+
end
|
57
|
+
|
58
|
+
should "be able to clear the map of all models" do
|
59
|
+
person = @person_class.create(:name => 'John')
|
60
|
+
post = @post_class.create(:title => 'IM 4eva')
|
61
|
+
assert_in_map(person, post)
|
62
|
+
|
63
|
+
MongoMapper::Plugins::IdentityMap.clear
|
64
|
+
|
65
|
+
assert_not_in_map(person, post)
|
66
|
+
|
67
|
+
[@person_class, @post_class].each { |klass| klass.identity_map.should == {} }
|
68
|
+
end
|
69
|
+
|
70
|
+
context "IM on off status" do
|
71
|
+
teardown do
|
72
|
+
@post_class.identity_map_on
|
73
|
+
@person_class.identity_map_on
|
74
|
+
end
|
75
|
+
|
76
|
+
should "default identity map status to on" do
|
77
|
+
Doc { plugin MongoMapper::Plugins::IdentityMap }.identity_map_status.should be_true
|
78
|
+
end
|
79
|
+
|
80
|
+
should "be true if on" do
|
81
|
+
@post_class.identity_map_on
|
82
|
+
@post_class.should be_identity_map_on
|
83
|
+
@post_class.should_not be_identity_map_off
|
84
|
+
end
|
85
|
+
|
86
|
+
should "be false if off" do
|
87
|
+
@post_class.identity_map_off
|
88
|
+
@post_class.should be_identity_map_off
|
89
|
+
@post_class.should_not be_identity_map_on
|
90
|
+
end
|
91
|
+
|
92
|
+
should "not share with other classes" do
|
93
|
+
@post_class.identity_map_off
|
94
|
+
@person_class.identity_map_on
|
95
|
+
@post_class.identity_map_status.should_not == @person_class.identity_map_status
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
should "default identity map to hash" do
|
100
|
+
Doc { plugin MongoMapper::Plugins::IdentityMap }.identity_map.should == {}
|
101
|
+
end
|
102
|
+
|
103
|
+
should "add key to map when saved" do
|
104
|
+
person = @person_class.new
|
105
|
+
assert_not_in_map(person)
|
106
|
+
person.save.should be_true
|
107
|
+
assert_in_map(person)
|
108
|
+
end
|
109
|
+
|
110
|
+
should "allow saving with options" do
|
111
|
+
person = @person_class.new
|
112
|
+
assert_nothing_raised do
|
113
|
+
person.save(:validate => false).should be_true
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
should "remove key from map when deleted" do
|
118
|
+
person = @person_class.create(:name => 'Fred')
|
119
|
+
assert_in_map(person)
|
120
|
+
person.destroy
|
121
|
+
assert_not_in_map(person)
|
122
|
+
end
|
123
|
+
|
124
|
+
context "reload" do
|
125
|
+
setup do
|
126
|
+
@person = @person_class.create(:name => 'Fred')
|
127
|
+
end
|
128
|
+
|
129
|
+
should "remove object from identity and re-query" do
|
130
|
+
assert_in_map(@person)
|
131
|
+
expects_one_query
|
132
|
+
@person.reload
|
133
|
+
end
|
134
|
+
|
135
|
+
should "add object back into map" do
|
136
|
+
assert_in_map(@person)
|
137
|
+
before_reload = @person
|
138
|
+
@person.reload.should equal(before_reload)
|
139
|
+
assert_in_map(@person)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context "#load" do
|
144
|
+
setup do
|
145
|
+
@id = Mongo::ObjectID.new
|
146
|
+
end
|
147
|
+
|
148
|
+
should "add document to map" do
|
149
|
+
loaded = @person_class.load({'_id' => @id, 'name' => 'Frank'})
|
150
|
+
assert_in_map(loaded)
|
151
|
+
end
|
152
|
+
|
153
|
+
should "return document if already in map" do
|
154
|
+
first_load = @person_class.load({'_id' => @id, 'name' => 'Frank'})
|
155
|
+
@person_class.identity_map.expects(:[]=).never
|
156
|
+
second_load = @person_class.load({'_id' => @id, 'name' => 'Frank'})
|
157
|
+
first_load.should equal(second_load)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "#find (with one id)" do
|
162
|
+
context "for object not in map" do
|
163
|
+
setup do
|
164
|
+
@person = @person_class.create(:name => 'Fred')
|
165
|
+
@person_class.identity_map.clear
|
166
|
+
end
|
167
|
+
|
168
|
+
should "query the database" do
|
169
|
+
expects_one_query
|
170
|
+
@person_class.find(@person.id)
|
171
|
+
end
|
172
|
+
|
173
|
+
should "add object to map" do
|
174
|
+
assert_not_in_map(@person)
|
175
|
+
found_person = @person_class.find(@person.id)
|
176
|
+
assert_in_map(found_person)
|
177
|
+
end
|
178
|
+
|
179
|
+
should "return nil if not found " do
|
180
|
+
@person_class.find(1234).should be_nil
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context "for object in map" do
|
185
|
+
setup do
|
186
|
+
@person = @person_class.create(:name => 'Fred')
|
187
|
+
end
|
188
|
+
|
189
|
+
should "not query database" do
|
190
|
+
expect_no_queries
|
191
|
+
@person_class.find(@person.id)
|
192
|
+
end
|
193
|
+
|
194
|
+
should "return exact object" do
|
195
|
+
assert_in_map(@person)
|
196
|
+
found_person = @person_class.find(@person.id)
|
197
|
+
found_person.should equal(@person)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context "#find (with one id and options)" do
|
203
|
+
setup do
|
204
|
+
@person = @person_class.create(:name => 'Fred')
|
205
|
+
@post1 = @person.posts.create(:title => 'I Love Mongo')
|
206
|
+
@post2 = @person.posts.create(:title => 'Migrations Suck!')
|
207
|
+
end
|
208
|
+
|
209
|
+
# There are times when even though the id matches, other criteria doesn't
|
210
|
+
# so we need to do the query to ensure that when criteria doesn't match
|
211
|
+
# the document is in fact not found.
|
212
|
+
#
|
213
|
+
# I'm open to not making this query if someone can figure out reliable
|
214
|
+
# way to check if document matches criteria without querying.
|
215
|
+
should "query the database" do
|
216
|
+
assert_in_map(@post1)
|
217
|
+
expects_one_query
|
218
|
+
@person.posts.find(@post1.id)
|
219
|
+
end
|
220
|
+
|
221
|
+
should "return exact object" do
|
222
|
+
assert_in_map(@post1)
|
223
|
+
@person.posts.find(@post1.id)
|
224
|
+
assert_in_map(@post1)
|
225
|
+
end
|
226
|
+
|
227
|
+
should "return nil if not found " do
|
228
|
+
@person.posts.find(1234).should be_nil
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context "#find (with multiple ids)" do
|
233
|
+
should "add all documents to map" do
|
234
|
+
person1 = @person_class.create(:name => 'Fred')
|
235
|
+
person2 = @person_class.create(:name => 'Bill')
|
236
|
+
person3 = @person_class.create(:name => 'Jesse')
|
237
|
+
@person_class.identity_map.clear
|
238
|
+
|
239
|
+
people = @person_class.find(person1.id, person2.id, person3.id)
|
240
|
+
assert_in_map(people)
|
241
|
+
end
|
242
|
+
|
243
|
+
should "add missing documents to map and return existing ones" do
|
244
|
+
person1 = @person_class.create(:name => 'Fred')
|
245
|
+
@person_class.identity_map.clear
|
246
|
+
person2 = @person_class.create(:name => 'Bill')
|
247
|
+
person3 = @person_class.create(:name => 'Jesse')
|
248
|
+
|
249
|
+
assert_not_in_map(person1)
|
250
|
+
assert_in_map(person2, person3)
|
251
|
+
|
252
|
+
people = @person_class.find(person1.id, person2.id, person3.id)
|
253
|
+
assert_in_map(people.first) # making sure one that wasn't mapped now is
|
254
|
+
assert_in_map(person2, person3)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context "#first" do
|
259
|
+
context "for object not in map" do
|
260
|
+
setup do
|
261
|
+
@person = @person_class.create(:name => 'Fred')
|
262
|
+
@person_class.identity_map.clear
|
263
|
+
end
|
264
|
+
|
265
|
+
should "query the database" do
|
266
|
+
expects_one_query
|
267
|
+
@person_class.first(:_id => @person.id)
|
268
|
+
end
|
269
|
+
|
270
|
+
should "add object to map" do
|
271
|
+
assert_not_in_map(@person)
|
272
|
+
found_person = @person_class.first(:_id => @person.id)
|
273
|
+
assert_in_map(found_person)
|
274
|
+
end
|
275
|
+
|
276
|
+
should "return nil if not found" do
|
277
|
+
@person_class.first(:name => 'Bill').should be_nil
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
context "for object in map" do
|
282
|
+
setup do
|
283
|
+
@person = @person_class.create(:name => 'Fred')
|
284
|
+
end
|
285
|
+
|
286
|
+
should "not query database" do
|
287
|
+
expect_no_queries
|
288
|
+
@person_class.first(:_id => @person.id)
|
289
|
+
end
|
290
|
+
|
291
|
+
should "return exact object" do
|
292
|
+
assert_in_map(@person)
|
293
|
+
found_person = @person_class.first(:_id => @person.id)
|
294
|
+
found_person.should equal(@person)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
context "#all" do
|
300
|
+
should "add all documents to map" do
|
301
|
+
person1 = @person_class.create(:name => 'Fred')
|
302
|
+
person2 = @person_class.create(:name => 'Bill')
|
303
|
+
person3 = @person_class.create(:name => 'Jesse')
|
304
|
+
@person_class.identity_map.clear
|
305
|
+
|
306
|
+
people = @person_class.all(:_id => [person1.id, person2.id, person3.id])
|
307
|
+
assert_in_map(people)
|
308
|
+
end
|
309
|
+
|
310
|
+
should "add missing documents to map and return existing ones" do
|
311
|
+
person1 = @person_class.create(:name => 'Fred')
|
312
|
+
@person_class.identity_map.clear
|
313
|
+
person2 = @person_class.create(:name => 'Bill')
|
314
|
+
person3 = @person_class.create(:name => 'Jesse')
|
315
|
+
|
316
|
+
assert_not_in_map(person1)
|
317
|
+
assert_in_map(person2, person3)
|
318
|
+
|
319
|
+
people = @person_class.all(:_id => [person1.id, person2.id, person3.id])
|
320
|
+
# people.first is making sure one that wasn't mapped now is
|
321
|
+
assert_in_map(people.first, person2, person3)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
context "#find_by_id" do
|
326
|
+
setup do
|
327
|
+
@person = @person_class.create(:name => 'Bill')
|
328
|
+
end
|
329
|
+
|
330
|
+
should "return nil for document id not found in collection" do
|
331
|
+
assert_in_map(@person)
|
332
|
+
@person_class.find_by_id(1234).should be_nil
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
context "querying and selecting certain fields" do
|
337
|
+
setup do
|
338
|
+
@person = @person_class.create(:name => 'Bill')
|
339
|
+
@person_class.identity_map.clear
|
340
|
+
end
|
341
|
+
|
342
|
+
should "not add to map" do
|
343
|
+
assert_not_in_map(@person)
|
344
|
+
@person_class.first(:_id => @person.id, :select => 'name').should == @person
|
345
|
+
@person_class.first(:_id => @person.id, 'fields' => ['name']).should == @person
|
346
|
+
@person_class.last(:_id => @person.id, :select => 'name', :order => 'name').should == @person
|
347
|
+
@person_class.find(@person.id, :select => 'name').should == @person
|
348
|
+
@person_class.all(:_id => @person.id, :select => 'name').should == [@person]
|
349
|
+
assert_not_in_map(@person)
|
350
|
+
end
|
351
|
+
|
352
|
+
should "return nil if not found" do
|
353
|
+
@person_class.find(1234, :select => 'name').should be_nil
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
context "single collection inherited models" do
|
358
|
+
setup do
|
359
|
+
class ::Item
|
360
|
+
include MongoMapper::Document
|
361
|
+
plugin MongoMapper::Plugins::IdentityMap
|
362
|
+
|
363
|
+
key :_type, String
|
364
|
+
key :title, String
|
365
|
+
key :parent_id, ObjectId
|
366
|
+
|
367
|
+
belongs_to :parent, :class_name => 'Item'
|
368
|
+
one :blog, :class_name => 'Blog', :foreign_key => 'parent_id'
|
369
|
+
end
|
370
|
+
Item.collection.remove
|
371
|
+
|
372
|
+
class ::Blog < ::Item; end
|
373
|
+
|
374
|
+
class ::BlogPost < ::Item
|
375
|
+
key :blog_id, ObjectId
|
376
|
+
belongs_to :blog
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
teardown do
|
381
|
+
Object.send :remove_const, 'Item' if defined?(::Item)
|
382
|
+
Object.send :remove_const, 'Blog' if defined?(::Blog)
|
383
|
+
Object.send :remove_const, 'BlogPost' if defined?(::BlogPost)
|
384
|
+
end
|
385
|
+
|
386
|
+
should "share the same identity map" do
|
387
|
+
blog = Blog.create(:title => 'Jill')
|
388
|
+
assert_in_map(blog)
|
389
|
+
Item.identity_map.should equal(Blog.identity_map)
|
390
|
+
end
|
391
|
+
|
392
|
+
should "not query when finding by _id and _type" do
|
393
|
+
blog = Blog.create(:title => 'Blog')
|
394
|
+
post = BlogPost.create(:title => 'Mongo Rocks', :blog => blog)
|
395
|
+
Item.identity_map.clear
|
396
|
+
|
397
|
+
blog = Item.find(blog.id)
|
398
|
+
post = Item.find(post.id)
|
399
|
+
assert_in_map(blog, post)
|
400
|
+
|
401
|
+
expect_no_queries
|
402
|
+
post.blog
|
403
|
+
Blog.find(blog.id)
|
404
|
+
end
|
405
|
+
|
406
|
+
should "load from map when using parent collection inherited class" do
|
407
|
+
blog = Blog.create(:title => 'Jill')
|
408
|
+
Item.find(blog.id).should equal(blog)
|
409
|
+
end
|
410
|
+
|
411
|
+
should "work correctly with belongs to proxy" do
|
412
|
+
root = Item.create(:title => 'Root')
|
413
|
+
assert_in_map(root)
|
414
|
+
|
415
|
+
blog = Blog.create(:title => 'Jill', :parent => root)
|
416
|
+
assert_in_map(blog)
|
417
|
+
root.should equal(blog.parent)
|
418
|
+
end
|
419
|
+
|
420
|
+
should "work correctly with one proxy" do
|
421
|
+
blog = Blog.create(:title => 'Jill')
|
422
|
+
assert_in_map(blog)
|
423
|
+
|
424
|
+
root = Item.create(:title => 'Root', :blog => blog)
|
425
|
+
assert_in_map(root)
|
426
|
+
root.blog.should equal(blog)
|
427
|
+
end
|
428
|
+
|
429
|
+
should "work correctly with one proxy create" do
|
430
|
+
root = Item.create(:title => 'Root')
|
431
|
+
blog = root.blog.create(:title => 'Blog')
|
432
|
+
blog.parent.should equal(root)
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
context "without identity map" do
|
437
|
+
should "not add to map on save" do
|
438
|
+
@post_class.without_identity_map do
|
439
|
+
post = @post_class.create(:title => 'Bill')
|
440
|
+
assert_not_in_map(post)
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
should "not remove from map on delete" do
|
445
|
+
post = @post_class.create(:title => 'Bill')
|
446
|
+
assert_in_map(post)
|
447
|
+
|
448
|
+
@post_class.without_identity_map do
|
449
|
+
post.destroy
|
450
|
+
end
|
451
|
+
|
452
|
+
assert_in_map(post)
|
453
|
+
end
|
454
|
+
|
455
|
+
should "not add to map when loading" do
|
456
|
+
@post_class.without_identity_map do
|
457
|
+
post = @post_class.load({'_id' => Mongo::ObjectID.new, 'title' => 'Awesome!'})
|
458
|
+
assert_not_in_map(post)
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
should "not load from map when loading" do
|
463
|
+
post = @post_class.create(:title => 'Awesome!')
|
464
|
+
|
465
|
+
@post_class.without_identity_map do
|
466
|
+
loaded = @post_class.load('_id' => post._id, 'title' => 'Awesome!')
|
467
|
+
loaded.should_not equal(post)
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
context "all" do
|
472
|
+
should "not add to map" do
|
473
|
+
@post_class.without_identity_map do
|
474
|
+
post1 = @post_class.create(:title => 'Foo')
|
475
|
+
post2 = @post_class.create(:title => 'Bar')
|
476
|
+
@post_class.identity_map.clear
|
477
|
+
|
478
|
+
assert_not_in_map(@post_class.all)
|
479
|
+
end
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
context "first" do
|
484
|
+
should "not add to map" do
|
485
|
+
@post_class.without_identity_map do
|
486
|
+
post1 = @post_class.create(:title => 'Foo')
|
487
|
+
post2 = @post_class.create(:title => 'Bar')
|
488
|
+
@post_class.identity_map.clear
|
489
|
+
|
490
|
+
assert_not_in_map(@post_class.first)
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
context "last" do
|
496
|
+
should "not add to map" do
|
497
|
+
@post_class.without_identity_map do
|
498
|
+
post1 = @post_class.create(:title => 'Foo')
|
499
|
+
post2 = @post_class.create(:title => 'Bar')
|
500
|
+
@post_class.identity_map.clear
|
501
|
+
|
502
|
+
assert_not_in_map(@post_class.last(:order => 'title'))
|
503
|
+
end
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|
507
|
+
end
|
508
|
+
end
|