mongoid 1.2.14 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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