mongoid 1.2.14 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. data/lib/mongoid.rb +10 -3
  2. data/lib/mongoid/associations.rb +133 -97
  3. data/lib/mongoid/associations/belongs_to_related.rb +2 -3
  4. data/lib/mongoid/associations/{belongs_to.rb → embedded_in.rb} +14 -6
  5. data/lib/mongoid/associations/{has_many.rb → embeds_many.rb} +89 -31
  6. data/lib/mongoid/associations/{has_one.rb → embeds_one.rb} +8 -7
  7. data/lib/mongoid/associations/has_many_related.rb +52 -7
  8. data/lib/mongoid/associations/has_one_related.rb +8 -4
  9. data/lib/mongoid/associations/meta_data.rb +2 -1
  10. data/lib/mongoid/associations/options.rb +6 -1
  11. data/lib/mongoid/associations/proxy.rb +14 -21
  12. data/lib/mongoid/attributes.rb +27 -12
  13. data/lib/mongoid/collection.rb +4 -3
  14. data/lib/mongoid/collections.rb +41 -0
  15. data/lib/mongoid/collections/master.rb +3 -2
  16. data/lib/mongoid/collections/slaves.rb +3 -2
  17. data/lib/mongoid/components.rb +21 -19
  18. data/lib/mongoid/concern.rb +31 -0
  19. data/lib/mongoid/config.rb +117 -12
  20. data/lib/mongoid/contexts.rb +1 -1
  21. data/lib/mongoid/contexts/enumerable.rb +1 -1
  22. data/lib/mongoid/contexts/mongo.rb +1 -1
  23. data/lib/mongoid/contexts/paging.rb +10 -2
  24. data/lib/mongoid/criterion/inclusion.rb +17 -0
  25. data/lib/mongoid/criterion/optional.rb +1 -1
  26. data/lib/mongoid/dirty.rb +253 -0
  27. data/lib/mongoid/document.rb +81 -52
  28. data/lib/mongoid/errors.rb +32 -1
  29. data/lib/mongoid/extensions.rb +11 -9
  30. data/lib/mongoid/extensions/big_decimal/conversions.rb +2 -2
  31. data/lib/mongoid/extensions/boolean/conversions.rb +8 -2
  32. data/lib/mongoid/extensions/date/conversions.rb +13 -4
  33. data/lib/mongoid/extensions/datetime/conversions.rb +1 -6
  34. data/lib/mongoid/extensions/float/conversions.rb +5 -1
  35. data/lib/mongoid/extensions/hash/assimilation.rb +12 -3
  36. data/lib/mongoid/extensions/hash/conversions.rb +34 -4
  37. data/lib/mongoid/extensions/integer/conversions.rb +5 -1
  38. data/lib/mongoid/extensions/nil/assimilation.rb +4 -0
  39. data/lib/mongoid/extensions/object/conversions.rb +1 -1
  40. data/lib/mongoid/extensions/string/conversions.rb +1 -1
  41. data/lib/mongoid/extensions/symbol/inflections.rb +1 -1
  42. data/lib/mongoid/extensions/time_conversions.rb +35 -0
  43. data/lib/mongoid/extras.rb +6 -9
  44. data/lib/mongoid/factory.rb +2 -1
  45. data/lib/mongoid/field.rb +9 -2
  46. data/lib/mongoid/fields.rb +1 -0
  47. data/lib/mongoid/identity.rb +3 -3
  48. data/lib/mongoid/indexes.rb +3 -3
  49. data/lib/mongoid/memoization.rb +8 -2
  50. data/lib/mongoid/named_scope.rb +0 -3
  51. data/lib/mongoid/observable.rb +30 -0
  52. data/lib/mongoid/paths.rb +62 -0
  53. data/lib/mongoid/persistence.rb +222 -0
  54. data/lib/mongoid/persistence/command.rb +39 -0
  55. data/lib/mongoid/persistence/insert.rb +50 -0
  56. data/lib/mongoid/persistence/insert_embedded.rb +38 -0
  57. data/lib/mongoid/persistence/remove.rb +39 -0
  58. data/lib/mongoid/persistence/remove_all.rb +37 -0
  59. data/lib/mongoid/persistence/remove_embedded.rb +50 -0
  60. data/lib/mongoid/persistence/update.rb +63 -0
  61. data/lib/mongoid/state.rb +28 -21
  62. data/lib/mongoid/timestamps.rb +5 -8
  63. data/lib/mongoid/version.rb +4 -0
  64. data/lib/mongoid/versioning.rb +6 -7
  65. metadata +81 -300
  66. data/.gitignore +0 -6
  67. data/.watchr +0 -29
  68. data/Rakefile +0 -53
  69. data/VERSION +0 -1
  70. data/caliper.yml +0 -4
  71. data/lib/mongoid/collections/mimic.rb +0 -46
  72. data/lib/mongoid/commands.rb +0 -174
  73. data/lib/mongoid/commands/create.rb +0 -21
  74. data/lib/mongoid/commands/delete.rb +0 -16
  75. data/lib/mongoid/commands/delete_all.rb +0 -23
  76. data/lib/mongoid/commands/deletion.rb +0 -18
  77. data/lib/mongoid/commands/destroy.rb +0 -19
  78. data/lib/mongoid/commands/destroy_all.rb +0 -23
  79. data/lib/mongoid/commands/save.rb +0 -27
  80. data/lib/mongoid/extensions/time/conversions.rb +0 -18
  81. data/mongoid.gemspec +0 -395
  82. data/perf/benchmark.rb +0 -77
  83. data/spec/integration/mongoid/associations_spec.rb +0 -340
  84. data/spec/integration/mongoid/attributes_spec.rb +0 -22
  85. data/spec/integration/mongoid/commands_spec.rb +0 -218
  86. data/spec/integration/mongoid/contexts/enumerable_spec.rb +0 -33
  87. data/spec/integration/mongoid/criteria_spec.rb +0 -272
  88. data/spec/integration/mongoid/document_spec.rb +0 -593
  89. data/spec/integration/mongoid/extensions_spec.rb +0 -26
  90. data/spec/integration/mongoid/finders_spec.rb +0 -119
  91. data/spec/integration/mongoid/inheritance_spec.rb +0 -137
  92. data/spec/integration/mongoid/named_scope_spec.rb +0 -46
  93. data/spec/models/address.rb +0 -39
  94. data/spec/models/animal.rb +0 -6
  95. data/spec/models/callbacks.rb +0 -18
  96. data/spec/models/comment.rb +0 -8
  97. data/spec/models/country_code.rb +0 -6
  98. data/spec/models/employer.rb +0 -5
  99. data/spec/models/game.rb +0 -7
  100. data/spec/models/inheritance.rb +0 -56
  101. data/spec/models/location.rb +0 -5
  102. data/spec/models/mixed_drink.rb +0 -4
  103. data/spec/models/name.rb +0 -13
  104. data/spec/models/namespacing.rb +0 -11
  105. data/spec/models/patient.rb +0 -4
  106. data/spec/models/person.rb +0 -99
  107. data/spec/models/pet.rb +0 -7
  108. data/spec/models/pet_owner.rb +0 -6
  109. data/spec/models/phone.rb +0 -7
  110. data/spec/models/post.rb +0 -15
  111. data/spec/models/translation.rb +0 -5
  112. data/spec/models/vet_visit.rb +0 -5
  113. data/spec/spec.opts +0 -3
  114. data/spec/spec_helper.rb +0 -31
  115. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +0 -145
  116. data/spec/unit/mongoid/associations/belongs_to_spec.rb +0 -193
  117. data/spec/unit/mongoid/associations/has_many_related_spec.rb +0 -420
  118. data/spec/unit/mongoid/associations/has_many_spec.rb +0 -519
  119. data/spec/unit/mongoid/associations/has_one_related_spec.rb +0 -179
  120. data/spec/unit/mongoid/associations/has_one_spec.rb +0 -282
  121. data/spec/unit/mongoid/associations/meta_data_spec.rb +0 -88
  122. data/spec/unit/mongoid/associations/options_spec.rb +0 -192
  123. data/spec/unit/mongoid/associations_spec.rb +0 -595
  124. data/spec/unit/mongoid/attributes_spec.rb +0 -507
  125. data/spec/unit/mongoid/callbacks_spec.rb +0 -55
  126. data/spec/unit/mongoid/collection_spec.rb +0 -187
  127. data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +0 -75
  128. data/spec/unit/mongoid/collections/master_spec.rb +0 -41
  129. data/spec/unit/mongoid/collections/mimic_spec.rb +0 -43
  130. data/spec/unit/mongoid/collections/slaves_spec.rb +0 -81
  131. data/spec/unit/mongoid/commands/create_spec.rb +0 -30
  132. data/spec/unit/mongoid/commands/delete_all_spec.rb +0 -58
  133. data/spec/unit/mongoid/commands/delete_spec.rb +0 -38
  134. data/spec/unit/mongoid/commands/destroy_all_spec.rb +0 -23
  135. data/spec/unit/mongoid/commands/destroy_spec.rb +0 -50
  136. data/spec/unit/mongoid/commands/save_spec.rb +0 -105
  137. data/spec/unit/mongoid/commands_spec.rb +0 -275
  138. data/spec/unit/mongoid/config_spec.rb +0 -172
  139. data/spec/unit/mongoid/contexts/enumerable_spec.rb +0 -421
  140. data/spec/unit/mongoid/contexts/mongo_spec.rb +0 -682
  141. data/spec/unit/mongoid/contexts_spec.rb +0 -25
  142. data/spec/unit/mongoid/criteria_spec.rb +0 -824
  143. data/spec/unit/mongoid/criterion/complex_spec.rb +0 -19
  144. data/spec/unit/mongoid/criterion/exclusion_spec.rb +0 -91
  145. data/spec/unit/mongoid/criterion/inclusion_spec.rb +0 -219
  146. data/spec/unit/mongoid/criterion/optional_spec.rb +0 -319
  147. data/spec/unit/mongoid/cursor_spec.rb +0 -74
  148. data/spec/unit/mongoid/deprecation_spec.rb +0 -24
  149. data/spec/unit/mongoid/document_spec.rb +0 -952
  150. data/spec/unit/mongoid/errors_spec.rb +0 -103
  151. data/spec/unit/mongoid/extensions/array/accessors_spec.rb +0 -50
  152. data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +0 -24
  153. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +0 -35
  154. data/spec/unit/mongoid/extensions/array/parentization_spec.rb +0 -20
  155. data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +0 -22
  156. data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +0 -22
  157. data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +0 -49
  158. data/spec/unit/mongoid/extensions/date/conversions_spec.rb +0 -102
  159. data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +0 -70
  160. data/spec/unit/mongoid/extensions/float/conversions_spec.rb +0 -61
  161. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +0 -184
  162. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +0 -46
  163. data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +0 -21
  164. data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +0 -17
  165. data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +0 -14
  166. data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +0 -61
  167. data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +0 -24
  168. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +0 -57
  169. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +0 -34
  170. data/spec/unit/mongoid/extensions/string/conversions_spec.rb +0 -17
  171. data/spec/unit/mongoid/extensions/string/inflections_spec.rb +0 -208
  172. data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +0 -91
  173. data/spec/unit/mongoid/extensions/time/conversions_spec.rb +0 -70
  174. data/spec/unit/mongoid/extras_spec.rb +0 -102
  175. data/spec/unit/mongoid/factory_spec.rb +0 -31
  176. data/spec/unit/mongoid/field_spec.rb +0 -143
  177. data/spec/unit/mongoid/fields_spec.rb +0 -181
  178. data/spec/unit/mongoid/finders_spec.rb +0 -404
  179. data/spec/unit/mongoid/identity_spec.rb +0 -109
  180. data/spec/unit/mongoid/indexes_spec.rb +0 -93
  181. data/spec/unit/mongoid/javascript_spec.rb +0 -48
  182. data/spec/unit/mongoid/matchers/all_spec.rb +0 -27
  183. data/spec/unit/mongoid/matchers/default_spec.rb +0 -27
  184. data/spec/unit/mongoid/matchers/exists_spec.rb +0 -56
  185. data/spec/unit/mongoid/matchers/gt_spec.rb +0 -39
  186. data/spec/unit/mongoid/matchers/gte_spec.rb +0 -49
  187. data/spec/unit/mongoid/matchers/in_spec.rb +0 -27
  188. data/spec/unit/mongoid/matchers/lt_spec.rb +0 -39
  189. data/spec/unit/mongoid/matchers/lte_spec.rb +0 -49
  190. data/spec/unit/mongoid/matchers/ne_spec.rb +0 -27
  191. data/spec/unit/mongoid/matchers/nin_spec.rb +0 -27
  192. data/spec/unit/mongoid/matchers/size_spec.rb +0 -27
  193. data/spec/unit/mongoid/matchers_spec.rb +0 -329
  194. data/spec/unit/mongoid/memoization_spec.rb +0 -75
  195. data/spec/unit/mongoid/named_scope_spec.rb +0 -123
  196. data/spec/unit/mongoid/scope_spec.rb +0 -240
  197. data/spec/unit/mongoid/state_spec.rb +0 -83
  198. data/spec/unit/mongoid/timestamps_spec.rb +0 -25
  199. data/spec/unit/mongoid/versioning_spec.rb +0 -41
  200. data/spec/unit/mongoid_spec.rb +0 -46
@@ -1,74 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Mongoid::Cursor do
4
-
5
- let(:collection) do
6
- stub.quacks_like(Mongoid::Collection.allocate)
7
- end
8
-
9
- let(:proxy) do
10
- stub.quacks_like(Mongo::Cursor.allocate)
11
- end
12
-
13
- let(:cursor) do
14
- Mongoid::Cursor.new(Person, collection, proxy)
15
- end
16
-
17
- (Mongoid::Cursor::OPERATIONS - [ :timeout ]).each do |name|
18
-
19
- describe "##{name}" do
20
-
21
- before do
22
- proxy.expects(name)
23
- end
24
-
25
- it "delegates to the proxy" do
26
- cursor.send(name)
27
- end
28
- end
29
- end
30
-
31
- describe "#collection" do
32
-
33
- it "returns the mongoid collection" do
34
- cursor.collection.should == collection
35
- end
36
- end
37
-
38
- describe "#each" do
39
-
40
- before do
41
- proxy.expects(:each).yields({ "_type" => "Person" })
42
- end
43
-
44
- it "yields to the next document" do
45
- cursor.each do |doc|
46
- doc.attributes.except(:_id).should == Person.new.attributes.except(:_id)
47
- end
48
- end
49
- end
50
-
51
- describe "#next_document" do
52
-
53
- before do
54
- proxy.expects(:next_document).returns({ "_type" => "Person" })
55
- end
56
-
57
- it "returns the next document from the proxied cursor" do
58
- doc = cursor.next_document
59
- doc.attributes.except(:_id).should == Person.new.attributes.except(:_id)
60
- end
61
- end
62
-
63
- describe "#to_a" do
64
-
65
- before do
66
- proxy.expects(:to_a).returns([{ "_type" => "Person" }])
67
- end
68
-
69
- it "converts the proxy cursor to an array of documents" do
70
- docs = cursor.to_a
71
- docs[0].attributes.except(:_id).should == Person.new.attributes.except(:_id)
72
- end
73
- end
74
- end
@@ -1,24 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Mongoid::Deprecation do
4
-
5
- let(:logger) do
6
- stub.quacks_like(Logger.allocate)
7
- end
8
-
9
- before do
10
- Logger.expects(:new).with($stdout).returns(logger)
11
- end
12
-
13
- describe "#alert" do
14
-
15
- let(:deprecation) do
16
- Mongoid::Deprecation.instance
17
- end
18
-
19
- it "calls warn on the memoized logger" do
20
- logger.expects(:warn).with("Deprecation: testing")
21
- deprecation.alert("testing")
22
- end
23
- end
24
- end
@@ -1,952 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Mongoid::Document do
4
-
5
- before do
6
- @database = mock
7
- @collection = stub(:name => "people")
8
- @canvas_collection = stub(:name => "canvases")
9
- Mongoid::Collection.stubs(:new).with(Person, "people").returns(@collection)
10
- Mongoid::Collection.stubs(:new).with(Canvas, "canvases").returns(@canvas_collection)
11
- @collection.stubs(:create_index).with(:_type, false)
12
- @canvas_collection.stubs(:create_index).with(:_type, false)
13
- end
14
-
15
- after do
16
- Person._collection = nil
17
- Canvas._collection = nil
18
- end
19
-
20
- describe "#==" do
21
-
22
- context "when other object is a Document" do
23
-
24
- context "when attributes are equal" do
25
-
26
- before do
27
- @document = Person.new(:_id => 1, :title => "Sir")
28
- @other = Person.new(:_id => 1, :title => "Sir")
29
- end
30
-
31
- it "returns true" do
32
- @document.should == @other
33
- end
34
-
35
- end
36
-
37
- context "when attributes are not equal" do
38
-
39
- before do
40
- @document = Person.new(:title => "Sir")
41
- @other = Person.new(:title => "Madam")
42
- end
43
-
44
- it "returns false" do
45
- @document.should_not == @other
46
- end
47
-
48
- end
49
-
50
- end
51
-
52
- context "when other object is not a Document" do
53
-
54
- it "returns false" do
55
- Person.new.==("Test").should be_false
56
- end
57
-
58
- end
59
-
60
- context "when comapring parent to its subclass" do
61
-
62
- it "returns false" do
63
- Canvas.new.should_not == Firefox.new
64
- end
65
-
66
- end
67
-
68
- end
69
-
70
- describe "#eql?" do
71
-
72
- context "when other object is a Document" do
73
-
74
- context "when attributes are equal" do
75
-
76
- before do
77
- @document = Person.new(:_id => 1, :title => "Sir")
78
- @other = Person.new(:_id => 1, :title => "Sir")
79
- end
80
-
81
- it "returns true" do
82
- @document.eql?(@other).should be_true
83
- end
84
-
85
- end
86
-
87
- context "when attributes are not equal" do
88
-
89
- before do
90
- @document = Person.new(:title => "Sir")
91
- @other = Person.new(:title => "Madam")
92
- end
93
-
94
- it "returns false" do
95
- @document.eql?(@other).should_not be_true
96
- end
97
-
98
- end
99
-
100
- end
101
-
102
- context "when other object is not a Document" do
103
-
104
- it "returns false" do
105
- Person.new.eql?("Test").should be_false
106
- end
107
-
108
- end
109
-
110
- context "when comapring parent to its subclass" do
111
-
112
- it "returns false" do
113
- Canvas.new.eql?(Firefox.new).should_not be_true
114
- end
115
-
116
- end
117
-
118
- end
119
-
120
- describe "#hash" do
121
-
122
- before do
123
- @document = Person.new(:_id => 1, :title => "Sir")
124
- @other = Person.new(:_id => 2, :title => "Sir")
125
- end
126
-
127
- it "deligates to id" do
128
- @document.hash.should == @document.id.hash
129
- end
130
-
131
- it "has unique hash per id" do
132
- @document.hash.should_not == @other.hash
133
- end
134
-
135
- end
136
-
137
- describe "#alias_method_chain" do
138
-
139
- context "on a field setter" do
140
-
141
- before do
142
- @person = Person.new
143
- end
144
-
145
- it "chains the method properly" do
146
- @person.score = 10
147
- @person.rescored.should == 30
148
- end
149
-
150
- end
151
-
152
- end
153
-
154
- describe "#assimilate" do
155
-
156
- before do
157
- @child = Name.new(:first_name => "Hank", :last_name => "Moody")
158
- @parent = Person.new(:title => "Mr.")
159
- @options = Mongoid::Associations::Options.new(:name => :name)
160
- end
161
-
162
- it "sets up all associations in the object graph" do
163
- @child.assimilate(@parent, @options)
164
- @parent.name.should == @child
165
- end
166
-
167
- end
168
-
169
- describe ".db" do
170
-
171
- before do
172
- @db = stub
173
- @collection.expects(:db).returns(@db)
174
- end
175
-
176
- it "returns the database from the collection" do
177
- Person.db.should == @db
178
- end
179
- end
180
-
181
- describe "#clone" do
182
-
183
- before do
184
- @comment = Comment.new(:text => "Woooooo")
185
- @clone = @comment.clone
186
- end
187
-
188
- it "returns a new document sans id and versions" do
189
- @clone.id.should_not == @comment.id
190
- @clone.versions.should be_empty
191
- end
192
-
193
- end
194
-
195
- describe ".collection" do
196
-
197
- before do
198
- @person = Person.new
199
- end
200
-
201
- it "sets the collection name to the class pluralized" do
202
- Person.collection.name.should == "people"
203
- end
204
-
205
- context "when document is embedded" do
206
-
207
- before do
208
- @address = Address.new
209
- end
210
-
211
- it "raises an error" do
212
- lambda { Address.collection }.should raise_error
213
- end
214
-
215
- end
216
-
217
- end
218
-
219
- describe ".collection_name=" do
220
-
221
- context "on a parent class" do
222
-
223
- it "sets the collection name on the document class" do
224
- Patient.collection_name = "pats"
225
- Patient.collection_name.should == "pats"
226
- end
227
-
228
- end
229
-
230
- context "on a subclass" do
231
-
232
- after do
233
- Canvas.collection_name = "canvases"
234
- end
235
-
236
- it "sets the collection name for the entire hierarchy" do
237
- Firefox.collection_name = "browsers"
238
- Canvas.collection_name.should == "browsers"
239
- end
240
-
241
- end
242
-
243
- end
244
-
245
- describe ".embedded" do
246
-
247
- context "when the document is embedded" do
248
-
249
- it "returns true" do
250
- address = Address.new
251
- address.embedded.should be_true
252
- end
253
-
254
- end
255
-
256
- context "when the document is not embedded" do
257
-
258
- it "returns false" do
259
- person = Person.new
260
- person.embedded.should be_false
261
- end
262
-
263
- end
264
-
265
- context "when a subclass is embedded" do
266
-
267
- it "returns true" do
268
- circle = Circle.new
269
- circle.embedded.should be_true
270
- end
271
-
272
- end
273
-
274
- end
275
-
276
- describe ".hereditary" do
277
-
278
- context "when the class is part of a hierarchy" do
279
-
280
- it "returns true" do
281
- Canvas.hereditary.should be_true
282
- end
283
-
284
- end
285
-
286
- context "when the class is not part of a hierarchy" do
287
-
288
- it "returns false" do
289
- Game.hereditary.should be_false
290
- end
291
-
292
- end
293
-
294
- end
295
-
296
- describe ".human_name" do
297
-
298
- it "returns the class name underscored and humanized" do
299
- MixedDrink.human_name.should == "Mixed drink"
300
- end
301
-
302
- end
303
-
304
- describe ".initialize" do
305
-
306
- context "when passed a block" do
307
-
308
- it "yields self to the block" do
309
- person = Person.new do |p|
310
- p.title = "Sir"
311
- p.age = 60
312
- end
313
- person.title.should == "Sir"
314
- person.age.should == 60
315
- end
316
-
317
- end
318
-
319
- context "with no attributes" do
320
-
321
- it "sets default attributes" do
322
- person = Person.new
323
- person.attributes.empty?.should be_false
324
- person.age.should == 100
325
- person.blood_alcohol_content.should == 0.0
326
- end
327
-
328
- end
329
-
330
- context "with nil attributes" do
331
-
332
- before do
333
- @person = Person.new(nil)
334
- end
335
-
336
- it "sets default attributes" do
337
- @person.attributes.empty?.should be_false
338
- @person.age.should == 100
339
- @person.blood_alcohol_content.should == 0.0
340
- end
341
-
342
- end
343
-
344
- context "with attributes" do
345
-
346
- before do
347
- @attributes = {
348
- :_id => "1",
349
- :title => "value",
350
- :age => "30",
351
- :terms => "true",
352
- :name => {
353
- :_id => "2", :first_name => "Test", :last_name => "User"
354
- },
355
- :addresses => [
356
- { :_id => "3", :street => "First Street" },
357
- { :_id => "4", :street => "Second Street" }
358
- ]
359
- }
360
- end
361
-
362
- it "sets the attributes hash on the object properly casted" do
363
- person = Person.new(@attributes)
364
- person.attributes[:age].should == 30
365
- person.attributes[:terms].should be_true
366
- end
367
-
368
- end
369
-
370
- context "with a primary key" do
371
-
372
- context "when the value for the key exists" do
373
-
374
- before do
375
- Address.key :street
376
- @address = Address.new(:street => "Test")
377
- end
378
-
379
- it "sets the primary key" do
380
- @address.id.should == "test"
381
- end
382
-
383
- end
384
-
385
- end
386
-
387
- context "without a type specified" do
388
-
389
- it "sets the type" do
390
- Person.new._type.should == "Person"
391
- end
392
-
393
- end
394
-
395
- end
396
-
397
- describe ".instantiate" do
398
-
399
- context "when attributes have an id" do
400
-
401
- before do
402
- @attributes = { "_id" => "1", "_type" => "Person", "title" => "Sir", "age" => 30 }
403
- end
404
-
405
- it "sets the attributes directly" do
406
- person = Person.instantiate(@attributes)
407
- person._id.should == "1"
408
- person._type.should == "Person"
409
- person.title.should == "Sir"
410
- person.age.should == 30
411
- end
412
-
413
- end
414
-
415
- context "with nil attributes" do
416
-
417
- it "sets the attributes directly" do
418
- person = Person.instantiate(nil)
419
- person.id.should_not be_nil
420
- end
421
-
422
- end
423
-
424
- end
425
-
426
- describe ".key" do
427
-
428
- context "when key is single field" do
429
-
430
- before do
431
- Address.key :street
432
- @address = Address.new(:street => "Testing Street Name")
433
- @address.expects(:collection).returns(@collection)
434
- @collection.expects(:save)
435
- end
436
-
437
- it "adds the callback for primary key generation" do
438
- @address.save
439
- @address.id.should == "testing-street-name"
440
- end
441
-
442
- end
443
-
444
- context "when key is composite" do
445
-
446
- before do
447
- Address.key :street, :post_code
448
- @address = Address.new(:street => "Testing Street Name", :post_code => "94123")
449
- @address.expects(:collection).returns(@collection)
450
- @collection.expects(:save)
451
- end
452
-
453
- it "combines all fields" do
454
- @address.save
455
- @address.id.should == "testing-street-name-94123"
456
- end
457
-
458
- end
459
-
460
- context "when key is on a subclass" do
461
-
462
- before do
463
- Firefox.key :name
464
- end
465
-
466
- it "sets the key for the entire hierarchy" do
467
- Canvas.primary_key.should == [:name]
468
- end
469
-
470
- end
471
-
472
- end
473
-
474
- describe "#_parent" do
475
-
476
- before do
477
- @attributes = { :title => "Sir",
478
- :addresses => [
479
- { :street => "Street 1" },
480
- { :street => "Street 2" } ] }
481
- @person = Person.new(@attributes)
482
- end
483
-
484
- context "when document is embedded" do
485
-
486
- it "returns the parent document" do
487
- @person.addresses.first._parent.should == @person
488
- end
489
-
490
- end
491
-
492
- context "when document is root" do
493
-
494
- it "returns nil" do
495
- @person._parent.should be_nil
496
- end
497
-
498
- end
499
-
500
- end
501
-
502
- describe "#parentize" do
503
-
504
- before do
505
- @parent = Person.new
506
- @child = Name.new
507
- end
508
-
509
- it "sets the parent on each element" do
510
- @child.parentize(@parent, :child)
511
- @child._parent.should == @parent
512
- end
513
-
514
- end
515
-
516
- describe "#reload" do
517
-
518
- before do
519
- @attributes = { "title" => "Herr" }
520
- @person = Person.new(:_id => Mongo::ObjectID.new.to_s)
521
- @collection.expects(:find_one).with(:_id => @person.id).returns(@attributes)
522
- end
523
-
524
- it "reloads the object attribtues from the database" do
525
- @person.reload
526
- @person.attributes.should == @attributes
527
- end
528
-
529
- it 'should return a person object' do
530
- @person.reload.should be_kind_of(Person)
531
- end
532
-
533
- end
534
-
535
- describe "#remove" do
536
-
537
- context "when removing an element from a has many" do
538
-
539
- before do
540
- @person = Person.new
541
- @address = Address.new(:street => "Testing")
542
- @person.addresses << @address
543
- end
544
-
545
- it "removes the child document attributes" do
546
- @person.remove(@address)
547
- @person.addresses.size.should == 0
548
- end
549
-
550
- end
551
-
552
- context "when removing a has one" do
553
-
554
- before do
555
- @person = Person.new
556
- @name = Name.new(:first_name => "Neytiri")
557
- @person.name = @name
558
- end
559
-
560
- it "removes the child document attributes" do
561
- @person.remove(@name)
562
- @person.name.should be_nil
563
- end
564
- end
565
- end
566
-
567
- describe "#_root" do
568
-
569
- before do
570
- @person = Person.new(:title => "Mr")
571
- @phone_number = Phone.new(:number => "415-555-1212")
572
- @country_code = CountryCode.new(:code => 1)
573
- @phone_number.country_code = @country_code
574
- @person.phone_numbers << @phone_number
575
- end
576
-
577
- context "when document is the root" do
578
-
579
- it "returns self" do
580
- @person._root.should == @person
581
- end
582
- end
583
-
584
- context "when document is embedded one level" do
585
-
586
- it "returns the parent" do
587
- @phone_number._root.should == @person
588
- end
589
- end
590
-
591
- context "when document is embedded multiple levels" do
592
-
593
- it "returns the top level parent" do
594
- @country_code._root.should == @person
595
- end
596
- end
597
- end
598
-
599
- describe ".store_in" do
600
-
601
- context "on a parent class" do
602
-
603
- it "sets the collection name and collection for the document" do
604
- Mongoid::Collection.expects(:new).with(Patient, "population").returns(@collection)
605
- Patient.store_in :population
606
- Patient.collection_name.should == "population"
607
- end
608
-
609
- end
610
-
611
- context "on a subclass" do
612
-
613
- after do
614
- Mongoid::Collection.expects(:new).with(Firefox, "canvases")
615
- Firefox.store_in :canvases
616
- end
617
-
618
- it "changes the collection name for the entire hierarchy" do
619
- Mongoid::Collection.expects(:new).with(Firefox, "browsers").returns(@collection)
620
- Firefox.store_in :browsers
621
- Canvas.collection_name.should == "browsers"
622
- end
623
-
624
- end
625
-
626
- end
627
-
628
- describe "._types" do
629
-
630
- it "returns all subclasses for the class plus the class" do
631
- types = Canvas._types
632
- types.size.should == 3
633
- types.should include("Firefox")
634
- types.should include("Browser")
635
- types.should include("Canvas")
636
- end
637
-
638
- it "does not return parent classes" do
639
- types = Browser._types
640
- types.size.should == 2
641
- types.should include("Firefox")
642
- types.should include("Browser")
643
- end
644
-
645
- end
646
-
647
- describe "#to_a" do
648
-
649
- it "returns an array with the document in it" do
650
- person = Person.new
651
- person.to_a.should == [ person ]
652
- end
653
-
654
- end
655
-
656
- describe "#to_param" do
657
-
658
- it "returns the id" do
659
- id = Mongo::ObjectID.new.to_s
660
- Person.new(:_id => id).to_param.should == id.to_s
661
- end
662
-
663
- end
664
-
665
- context "validations" do
666
-
667
- context "when defining using macros" do
668
-
669
- after do
670
- Person.validations.clear
671
- end
672
-
673
- describe "#validates_acceptance_of" do
674
-
675
- it "adds the acceptance validation" do
676
- Person.class_eval do
677
- validates_acceptance_of :terms
678
- end
679
- Person.validations.first.should be_a_kind_of(Validatable::ValidatesAcceptanceOf)
680
- end
681
-
682
- end
683
-
684
- describe "#validates_associated" do
685
-
686
- it "adds the associated validation" do
687
- Person.class_eval do
688
- validates_associated :name
689
- end
690
- Person.validations.first.should be_a_kind_of(Validatable::ValidatesAssociated)
691
- end
692
-
693
- end
694
-
695
- describe "#validates_format_of" do
696
-
697
- it "adds the format validation" do
698
- Person.class_eval do
699
- validates_format_of :title, :with => /[A-Za-z]/
700
- end
701
- Person.validations.first.should be_a_kind_of(Validatable::ValidatesFormatOf)
702
- end
703
-
704
- end
705
-
706
- describe "#validates_length_of" do
707
-
708
- it "adds the length validation" do
709
- Person.class_eval do
710
- validates_length_of :title, :minimum => 10
711
- end
712
- Person.validations.first.should be_a_kind_of(Validatable::ValidatesLengthOf)
713
- end
714
-
715
- end
716
-
717
- describe "#validates_numericality_of" do
718
-
719
- it "adds the numericality validation" do
720
- Person.class_eval do
721
- validates_numericality_of :age
722
- end
723
- Person.validations.first.should be_a_kind_of(Validatable::ValidatesNumericalityOf)
724
- end
725
-
726
- end
727
-
728
- describe "#validates_presence_of" do
729
-
730
- it "adds the presence validation" do
731
- Person.class_eval do
732
- validates_presence_of :title
733
- end
734
- Person.validations.first.should be_a_kind_of(Validatable::ValidatesPresenceOf)
735
- end
736
-
737
- end
738
-
739
- describe "#validates_uniqueness_of" do
740
-
741
- it "adds the uniqueness validation" do
742
- Person.class_eval do
743
- validates_uniqueness_of :title
744
- end
745
- Person.validations.first.should be_a_kind_of(Validatable::ValidatesUniquenessOf)
746
- end
747
-
748
- end
749
-
750
- describe "#validates_inclusion_of" do
751
-
752
- it "adds the inclusion validation" do
753
- Person.class_eval do
754
- validates_inclusion_of :title, :within => ["test"]
755
- end
756
- Person.validations.first.should be_a_kind_of(Validatable::ValidatesInclusionOf)
757
- end
758
-
759
- end
760
-
761
- describe "#validates_exclusion_of" do
762
-
763
- it "adds the exclusion validation" do
764
- Person.class_eval do
765
- validates_exclusion_of :title, :within => ["test"]
766
- end
767
- Person.validations.first.should be_a_kind_of(Validatable::ValidatesExclusionOf)
768
- end
769
-
770
- end
771
-
772
- describe "#validates_true_for" do
773
-
774
- it "adds the true validation" do
775
- Person.class_eval do
776
- validates_true_for :title, :logic => lambda { title == "Esquire" }
777
- end
778
- Person.validations.first.should be_a_kind_of(Validatable::ValidatesTrueFor)
779
- end
780
-
781
- end
782
-
783
- end
784
-
785
- context "when running validations" do
786
-
787
- before do
788
- @person = Person.new
789
- @canvas = Canvas.new
790
- @firefox = Firefox.new
791
- end
792
-
793
- after do
794
- Person.validations.clear
795
- Canvas.validations.clear
796
- Firefox.validations.clear
797
- end
798
-
799
- describe "#validates_acceptance_of" do
800
-
801
- it "fails if field not accepted" do
802
- Person.class_eval do
803
- validates_acceptance_of :terms
804
- end
805
- @person.valid?.should be_false
806
- @person.errors.on(:terms).should_not be_nil
807
- end
808
-
809
- end
810
-
811
- describe "#validates_associated" do
812
-
813
- context "when association is a has_many" do
814
-
815
- it "fails when any association fails validation" do
816
- Person.class_eval do
817
- validates_associated :addresses
818
- end
819
- Address.class_eval do
820
- validates_presence_of :street
821
- end
822
- @person.addresses << Address.new
823
- @person.valid?.should be_false
824
- @person.errors.on(:addresses).should_not be_nil
825
- end
826
-
827
- end
828
-
829
- context "when association is a has_one" do
830
-
831
- context "when the associated is not nil" do
832
-
833
- it "fails when the association fails validation" do
834
- Person.class_eval do
835
- validates_associated :name
836
- end
837
- Name.class_eval do
838
- validates_presence_of :first_name
839
- end
840
- @person.name = Name.new
841
- @person.valid?.should be_false
842
- @person.errors.on(:name).should_not be_nil
843
- end
844
-
845
- end
846
-
847
- context "when the associated is nil" do
848
-
849
- it "returns true" do
850
- Person.class_eval do
851
- validates_associated :name
852
- end
853
- @person.valid?.should be_true
854
- end
855
-
856
- end
857
-
858
- end
859
-
860
- end
861
-
862
- describe "#validates_format_of" do
863
-
864
- it "fails if the field is in the wrong format" do
865
- Person.class_eval do
866
- validates_format_of :title, :with => /[A-Za-z]/
867
- end
868
- @person.title = 10
869
- @person.valid?.should be_false
870
- @person.errors.on(:title).should_not be_nil
871
- end
872
-
873
- end
874
-
875
- describe "#validates_length_of" do
876
-
877
- it "fails if the field is the wrong length" do
878
- Person.class_eval do
879
- validates_length_of :title, :minimum => 10
880
- end
881
- @person.title = "Testing"
882
- @person.valid?.should be_false
883
- @person.errors.on(:title).should_not be_nil
884
- end
885
-
886
- end
887
-
888
- describe "#validates_numericality_of" do
889
-
890
- it "fails if the field is not a number" do
891
- Person.class_eval do
892
- validates_numericality_of :age
893
- end
894
- @person.age = "foo"
895
- @person.valid?.should be_false
896
- @person.errors.on(:age).should_not be_nil
897
- end
898
-
899
- end
900
-
901
- describe "#validates_presence_of" do
902
-
903
- context "on a parent class" do
904
-
905
- it "fails if the field is nil on the parent" do
906
- Person.class_eval do
907
- validates_presence_of :title
908
- end
909
- @person.valid?.should be_false
910
- @person.errors.on(:title).should_not be_nil
911
- end
912
-
913
- it "fails if the field is nil on a subclass" do
914
- Canvas.class_eval do
915
- validates_presence_of :name
916
- end
917
- @firefox.valid?.should be_false
918
- @firefox.errors.on(:name).should_not be_nil
919
- end
920
-
921
- end
922
-
923
- context "on a subclass" do
924
-
925
- it "parent class does not get subclass validations" do
926
- Firefox.class_eval do
927
- validates_presence_of :name
928
- end
929
- @canvas.valid?.should be_true
930
- end
931
-
932
- end
933
-
934
- end
935
-
936
- describe "#validates_true_for" do
937
-
938
- it "fails if the logic returns false" do
939
- Person.class_eval do
940
- validates_true_for :title, :logic => lambda { title == "Esquire" }
941
- end
942
- @person.valid?.should be_false
943
- @person.errors.on(:title).should_not be_nil
944
- end
945
-
946
- end
947
-
948
- end
949
-
950
- end
951
-
952
- end