mongoid 1.1.3 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/.watchr +20 -2
  2. data/VERSION +1 -1
  3. data/caliper.yml +4 -0
  4. data/lib/mongoid.rb +0 -1
  5. data/lib/mongoid/associations.rb +25 -13
  6. data/lib/mongoid/associations/belongs_to.rb +15 -17
  7. data/lib/mongoid/associations/belongs_to_related.rb +12 -14
  8. data/lib/mongoid/associations/has_many.rb +53 -35
  9. data/lib/mongoid/associations/has_many_related.rb +10 -15
  10. data/lib/mongoid/associations/has_one.rb +31 -30
  11. data/lib/mongoid/associations/has_one_related.rb +18 -20
  12. data/lib/mongoid/associations/options.rb +10 -0
  13. data/lib/mongoid/associations/proxy.rb +18 -1
  14. data/lib/mongoid/criteria.rb +9 -233
  15. data/lib/mongoid/criterion/complex.rb +21 -0
  16. data/lib/mongoid/criterion/exclusion.rb +63 -0
  17. data/lib/mongoid/criterion/inclusion.rb +91 -0
  18. data/lib/mongoid/criterion/optional.rb +96 -0
  19. data/lib/mongoid/document.rb +2 -2
  20. data/lib/mongoid/extensions/hash/accessors.rb +6 -0
  21. data/lib/mongoid/extensions/hash/criteria_helpers.rb +2 -2
  22. data/lib/mongoid/extensions/symbol/inflections.rb +1 -1
  23. data/mongoid.gemspec +53 -3
  24. data/spec/integration/mongoid/associations_spec.rb +41 -0
  25. data/spec/models/address.rb +39 -0
  26. data/spec/models/animal.rb +6 -0
  27. data/spec/models/comment.rb +8 -0
  28. data/spec/models/country_code.rb +6 -0
  29. data/spec/models/employer.rb +5 -0
  30. data/spec/models/game.rb +6 -0
  31. data/spec/models/inheritance.rb +56 -0
  32. data/spec/models/location.rb +5 -0
  33. data/spec/models/mixed_drink.rb +4 -0
  34. data/spec/models/name.rb +13 -0
  35. data/spec/models/namespacing.rb +11 -0
  36. data/spec/models/patient.rb +4 -0
  37. data/spec/models/person.rb +97 -0
  38. data/spec/models/pet.rb +7 -0
  39. data/spec/models/pet_owner.rb +6 -0
  40. data/spec/models/phone.rb +7 -0
  41. data/spec/models/post.rb +15 -0
  42. data/spec/models/translation.rb +5 -0
  43. data/spec/models/vet_visit.rb +5 -0
  44. data/spec/spec_helper.rb +9 -326
  45. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +26 -5
  46. data/spec/unit/mongoid/associations/belongs_to_spec.rb +96 -30
  47. data/spec/unit/mongoid/associations/has_many_related_spec.rb +32 -12
  48. data/spec/unit/mongoid/associations/has_many_spec.rb +48 -12
  49. data/spec/unit/mongoid/associations/has_one_related_spec.rb +29 -4
  50. data/spec/unit/mongoid/associations/has_one_spec.rb +46 -1
  51. data/spec/unit/mongoid/associations/options_spec.rb +58 -0
  52. data/spec/unit/mongoid/associations_spec.rb +58 -1
  53. data/spec/unit/mongoid/criteria_spec.rb +71 -735
  54. data/spec/unit/mongoid/criterion/complex_spec.rb +19 -0
  55. data/spec/unit/mongoid/criterion/exclusion_spec.rb +75 -0
  56. data/spec/unit/mongoid/criterion/inclusion_spec.rb +213 -0
  57. data/spec/unit/mongoid/criterion/optional_spec.rb +244 -0
  58. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +20 -0
  59. metadata +53 -3
  60. data/lib/mongoid/complex_criterion.rb +0 -10
@@ -20,6 +20,27 @@ describe Mongoid::Associations::BelongsToRelated do
20
20
 
21
21
  end
22
22
 
23
+ context "when options have an extension" do
24
+
25
+ before do
26
+ @document = stub(:person_id => "5")
27
+ @block = Proc.new {
28
+ def extension
29
+ "Testing"
30
+ end
31
+ }
32
+ @options = Mongoid::Associations::Options.new(:name => :person, :extend => @block)
33
+ @related = stub
34
+ Person.expects(:find).with(@document.person_id).returns(@related)
35
+ @association = Mongoid::Associations::BelongsToRelated.new(@document, "5", @options)
36
+ end
37
+
38
+ it "adds the extension module" do
39
+ @association.extension.should == "Testing"
40
+ end
41
+
42
+ end
43
+
23
44
  end
24
45
 
25
46
  describe ".instantiate" do
@@ -32,7 +53,7 @@ describe Mongoid::Associations::BelongsToRelated do
32
53
  end
33
54
 
34
55
  it "delegates to new" do
35
- Mongoid::Associations::BelongsToRelated.expects(:new).with(@document, "5", @options)
56
+ Mongoid::Associations::BelongsToRelated.expects(:new).with(@document, "5", @options, nil)
36
57
  Mongoid::Associations::BelongsToRelated.instantiate(@document, @options)
37
58
  end
38
59
 
@@ -96,18 +117,18 @@ describe Mongoid::Associations::BelongsToRelated do
96
117
  @related = stub(:id => "5")
97
118
  @child = Game.new
98
119
  @options = Mongoid::Associations::Options.new(:name => :person)
120
+ @association = Mongoid::Associations::BelongsToRelated.update(@related, @child, @options)
99
121
  end
100
122
 
101
123
  it "sets the related object id on the parent" do
102
- Mongoid::Associations::BelongsToRelated.update(@related, @child, @options)
103
124
  @child.person_id.should == "5"
104
125
  end
105
126
 
106
- it "returns the related object" do
107
- Mongoid::Associations::BelongsToRelated.update(@related, @child, @options).should == @related
127
+ it "returns the proxy" do
128
+ @association.target.should == @related
108
129
  end
109
130
 
110
- context "when related is nil" do
131
+ context "when target is nil" do
111
132
 
112
133
  it "returns nil" do
113
134
  Mongoid::Associations::BelongsToRelated.update(nil, @child, @options).should be_nil
@@ -2,46 +2,73 @@ require "spec_helper"
2
2
 
3
3
  describe Mongoid::Associations::BelongsTo do
4
4
 
5
+ let(:child) do
6
+ Name.new(:first_name => "Drexel", :last_name => "Spivey")
7
+ end
8
+
9
+ let(:target) do
10
+ Person.new(:title => "Pimp")
11
+ end
12
+
13
+ let(:options) do
14
+ Mongoid::Associations::Options.new(:name => :person, :inverse_of => :name)
15
+ end
16
+
17
+ let(:has_many_options) do
18
+ Mongoid::Associations::Options.new(:name => :person, :inverse_of => :addresses)
19
+ end
20
+
5
21
  describe "#find" do
6
22
 
7
23
  before do
8
- @parent = Name.new(:first_name => "Drexel")
9
- @options = Mongoid::Associations::Options.new(:name => :person)
10
- @association = Mongoid::Associations::BelongsTo.new(@parent, @options)
24
+ @association = Mongoid::Associations::BelongsTo.new(target, options)
11
25
  end
12
26
 
13
27
  context "when finding by id" do
14
28
 
15
- it "returns the document in the array with that id" do
16
- name = @association.find(Mongo::ObjectID.new.to_s)
17
- name.should == @parent
29
+ it "always returns the target document" do
30
+ @association.find("").should == target
18
31
  end
19
32
 
20
33
  end
21
34
 
22
35
  end
23
36
 
24
- context "when decorating" do
37
+ describe "#initialize" do
25
38
 
26
39
  before do
27
- @parent = Name.new(:first_name => "Drexel")
28
- @options = Mongoid::Associations::Options.new(:name => :person)
29
- @association = Mongoid::Associations::BelongsTo.new(@parent, @options)
40
+ @association = Mongoid::Associations::BelongsTo.new(target, options)
30
41
  end
31
42
 
32
- context "when getting values" do
43
+ it "sets the target" do
44
+ @association.target.should == target
45
+ end
33
46
 
34
- it "delegates to the document" do
35
- @association.first_name.should == "Drexel"
36
- end
47
+ it "sets the options" do
48
+ @association.options.should == options
49
+ end
50
+
51
+ end
37
52
 
53
+ describe "#initialize" do
54
+
55
+ before do
56
+ @parent = Person.new(:title => "Dr")
57
+ @name = Name.new(:first_name => "Richard", :last_name => "Dawkins")
58
+ @parent.name = @name
59
+ @block = Proc.new {
60
+ def extension
61
+ "Testing"
62
+ end
63
+ }
64
+ @options = Mongoid::Associations::Options.new(:name => :person, :extend => @block)
65
+ @association = Mongoid::Associations::BelongsTo.new(@parent, @options)
38
66
  end
39
67
 
40
- context "when setting values" do
68
+ context "when the options have an extension" do
41
69
 
42
- it "delegates to the document" do
43
- @association.first_name = "Test"
44
- @association.first_name.should == "Test"
70
+ it "adds the extension module" do
71
+ @association.extension.should == "Testing"
45
72
  end
46
73
 
47
74
  end
@@ -53,14 +80,13 @@ describe Mongoid::Associations::BelongsTo do
53
80
  context "when parent exists" do
54
81
 
55
82
  before do
56
- @parent = Name.new(:first_name => "Drexel")
57
- @document = stub(:_parent => @parent)
58
- @options = Mongoid::Associations::Options.new(:name => :person)
83
+ @parent = stub
84
+ @target = stub(:_parent => @parent)
85
+ @association = Mongoid::Associations::BelongsTo.instantiate(@target, options)
59
86
  end
60
87
 
61
- it "delegates to new" do
62
- Mongoid::Associations::BelongsTo.expects(:new).with(@parent, @options)
63
- Mongoid::Associations::BelongsTo.instantiate(@document, @options)
88
+ it "sets the parent to the target" do
89
+ @association.target.should == @parent
64
90
  end
65
91
 
66
92
  end
@@ -69,11 +95,10 @@ describe Mongoid::Associations::BelongsTo do
69
95
 
70
96
  before do
71
97
  @document = stub(:_parent => nil)
72
- @options = Mongoid::Associations::Options.new(:name => :person)
73
98
  end
74
99
 
75
100
  it "returns nil" do
76
- Mongoid::Associations::BelongsTo.instantiate(@document, @options).should be_nil
101
+ Mongoid::Associations::BelongsTo.instantiate(@document, options).should be_nil
77
102
  end
78
103
 
79
104
  end
@@ -88,6 +113,42 @@ describe Mongoid::Associations::BelongsTo do
88
113
 
89
114
  end
90
115
 
116
+ describe "#method_missing" do
117
+
118
+ before do
119
+ @association = Mongoid::Associations::BelongsTo.new(target, options)
120
+ end
121
+
122
+ context "when method is a getter" do
123
+
124
+ it "delegates to the target" do
125
+ @association.title.should == "Pimp"
126
+ end
127
+
128
+ end
129
+
130
+ context "when method is a setter" do
131
+
132
+ before do
133
+ @association.title = "Dealer"
134
+ end
135
+
136
+ it "delegates to the target" do
137
+ @association.title.should == "Dealer"
138
+ end
139
+
140
+ end
141
+
142
+ context "when method does not exist" do
143
+
144
+ it "raises an error" do
145
+ lambda { @association.nothing }.should raise_error(NoMethodError)
146
+ end
147
+
148
+ end
149
+
150
+ end
151
+
91
152
  describe ".update" do
92
153
 
93
154
  context "when child is a has one" do
@@ -95,16 +156,22 @@ describe Mongoid::Associations::BelongsTo do
95
156
  before do
96
157
  @name = Name.new(:first_name => "Test", :last_name => "User")
97
158
  @person = Person.new(:title => "Mrs")
98
- @options = Mongoid::Associations::Options.new(:name => :person, :inverse_of => :name)
99
- Mongoid::Associations::BelongsTo.update(@person, @name, @options)
159
+ @association = Mongoid::Associations::BelongsTo.update(@person, @name, options)
100
160
  end
101
161
 
102
162
  it "updates the parent document" do
103
163
  @person.name.should == @name
164
+ end
165
+
166
+ it "updates the parent attributes" do
104
167
  @person.attributes[:name].except(:_id).should ==
105
168
  { "first_name" => "Test", "last_name" => "User", "_type" => "Name" }
106
169
  end
107
170
 
171
+ it "returns the proxy association" do
172
+ @association.target.should == @person
173
+ end
174
+
108
175
  end
109
176
 
110
177
  context "when child is a has many" do
@@ -112,8 +179,7 @@ describe Mongoid::Associations::BelongsTo do
112
179
  before do
113
180
  @address = Address.new(:street => "Broadway")
114
181
  @person = Person.new(:title => "Mrs")
115
- @options = Mongoid::Associations::Options.new(:name => :person, :inverse_of => :addresses)
116
- Mongoid::Associations::BelongsTo.update(@person, @address, @options)
182
+ Mongoid::Associations::BelongsTo.update(@person, @address, has_many_options)
117
183
  end
118
184
 
119
185
  it "updates the parent document" do
@@ -2,7 +2,17 @@ require "spec_helper"
2
2
 
3
3
  describe Mongoid::Associations::HasManyRelated do
4
4
 
5
- let(:options) { Mongoid::Associations::Options.new(:name => :posts) }
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(:name => :posts, :extend => block)
15
+ end
6
16
 
7
17
  describe "#<<" do
8
18
 
@@ -239,24 +249,33 @@ describe Mongoid::Associations::HasManyRelated do
239
249
 
240
250
  describe ".initialize" do
241
251
 
242
- context "when related id has been set" do
252
+ before do
253
+ @document = Person.new
254
+ @criteria = stub
255
+ @first = stub(:person_id => @document.id)
256
+ @second = stub(:person_id => @document.id)
257
+ @related = [@first, @second]
258
+ Post.expects(:all).with(:conditions => { "person_id" => @document.id }).returns(@related)
259
+ end
243
260
 
244
- before do
245
- @document = Person.new
246
- @criteria = stub
247
- @first = stub(:person_id => @document.id)
248
- @second = stub(:person_id => @document.id)
249
- @related = [@first, @second]
250
- end
261
+ context "when related id has been set" do
251
262
 
252
263
  it "finds the object by id" do
253
- Post.expects(:all).with(:conditions => { "person_id" => @document.id }).returns(@related)
254
264
  association = Mongoid::Associations::HasManyRelated.new(@document, options)
255
265
  association.should == @related
256
266
  end
257
267
 
258
268
  end
259
269
 
270
+ context "when the options have an extension" do
271
+
272
+ it "adds the extension module" do
273
+ association = Mongoid::Associations::HasManyRelated.new(@document, options)
274
+ association.extension.should == "Testing"
275
+ end
276
+
277
+ end
278
+
260
279
  end
261
280
 
262
281
  describe ".instantiate" do
@@ -268,7 +287,7 @@ describe Mongoid::Associations::HasManyRelated do
268
287
  end
269
288
 
270
289
  it "delegates to new" do
271
- Mongoid::Associations::HasManyRelated.expects(:new).with(@document, options)
290
+ Mongoid::Associations::HasManyRelated.expects(:new).with(@document, options, nil)
272
291
  association = Mongoid::Associations::HasManyRelated.instantiate(@document, options)
273
292
  end
274
293
 
@@ -359,7 +378,8 @@ describe Mongoid::Associations::HasManyRelated do
359
378
  end
360
379
 
361
380
  it "returns the related objects" do
362
- Mongoid::Associations::HasManyRelated.update(@related, @parent, options).should == @related
381
+ @proxy = Mongoid::Associations::HasManyRelated.update(@related, @parent, options)
382
+ @proxy.target.should == @related
363
383
  end
364
384
 
365
385
  end
@@ -200,7 +200,10 @@ describe Mongoid::Associations::HasMany do
200
200
  describe "#find" do
201
201
 
202
202
  before do
203
- @association = Mongoid::Associations::HasMany.new(@document, Mongoid::Associations::Options.new(:name => :addresses))
203
+ @association = Mongoid::Associations::HasMany.new(
204
+ @document,
205
+ Mongoid::Associations::Options.new(:name => :addresses)
206
+ )
204
207
  end
205
208
 
206
209
  context "when finding all" do
@@ -259,18 +262,43 @@ describe Mongoid::Associations::HasMany do
259
262
 
260
263
  describe "#initialize" do
261
264
 
262
- before do
263
- @canvas = stub(:raw_attributes => { "shapes" => [{ "_type" => "Circle", "radius" => 5 }] }, :update => true)
264
- @association = Mongoid::Associations::HasMany.new(
265
- @canvas,
266
- Mongoid::Associations::Options.new(:name => :shapes)
267
- )
265
+ context "when no extension exists" do
266
+
267
+ before do
268
+ @canvas = stub(:raw_attributes => { "shapes" => [{ "_type" => "Circle", "radius" => 5 }] }, :update => true)
269
+ @association = Mongoid::Associations::HasMany.new(
270
+ @canvas,
271
+ Mongoid::Associations::Options.new(:name => :shapes)
272
+ )
273
+ end
274
+
275
+ it "creates the classes based on their types" do
276
+ circle = @association.first
277
+ circle.should be_a_kind_of(Circle)
278
+ circle.radius.should == 5
279
+ end
280
+
268
281
  end
269
282
 
270
- it "creates the classes based on their types" do
271
- circle = @association.first
272
- circle.should be_a_kind_of(Circle)
273
- circle.radius.should == 5
283
+ context "when an extension is in the options" do
284
+
285
+ before do
286
+ @person = Person.new
287
+ @block = Proc.new do
288
+ def extension
289
+ "Testing"
290
+ end
291
+ end
292
+ @association = Mongoid::Associations::HasMany.new(
293
+ @person,
294
+ Mongoid::Associations::Options.new(:name => :addresses, :extend => @block)
295
+ )
296
+ end
297
+
298
+ it "adds the extension module" do
299
+ @association.extension.should == "Testing"
300
+ end
301
+
274
302
  end
275
303
 
276
304
  end
@@ -399,7 +427,11 @@ describe Mongoid::Associations::HasMany do
399
427
  before do
400
428
  @address = Address.new(:street => "Madison Ave")
401
429
  @person = Person.new(:title => "Sir")
402
- Mongoid::Associations::HasMany.update([@address], @person, Mongoid::Associations::Options.new(:name => :addresses))
430
+ @association = Mongoid::Associations::HasMany.update(
431
+ [@address],
432
+ @person,
433
+ Mongoid::Associations::Options.new(:name => :addresses)
434
+ )
403
435
  end
404
436
 
405
437
  it "parentizes the child document" do
@@ -411,6 +443,10 @@ describe Mongoid::Associations::HasMany do
411
443
  [{ "_id" => "madison-ave", "street" => "Madison Ave", "_type" => "Address" }]
412
444
  end
413
445
 
446
+ it "returns the association proxy" do
447
+ @association.target.size.should == 1
448
+ end
449
+
414
450
  end
415
451
 
416
452
  end
@@ -3,7 +3,16 @@ require "spec_helper"
3
3
  describe Mongoid::Associations::HasOneRelated do
4
4
 
5
5
  let(:document) { stub(:id => "1") }
6
- let(:options) { Mongoid::Associations::Options.new(:name => :game) }
6
+ let(:block) do
7
+ Proc.new do
8
+ def extension
9
+ "Testing"
10
+ end
11
+ end
12
+ end
13
+ let(:options) do
14
+ Mongoid::Associations::Options.new(:name => :game, :extend => block)
15
+ end
7
16
 
8
17
  describe "#build" do
9
18
 
@@ -82,12 +91,27 @@ describe Mongoid::Associations::HasOneRelated do
82
91
  @person.game.should == @game
83
92
  end
84
93
 
94
+ context "when the options have an extension" do
95
+
96
+ before do
97
+ @parent = stub(:id => "5", :class => Person)
98
+ @game = Game.new
99
+ Game.expects(:first).returns(@game)
100
+ @association = Mongoid::Associations::HasOneRelated.new(@parent, options)
101
+ end
102
+
103
+ it "adds the extension to the module" do
104
+ @association.extension.should == "Testing"
105
+ end
106
+
107
+ end
108
+
85
109
  end
86
110
 
87
111
  describe ".instantiate" do
88
112
 
89
113
  it "delegates to new" do
90
- Mongoid::Associations::HasOneRelated.expects(:new).with(document, options)
114
+ Mongoid::Associations::HasOneRelated.expects(:new).with(document, options, nil)
91
115
  Mongoid::Associations::HasOneRelated.instantiate(document, options)
92
116
  end
93
117
 
@@ -144,9 +168,10 @@ describe Mongoid::Associations::HasOneRelated do
144
168
  Mongoid::Associations::HasOneRelated.update(@game, @person, options)
145
169
  end
146
170
 
147
- it "returns the child" do
171
+ it "returns the proxy" do
148
172
  @game.expects(:person=).with(@person)
149
- Mongoid::Associations::HasOneRelated.update(@game, @person, options).should == @game
173
+ @proxy = Mongoid::Associations::HasOneRelated.update(@game, @person, options)
174
+ @proxy.target.should == @game
150
175
  end
151
176
 
152
177
  end