mongo_mapper 0.7.1 → 0.7.2
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.
- data/Rakefile +1 -1
- data/lib/mongo_mapper.rb +1 -1
- data/lib/mongo_mapper/document.rb +4 -0
- data/lib/mongo_mapper/embedded_document.rb +9 -1
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +4 -4
- data/lib/mongo_mapper/plugins/keys.rb +15 -19
- data/lib/mongo_mapper/plugins/modifiers.rb +4 -0
- data/lib/mongo_mapper/plugins/rails.rb +5 -1
- data/lib/mongo_mapper/plugins/validations.rb +1 -1
- data/lib/mongo_mapper/query.rb +9 -4
- data/lib/mongo_mapper/support.rb +2 -4
- data/lib/mongo_mapper/version.rb +1 -1
- data/mongo_mapper.gemspec +6 -6
- data/test/active_model_lint_test.rb +2 -0
- data/test/functional/test_document.rb +32 -2
- data/test/functional/test_embedded_document.rb +70 -8
- data/test/functional/test_modifiers.rb +9 -1
- data/test/functional/test_validations.rb +44 -31
- data/test/test_helper.rb +1 -0
- data/test/unit/test_document.rb +0 -6
- data/test/unit/test_embedded_document.rb +1 -7
- data/test/unit/test_query.rb +80 -56
- data/test/unit/test_rails.rb +77 -19
- data/test/unit/test_support.rb +6 -2
- metadata +69 -34
@@ -317,6 +317,14 @@ class ModifierTest < Test::Unit::TestCase
|
|
317
317
|
page2.reload
|
318
318
|
page.tags.should == %w(foo)
|
319
319
|
end
|
320
|
-
|
320
|
+
|
321
|
+
should "be able to pop with modifier hashes" do
|
322
|
+
page = @page_class.create(:tags => %w(foo bar))
|
323
|
+
|
324
|
+
page.pop({:tags => 1})
|
321
325
|
|
326
|
+
page.reload
|
327
|
+
page.tags.should == %w(foo)
|
328
|
+
end
|
329
|
+
end
|
322
330
|
end
|
@@ -1,19 +1,19 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class ValidationsTest < Test::Unit::TestCase
|
3
|
+
class ValidationsTest < Test::Unit::TestCase
|
4
4
|
context "Saving a new document that is invalid" do
|
5
5
|
setup do
|
6
6
|
@document = Doc do
|
7
7
|
key :name, String, :required => true
|
8
8
|
end
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
should "not insert document" do
|
12
12
|
doc = @document.new
|
13
13
|
doc.save
|
14
14
|
@document.count.should == 0
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
should "populate document's errors" do
|
18
18
|
doc = @document.new
|
19
19
|
doc.errors.size.should == 0
|
@@ -28,7 +28,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
28
28
|
key :name, String, :required => true
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
should "raise error" do
|
33
33
|
doc = @document.new
|
34
34
|
lambda { doc.save! }.should raise_error(MongoMapper::DocumentNotValid)
|
@@ -41,7 +41,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
41
41
|
key :name, String, :required => true
|
42
42
|
end
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
should "raise error" do
|
46
46
|
lambda { @document.create! }.should raise_error(MongoMapper::DocumentNotValid)
|
47
47
|
end
|
@@ -51,29 +51,29 @@ class ValidationsTest < Test::Unit::TestCase
|
|
51
51
|
instance.new_record?.should be_false
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
context "Saving an existing document that is invalid" do
|
56
56
|
setup do
|
57
57
|
@document = Doc do
|
58
58
|
key :name, String, :required => true
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
@doc = @document.create(:name => 'John Nunemaker')
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
should "not update document" do
|
65
65
|
@doc.name = nil
|
66
66
|
@doc.save
|
67
67
|
@doc.reload.name.should == 'John Nunemaker'
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
should "populate document's errors" do
|
71
71
|
@doc.name = nil
|
72
72
|
@doc.save
|
73
73
|
@doc.errors.full_messages.should == ["Name can't be empty"]
|
74
74
|
end
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
context "Adding validation errors" do
|
78
78
|
setup do
|
79
79
|
@document = Doc do
|
@@ -83,38 +83,38 @@ class ValidationsTest < Test::Unit::TestCase
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
should "work with validate_on_create callback" do
|
88
88
|
@document.validate_on_create :action_present
|
89
|
-
|
89
|
+
|
90
90
|
doc = @document.new
|
91
91
|
doc.action = nil
|
92
92
|
doc.should have_error_on(:action)
|
93
|
-
|
93
|
+
|
94
94
|
doc.action = 'kick'
|
95
95
|
doc.should_not have_error_on(:action)
|
96
96
|
doc.save
|
97
|
-
|
97
|
+
|
98
98
|
doc.action = nil
|
99
99
|
doc.should_not have_error_on(:action)
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
should "work with validate_on_update callback" do
|
103
103
|
@document.validate_on_update :action_present
|
104
|
-
|
104
|
+
|
105
105
|
doc = @document.new
|
106
106
|
doc.action = nil
|
107
107
|
doc.should_not have_error_on(:action)
|
108
108
|
doc.save
|
109
|
-
|
109
|
+
|
110
110
|
doc.action = nil
|
111
111
|
doc.should have_error_on(:action)
|
112
|
-
|
112
|
+
|
113
113
|
doc.action = 'kick'
|
114
114
|
doc.should_not have_error_on(:action)
|
115
115
|
end
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
118
|
context "validating uniqueness of" do
|
119
119
|
setup do
|
120
120
|
@document = Doc do
|
@@ -167,13 +167,13 @@ class ValidationsTest < Test::Unit::TestCase
|
|
167
167
|
doc2 = @document.new("name" => "joe")
|
168
168
|
doc2.should have_error_on(:name)
|
169
169
|
end
|
170
|
-
|
170
|
+
|
171
171
|
should "allow multiple blank entries if :allow_blank => true" do
|
172
172
|
document = Doc do
|
173
173
|
key :name
|
174
174
|
validates_uniqueness_of :name, :allow_blank => :true
|
175
175
|
end
|
176
|
-
|
176
|
+
|
177
177
|
doc = document.new("name" => "")
|
178
178
|
doc.save.should be_true
|
179
179
|
|
@@ -219,7 +219,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
219
219
|
validates_uniqueness_of :name, :case_sensitive => false
|
220
220
|
end
|
221
221
|
end
|
222
|
-
|
222
|
+
|
223
223
|
should "fail on entries that differ only in case" do
|
224
224
|
doc = @document.new("name" => "BLAMMO")
|
225
225
|
doc.save.should be_true
|
@@ -232,6 +232,19 @@ class ValidationsTest < Test::Unit::TestCase
|
|
232
232
|
doc = @document.new("name" => nil)
|
233
233
|
lambda { doc.valid? }.should_not raise_error
|
234
234
|
end
|
235
|
+
|
236
|
+
should "not raise an error if special Regexp characters used" do
|
237
|
+
doc = @document.new("name" => '?')
|
238
|
+
lambda { doc.valid? }.should_not raise_error
|
239
|
+
end
|
240
|
+
|
241
|
+
should "check for uniqueness using entire string" do
|
242
|
+
doc = @document.new("name" => "John Doe")
|
243
|
+
doc.save.should be_true
|
244
|
+
|
245
|
+
doc2 = @document.new("name" => "John")
|
246
|
+
doc2.valid?.should be_true
|
247
|
+
end
|
235
248
|
end
|
236
249
|
|
237
250
|
context "scoped by a single attribute" do
|
@@ -246,7 +259,7 @@ class ValidationsTest < Test::Unit::TestCase
|
|
246
259
|
should "fail if the same name exists in the scope" do
|
247
260
|
doc = @document.new("name" => "joe", "scope" => "one")
|
248
261
|
doc.save.should be_true
|
249
|
-
|
262
|
+
|
250
263
|
@document \
|
251
264
|
.stubs(:first) \
|
252
265
|
.with(:name => 'joe', :scope => "one") \
|
@@ -279,11 +292,11 @@ class ValidationsTest < Test::Unit::TestCase
|
|
279
292
|
validates_uniqueness_of :name, :scope => [:first_scope, :second_scope]
|
280
293
|
end
|
281
294
|
end
|
282
|
-
|
295
|
+
|
283
296
|
should "fail if the same name exists in the scope" do
|
284
297
|
doc = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
|
285
298
|
doc.save.should be_true
|
286
|
-
|
299
|
+
|
287
300
|
@document \
|
288
301
|
.stubs(:first) \
|
289
302
|
.with(:name => 'joe', :first_scope => 'one', :second_scope => 'two') \
|
@@ -292,11 +305,11 @@ class ValidationsTest < Test::Unit::TestCase
|
|
292
305
|
doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
|
293
306
|
doc2.should have_error_on(:name)
|
294
307
|
end
|
295
|
-
|
308
|
+
|
296
309
|
should "pass if the same name exists in a different scope" do
|
297
310
|
doc = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
|
298
311
|
doc.save.should be_true
|
299
|
-
|
312
|
+
|
300
313
|
@document \
|
301
314
|
.stubs(:first) \
|
302
315
|
.with(:name => 'joe', :first_scope => 'one', :second_scope => 'one') \
|
@@ -307,21 +320,21 @@ class ValidationsTest < Test::Unit::TestCase
|
|
307
320
|
end
|
308
321
|
end
|
309
322
|
end
|
310
|
-
|
323
|
+
|
311
324
|
context "validates uniqueness of with :unique shortcut" do
|
312
325
|
should "work" do
|
313
326
|
@document = Doc do
|
314
327
|
key :name, String, :unique => true
|
315
328
|
end
|
316
|
-
|
329
|
+
|
317
330
|
doc = @document.create(:name => 'John')
|
318
331
|
doc.should_not have_error_on(:name)
|
319
|
-
|
332
|
+
|
320
333
|
@document \
|
321
334
|
.stubs(:first) \
|
322
335
|
.with(:name => 'John') \
|
323
336
|
.returns(doc)
|
324
|
-
|
337
|
+
|
325
338
|
second_john = @document.create(:name => 'John')
|
326
339
|
second_john.should have_error_on(:name, 'has already been taken')
|
327
340
|
end
|
data/test/test_helper.rb
CHANGED
data/test/unit/test_document.rb
CHANGED
@@ -105,12 +105,6 @@ class DocumentTest < Test::Unit::TestCase
|
|
105
105
|
@document.new._id.should be_instance_of(Mongo::ObjectID)
|
106
106
|
end
|
107
107
|
|
108
|
-
should "have to_param that is string representation of id" do
|
109
|
-
doc = @document.new(:id => Mongo::ObjectID.new)
|
110
|
-
doc.to_param.should == doc.id.to_s
|
111
|
-
doc.to_param.should be_instance_of(String)
|
112
|
-
end
|
113
|
-
|
114
108
|
should "have access to logger" do
|
115
109
|
doc = @document.new
|
116
110
|
doc.logger.should == @document.logger
|
@@ -11,7 +11,7 @@ module KeyOverride
|
|
11
11
|
end
|
12
12
|
|
13
13
|
class EmbeddedDocumentTest < Test::Unit::TestCase
|
14
|
-
context "" do
|
14
|
+
context "EmbeddedDocuments" do
|
15
15
|
setup do
|
16
16
|
class ::Grandparent
|
17
17
|
include MongoMapper::EmbeddedDocument
|
@@ -221,12 +221,6 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
|
|
221
221
|
end
|
222
222
|
end
|
223
223
|
|
224
|
-
should "have to_param that is string representation of id" do
|
225
|
-
doc = @document.new
|
226
|
-
doc.to_param.should == doc.id.to_s
|
227
|
-
doc.to_param.should be_instance_of(String)
|
228
|
-
end
|
229
|
-
|
230
224
|
should "have access to class logger" do
|
231
225
|
doc = @document.new
|
232
226
|
doc.logger.should == @document.logger
|
data/test/unit/test_query.rb
CHANGED
@@ -3,25 +3,25 @@ require 'models'
|
|
3
3
|
|
4
4
|
class QueryTest < Test::Unit::TestCase
|
5
5
|
include MongoMapper
|
6
|
-
|
6
|
+
|
7
7
|
should "raise error if provided something other than a hash" do
|
8
8
|
lambda { Query.new(Room) }.should raise_error(ArgumentError)
|
9
9
|
lambda { Query.new(Room, 1) }.should raise_error(ArgumentError)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
should "symbolize the keys of the hash provided" do
|
13
13
|
Query.new(Room, 'offset' => 1).options.keys.map do |key|
|
14
14
|
key.should be_instance_of(Symbol)
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
context "Converting conditions to criteria" do
|
19
19
|
should "not add _type to query if model does not have superclass that is single collection inherited" do
|
20
20
|
Query.new(Message, :foo => 'bar').criteria.should == {
|
21
21
|
:foo => 'bar'
|
22
22
|
}
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
should "not add _type to nested conditions" do
|
26
26
|
Query.new(Enter, :foo => 'bar', :age => {'$gt' => 21}).criteria.should == {
|
27
27
|
:foo => 'bar',
|
@@ -29,14 +29,14 @@ class QueryTest < Test::Unit::TestCase
|
|
29
29
|
:_type => 'Enter'
|
30
30
|
}
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
should "automatically add _type to query if model is single collection inherited" do
|
34
34
|
Query.new(Enter, :foo => 'bar').criteria.should == {
|
35
35
|
:foo => 'bar',
|
36
36
|
:_type => 'Enter'
|
37
37
|
}
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
%w{gt lt gte lte ne in nin mod all size where exists}.each do |operator|
|
41
41
|
next if operator == 'size' && RUBY_VERSION >= '1.9.1' # 1.9 defines Symbol#size
|
42
42
|
|
@@ -46,75 +46,75 @@ class QueryTest < Test::Unit::TestCase
|
|
46
46
|
}
|
47
47
|
end
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
should "normalize value when using symbol operators" do
|
51
51
|
time = Time.now.in_time_zone('Indiana (East)')
|
52
52
|
criteria = Query.new(Room, :created_at.gt => time).criteria
|
53
53
|
criteria[:created_at]['$gt'].should be_utc
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
should "work with simple criteria" do
|
57
57
|
Query.new(Room, :foo => 'bar').criteria.should == {
|
58
58
|
:foo => 'bar'
|
59
59
|
}
|
60
|
-
|
60
|
+
|
61
61
|
Query.new(Room, :foo => 'bar', :baz => 'wick').criteria.should == {
|
62
|
-
:foo => 'bar',
|
62
|
+
:foo => 'bar',
|
63
63
|
:baz => 'wick'
|
64
64
|
}
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
should "convert id to _id" do
|
68
68
|
id = Mongo::ObjectID.new
|
69
69
|
Query.new(Room, :id => id).criteria.should == {:_id => id}
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
should "convert id with symbol operator to _id with modifier" do
|
73
73
|
id = Mongo::ObjectID.new
|
74
74
|
Query.new(Room, :id.ne => id).criteria.should == {
|
75
75
|
:_id => {'$ne' => id}
|
76
76
|
}
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
should "make sure that _id's are object ids" do
|
80
80
|
id = Mongo::ObjectID.new
|
81
81
|
Query.new(Room, :_id => id.to_s).criteria.should == {:_id => id}
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
should "work fine with _id's that are object ids" do
|
85
85
|
id = Mongo::ObjectID.new
|
86
86
|
Query.new(Room, :_id => id).criteria.should == {:_id => id}
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
should "make sure other object id typed keys get converted" do
|
90
90
|
id = Mongo::ObjectID.new
|
91
91
|
Query.new(Message, :room_id => id.to_s).criteria.should == {:room_id => id}
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
should "work fine with object ids for object id typed keys" do
|
95
95
|
id = Mongo::ObjectID.new
|
96
96
|
Query.new(Message, :room_id => id).criteria.should == {:room_id => id}
|
97
97
|
end
|
98
|
-
|
98
|
+
|
99
99
|
should "convert times to utc if they aren't already" do
|
100
100
|
time = Time.now.in_time_zone('Indiana (East)')
|
101
101
|
criteria = Query.new(Room, :created_at => time).criteria
|
102
102
|
criteria[:created_at].utc?.should be_true
|
103
103
|
end
|
104
|
-
|
104
|
+
|
105
105
|
should "not funk with times already in utc" do
|
106
106
|
time = Time.now.utc
|
107
107
|
criteria = Query.new(Room, :created_at => time).criteria
|
108
108
|
criteria[:created_at].utc?.should be_true
|
109
109
|
criteria[:created_at].should == time
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
should "use $in for arrays" do
|
113
113
|
Query.new(Room, :foo => [1,2,3]).criteria.should == {
|
114
114
|
:foo => {'$in' => [1,2,3]}
|
115
115
|
}
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
118
|
should "not use $in for arrays if already using array operator" do
|
119
119
|
Query.new(Room, :foo => {'$all' => [1,2,3]}).criteria.should == {
|
120
120
|
:foo => {'$all' => [1,2,3]}
|
@@ -124,155 +124,179 @@ class QueryTest < Test::Unit::TestCase
|
|
124
124
|
:foo => {'$any' => [1,2,3]}
|
125
125
|
}
|
126
126
|
end
|
127
|
-
|
127
|
+
|
128
|
+
should "use $in for sets" do
|
129
|
+
Query.new(Room, :foo => Set.new([1,2,3])).criteria.should == {
|
130
|
+
:foo => {'$in' => [1,2,3]}
|
131
|
+
}
|
132
|
+
end
|
133
|
+
|
134
|
+
should "not use $in for sets if already using array operator" do
|
135
|
+
Query.new(Room, :foo => {'$all' => Set.new([1,2,3])}).criteria.should == {
|
136
|
+
:foo => {'$all' => [1,2,3]}
|
137
|
+
}
|
138
|
+
|
139
|
+
Query.new(Room, :foo => {'$any' => Set.new([1,2,3])}).criteria.should == {
|
140
|
+
:foo => {'$any' => [1,2,3]}
|
141
|
+
}
|
142
|
+
end
|
143
|
+
|
128
144
|
should "work arbitrarily deep" do
|
129
145
|
Query.new(Room, :foo => {:bar => [1,2,3]}).criteria.should == {
|
130
146
|
:foo => {:bar => {'$in' => [1,2,3]}}
|
131
147
|
}
|
132
|
-
|
148
|
+
|
133
149
|
Query.new(Room, :foo => {:bar => {'$any' => [1,2,3]}}).criteria.should == {
|
134
150
|
:foo => {:bar => {'$any' => [1,2,3]}}
|
135
151
|
}
|
136
152
|
end
|
153
|
+
|
154
|
+
should "make sure that ids in array are object ids" do
|
155
|
+
id1, id2, id3 = Mongo::ObjectID.new, Mongo::ObjectID.new, Mongo::ObjectID.new
|
156
|
+
|
157
|
+
Query.new(Room, :_id => [id1.to_s, id2.to_s, id3.to_s]).criteria.should == {
|
158
|
+
:_id => {'$in' => [id1, id2, id3]}
|
159
|
+
}
|
160
|
+
end
|
137
161
|
end
|
138
|
-
|
162
|
+
|
139
163
|
context "ordering" do
|
140
164
|
should "single field with ascending direction" do
|
141
165
|
sort = [['foo', 1]]
|
142
166
|
Query.new(Room, :order => 'foo asc').options[:sort].should == sort
|
143
167
|
Query.new(Room, :order => 'foo ASC').options[:sort].should == sort
|
144
168
|
end
|
145
|
-
|
169
|
+
|
146
170
|
should "single field with descending direction" do
|
147
171
|
sort = [['foo', -1]]
|
148
172
|
Query.new(Room, :order => 'foo desc').options[:sort].should == sort
|
149
173
|
Query.new(Room, :order => 'foo DESC').options[:sort].should == sort
|
150
174
|
end
|
151
|
-
|
175
|
+
|
152
176
|
should "convert order operators to mongo sort" do
|
153
177
|
Query.new(Room, :order => :foo.asc).options[:sort].should == [['foo', 1]]
|
154
178
|
Query.new(Room, :order => :foo.desc).options[:sort].should == [['foo', -1]]
|
155
179
|
end
|
156
|
-
|
180
|
+
|
157
181
|
should "convert array of order operators to mongo sort" do
|
158
182
|
Query.new(Room, :order => [:foo.asc, :bar.desc]).options[:sort].should == [['foo', 1], ['bar', -1]]
|
159
183
|
end
|
160
|
-
|
184
|
+
|
161
185
|
should "convert field without direction to ascending" do
|
162
186
|
sort = [['foo', 1]]
|
163
187
|
Query.new(Room, :order => 'foo').options[:sort].should == sort
|
164
188
|
end
|
165
|
-
|
189
|
+
|
166
190
|
should "convert multiple fields with directions" do
|
167
191
|
sort = [['foo', -1], ['bar', 1], ['baz', -1]]
|
168
192
|
Query.new(Room, :order => 'foo desc, bar asc, baz desc').options[:sort].should == sort
|
169
193
|
end
|
170
|
-
|
194
|
+
|
171
195
|
should "convert multiple fields with some missing directions" do
|
172
196
|
sort = [['foo', -1], ['bar', 1], ['baz', 1]]
|
173
197
|
Query.new(Room, :order => 'foo desc, bar, baz').options[:sort].should == sort
|
174
198
|
end
|
175
|
-
|
199
|
+
|
176
200
|
should "just use sort if sort and order are present" do
|
177
201
|
sort = [['$natural', 1]]
|
178
202
|
Query.new(Room, :sort => sort, :order => 'foo asc').options[:sort].should == sort
|
179
203
|
end
|
180
|
-
|
204
|
+
|
181
205
|
should "normalize id to _id" do
|
182
206
|
Query.new(Room, :order => :id.asc).options[:sort].should == [['_id', 1]]
|
183
207
|
end
|
184
|
-
|
208
|
+
|
185
209
|
should "convert natural in order to proper" do
|
186
210
|
sort = [['$natural', 1]]
|
187
211
|
Query.new(Room, :order => '$natural asc').options[:sort].should == sort
|
188
212
|
sort = [['$natural', -1]]
|
189
213
|
Query.new(Room, :order => '$natural desc').options[:sort].should == sort
|
190
214
|
end
|
191
|
-
|
215
|
+
|
192
216
|
should "work for natural order ascending" do
|
193
217
|
Query.new(Room, :sort => {'$natural' => 1}).options[:sort]['$natural'].should == 1
|
194
218
|
end
|
195
|
-
|
219
|
+
|
196
220
|
should "work for natural order descending" do
|
197
221
|
Query.new(Room, :sort => {'$natural' => -1}).options[:sort]['$natural'].should == -1
|
198
222
|
end
|
199
223
|
end
|
200
|
-
|
224
|
+
|
201
225
|
context "skip" do
|
202
226
|
should "default to 0" do
|
203
227
|
Query.new(Room, {}).options[:skip].should == 0
|
204
228
|
end
|
205
|
-
|
229
|
+
|
206
230
|
should "use skip provided" do
|
207
231
|
Query.new(Room, :skip => 2).options[:skip].should == 2
|
208
232
|
end
|
209
|
-
|
233
|
+
|
210
234
|
should "covert string to integer" do
|
211
235
|
Query.new(Room, :skip => '2').options[:skip].should == 2
|
212
236
|
end
|
213
|
-
|
237
|
+
|
214
238
|
should "convert offset to skip" do
|
215
239
|
Query.new(Room, :offset => 1).options[:skip].should == 1
|
216
240
|
end
|
217
241
|
end
|
218
|
-
|
242
|
+
|
219
243
|
context "limit" do
|
220
244
|
should "default to 0" do
|
221
245
|
Query.new(Room, {}).options[:limit].should == 0
|
222
246
|
end
|
223
|
-
|
247
|
+
|
224
248
|
should "use limit provided" do
|
225
249
|
Query.new(Room, :limit => 2).options[:limit].should == 2
|
226
250
|
end
|
227
|
-
|
251
|
+
|
228
252
|
should "covert string to integer" do
|
229
253
|
Query.new(Room, :limit => '2').options[:limit].should == 2
|
230
254
|
end
|
231
255
|
end
|
232
|
-
|
256
|
+
|
233
257
|
context "fields" do
|
234
258
|
should "default to nil" do
|
235
259
|
Query.new(Room, {}).options[:fields].should be(nil)
|
236
260
|
end
|
237
|
-
|
261
|
+
|
238
262
|
should "be converted to nil if empty string" do
|
239
263
|
Query.new(Room, :fields => '').options[:fields].should be(nil)
|
240
264
|
end
|
241
|
-
|
265
|
+
|
242
266
|
should "be converted to nil if []" do
|
243
267
|
Query.new(Room, :fields => []).options[:fields].should be(nil)
|
244
268
|
end
|
245
|
-
|
269
|
+
|
246
270
|
should "should work with array" do
|
247
271
|
Query.new(Room, {:fields => %w(a b)}).options[:fields].should == %w(a b)
|
248
272
|
end
|
249
|
-
|
273
|
+
|
250
274
|
should "convert comma separated list to array" do
|
251
275
|
Query.new(Room, {:fields => 'a, b'}).options[:fields].should == %w(a b)
|
252
276
|
end
|
253
|
-
|
277
|
+
|
254
278
|
should "also work as select" do
|
255
279
|
Query.new(Room, :select => %w(a b)).options[:fields].should == %w(a b)
|
256
280
|
end
|
257
|
-
|
281
|
+
|
258
282
|
should "also work with select as array of symbols" do
|
259
283
|
Query.new(Room, :select => [:a, :b]).options[:fields].should == [:a, :b]
|
260
284
|
end
|
261
285
|
end
|
262
|
-
|
286
|
+
|
263
287
|
context "Condition auto-detection" do
|
264
288
|
should "know :conditions are criteria" do
|
265
289
|
finder = Query.new(Room, :conditions => {:foo => 'bar'})
|
266
290
|
finder.criteria.should == {:foo => 'bar'}
|
267
291
|
finder.options.keys.should_not include(:conditions)
|
268
292
|
end
|
269
|
-
|
293
|
+
|
270
294
|
should "know fields is an option" do
|
271
295
|
finder = Query.new(Room, :fields => ['foo'])
|
272
296
|
finder.options[:fields].should == ['foo']
|
273
297
|
finder.criteria.keys.should_not include(:fields)
|
274
298
|
end
|
275
|
-
|
299
|
+
|
276
300
|
# select gets converted to fields so just checking keys
|
277
301
|
should "know select is an option" do
|
278
302
|
finder = Query.new(Room, :select => 'foo')
|
@@ -280,13 +304,13 @@ class QueryTest < Test::Unit::TestCase
|
|
280
304
|
finder.criteria.keys.should_not include(:select)
|
281
305
|
finder.criteria.keys.should_not include(:fields)
|
282
306
|
end
|
283
|
-
|
307
|
+
|
284
308
|
should "know skip is an option" do
|
285
309
|
finder = Query.new(Room, :skip => 10)
|
286
310
|
finder.options[:skip].should == 10
|
287
311
|
finder.criteria.keys.should_not include(:skip)
|
288
312
|
end
|
289
|
-
|
313
|
+
|
290
314
|
# offset gets converted to skip so just checking keys
|
291
315
|
should "know offset is an option" do
|
292
316
|
finder = Query.new(Room, :offset => 10)
|
@@ -313,7 +337,7 @@ class QueryTest < Test::Unit::TestCase
|
|
313
337
|
finder.options.keys.should include(:sort)
|
314
338
|
finder.criteria.keys.should_not include(:sort)
|
315
339
|
end
|
316
|
-
|
340
|
+
|
317
341
|
should "work with full range of things" do
|
318
342
|
query_options = Query.new(Room, {
|
319
343
|
:foo => 'bar',
|
@@ -323,12 +347,12 @@ class QueryTest < Test::Unit::TestCase
|
|
323
347
|
:limit => 10,
|
324
348
|
:skip => 10,
|
325
349
|
})
|
326
|
-
|
350
|
+
|
327
351
|
query_options.criteria.should == {
|
328
352
|
:foo => 'bar',
|
329
353
|
:baz => true,
|
330
354
|
}
|
331
|
-
|
355
|
+
|
332
356
|
query_options.options.should == {
|
333
357
|
:sort => [['foo', 1]],
|
334
358
|
:fields => ['foo', 'baz'],
|