mongoid 1.1.3 → 1.1.4

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 (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