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,256 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models'
|
3
|
+
|
4
|
+
class ManyEmbeddedProxyTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@comment_class = EDoc do
|
7
|
+
key :name, String
|
8
|
+
key :body, String
|
9
|
+
end
|
10
|
+
@post_class = Doc do
|
11
|
+
key :title, String
|
12
|
+
end
|
13
|
+
@post_class.many :comments, :class => @comment_class
|
14
|
+
|
15
|
+
@pet_class = EDoc do
|
16
|
+
key :name, String
|
17
|
+
end
|
18
|
+
@pet_class.embedded_in :person
|
19
|
+
@person_class = EDoc do
|
20
|
+
key :name, String
|
21
|
+
end
|
22
|
+
@person_class.key :child, @person_class
|
23
|
+
@person_class.many :pets, :class => @pet_class
|
24
|
+
|
25
|
+
@owner_class = Doc do
|
26
|
+
key :name, String
|
27
|
+
end
|
28
|
+
@owner_class.many :pets, :class => @pet_class
|
29
|
+
end
|
30
|
+
|
31
|
+
should "default reader to empty array" do
|
32
|
+
@post_class.new.comments.should == []
|
33
|
+
end
|
34
|
+
|
35
|
+
should "allow adding to association like it was an array" do
|
36
|
+
post = @post_class.new
|
37
|
+
post.comments << @comment_class.new
|
38
|
+
post.comments.push @comment_class.new
|
39
|
+
post.comments.size.should == 2
|
40
|
+
end
|
41
|
+
|
42
|
+
should "be embedded in document on save" do
|
43
|
+
frank = @comment_class.new(:name => 'Frank', :body => 'Hi!')
|
44
|
+
bill = @comment_class.new(:name => 'Bill', :body => 'Hi!')
|
45
|
+
post = @post_class.new
|
46
|
+
post.comments << frank
|
47
|
+
post.comments << bill
|
48
|
+
post.save
|
49
|
+
|
50
|
+
post.reload
|
51
|
+
post.comments.size.should == 2
|
52
|
+
post.comments[0].should == frank
|
53
|
+
post.comments[0].new?.should == false
|
54
|
+
post.comments[1].should == bill
|
55
|
+
post.comments[1].new?.should == false
|
56
|
+
end
|
57
|
+
|
58
|
+
should "allow embedding arbitrarily deep" do
|
59
|
+
@klass = Doc()
|
60
|
+
@klass.key :person, @person_class
|
61
|
+
|
62
|
+
meg = @person_class.new(:name => 'Meg')
|
63
|
+
meg.child = @person_class.new(:name => 'Steve')
|
64
|
+
meg.child.child = @person_class.new(:name => 'Linda')
|
65
|
+
|
66
|
+
doc = @klass.new(:person => meg)
|
67
|
+
doc.save
|
68
|
+
doc.reload
|
69
|
+
|
70
|
+
doc.person.name.should == 'Meg'
|
71
|
+
doc.person.child.name.should == 'Steve'
|
72
|
+
doc.person.child.child.name.should == 'Linda'
|
73
|
+
end
|
74
|
+
|
75
|
+
should "allow assignment of many embedded documents using a hash" do
|
76
|
+
person_attributes = {
|
77
|
+
'name' => 'Mr. Pet Lover',
|
78
|
+
'pets' => [
|
79
|
+
{'name' => 'Jimmy', 'species' => 'Cocker Spainel'},
|
80
|
+
{'name' => 'Sasha', 'species' => 'Siberian Husky'},
|
81
|
+
]
|
82
|
+
}
|
83
|
+
|
84
|
+
owner = @owner_class.new(person_attributes)
|
85
|
+
owner.name.should == 'Mr. Pet Lover'
|
86
|
+
owner.pets[0].name.should == 'Jimmy'
|
87
|
+
owner.pets[0].species.should == 'Cocker Spainel'
|
88
|
+
owner.pets[1].name.should == 'Sasha'
|
89
|
+
owner.pets[1].species.should == 'Siberian Husky'
|
90
|
+
|
91
|
+
owner.save.should be_true
|
92
|
+
owner.reload
|
93
|
+
|
94
|
+
owner.name.should == 'Mr. Pet Lover'
|
95
|
+
owner.pets[0].name.should == 'Jimmy'
|
96
|
+
owner.pets[0].species.should == 'Cocker Spainel'
|
97
|
+
owner.pets[1].name.should == 'Sasha'
|
98
|
+
owner.pets[1].species.should == 'Siberian Husky'
|
99
|
+
end
|
100
|
+
|
101
|
+
context "embedding many embedded documents" do
|
102
|
+
setup do
|
103
|
+
@klass = Doc()
|
104
|
+
@klass.many :people, :class => @person_class
|
105
|
+
end
|
106
|
+
|
107
|
+
should "persist all embedded documents" do
|
108
|
+
meg = @person_class.new(:name => 'Meg', :pets => [
|
109
|
+
@pet_class.new(:name => 'Sparky', :species => 'Dog'),
|
110
|
+
@pet_class.new(:name => 'Koda', :species => 'Dog')
|
111
|
+
])
|
112
|
+
|
113
|
+
doc = @klass.new
|
114
|
+
doc.people << meg
|
115
|
+
doc.save
|
116
|
+
doc.reload
|
117
|
+
|
118
|
+
doc.people.first.name.should == 'Meg'
|
119
|
+
doc.people.first.pets.should_not == []
|
120
|
+
doc.people.first.pets.first.name.should == 'Sparky'
|
121
|
+
doc.people.first.pets.first.species.should == 'Dog'
|
122
|
+
doc.people.first.pets[1].name.should == 'Koda'
|
123
|
+
doc.people.first.pets[1].species.should == 'Dog'
|
124
|
+
end
|
125
|
+
|
126
|
+
should "create a reference to the root document for all embedded documents before save" do
|
127
|
+
doc = @klass.new
|
128
|
+
meg = @person_class.new(:name => 'Meg')
|
129
|
+
pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
130
|
+
|
131
|
+
doc.people << meg
|
132
|
+
meg.pets << pet
|
133
|
+
|
134
|
+
doc.people.first._root_document.should == doc
|
135
|
+
doc.people.first.pets.first._root_document.should == doc
|
136
|
+
end
|
137
|
+
should "create a reference to the owning document for all embedded documents before save" do
|
138
|
+
doc = @klass.new
|
139
|
+
meg = @person_class.new(:name => 'Meg')
|
140
|
+
pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
141
|
+
|
142
|
+
doc.people << meg
|
143
|
+
meg.pets << pet
|
144
|
+
|
145
|
+
doc.people.first._parent_document.should == doc
|
146
|
+
doc.people.first.pets.first._parent_document.should == doc.people.first
|
147
|
+
end
|
148
|
+
|
149
|
+
should "create a reference to the root document for all embedded documents" do
|
150
|
+
sparky = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
151
|
+
meg = @person_class.new(:name => 'Meg', :pets => [sparky])
|
152
|
+
doc = @klass.new
|
153
|
+
doc.people << meg
|
154
|
+
doc.save
|
155
|
+
|
156
|
+
doc.reload
|
157
|
+
doc.people.first._root_document.should == doc
|
158
|
+
doc.people.first.pets.first._root_document.should == doc
|
159
|
+
end
|
160
|
+
should "create a reference to the owning document for all embedded documents" do
|
161
|
+
doc = @klass.new
|
162
|
+
meg = @person_class.new(:name => 'Meg')
|
163
|
+
pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
164
|
+
|
165
|
+
doc.people << meg
|
166
|
+
meg.pets << pet
|
167
|
+
doc.save
|
168
|
+
|
169
|
+
doc.reload
|
170
|
+
doc.people.first._parent_document.should == doc
|
171
|
+
doc.people.first.pets.first._parent_document.should == doc.people.first
|
172
|
+
end
|
173
|
+
|
174
|
+
should "create embedded_in relationship for embedded docs" do
|
175
|
+
doc = @klass.new
|
176
|
+
meg = @person_class.new(:name => 'Meg')
|
177
|
+
pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
178
|
+
|
179
|
+
doc.people << meg
|
180
|
+
meg.pets << pet
|
181
|
+
doc.save
|
182
|
+
|
183
|
+
doc.reload
|
184
|
+
doc.people.first.pets.first.person.should == doc.people.first
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
should "allow finding by id" do
|
189
|
+
sparky = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
190
|
+
meg = @owner_class.create(:name => 'Meg', :pets => [sparky])
|
191
|
+
|
192
|
+
meg.pets.find(sparky._id).should == sparky # oid
|
193
|
+
meg.pets.find(sparky.id.to_s).should == sparky # string
|
194
|
+
end
|
195
|
+
|
196
|
+
context "count" do
|
197
|
+
should "default to 0" do
|
198
|
+
@owner_class.new.pets.count.should == 0
|
199
|
+
end
|
200
|
+
|
201
|
+
should "return correct count if any are embedded" do
|
202
|
+
owner = @owner_class.new(:name => 'Meg')
|
203
|
+
owner.pets = [@pet_class.new, @pet_class.new]
|
204
|
+
owner.pets.count.should == 2
|
205
|
+
owner.save
|
206
|
+
owner.reload
|
207
|
+
owner.pets.count.should == 2
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
context "extending the association" do
|
212
|
+
setup do
|
213
|
+
@address_class = EDoc do
|
214
|
+
key :address, String
|
215
|
+
key :city, String
|
216
|
+
key :state, String
|
217
|
+
key :zip, Integer
|
218
|
+
end
|
219
|
+
|
220
|
+
@project_class = Doc do
|
221
|
+
key :name, String
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
should "work using a block passed to many" do
|
226
|
+
@project_class.many :addresses, :class => @address_class do
|
227
|
+
def find_all_by_state(state)
|
228
|
+
find_all { |a| a.state == state }
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
addr1 = @address_class.new(:address => "Gate-3 Lankershim Blvd.", :city => "Universal City", :state => "CA", :zip => "91608")
|
233
|
+
addr2 = @address_class.new(:address => "3000 W. Alameda Ave.", :city => "Burbank", :state => "CA", :zip => "91523")
|
234
|
+
addr3 = @address_class.new(:address => "111 Some Ln", :city => "Nashville", :state => "TN", :zip => "37211")
|
235
|
+
project = @project_class.create(:name => "Some Project", :addresses => [addr1, addr2, addr3])
|
236
|
+
|
237
|
+
project.addresses.find_all_by_state("CA").should == [addr1, addr2]
|
238
|
+
end
|
239
|
+
|
240
|
+
should "work using many's :extend option" do
|
241
|
+
module FindByCity
|
242
|
+
def find_by_city(city)
|
243
|
+
find_all { |a| a.city == city }
|
244
|
+
end
|
245
|
+
end
|
246
|
+
@project_class.many :addresses, :class => @address_class, :extend => FindByCity
|
247
|
+
|
248
|
+
addr1 = @address_class.new(:address => "Gate-3 Lankershim Blvd.", :city => "Universal City", :state => "CA", :zip => "91608")
|
249
|
+
addr2 = @address_class.new(:address => "3000 W. Alameda Ave.", :city => "Burbank", :state => "CA", :zip => "91523")
|
250
|
+
addr3 = @address_class.new(:address => "111 Some Ln", :city => "Nashville", :state => "TN", :zip => "37211")
|
251
|
+
project = @project_class.create(:name => "Some Project", :addresses => [addr1, addr2, addr3])
|
252
|
+
|
253
|
+
project.addresses.find_by_city('Burbank').should == [addr2]
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
@@ -0,0 +1,302 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models'
|
3
|
+
|
4
|
+
class ManyPolymorphicProxyTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
Room.collection.remove
|
7
|
+
Message.collection.remove
|
8
|
+
end
|
9
|
+
|
10
|
+
should "default reader to empty array" do
|
11
|
+
Room.new.messages.should == []
|
12
|
+
end
|
13
|
+
|
14
|
+
should "add type key to polymorphic class base" do
|
15
|
+
Message.keys.keys.should include('_type')
|
16
|
+
end
|
17
|
+
|
18
|
+
should "allow adding to assiciation like it was an array" do
|
19
|
+
room = Room.new
|
20
|
+
room.messages << Enter.new
|
21
|
+
room.messages.push Exit.new
|
22
|
+
room.messages.concat Exit.new
|
23
|
+
room.messages.size.should == 3
|
24
|
+
end
|
25
|
+
|
26
|
+
should "be able to replace the association" do
|
27
|
+
room = Room.create(:name => 'Lounge')
|
28
|
+
|
29
|
+
lambda {
|
30
|
+
room.messages = [
|
31
|
+
Enter.new(:body => 'John entered room', :position => 1),
|
32
|
+
Chat.new(:body => 'Heyyyoooo!', :position => 2),
|
33
|
+
Exit.new(:body => 'John exited room', :position => 3)
|
34
|
+
]
|
35
|
+
}.should change { Message.count }.by(3)
|
36
|
+
|
37
|
+
room = room.reload
|
38
|
+
messages = room.messages.all :order => "position"
|
39
|
+
messages.size.should == 3
|
40
|
+
messages[0].body.should == 'John entered room'
|
41
|
+
messages[1].body.should == 'Heyyyoooo!'
|
42
|
+
messages[2].body.should == 'John exited room'
|
43
|
+
end
|
44
|
+
|
45
|
+
should "correctly store type when using <<, push and concat" do
|
46
|
+
room = Room.new
|
47
|
+
room.messages << Enter.new(:body => 'John entered the room', :position => 1)
|
48
|
+
room.messages.push Exit.new(:body => 'John entered the room', :position => 2)
|
49
|
+
room.messages.concat Chat.new(:body => 'Holla!' , :position => 3)
|
50
|
+
|
51
|
+
room = room.reload
|
52
|
+
messages = room.messages.all :order => "position"
|
53
|
+
messages[0]._type.should == 'Enter'
|
54
|
+
messages[1]._type.should == 'Exit'
|
55
|
+
messages[2]._type.should == 'Chat'
|
56
|
+
end
|
57
|
+
|
58
|
+
context "build" do
|
59
|
+
should "assign foreign key" do
|
60
|
+
room = Room.create
|
61
|
+
message = room.messages.build
|
62
|
+
message.room_id.should == room._id
|
63
|
+
end
|
64
|
+
|
65
|
+
should "assign _type" do
|
66
|
+
room = Room.create
|
67
|
+
message = room.messages.build
|
68
|
+
message._type.should == 'Message'
|
69
|
+
end
|
70
|
+
|
71
|
+
should "allow assigning attributes" do
|
72
|
+
room = Room.create
|
73
|
+
message = room.messages.build(:body => 'Foo!')
|
74
|
+
message.body.should == 'Foo!'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "create" do
|
79
|
+
should "assign foreign key" do
|
80
|
+
room = Room.create
|
81
|
+
message = room.messages.create
|
82
|
+
message.room_id.should == room._id
|
83
|
+
end
|
84
|
+
|
85
|
+
should "assign _type" do
|
86
|
+
room = Room.create
|
87
|
+
message = room.messages.create
|
88
|
+
message._type.should == 'Message'
|
89
|
+
end
|
90
|
+
|
91
|
+
should "save record" do
|
92
|
+
room = Room.create
|
93
|
+
lambda {
|
94
|
+
room.messages.create
|
95
|
+
}.should change { Message.count }
|
96
|
+
end
|
97
|
+
|
98
|
+
should "allow passing attributes" do
|
99
|
+
room = Room.create
|
100
|
+
message = room.messages.create(:body => 'Foo!')
|
101
|
+
message.body.should == 'Foo!'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "count" do
|
106
|
+
should "work scoped to association" do
|
107
|
+
room = Room.create
|
108
|
+
3.times { room.messages.create }
|
109
|
+
|
110
|
+
other_room = Room.create
|
111
|
+
2.times { other_room.messages.create }
|
112
|
+
|
113
|
+
room.messages.count.should == 3
|
114
|
+
other_room.messages.count.should == 2
|
115
|
+
end
|
116
|
+
|
117
|
+
should "work with conditions" do
|
118
|
+
room = Room.create
|
119
|
+
room.messages.create(:body => 'Foo')
|
120
|
+
room.messages.create(:body => 'Other 1')
|
121
|
+
room.messages.create(:body => 'Other 2')
|
122
|
+
|
123
|
+
room.messages.count(:body => 'Foo').should == 1
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context "Finding scoped to association" do
|
128
|
+
setup do
|
129
|
+
@lounge = Room.create(:name => 'Lounge')
|
130
|
+
@lm1 = Message.create(:body => 'Loungin!', :position => 1)
|
131
|
+
@lm2 = Message.create(:body => 'I love loungin!', :position => 2)
|
132
|
+
@lounge.messages = [@lm1, @lm2]
|
133
|
+
@lounge.save
|
134
|
+
|
135
|
+
@hall = Room.create(:name => 'Hall')
|
136
|
+
@hm1 = Message.create(:body => 'Do not fall in the hall', :position => 1)
|
137
|
+
@hm3 = Message.create(:body => 'Loungin!', :position => 3)
|
138
|
+
@hm2 = Message.create(:body => 'Hall the king!', :position => 2)
|
139
|
+
@hall.messages = [@hm1, @hm2, @hm3]
|
140
|
+
@hall.save
|
141
|
+
end
|
142
|
+
|
143
|
+
context "dynamic finders" do
|
144
|
+
should "work with single key" do
|
145
|
+
@lounge.messages.find_by_position(1).should == @lm1
|
146
|
+
@hall.messages.find_by_position(2).should == @hm2
|
147
|
+
end
|
148
|
+
|
149
|
+
should "work with multiple keys" do
|
150
|
+
@lounge.messages.find_by_body_and_position('Loungin!', 1).should == @lm1
|
151
|
+
@lounge.messages.find_by_body_and_position('Loungin!', 2).should be_nil
|
152
|
+
end
|
153
|
+
|
154
|
+
should "raise error when using !" do
|
155
|
+
lambda {
|
156
|
+
@lounge.messages.find_by_position!(222)
|
157
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
158
|
+
end
|
159
|
+
|
160
|
+
context "find_or_create_by" do
|
161
|
+
should "not create document if found" do
|
162
|
+
lambda {
|
163
|
+
message = @lounge.messages.find_or_create_by_body('Loungin!')
|
164
|
+
message.room.should == @lounge
|
165
|
+
message.should == @lm1
|
166
|
+
}.should_not change { Message.count }
|
167
|
+
end
|
168
|
+
|
169
|
+
should "create document if not found" do
|
170
|
+
lambda {
|
171
|
+
message = @lounge.messages.find_or_create_by_body('Yo dawg!')
|
172
|
+
message.room.should == @lounge
|
173
|
+
message._type.should == 'Message'
|
174
|
+
}.should change { Message.count }.by(1)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "with #all" do
|
180
|
+
should "work" do
|
181
|
+
@lounge.messages.all(:order => "position").should == [@lm1, @lm2]
|
182
|
+
end
|
183
|
+
|
184
|
+
should "work with conditions" do
|
185
|
+
messages = @lounge.messages.all(:body => 'Loungin!', :order => "position")
|
186
|
+
messages.should == [@lm1]
|
187
|
+
end
|
188
|
+
|
189
|
+
should "work with order" do
|
190
|
+
messages = @lounge.messages.all(:order => 'position desc')
|
191
|
+
messages.should == [@lm2, @lm1]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "with #first" do
|
196
|
+
should "work" do
|
197
|
+
@lounge.messages.first(:order => "position asc").should == @lm1
|
198
|
+
end
|
199
|
+
|
200
|
+
should "work with conditions" do
|
201
|
+
message = @lounge.messages.first(:body => 'I love loungin!', :order => "position asc")
|
202
|
+
message.should == @lm2
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context "with #last" do
|
207
|
+
should "work" do
|
208
|
+
@lounge.messages.last(:order => "position asc").should == @lm2
|
209
|
+
end
|
210
|
+
|
211
|
+
should "work with conditions" do
|
212
|
+
message = @lounge.messages.last(:body => 'Loungin!', :order => "position asc")
|
213
|
+
message.should == @lm1
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context "with one id" do
|
218
|
+
should "work for id in association" do
|
219
|
+
@lounge.messages.find(@lm2._id).should == @lm2
|
220
|
+
end
|
221
|
+
|
222
|
+
should "not work for id not in association" do
|
223
|
+
lambda {
|
224
|
+
@lounge.messages.find!(@hm2._id)
|
225
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context "with query options/criteria" do
|
230
|
+
should "work with order on association" do
|
231
|
+
@lounge.messages.should == [@lm1, @lm2]
|
232
|
+
end
|
233
|
+
|
234
|
+
should "allow overriding the order provided to the association" do
|
235
|
+
@lounge.messages.all(:order => 'position').should == [@lm1, @lm2]
|
236
|
+
end
|
237
|
+
|
238
|
+
should "allow using conditions on association" do
|
239
|
+
@hall.latest_messages.should == [@hm3, @hm2]
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context "with multiple ids" do
|
244
|
+
should "work for ids in association" do
|
245
|
+
messages = @lounge.messages.find(@lm1._id, @lm2._id)
|
246
|
+
messages.should == [@lm1, @lm2]
|
247
|
+
end
|
248
|
+
|
249
|
+
should "not work for ids not in association" do
|
250
|
+
assert_raises(MongoMapper::DocumentNotFound) do
|
251
|
+
@lounge.messages.find!(@lm1._id, @lm2._id, @hm2._id)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
context "with #paginate" do
|
257
|
+
setup do
|
258
|
+
@messages = @hall.messages.paginate(:per_page => 2, :page => 1, :order => 'position asc')
|
259
|
+
end
|
260
|
+
|
261
|
+
should "return total pages" do
|
262
|
+
@messages.total_pages.should == 2
|
263
|
+
end
|
264
|
+
|
265
|
+
should "return total entries" do
|
266
|
+
@messages.total_entries.should == 3
|
267
|
+
end
|
268
|
+
|
269
|
+
should "return the subject" do
|
270
|
+
@messages.should == [@hm1, @hm2]
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
context "extending the association" do
|
276
|
+
should "work using a block passed to many" do
|
277
|
+
room = Room.new(:name => "Amazing Room")
|
278
|
+
messages = room.messages = [
|
279
|
+
Enter.new(:body => 'John entered room', :position => 3),
|
280
|
+
Chat.new(:body => 'Heyyyoooo!', :position => 4),
|
281
|
+
Exit.new(:body => 'John exited room', :position => 5),
|
282
|
+
Enter.new(:body => 'Steve entered room', :position => 6),
|
283
|
+
Chat.new(:body => 'Anyone there?', :position => 7),
|
284
|
+
Exit.new(:body => 'Steve exited room', :position => 8)
|
285
|
+
]
|
286
|
+
room.save
|
287
|
+
room.messages.older.should == messages[3..5]
|
288
|
+
end
|
289
|
+
|
290
|
+
should "work using many's :extend option" do
|
291
|
+
|
292
|
+
room = Room.new(:name => "Amazing Room")
|
293
|
+
accounts = room.accounts = [
|
294
|
+
Bot.new(:last_logged_in => 3.weeks.ago),
|
295
|
+
AccountUser.new(:last_logged_in => nil),
|
296
|
+
Bot.new(:last_logged_in => 1.week.ago)
|
297
|
+
]
|
298
|
+
room.save
|
299
|
+
room.accounts.inactive.should == [accounts[1]]
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|