mongoid-pre 2.0.0.beta1

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 (246) hide show
  1. data/.gitignore +6 -0
  2. data/.watchr +24 -0
  3. data/MIT_LICENSE +20 -0
  4. data/README.rdoc +49 -0
  5. data/Rakefile +52 -0
  6. data/VERSION +1 -0
  7. data/caliper.yml +4 -0
  8. data/lib/mongoid.rb +135 -0
  9. data/lib/mongoid/associations.rb +263 -0
  10. data/lib/mongoid/associations/belongs_to_related.rb +59 -0
  11. data/lib/mongoid/associations/embedded_in.rb +64 -0
  12. data/lib/mongoid/associations/embeds_many.rb +193 -0
  13. data/lib/mongoid/associations/embeds_one.rb +95 -0
  14. data/lib/mongoid/associations/has_many_related.rb +133 -0
  15. data/lib/mongoid/associations/has_one_related.rb +81 -0
  16. data/lib/mongoid/associations/meta_data.rb +28 -0
  17. data/lib/mongoid/associations/options.rb +52 -0
  18. data/lib/mongoid/associations/proxy.rb +31 -0
  19. data/lib/mongoid/attributes.rb +185 -0
  20. data/lib/mongoid/callbacks.rb +18 -0
  21. data/lib/mongoid/collection.rb +119 -0
  22. data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
  23. data/lib/mongoid/collections/master.rb +28 -0
  24. data/lib/mongoid/collections/mimic.rb +46 -0
  25. data/lib/mongoid/collections/operations.rb +41 -0
  26. data/lib/mongoid/collections/slaves.rb +44 -0
  27. data/lib/mongoid/commands.rb +161 -0
  28. data/lib/mongoid/commands/create.rb +19 -0
  29. data/lib/mongoid/commands/delete.rb +16 -0
  30. data/lib/mongoid/commands/delete_all.rb +25 -0
  31. data/lib/mongoid/commands/deletion.rb +18 -0
  32. data/lib/mongoid/commands/destroy.rb +17 -0
  33. data/lib/mongoid/commands/destroy_all.rb +25 -0
  34. data/lib/mongoid/commands/save.rb +30 -0
  35. data/lib/mongoid/components.rb +31 -0
  36. data/lib/mongoid/config.rb +86 -0
  37. data/lib/mongoid/contexts.rb +25 -0
  38. data/lib/mongoid/contexts/enumerable.rb +151 -0
  39. data/lib/mongoid/contexts/ids.rb +25 -0
  40. data/lib/mongoid/contexts/mongo.rb +285 -0
  41. data/lib/mongoid/contexts/paging.rb +42 -0
  42. data/lib/mongoid/criteria.rb +239 -0
  43. data/lib/mongoid/criterion/complex.rb +21 -0
  44. data/lib/mongoid/criterion/exclusion.rb +65 -0
  45. data/lib/mongoid/criterion/inclusion.rb +93 -0
  46. data/lib/mongoid/criterion/optional.rb +136 -0
  47. data/lib/mongoid/cursor.rb +82 -0
  48. data/lib/mongoid/deprecation.rb +22 -0
  49. data/lib/mongoid/dirty.rb +203 -0
  50. data/lib/mongoid/document.rb +306 -0
  51. data/lib/mongoid/errors.rb +77 -0
  52. data/lib/mongoid/extensions.rb +99 -0
  53. data/lib/mongoid/extensions/array/accessors.rb +17 -0
  54. data/lib/mongoid/extensions/array/aliasing.rb +4 -0
  55. data/lib/mongoid/extensions/array/assimilation.rb +26 -0
  56. data/lib/mongoid/extensions/array/conversions.rb +27 -0
  57. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  58. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  59. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  60. data/lib/mongoid/extensions/boolean/conversions.rb +16 -0
  61. data/lib/mongoid/extensions/date/conversions.rb +15 -0
  62. data/lib/mongoid/extensions/datetime/conversions.rb +17 -0
  63. data/lib/mongoid/extensions/float/conversions.rb +16 -0
  64. data/lib/mongoid/extensions/hash/accessors.rb +38 -0
  65. data/lib/mongoid/extensions/hash/assimilation.rb +30 -0
  66. data/lib/mongoid/extensions/hash/conversions.rb +15 -0
  67. data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
  68. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  69. data/lib/mongoid/extensions/integer/conversions.rb +16 -0
  70. data/lib/mongoid/extensions/nil/assimilation.rb +13 -0
  71. data/lib/mongoid/extensions/object/conversions.rb +27 -0
  72. data/lib/mongoid/extensions/objectid/conversions.rb +15 -0
  73. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  74. data/lib/mongoid/extensions/string/conversions.rb +15 -0
  75. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  76. data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
  77. data/lib/mongoid/extensions/time/conversions.rb +18 -0
  78. data/lib/mongoid/extras.rb +61 -0
  79. data/lib/mongoid/factory.rb +19 -0
  80. data/lib/mongoid/field.rb +52 -0
  81. data/lib/mongoid/fields.rb +62 -0
  82. data/lib/mongoid/finders.rb +136 -0
  83. data/lib/mongoid/identity.rb +39 -0
  84. data/lib/mongoid/indexes.rb +27 -0
  85. data/lib/mongoid/javascript.rb +21 -0
  86. data/lib/mongoid/javascript/functions.yml +37 -0
  87. data/lib/mongoid/matchers.rb +36 -0
  88. data/lib/mongoid/matchers/all.rb +11 -0
  89. data/lib/mongoid/matchers/default.rb +26 -0
  90. data/lib/mongoid/matchers/exists.rb +13 -0
  91. data/lib/mongoid/matchers/gt.rb +11 -0
  92. data/lib/mongoid/matchers/gte.rb +11 -0
  93. data/lib/mongoid/matchers/in.rb +11 -0
  94. data/lib/mongoid/matchers/lt.rb +11 -0
  95. data/lib/mongoid/matchers/lte.rb +11 -0
  96. data/lib/mongoid/matchers/ne.rb +11 -0
  97. data/lib/mongoid/matchers/nin.rb +11 -0
  98. data/lib/mongoid/matchers/size.rb +11 -0
  99. data/lib/mongoid/memoization.rb +27 -0
  100. data/lib/mongoid/named_scope.rb +42 -0
  101. data/lib/mongoid/observable.rb +30 -0
  102. data/lib/mongoid/paths.rb +54 -0
  103. data/lib/mongoid/persistence.rb +27 -0
  104. data/lib/mongoid/persistence/command.rb +20 -0
  105. data/lib/mongoid/persistence/insert.rb +71 -0
  106. data/lib/mongoid/persistence/update.rb +78 -0
  107. data/lib/mongoid/scope.rb +75 -0
  108. data/lib/mongoid/state.rb +32 -0
  109. data/lib/mongoid/timestamps.rb +27 -0
  110. data/lib/mongoid/validations.rb +51 -0
  111. data/lib/mongoid/validations/associated.rb +32 -0
  112. data/lib/mongoid/validations/locale/en.yml +4 -0
  113. data/lib/mongoid/validations/uniqueness.rb +22 -0
  114. data/lib/mongoid/versioning.rb +26 -0
  115. data/mongoid.gemspec +413 -0
  116. data/perf/benchmark.rb +77 -0
  117. data/spec/integration/mongoid/associations_spec.rb +340 -0
  118. data/spec/integration/mongoid/attributes_spec.rb +22 -0
  119. data/spec/integration/mongoid/commands_spec.rb +230 -0
  120. data/spec/integration/mongoid/contexts/enumerable_spec.rb +33 -0
  121. data/spec/integration/mongoid/criteria_spec.rb +272 -0
  122. data/spec/integration/mongoid/dirty_spec.rb +70 -0
  123. data/spec/integration/mongoid/document_spec.rb +650 -0
  124. data/spec/integration/mongoid/extensions_spec.rb +22 -0
  125. data/spec/integration/mongoid/finders_spec.rb +119 -0
  126. data/spec/integration/mongoid/inheritance_spec.rb +137 -0
  127. data/spec/integration/mongoid/named_scope_spec.rb +46 -0
  128. data/spec/integration/mongoid/persistence/update_spec.rb +46 -0
  129. data/spec/models/address.rb +39 -0
  130. data/spec/models/animal.rb +6 -0
  131. data/spec/models/callbacks.rb +18 -0
  132. data/spec/models/comment.rb +8 -0
  133. data/spec/models/country_code.rb +6 -0
  134. data/spec/models/employer.rb +5 -0
  135. data/spec/models/game.rb +7 -0
  136. data/spec/models/inheritance.rb +56 -0
  137. data/spec/models/location.rb +5 -0
  138. data/spec/models/mixed_drink.rb +4 -0
  139. data/spec/models/name.rb +13 -0
  140. data/spec/models/namespacing.rb +11 -0
  141. data/spec/models/patient.rb +6 -0
  142. data/spec/models/person.rb +99 -0
  143. data/spec/models/pet.rb +7 -0
  144. data/spec/models/pet_owner.rb +6 -0
  145. data/spec/models/phone.rb +7 -0
  146. data/spec/models/post.rb +15 -0
  147. data/spec/models/translation.rb +5 -0
  148. data/spec/models/vet_visit.rb +5 -0
  149. data/spec/spec.opts +3 -0
  150. data/spec/spec_helper.rb +31 -0
  151. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +145 -0
  152. data/spec/unit/mongoid/associations/embedded_in_spec.rb +193 -0
  153. data/spec/unit/mongoid/associations/embeds_many_spec.rb +516 -0
  154. data/spec/unit/mongoid/associations/embeds_one_spec.rb +282 -0
  155. data/spec/unit/mongoid/associations/has_many_related_spec.rb +418 -0
  156. data/spec/unit/mongoid/associations/has_one_related_spec.rb +179 -0
  157. data/spec/unit/mongoid/associations/meta_data_spec.rb +88 -0
  158. data/spec/unit/mongoid/associations/options_spec.rb +192 -0
  159. data/spec/unit/mongoid/associations_spec.rb +595 -0
  160. data/spec/unit/mongoid/attributes_spec.rb +507 -0
  161. data/spec/unit/mongoid/callbacks_spec.rb +55 -0
  162. data/spec/unit/mongoid/collection_spec.rb +187 -0
  163. data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +75 -0
  164. data/spec/unit/mongoid/collections/master_spec.rb +41 -0
  165. data/spec/unit/mongoid/collections/mimic_spec.rb +43 -0
  166. data/spec/unit/mongoid/collections/slaves_spec.rb +81 -0
  167. data/spec/unit/mongoid/commands/create_spec.rb +31 -0
  168. data/spec/unit/mongoid/commands/delete_all_spec.rb +59 -0
  169. data/spec/unit/mongoid/commands/delete_spec.rb +38 -0
  170. data/spec/unit/mongoid/commands/destroy_all_spec.rb +21 -0
  171. data/spec/unit/mongoid/commands/destroy_spec.rb +51 -0
  172. data/spec/unit/mongoid/commands/save_spec.rb +107 -0
  173. data/spec/unit/mongoid/commands_spec.rb +270 -0
  174. data/spec/unit/mongoid/config_spec.rb +176 -0
  175. data/spec/unit/mongoid/contexts/enumerable_spec.rb +421 -0
  176. data/spec/unit/mongoid/contexts/mongo_spec.rb +682 -0
  177. data/spec/unit/mongoid/contexts_spec.rb +25 -0
  178. data/spec/unit/mongoid/criteria_spec.rb +824 -0
  179. data/spec/unit/mongoid/criterion/complex_spec.rb +19 -0
  180. data/spec/unit/mongoid/criterion/exclusion_spec.rb +91 -0
  181. data/spec/unit/mongoid/criterion/inclusion_spec.rb +219 -0
  182. data/spec/unit/mongoid/criterion/optional_spec.rb +319 -0
  183. data/spec/unit/mongoid/cursor_spec.rb +74 -0
  184. data/spec/unit/mongoid/deprecation_spec.rb +24 -0
  185. data/spec/unit/mongoid/dirty_spec.rb +286 -0
  186. data/spec/unit/mongoid/document_spec.rb +818 -0
  187. data/spec/unit/mongoid/errors_spec.rb +103 -0
  188. data/spec/unit/mongoid/extensions/array/accessors_spec.rb +50 -0
  189. data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +24 -0
  190. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +35 -0
  191. data/spec/unit/mongoid/extensions/array/parentization_spec.rb +20 -0
  192. data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +22 -0
  193. data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +22 -0
  194. data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +49 -0
  195. data/spec/unit/mongoid/extensions/date/conversions_spec.rb +102 -0
  196. data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +67 -0
  197. data/spec/unit/mongoid/extensions/float/conversions_spec.rb +61 -0
  198. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +184 -0
  199. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +46 -0
  200. data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +21 -0
  201. data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +17 -0
  202. data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +14 -0
  203. data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +61 -0
  204. data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +24 -0
  205. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +57 -0
  206. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +34 -0
  207. data/spec/unit/mongoid/extensions/string/conversions_spec.rb +17 -0
  208. data/spec/unit/mongoid/extensions/string/inflections_spec.rb +208 -0
  209. data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +91 -0
  210. data/spec/unit/mongoid/extensions/time/conversions_spec.rb +70 -0
  211. data/spec/unit/mongoid/extras_spec.rb +102 -0
  212. data/spec/unit/mongoid/factory_spec.rb +31 -0
  213. data/spec/unit/mongoid/field_spec.rb +143 -0
  214. data/spec/unit/mongoid/fields_spec.rb +181 -0
  215. data/spec/unit/mongoid/finders_spec.rb +404 -0
  216. data/spec/unit/mongoid/identity_spec.rb +109 -0
  217. data/spec/unit/mongoid/indexes_spec.rb +93 -0
  218. data/spec/unit/mongoid/javascript_spec.rb +48 -0
  219. data/spec/unit/mongoid/matchers/all_spec.rb +27 -0
  220. data/spec/unit/mongoid/matchers/default_spec.rb +27 -0
  221. data/spec/unit/mongoid/matchers/exists_spec.rb +56 -0
  222. data/spec/unit/mongoid/matchers/gt_spec.rb +39 -0
  223. data/spec/unit/mongoid/matchers/gte_spec.rb +49 -0
  224. data/spec/unit/mongoid/matchers/in_spec.rb +27 -0
  225. data/spec/unit/mongoid/matchers/lt_spec.rb +39 -0
  226. data/spec/unit/mongoid/matchers/lte_spec.rb +49 -0
  227. data/spec/unit/mongoid/matchers/ne_spec.rb +27 -0
  228. data/spec/unit/mongoid/matchers/nin_spec.rb +27 -0
  229. data/spec/unit/mongoid/matchers/size_spec.rb +27 -0
  230. data/spec/unit/mongoid/matchers_spec.rb +329 -0
  231. data/spec/unit/mongoid/memoization_spec.rb +75 -0
  232. data/spec/unit/mongoid/named_scope_spec.rb +123 -0
  233. data/spec/unit/mongoid/observable_spec.rb +46 -0
  234. data/spec/unit/mongoid/paths_spec.rb +124 -0
  235. data/spec/unit/mongoid/persistence/insert_spec.rb +175 -0
  236. data/spec/unit/mongoid/persistence/update_spec.rb +148 -0
  237. data/spec/unit/mongoid/persistence_spec.rb +40 -0
  238. data/spec/unit/mongoid/scope_spec.rb +240 -0
  239. data/spec/unit/mongoid/state_spec.rb +83 -0
  240. data/spec/unit/mongoid/timestamps_spec.rb +25 -0
  241. data/spec/unit/mongoid/validations/associated_spec.rb +103 -0
  242. data/spec/unit/mongoid/validations/uniqueness_spec.rb +47 -0
  243. data/spec/unit/mongoid/validations_spec.rb +190 -0
  244. data/spec/unit/mongoid/versioning_spec.rb +41 -0
  245. data/spec/unit/mongoid_spec.rb +46 -0
  246. metadata +476 -0
@@ -0,0 +1,282 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Associations::EmbedsOne do
4
+
5
+ before do
6
+ @attributes = { "mixed_drink" => {
7
+ "name" => "Jack and Coke", "_type" => "MixedDrink" },
8
+ "writer" => { "speed" => 50, "_type" => "HtmlWriter" }
9
+ }
10
+ @document = stub(:raw_attributes => @attributes, :observe => true)
11
+ end
12
+
13
+ describe "#build_*" do
14
+
15
+ context "when attributes provided" do
16
+
17
+ before do
18
+ @association = Mongoid::Associations::EmbedsOne.new(
19
+ @document,
20
+ @attributes["mixed_drink"],
21
+ Mongoid::Associations::Options.new(:name => :mixed_drink)
22
+ )
23
+ end
24
+
25
+ it "replaces the existing has_one" do
26
+ drink = @association.send(:build, { :name => "Sapphire and Tonic" })
27
+ drink.name.should == "Sapphire and Tonic"
28
+ end
29
+
30
+ end
31
+
32
+ context "when a type is supplied" do
33
+
34
+ before do
35
+ @association = Mongoid::Associations::EmbedsOne.new(
36
+ @document,
37
+ @attributes["writer"],
38
+ Mongoid::Associations::Options.new(:name => :writer)
39
+ )
40
+ end
41
+
42
+ it "instantiates a class of that type" do
43
+ writer = @association.send(:build, { :speed => 500 }, HtmlWriter)
44
+ writer.should be_a_kind_of(HtmlWriter)
45
+ writer.speed.should == 500
46
+ end
47
+
48
+ end
49
+
50
+ context "setting the parent relationship" do
51
+
52
+ before do
53
+ @person = Person.new
54
+ end
55
+
56
+ it "happens before any other operation" do
57
+ name = @person.build_name(:set_parent => true, :street => "Madison Ave")
58
+ name._parent.should == @person
59
+ @person.name.should == name
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
66
+ describe "#initialize" do
67
+
68
+ before do
69
+ @parent = Person.new(:title => "Dr")
70
+ @name = Name.new(:first_name => "Richard", :last_name => "Dawkins")
71
+ @parent.name = @name
72
+ @block = Proc.new {
73
+ def extension
74
+ "Testing"
75
+ end
76
+ }
77
+ @options = Mongoid::Associations::Options.new(:name => :name, :extend => @block)
78
+ @association = Mongoid::Associations::EmbedsOne.new(@parent, {}, @options)
79
+ end
80
+
81
+ context "when the options have an extension" do
82
+
83
+ it "adds the extension module" do
84
+ @association.extension.should == "Testing"
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+
91
+ describe ".instantiate" do
92
+
93
+ context "when the attributes are nil" do
94
+
95
+ before do
96
+ @document = Person.new
97
+ @association = Mongoid::Associations::EmbedsOne.instantiate(
98
+ @document,
99
+ Mongoid::Associations::Options.new(:name => :name)
100
+ )
101
+ end
102
+
103
+ it "returns nil" do
104
+ @association.should be_nil
105
+ end
106
+
107
+ end
108
+
109
+ context "when attributes are empty" do
110
+
111
+ before do
112
+ @document = stub(:raw_attributes => { "name" => {} })
113
+ @association = Mongoid::Associations::EmbedsOne.instantiate(
114
+ @document,
115
+ Mongoid::Associations::Options.new(:name => :name)
116
+ )
117
+ end
118
+
119
+ it "returns nil" do
120
+ @association.should be_nil
121
+ end
122
+
123
+ end
124
+
125
+ context "when attributes exist" do
126
+
127
+ before do
128
+ @document = stub(:raw_attributes => { "name" => { "first_name" => "Test" } })
129
+ @options = Mongoid::Associations::Options.new(:name => :name)
130
+ end
131
+
132
+ it "delegates to new" do
133
+ Mongoid::Associations::EmbedsOne.expects(:new).with(@document, { "first_name" => "Test" }, @options)
134
+ Mongoid::Associations::EmbedsOne.instantiate(@document, @options)
135
+ end
136
+
137
+ end
138
+
139
+ end
140
+
141
+ describe "#method_missing" do
142
+
143
+ before do
144
+ @association = Mongoid::Associations::EmbedsOne.new(
145
+ @document,
146
+ @attributes["mixed_drink"],
147
+ Mongoid::Associations::Options.new(:name => :mixed_drink)
148
+ )
149
+ end
150
+
151
+ context "when getting values" do
152
+
153
+ it "delegates to the document" do
154
+ @association.name.should == "Jack and Coke"
155
+ end
156
+
157
+ end
158
+
159
+ context "when setting values" do
160
+
161
+ it "delegates to the document" do
162
+ @association.name = "Jack and Coke"
163
+ @association.name.should == "Jack and Coke"
164
+ end
165
+
166
+ end
167
+
168
+ end
169
+
170
+ describe "#nested_build" do
171
+
172
+ context "when attributes provided" do
173
+
174
+ before do
175
+ @association = Mongoid::Associations::EmbedsOne.new(
176
+ @document,
177
+ @attributes["mixed_drink"],
178
+ Mongoid::Associations::Options.new(:name => :mixed_drink)
179
+ )
180
+ end
181
+
182
+ it "replaces the existing has_one" do
183
+ drink = @association.nested_build({ :name => "Sapphire and Tonic" })
184
+ drink.name.should == "Sapphire and Tonic"
185
+ end
186
+
187
+ end
188
+
189
+ end
190
+
191
+ describe ".macro" do
192
+
193
+ it "returns :embeds_one" do
194
+ Mongoid::Associations::EmbedsOne.macro.should == :embeds_one
195
+ end
196
+
197
+ end
198
+
199
+ describe ".update" do
200
+
201
+ context "when setting to a non-nil value" do
202
+
203
+ before do
204
+ @name = Name.new(:first_name => "Donald")
205
+ @person = Person.new(:title => "Sir")
206
+ @association = Mongoid::Associations::EmbedsOne.update(
207
+ @name,
208
+ @person,
209
+ Mongoid::Associations::Options.new(:name => :name)
210
+ )
211
+ end
212
+
213
+ it "parentizes the child document" do
214
+ @name._parent.should == @person
215
+ end
216
+
217
+ it "sets the attributes of the child on the parent" do
218
+ @person.attributes[:name].should ==
219
+ { "_id" => "donald", "first_name" => "Donald", "_type" => "Name" }
220
+ end
221
+
222
+ it "returns the proxy" do
223
+ @association.target.should == @name
224
+ end
225
+
226
+ end
227
+
228
+ context "when setting the object to nil" do
229
+
230
+ before do
231
+ @name = Name.new(:first_name => "Donald")
232
+ @person = Person.new(:title => "Sir")
233
+ Mongoid::Associations::EmbedsOne.update(
234
+ nil,
235
+ @person,
236
+ Mongoid::Associations::Options.new(:name => :name)
237
+ )
238
+ end
239
+
240
+ it "clears out the association" do
241
+ @person.name.should be_nil
242
+ end
243
+
244
+ end
245
+
246
+ end
247
+
248
+ describe "#to_a" do
249
+
250
+ before do
251
+ @association = Mongoid::Associations::EmbedsOne.new(
252
+ @document,
253
+ @attributes["mixed_drink"],
254
+ Mongoid::Associations::Options.new(:name => :mixed_drink)
255
+ )
256
+ end
257
+
258
+ it "returns the target in a new array" do
259
+ @association.to_a.first.should be_a_kind_of(MixedDrink)
260
+ end
261
+
262
+ end
263
+
264
+ describe "#valid?" do
265
+
266
+ context "when the document is not nil" do
267
+
268
+ before do
269
+ @document = stub(:raw_attributes => { "name" => { "first_name" => "Test" } }, :observe => true)
270
+ @options = Mongoid::Associations::Options.new(:name => :name)
271
+ @association = Mongoid::Associations::EmbedsOne.instantiate(@document, @options)
272
+ end
273
+
274
+ it "validates the document" do
275
+ @association.valid?.should be_true
276
+ end
277
+
278
+ end
279
+
280
+ end
281
+
282
+ end
@@ -0,0 +1,418 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Associations::HasManyRelated do
4
+
5
+ let(:block) do
6
+ Proc.new do
7
+ def extension
8
+ "Testing"
9
+ end
10
+ end
11
+ end
12
+
13
+ let(:options) do
14
+ Mongoid::Associations::Options.new(
15
+ :name => :posts,
16
+ :foreign_key => "person_id",
17
+ :extend => block
18
+ )
19
+ end
20
+
21
+ describe "#<<" do
22
+
23
+ before do
24
+ @child = stub
25
+ @second = stub
26
+ @children = [@child, @second]
27
+ end
28
+
29
+ context "when parent document has been saved" do
30
+
31
+ before do
32
+ @parent = stub(:id => "1", :new_record? => false, :class => Person)
33
+ Post.expects(:all).returns([])
34
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
35
+ end
36
+
37
+ it "saves and appends the child document" do
38
+ @child.expects(:person_id=).with(@parent.id)
39
+ @child.expects(:save).returns(true)
40
+ @association << @child
41
+ @association.size.should == 1
42
+ end
43
+
44
+ end
45
+
46
+ context "when parent document has not been saved" do
47
+
48
+ context "when appending a non mongoid object" do
49
+
50
+ before do
51
+ @parent = stub(:id => "1", :new_record? => true, :class => Person)
52
+ Post.expects(:all).returns([])
53
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
54
+ end
55
+
56
+ it "appends the child document" do
57
+ @child.expects(:person_id=).with(@parent.id)
58
+ @association << @child
59
+ @association.size.should == 1
60
+ end
61
+ end
62
+
63
+ context "when appending a mongoid document" do
64
+
65
+ before do
66
+ @criteria = mock
67
+ @parent = stub(:id => "1", :new_record? => true, :class => Person)
68
+ Post.expects(:all).returns(@criteria)
69
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
70
+ end
71
+
72
+ it "appends the child document" do
73
+ @criteria.expects(:entries).returns([])
74
+ @child.expects(:person_id=).with(@parent.id)
75
+ @association << @child
76
+ @association.size.should == 1
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+ context "with multiple objects" do
83
+
84
+ before do
85
+ @parent = stub(:id => "1", :new_record? => true, :class => Person)
86
+ Post.expects(:all).returns([])
87
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
88
+ end
89
+
90
+ it "appends the child documents" do
91
+ @child.expects(:person_id=).with(@parent.id)
92
+ @second.expects(:person_id=).with(@parent.id)
93
+ @association << [@child, @second]
94
+ @association.size.should == 2
95
+ end
96
+
97
+ end
98
+
99
+ end
100
+
101
+ describe "#build" do
102
+
103
+ before do
104
+ @criteria = mock
105
+ @criteria.expects(:entries).returns([])
106
+ @parent = stub(:id => "5", :class => Person, :new_record? => true)
107
+ Post.expects(:all).returns(@criteria)
108
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
109
+ end
110
+
111
+ it "adds a new object to the association" do
112
+ @association.build(:title => "Sassy")
113
+ @association.size.should == 1
114
+ end
115
+
116
+ it "sets the parent object id on the child" do
117
+ @association.build(:title => "Sassy")
118
+ @association.first.person_id.should == @parent.id
119
+ end
120
+
121
+ it "returns the new object" do
122
+ @association.build(:title => "Sassy").title.should == "Sassy"
123
+ end
124
+
125
+ it "sets the parent object reference on the child" do
126
+ @association.build(:title => "Sassy")
127
+ @association.first.person.should == @parent
128
+ end
129
+
130
+ end
131
+
132
+ describe "#concat" do
133
+
134
+ before do
135
+ @child = stub
136
+ @second = stub
137
+ end
138
+
139
+ context "when parent document has been saved" do
140
+
141
+ before do
142
+ @parent = stub(:id => "1", :new_record? => false, :class => Person)
143
+ Post.expects(:all).returns([])
144
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
145
+ end
146
+
147
+ it "saves and appends the child document" do
148
+ @child.expects(:person_id=).with(@parent.id)
149
+ @child.expects(:save).returns(true)
150
+ @association.concat(@child)
151
+ @association.size.should == 1
152
+ end
153
+
154
+ end
155
+
156
+ context "when parent document has not been saved" do
157
+
158
+ before do
159
+ @parent = stub(:id => "1", :new_record? => true, :class => Person)
160
+ Post.expects(:all).returns([])
161
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
162
+ end
163
+
164
+ it "appends the child document" do
165
+ @child.expects(:person_id=).with(@parent.id)
166
+ @association.concat(@child)
167
+ @association.size.should == 1
168
+ end
169
+
170
+ end
171
+
172
+ context "with multiple objects" do
173
+
174
+ before do
175
+ @parent = stub(:id => "1", :new_record? => true, :class => Person)
176
+ Post.expects(:all).returns([])
177
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
178
+ end
179
+
180
+ it "appends the child documents" do
181
+ @child.expects(:person_id=).with(@parent.id)
182
+ @second.expects(:person_id=).with(@parent.id)
183
+ @association.concat([@child, @second])
184
+ @association.size.should == 2
185
+ end
186
+
187
+ end
188
+
189
+ end
190
+
191
+ describe "#create" do
192
+
193
+ before do
194
+ @post = mock
195
+ @parent = stub(:id => "5", :class => Person, :new_record? => true)
196
+ Post.expects(:all).returns([])
197
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
198
+ Post.expects(:instantiate).returns(@post)
199
+ end
200
+
201
+ it "builds and saves the new object" do
202
+ @post.expects(:run_callbacks).with(:create).yields
203
+ @post.expects(:save).returns(true)
204
+ @association.create(:title => "Sassy")
205
+ end
206
+
207
+ it "returns the new object" do
208
+ @post.expects(:run_callbacks).with(:create).yields
209
+ @post.expects(:save).returns(true)
210
+ @association.create(:title => "Sassy").should == @post
211
+ end
212
+
213
+ end
214
+
215
+ describe "#find" do
216
+
217
+ before do
218
+ @parent = stub(:id => "5", :class => Person)
219
+ Post.expects(:all).returns([])
220
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
221
+ end
222
+
223
+ context "when finding by id" do
224
+
225
+ before do
226
+ @post = stub
227
+ end
228
+
229
+ it "returns the document in the array with that id" do
230
+ Post.expects(:find).with("5").returns(@post)
231
+ post = @association.find("5")
232
+ post.should == @post
233
+ end
234
+
235
+ end
236
+
237
+ context "when finding all with conditions" do
238
+
239
+ before do
240
+ @post = stub
241
+ end
242
+
243
+ it "passes the conditions to the association class" do
244
+ Post.expects(:find).with(:all, :conditions => { :title => "Testing", :person_id => @parent.id }).returns([@post])
245
+ posts = @association.find(:all, :conditions => { :title => "Testing" })
246
+ posts.should == [@post]
247
+ end
248
+
249
+ end
250
+
251
+ context "when finding first with conditions" do
252
+
253
+ before do
254
+ @post = stub
255
+ end
256
+
257
+ it "passes the conditions to the association class" do
258
+ Post.expects(:find).with(:first, :conditions => { :title => "Testing", :person_id => @parent.id }).returns(@post)
259
+ post = @association.find(:first, :conditions => { :title => "Testing" })
260
+ post.should == @post
261
+ end
262
+
263
+ end
264
+
265
+ context "when finding last with conditions" do
266
+
267
+ before do
268
+ @post = stub
269
+ end
270
+
271
+ it "passes the conditions to the association class" do
272
+ Post.expects(:find).with(:last, :conditions => { :title => "Testing", :person_id => @parent.id }).returns(@post)
273
+ post = @association.find(:last, :conditions => { :title => "Testing" })
274
+ post.should == @post
275
+ end
276
+
277
+ end
278
+
279
+ end
280
+
281
+ describe ".initialize" do
282
+
283
+ before do
284
+ @document = Person.new
285
+ @criteria = stub
286
+ @first = stub(:person_id => @document.id)
287
+ @second = stub(:person_id => @document.id)
288
+ @related = [@first, @second]
289
+ Post.expects(:all).with(:conditions => { "person_id" => @document.id }).returns(@related)
290
+ end
291
+
292
+ context "when related id has been set" do
293
+
294
+ it "finds the object by id" do
295
+ association = Mongoid::Associations::HasManyRelated.new(@document, options)
296
+ association.should == @related
297
+ end
298
+
299
+ end
300
+
301
+ context "when the options have an extension" do
302
+
303
+ it "adds the extension module" do
304
+ association = Mongoid::Associations::HasManyRelated.new(@document, options)
305
+ association.extension.should == "Testing"
306
+ end
307
+
308
+ end
309
+
310
+ end
311
+
312
+ describe ".instantiate" do
313
+
314
+ context "when related id has been set" do
315
+
316
+ before do
317
+ @document = Person.new
318
+ end
319
+
320
+ it "delegates to new" do
321
+ Mongoid::Associations::HasManyRelated.expects(:new).with(@document, options, nil)
322
+ association = Mongoid::Associations::HasManyRelated.instantiate(@document, options)
323
+ end
324
+
325
+ end
326
+
327
+ end
328
+
329
+ describe ".macro" do
330
+
331
+ it "returns :has_many_related" do
332
+ Mongoid::Associations::HasManyRelated.macro.should == :has_many_related
333
+ end
334
+
335
+ end
336
+
337
+ describe "#push" do
338
+
339
+ before do
340
+ @child = stub
341
+ @second = stub
342
+ end
343
+
344
+ context "when parent document has been saved" do
345
+
346
+ before do
347
+ @parent = stub(:id => "1", :new_record? => false, :class => Person)
348
+ Post.expects(:all).returns([])
349
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
350
+ end
351
+
352
+ it "saves and appends the child document" do
353
+ @child.expects(:person_id=).with(@parent.id)
354
+ @child.expects(:save).returns(true)
355
+ @association.push(@child)
356
+ @association.size.should == 1
357
+ end
358
+
359
+ end
360
+
361
+ context "when parent document has not been saved" do
362
+
363
+ before do
364
+ @parent = stub(:id => "1", :new_record? => true, :class => Person)
365
+ Post.expects(:all).returns([])
366
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
367
+ end
368
+
369
+ it "appends the child document" do
370
+ @child.expects(:person_id=).with(@parent.id)
371
+ @association.push(@child)
372
+ @association.size.should == 1
373
+ end
374
+
375
+ end
376
+
377
+ context "with multiple objects" do
378
+
379
+ before do
380
+ @parent = stub(:id => "1", :new_record? => true, :class => Person)
381
+ Post.expects(:all).returns([])
382
+ @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
383
+ end
384
+
385
+ it "appends the child documents" do
386
+ @child.expects(:person_id=).with(@parent.id)
387
+ @second.expects(:person_id=).with(@parent.id)
388
+ @association.push(@child, @second)
389
+ @association.size.should == 2
390
+ end
391
+
392
+ end
393
+
394
+ end
395
+
396
+ describe ".update" do
397
+
398
+ before do
399
+ @first = Post.new
400
+ @second = Post.new
401
+ @related = [@first, @second]
402
+ @parent = Person.new
403
+ end
404
+
405
+ it "sets the related object id on the parent" do
406
+ Mongoid::Associations::HasManyRelated.update(@related, @parent, options)
407
+ @first.person_id.should == @parent.id
408
+ @second.person_id.should == @parent.id
409
+ end
410
+
411
+ it "returns the related objects" do
412
+ @proxy = Mongoid::Associations::HasManyRelated.update(@related, @parent, options)
413
+ @proxy.target.should == @related
414
+ end
415
+
416
+ end
417
+
418
+ end