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
@@ -0,0 +1,19 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Criterion::Complex do
4
+
5
+ let(:complex) { Mongoid::Criterion::Complex.new(:key => :field, :operator => "$gt") }
6
+
7
+ describe "#initialize" do
8
+
9
+ it "sets the key" do
10
+ complex.key.should == :field
11
+ end
12
+
13
+ it "sets the operator" do
14
+ complex.operator.should == "$gt"
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,75 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Criterion::Exclusion do
4
+
5
+ before do
6
+ @criteria = Mongoid::Criteria.new(Person)
7
+ @canvas_criteria = Mongoid::Criteria.new(Canvas)
8
+ end
9
+
10
+ describe "#excludes" do
11
+
12
+ it "adds the $ne query to the selector" do
13
+ @criteria.excludes(:title => "Bad Title", :text => "Bad Text")
14
+ @criteria.selector.should ==
15
+ { :_type =>
16
+ { "$in" =>
17
+ ["Doctor", "Person"]
18
+ },
19
+ :title =>
20
+ { "$ne" => "Bad Title"},
21
+ :text =>
22
+ { "$ne" => "Bad Text" }
23
+ }
24
+ end
25
+
26
+ it "returns self" do
27
+ @criteria.excludes(:title => "Bad").should == @criteria
28
+ end
29
+
30
+ end
31
+
32
+ describe "#not_in" do
33
+
34
+ it "adds the exclusion to the selector" do
35
+ @criteria.not_in(:title => ["title1", "title2"], :text => ["test"])
36
+ @criteria.selector.should == {
37
+ :_type => { "$in" => ["Doctor", "Person"] },
38
+ :title => { "$nin" => ["title1", "title2"] },
39
+ :text => { "$nin" => ["test"] }
40
+ }
41
+ end
42
+
43
+ it "returns self" do
44
+ @criteria.not_in(:title => ["title1"]).should == @criteria
45
+ end
46
+
47
+ end
48
+
49
+ describe "#only" do
50
+
51
+ context "when args are provided" do
52
+
53
+ it "adds the options for limiting by fields" do
54
+ @criteria.only(:title, :text)
55
+ @criteria.options.should == { :fields => [ :title, :text ] }
56
+ end
57
+
58
+ it "returns self" do
59
+ @criteria.only.should == @criteria
60
+ end
61
+
62
+ end
63
+
64
+ context "when no args provided" do
65
+
66
+ it "does not add the field option" do
67
+ @criteria.only
68
+ @criteria.options[:fields].should be_nil
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,213 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Criterion::Inclusion do
4
+
5
+ before do
6
+ @criteria = Mongoid::Criteria.new(Person)
7
+ @canvas_criteria = Mongoid::Criteria.new(Canvas)
8
+ end
9
+
10
+ describe "#all" do
11
+
12
+ it "adds the $all query to the selector" do
13
+ @criteria.all(:title => ["title1", "title2"])
14
+ @criteria.selector.should ==
15
+ { :_type => { "$in" => ["Doctor", "Person"] },
16
+ :title => { "$all" => ["title1", "title2"] }
17
+ }
18
+ end
19
+
20
+ it "returns self" do
21
+ @criteria.all(:title => [ "title1" ]).should == @criteria
22
+ end
23
+
24
+ end
25
+
26
+ describe "#and" do
27
+
28
+ context "when provided a hash" do
29
+
30
+ it "adds the clause to the selector" do
31
+ @criteria.and(:title => "Title", :text => "Text")
32
+ @criteria.selector.should ==
33
+ { :_type => { "$in" => ["Doctor", "Person"] },
34
+ :title => "Title",
35
+ :text => "Text"
36
+ }
37
+ end
38
+
39
+ end
40
+
41
+ context "when provided a string" do
42
+
43
+ it "adds the $where clause to the selector" do
44
+ @criteria.and("this.date < new Date()")
45
+ @criteria.selector.should ==
46
+ { :_type => { "$in" => ["Doctor", "Person"] },
47
+ "$where" => "this.date < new Date()"
48
+ }
49
+ end
50
+
51
+ end
52
+
53
+ it "returns self" do
54
+ @criteria.and.should == @criteria
55
+ end
56
+
57
+ end
58
+
59
+ describe "#in" do
60
+
61
+ it "adds the $in clause to the selector" do
62
+ @criteria.in(:title => ["title1", "title2"], :text => ["test"])
63
+ @criteria.selector.should ==
64
+ { :_type =>
65
+ { "$in" =>
66
+ ["Doctor", "Person"]
67
+ }, :title => { "$in" => ["title1", "title2"] }, :text => { "$in" => ["test"] }
68
+ }
69
+ end
70
+
71
+ it "returns self" do
72
+ @criteria.in(:title => ["title1"]).should == @criteria
73
+ end
74
+
75
+ end
76
+
77
+ describe "#where" do
78
+
79
+ context "when provided a hash" do
80
+
81
+ context "with simple hash keys" do
82
+
83
+ it "adds the clause to the selector" do
84
+ @criteria.where(:title => "Title", :text => "Text")
85
+ @criteria.selector.should ==
86
+ { :_type => { "$in" => ["Doctor", "Person"] }, :title => "Title", :text => "Text" }
87
+ end
88
+
89
+ end
90
+
91
+ context "with complex criterion" do
92
+
93
+ context "#all" do
94
+
95
+ it "returns those matching an all clause" do
96
+ @criteria.where(:title.all => ["Sir"])
97
+ @criteria.selector.should ==
98
+ { :_type => { "$in" => ["Doctor", "Person"] }, :title => { "$all" => ["Sir"] } }
99
+ end
100
+
101
+ end
102
+
103
+ context "#exists" do
104
+
105
+ it "returns those matching an exists clause" do
106
+ @criteria.where(:title.exists => true)
107
+ @criteria.selector.should ==
108
+ { :_type => { "$in" => ["Doctor", "Person"] }, :title => { "$exists" => true } }
109
+ end
110
+
111
+ end
112
+
113
+ context "#gt" do
114
+
115
+ it "returns those matching a gt clause" do
116
+ @criteria.where(:age.gt => 30)
117
+ @criteria.selector.should ==
118
+ { :_type => { "$in" => ["Doctor", "Person"] }, :age => { "$gt" => 30 } }
119
+ end
120
+
121
+ end
122
+
123
+ context "#gte" do
124
+
125
+ it "returns those matching a gte clause" do
126
+ @criteria.where(:age.gte => 33)
127
+ @criteria.selector.should ==
128
+ { :_type => { "$in" => ["Doctor", "Person"] }, :age => { "$gte" => 33 } }
129
+ end
130
+
131
+ end
132
+
133
+ context "#in" do
134
+
135
+ it "returns those matching an in clause" do
136
+ @criteria.where(:title.in => ["Sir", "Madam"])
137
+ @criteria.selector.should ==
138
+ { :_type => { "$in" => ["Doctor", "Person"] }, :title => { "$in" => ["Sir", "Madam"] } }
139
+ end
140
+
141
+ end
142
+
143
+ context "#lt" do
144
+
145
+ it "returns those matching a lt clause" do
146
+ @criteria.where(:age.lt => 34)
147
+ @criteria.selector.should ==
148
+ { :_type => { "$in" => ["Doctor", "Person"] }, :age => { "$lt" => 34 } }
149
+ end
150
+
151
+ end
152
+
153
+ context "#lte" do
154
+
155
+ it "returns those matching a lte clause" do
156
+ @criteria.where(:age.lte => 33)
157
+ @criteria.selector.should ==
158
+ { :_type => { "$in" => ["Doctor", "Person"] }, :age => { "$lte" => 33 } }
159
+ end
160
+
161
+ end
162
+
163
+ context "#ne" do
164
+
165
+ it "returns those matching a ne clause" do
166
+ @criteria.where(:age.ne => 50)
167
+ @criteria.selector.should ==
168
+ { :_type => { "$in" => ["Doctor", "Person"] }, :age => { "$ne" => 50 } }
169
+ end
170
+
171
+ end
172
+
173
+ context "#nin" do
174
+
175
+ it "returns those matching a nin clause" do
176
+ @criteria.where(:title.nin => ["Esquire", "Congressman"])
177
+ @criteria.selector.should ==
178
+ { :_type => { "$in" => ["Doctor", "Person"] }, :title => { "$nin" => ["Esquire", "Congressman"] } }
179
+ end
180
+
181
+ end
182
+
183
+ context "#size" do
184
+
185
+ it "returns those matching a size clause" do
186
+ @criteria.where(:aliases.size => 2)
187
+ @criteria.selector.should ==
188
+ { :_type => { "$in" => ["Doctor", "Person"] }, :aliases => { "$size" => 2 } }
189
+ end
190
+
191
+ end
192
+
193
+ end
194
+
195
+ end
196
+
197
+ context "when provided a string" do
198
+
199
+ it "adds the $where clause to the selector" do
200
+ @criteria.where("this.date < new Date()")
201
+ @criteria.selector.should ==
202
+ { :_type => { "$in" => ["Doctor", "Person"] }, "$where" => "this.date < new Date()" }
203
+ end
204
+
205
+ end
206
+
207
+ it "returns self" do
208
+ @criteria.where.should == @criteria
209
+ end
210
+
211
+ end
212
+
213
+ end
@@ -0,0 +1,244 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Criterion::Optional do
4
+
5
+ before do
6
+ @criteria = Mongoid::Criteria.new(Person)
7
+ @canvas_criteria = Mongoid::Criteria.new(Canvas)
8
+ end
9
+
10
+ describe "#extras" do
11
+
12
+ context "filtering" do
13
+
14
+ context "when page is provided" do
15
+
16
+ it "sets the limit and skip options" do
17
+ @criteria.extras({ :page => "2" })
18
+ @criteria.page.should == 2
19
+ @criteria.options.should == { :skip => 20, :limit => 20 }
20
+ end
21
+
22
+ end
23
+
24
+ context "when per_page is provided" do
25
+
26
+ it "sets the limit and skip options" do
27
+ @criteria.extras({ :per_page => 45 })
28
+ @criteria.options.should == { :skip => 0, :limit => 45 }
29
+ end
30
+
31
+ end
32
+
33
+ context "when page and per_page both provided" do
34
+
35
+ it "sets the limit and skip options" do
36
+ @criteria.extras({ :per_page => 30, :page => "4" })
37
+ @criteria.options.should == { :skip => 90, :limit => 30 }
38
+ @criteria.page.should == 4
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
45
+ it "adds the extras to the options" do
46
+ @criteria.limit(10).extras({ :skip => 10 })
47
+ @criteria.options.should == { :skip => 10, :limit => 10 }
48
+ end
49
+
50
+ it "returns self" do
51
+ @criteria.extras({}).should == @criteria
52
+ end
53
+
54
+ end
55
+
56
+ describe "#id" do
57
+
58
+ context "when passing a single id" do
59
+
60
+ it "adds the _id query to the selector" do
61
+ id = Mongo::ObjectID.new.to_s
62
+ @criteria.id(id)
63
+ @criteria.selector.should == { :_type => { "$in" => ["Doctor", "Person"] }, :_id => id }
64
+ end
65
+
66
+ it "returns self" do
67
+ id = Mongo::ObjectID.new.to_s
68
+ @criteria.id(id.to_s).should == @criteria
69
+ end
70
+
71
+ end
72
+
73
+ context "when passing in an array of ids" do
74
+
75
+ before do
76
+ @ids = []
77
+ 3.times { @ids << Mongo::ObjectID.new.to_s }
78
+ end
79
+
80
+ it "adds the _id query to the selector" do
81
+ @criteria.id(@ids)
82
+ @criteria.selector.should ==
83
+ { :_type => { "$in" => ["Doctor", "Person"] }, :_id => { "$in" => @ids } }
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ describe "#limit" do
91
+
92
+ context "when value provided" do
93
+
94
+ it "adds the limit to the options" do
95
+ @criteria.limit(100)
96
+ @criteria.options.should == { :limit => 100 }
97
+ end
98
+
99
+ end
100
+
101
+ context "when value not provided" do
102
+
103
+ it "defaults to 20" do
104
+ @criteria.limit
105
+ @criteria.options.should == { :limit => 20 }
106
+ end
107
+
108
+ end
109
+
110
+ it "returns self" do
111
+ @criteria.limit.should == @criteria
112
+ end
113
+
114
+ end
115
+
116
+ describe "#offset" do
117
+
118
+ context "when the per_page option exists" do
119
+
120
+ before do
121
+ @criteria = Mongoid::Criteria.new(Person).extras({ :per_page => 20, :page => 3 })
122
+ end
123
+
124
+ it "returns the per_page option" do
125
+ @criteria.offset.should == 40
126
+ end
127
+
128
+ end
129
+
130
+ context "when the skip option exists" do
131
+
132
+ before do
133
+ @criteria = Mongoid::Criteria.new(Person).extras({ :skip => 20 })
134
+ end
135
+
136
+ it "returns the skip option" do
137
+ @criteria.offset.should == 20
138
+ end
139
+
140
+ end
141
+
142
+ context "when no option exists" do
143
+
144
+ context "when page option exists" do
145
+
146
+ before do
147
+ @criteria = Mongoid::Criteria.new(Person).extras({ :page => 2 })
148
+ end
149
+
150
+ it "adds the skip option to the options and returns it" do
151
+ @criteria.offset.should == 20
152
+ @criteria.options[:skip].should == 20
153
+ end
154
+
155
+ end
156
+
157
+ context "when page option does not exist" do
158
+
159
+ before do
160
+ @criteria = Mongoid::Criteria.new(Person)
161
+ end
162
+
163
+ it "returns nil" do
164
+ @criteria.offset.should be_nil
165
+ @criteria.options[:skip].should be_nil
166
+ end
167
+
168
+ end
169
+
170
+ end
171
+
172
+ end
173
+
174
+ describe "#order_by" do
175
+
176
+ context "when field names and direction specified" do
177
+
178
+ it "adds the sort to the options" do
179
+ @criteria.order_by([[:title, :asc], [:text, :desc]])
180
+ @criteria.options.should == { :sort => [[:title, :asc], [:text, :desc]] }
181
+ end
182
+
183
+ end
184
+
185
+ it "returns self" do
186
+ @criteria.order_by.should == @criteria
187
+ end
188
+
189
+ end
190
+
191
+ describe "#page" do
192
+
193
+ context "when the page option exists" do
194
+
195
+ before do
196
+ @criteria = Mongoid::Criteria.new(Person).extras({ :page => 5 })
197
+ end
198
+
199
+ it "returns the page option" do
200
+ @criteria.page.should == 5
201
+ end
202
+
203
+ end
204
+
205
+ context "when the page option does not exist" do
206
+
207
+ before do
208
+ @criteria = Mongoid::Criteria.new(Person)
209
+ end
210
+
211
+ it "returns 1" do
212
+ @criteria.page.should == 1
213
+ end
214
+
215
+ end
216
+
217
+ end
218
+
219
+ describe "#skip" do
220
+
221
+ context "when value provided" do
222
+
223
+ it "adds the skip value to the options" do
224
+ @criteria.skip(20)
225
+ @criteria.options.should == { :skip => 20 }
226
+ end
227
+
228
+ end
229
+
230
+ context "when value not provided" do
231
+
232
+ it "defaults to zero" do
233
+ @criteria.skip
234
+ @criteria.options.should == { :skip => 0 }
235
+ end
236
+
237
+ end
238
+
239
+ it "returns self" do
240
+ @criteria.skip.should == @criteria
241
+ end
242
+
243
+ end
244
+ end