mongo_mapper 0.7.6 → 0.8.0
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/README.rdoc +4 -8
- data/bin/mmconsole +1 -1
- data/examples/keys.rb +37 -0
- data/examples/plugins.rb +41 -0
- data/examples/querying.rb +35 -0
- data/examples/scopes.rb +52 -0
- data/lib/mongo_mapper.rb +77 -97
- data/lib/mongo_mapper/connection.rb +83 -0
- data/lib/mongo_mapper/document.rb +10 -252
- data/lib/mongo_mapper/embedded_document.rb +7 -46
- data/lib/mongo_mapper/exceptions.rb +30 -0
- data/lib/mongo_mapper/extensions/array.rb +19 -0
- data/lib/mongo_mapper/extensions/binary.rb +22 -0
- data/lib/mongo_mapper/extensions/boolean.rb +44 -0
- data/lib/mongo_mapper/extensions/date.rb +25 -0
- data/lib/mongo_mapper/extensions/float.rb +14 -0
- data/lib/mongo_mapper/extensions/hash.rb +14 -0
- data/lib/mongo_mapper/extensions/integer.rb +19 -0
- data/lib/mongo_mapper/extensions/kernel.rb +9 -0
- data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
- data/lib/mongo_mapper/extensions/object.rb +27 -0
- data/lib/mongo_mapper/extensions/object_id.rb +30 -0
- data/lib/mongo_mapper/extensions/set.rb +20 -0
- data/lib/mongo_mapper/extensions/string.rb +18 -0
- data/lib/mongo_mapper/extensions/time.rb +29 -0
- data/lib/mongo_mapper/plugins.rb +1 -21
- data/lib/mongo_mapper/plugins/accessible.rb +44 -0
- data/lib/mongo_mapper/plugins/associations.rb +7 -24
- data/lib/mongo_mapper/plugins/associations/base.rb +1 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +5 -6
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +5 -6
- data/lib/mongo_mapper/plugins/associations/collection.rb +1 -0
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +2 -1
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +22 -39
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +4 -4
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +22 -23
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +1 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +1 -0
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +1 -0
- data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +2 -3
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +6 -7
- data/lib/mongo_mapper/plugins/associations/proxy.rb +8 -6
- data/lib/mongo_mapper/plugins/caching.rb +21 -0
- data/lib/mongo_mapper/plugins/callbacks.rb +4 -3
- data/lib/mongo_mapper/plugins/clone.rb +10 -4
- data/lib/mongo_mapper/plugins/descendants.rb +1 -0
- data/lib/mongo_mapper/plugins/dirty.rb +1 -0
- data/lib/mongo_mapper/plugins/document.rb +41 -0
- data/lib/mongo_mapper/plugins/dynamic_querying.rb +41 -0
- data/lib/mongo_mapper/{support/find.rb → plugins/dynamic_querying/dynamic_finder.rb} +3 -36
- data/lib/mongo_mapper/plugins/embedded_document.rb +49 -0
- data/lib/mongo_mapper/plugins/equality.rb +3 -9
- data/lib/mongo_mapper/plugins/identity_map.rb +8 -10
- data/lib/mongo_mapper/plugins/indexes.rb +12 -0
- data/lib/mongo_mapper/plugins/inspect.rb +1 -0
- data/lib/mongo_mapper/plugins/keys.rb +15 -27
- data/lib/mongo_mapper/plugins/keys/key.rb +14 -3
- data/lib/mongo_mapper/plugins/logger.rb +1 -0
- data/lib/mongo_mapper/plugins/modifiers.rb +3 -2
- data/lib/mongo_mapper/plugins/pagination.rb +5 -15
- data/lib/mongo_mapper/plugins/persistence.rb +12 -11
- data/lib/mongo_mapper/plugins/protected.rb +8 -0
- data/lib/mongo_mapper/plugins/querying.rb +236 -0
- data/lib/mongo_mapper/plugins/querying/decorator.rb +46 -0
- data/lib/mongo_mapper/plugins/rails.rb +1 -0
- data/lib/mongo_mapper/plugins/safe.rb +28 -0
- data/lib/mongo_mapper/plugins/sci.rb +32 -0
- data/lib/mongo_mapper/plugins/scopes.rb +21 -0
- data/lib/mongo_mapper/plugins/serialization.rb +1 -0
- data/lib/mongo_mapper/plugins/timestamps.rb +1 -0
- data/lib/mongo_mapper/plugins/userstamps.rb +1 -0
- data/lib/mongo_mapper/plugins/validations.rb +5 -1
- data/lib/mongo_mapper/support/descendant_appends.rb +5 -6
- data/lib/mongo_mapper/version.rb +2 -1
- data/test/NOTE_ON_TESTING +1 -0
- data/test/active_model_lint_test.rb +13 -0
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +63 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +93 -0
- data/test/functional/associations/test_in_array_proxy.rb +319 -0
- data/test/functional/associations/test_many_documents_as_proxy.rb +229 -0
- data/test/functional/associations/test_many_documents_proxy.rb +536 -0
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +176 -0
- data/test/functional/associations/test_many_embedded_proxy.rb +256 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +302 -0
- data/test/functional/associations/test_one_embedded_proxy.rb +58 -0
- data/test/functional/associations/test_one_proxy.rb +182 -0
- data/test/functional/test_accessible.rb +168 -0
- data/test/functional/test_associations.rb +44 -0
- data/test/functional/test_binary.rb +27 -0
- data/test/functional/test_caching.rb +76 -0
- data/test/functional/test_callbacks.rb +151 -0
- data/test/functional/test_dirty.rb +163 -0
- data/test/functional/test_document.rb +253 -0
- data/test/functional/test_dynamic_querying.rb +75 -0
- data/test/functional/test_embedded_document.rb +210 -0
- data/test/functional/test_identity_map.rb +506 -0
- data/test/functional/test_indexes.rb +42 -0
- data/test/functional/test_logger.rb +20 -0
- data/test/functional/test_modifiers.rb +416 -0
- data/test/functional/test_pagination.rb +91 -0
- data/test/functional/test_protected.rb +175 -0
- data/test/functional/test_querying.rb +873 -0
- data/test/functional/test_safe.rb +76 -0
- data/test/functional/test_sci.rb +230 -0
- data/test/functional/test_scopes.rb +171 -0
- data/test/functional/test_string_id_compatibility.rb +67 -0
- data/test/functional/test_timestamps.rb +62 -0
- data/test/functional/test_userstamps.rb +27 -0
- data/test/functional/test_validations.rb +342 -0
- data/test/models.rb +227 -0
- data/test/test_helper.rb +98 -0
- data/test/unit/associations/test_base.rb +212 -0
- data/test/unit/associations/test_proxy.rb +105 -0
- data/test/unit/serializers/test_json_serializer.rb +202 -0
- data/test/unit/test_clone.rb +69 -0
- data/test/unit/test_descendant_appends.rb +71 -0
- data/test/unit/test_document.rb +213 -0
- data/test/unit/test_dynamic_finder.rb +125 -0
- data/test/unit/test_embedded_document.rb +644 -0
- data/test/unit/test_extensions.rb +380 -0
- data/test/unit/test_key.rb +185 -0
- data/test/unit/test_keys.rb +55 -0
- data/test/unit/test_mongo_mapper.rb +110 -0
- data/test/unit/test_pagination.rb +11 -0
- data/test/unit/test_plugins.rb +50 -0
- data/test/unit/test_rails.rb +181 -0
- data/test/unit/test_rails_compatibility.rb +52 -0
- data/test/unit/test_serialization.rb +51 -0
- data/test/unit/test_time_zones.rb +39 -0
- data/test/unit/test_validations.rb +544 -0
- metadata +113 -44
- data/lib/mongo_mapper/plugins/pagination/proxy.rb +0 -72
- data/lib/mongo_mapper/query.rb +0 -23
- data/lib/mongo_mapper/support.rb +0 -196
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SafeTest < Test::Unit::TestCase
|
4
|
+
context "A Document" do
|
5
|
+
should "default safe to off" do
|
6
|
+
Doc().should_not be_safe
|
7
|
+
end
|
8
|
+
|
9
|
+
should "allow turning safe on" do
|
10
|
+
Doc() { safe }.should be_safe
|
11
|
+
end
|
12
|
+
|
13
|
+
context "inherited with safe setting on" do
|
14
|
+
should "set subclass safe setting on" do
|
15
|
+
inherited = Class.new(Doc() { safe })
|
16
|
+
inherited.should be_safe
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "inherited with safe setting off" do
|
21
|
+
should "leave subclass safe setting off" do
|
22
|
+
inherited = Class.new(Doc())
|
23
|
+
inherited.should_not be_safe
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "A safe document" do
|
29
|
+
setup do
|
30
|
+
@klass = Doc() do
|
31
|
+
safe
|
32
|
+
end
|
33
|
+
end
|
34
|
+
teardown { drop_indexes(@klass) }
|
35
|
+
|
36
|
+
context "#save" do
|
37
|
+
setup do
|
38
|
+
@klass.ensure_index :email, :unique => true
|
39
|
+
end
|
40
|
+
|
41
|
+
context "using safe setting from class" do
|
42
|
+
should "work fine when all is well" do
|
43
|
+
assert_nothing_raised do
|
44
|
+
@klass.new(:email => 'john@doe.com').save
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
should "raise error when operation fails" do
|
49
|
+
assert_raises(Mongo::OperationFailure) do
|
50
|
+
2.times do
|
51
|
+
@klass.new(:email => 'john@doe.com').save
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "overriding safe setting" do
|
58
|
+
should "raise error if safe is true" do
|
59
|
+
assert_raises(Mongo::OperationFailure) do
|
60
|
+
2.times do
|
61
|
+
@klass.new(:email => 'john@doe.com').save(:safe => true)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
should "not raise error if safe is false" do
|
67
|
+
assert_nothing_raised do
|
68
|
+
2.times do
|
69
|
+
@klass.new(:email => 'john@doe.com').save(:safe => false)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SciTest < Test::Unit::TestCase
|
4
|
+
context "Single collection inheritance (document)" do
|
5
|
+
setup do
|
6
|
+
class ::DocParent
|
7
|
+
include MongoMapper::Document
|
8
|
+
key :name, String
|
9
|
+
end
|
10
|
+
DocParent.collection.remove
|
11
|
+
|
12
|
+
class ::DocDaughter < ::DocParent; end
|
13
|
+
class ::DocSon < ::DocParent; end
|
14
|
+
class ::DocGrandSon < ::DocSon; end
|
15
|
+
|
16
|
+
DocSon.many :children, :class_name => 'DocGrandSon'
|
17
|
+
|
18
|
+
@parent = DocParent.new({:name => "Daddy Warbucks"})
|
19
|
+
@daughter = DocDaughter.new({:name => "Little Orphan Annie"})
|
20
|
+
end
|
21
|
+
|
22
|
+
teardown do
|
23
|
+
Object.send :remove_const, 'DocParent' if defined?(::DocParent)
|
24
|
+
Object.send :remove_const, 'DocDaughter' if defined?(::DocDaughter)
|
25
|
+
Object.send :remove_const, 'DocSon' if defined?(::DocSon)
|
26
|
+
Object.send :remove_const, 'DocGrandSon' if defined?(::DocGrandSon)
|
27
|
+
end
|
28
|
+
|
29
|
+
should "automatically add _type key to store class" do
|
30
|
+
DocParent.key?(:_type).should be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
should "use the same collection in the subclass" do
|
34
|
+
DocDaughter.collection.name.should == DocParent.collection.name
|
35
|
+
end
|
36
|
+
|
37
|
+
context ".single_collection_inherited?" do
|
38
|
+
should "be false if has not inherited" do
|
39
|
+
DocParent.should_not be_single_collection_inherited
|
40
|
+
end
|
41
|
+
|
42
|
+
should "be true if inherited" do
|
43
|
+
DocDaughter.should be_single_collection_inherited
|
44
|
+
DocSon.should be_single_collection_inherited
|
45
|
+
DocGrandSon.should be_single_collection_inherited
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
should "set _type on initialize" do
|
50
|
+
DocDaughter.new._type.should == 'DocDaughter'
|
51
|
+
DocSon.new._type.should == 'DocSon'
|
52
|
+
DocGrandSon.new._type.should == 'DocGrandSon'
|
53
|
+
end
|
54
|
+
|
55
|
+
should "set _type based on class and ignore assigned values" do
|
56
|
+
DocSon.new(:_type => 'DocDaughter')._type.should == 'DocSon'
|
57
|
+
end
|
58
|
+
|
59
|
+
context "loading" do
|
60
|
+
should "be based on _type" do
|
61
|
+
@parent.save
|
62
|
+
@daughter.save
|
63
|
+
|
64
|
+
collection = DocParent.all
|
65
|
+
collection.size.should == 2
|
66
|
+
collection.first.should be_kind_of(DocParent)
|
67
|
+
collection.first.name.should == "Daddy Warbucks"
|
68
|
+
collection.last.should be_kind_of(DocDaughter)
|
69
|
+
collection.last.name.should == "Little Orphan Annie"
|
70
|
+
end
|
71
|
+
|
72
|
+
should "gracefully handle when _type cannot be constantized" do
|
73
|
+
doc = DocParent.new(:name => 'Nunes')
|
74
|
+
doc._type = 'FoobarBaz'
|
75
|
+
doc.save
|
76
|
+
|
77
|
+
collection = DocParent.all
|
78
|
+
collection.last.should == doc
|
79
|
+
collection.last.should be_kind_of(DocParent)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "querying" do
|
84
|
+
should "find scoped to class" do
|
85
|
+
john = DocSon.create(:name => 'John')
|
86
|
+
steve = DocSon.create(:name => 'Steve')
|
87
|
+
steph = DocDaughter.create(:name => 'Steph')
|
88
|
+
carrie = DocDaughter.create(:name => 'Carrie')
|
89
|
+
|
90
|
+
DocGrandSon.all(:order => 'name').should == []
|
91
|
+
DocSon.all(:order => 'name').should == [john, steve]
|
92
|
+
DocDaughter.all(:order => 'name').should == [carrie, steph]
|
93
|
+
DocParent.all(:order => 'name').should == [carrie, john, steph, steve]
|
94
|
+
end
|
95
|
+
|
96
|
+
should "work with nested hash conditions" do
|
97
|
+
john = DocSon.create(:name => 'John')
|
98
|
+
steve = DocSon.create(:name => 'Steve')
|
99
|
+
DocSon.all(:name => {'$ne' => 'Steve'}).should == [john]
|
100
|
+
end
|
101
|
+
|
102
|
+
should "raise error if not found scoped to class" do
|
103
|
+
john = DocSon.create(:name => 'John')
|
104
|
+
steph = DocDaughter.create(:name => 'Steph')
|
105
|
+
|
106
|
+
lambda {
|
107
|
+
DocSon.find!(steph._id)
|
108
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
109
|
+
end
|
110
|
+
|
111
|
+
should "not raise error for find with parent" do
|
112
|
+
john = DocSon.create(:name => 'John')
|
113
|
+
|
114
|
+
DocParent.find!(john._id).should == john
|
115
|
+
end
|
116
|
+
|
117
|
+
should "count scoped to class" do
|
118
|
+
john = DocSon.create(:name => 'John')
|
119
|
+
steve = DocSon.create(:name => 'Steve')
|
120
|
+
steph = DocDaughter.create(:name => 'Steph')
|
121
|
+
carrie = DocDaughter.create(:name => 'Carrie')
|
122
|
+
|
123
|
+
DocGrandSon.count.should == 0
|
124
|
+
DocSon.count.should == 2
|
125
|
+
DocDaughter.count.should == 2
|
126
|
+
DocParent.count.should == 4
|
127
|
+
end
|
128
|
+
|
129
|
+
should "not be able to destroy each other" do
|
130
|
+
john = DocSon.create(:name => 'John')
|
131
|
+
steph = DocDaughter.create(:name => 'Steph')
|
132
|
+
|
133
|
+
lambda {
|
134
|
+
DocSon.destroy(steph._id)
|
135
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
136
|
+
end
|
137
|
+
|
138
|
+
should "not be able to delete each other" do
|
139
|
+
john = DocSon.create(:name => 'John')
|
140
|
+
steph = DocDaughter.create(:name => 'Steph')
|
141
|
+
|
142
|
+
lambda {
|
143
|
+
DocSon.delete(steph._id)
|
144
|
+
}.should_not change { DocParent.count }
|
145
|
+
end
|
146
|
+
|
147
|
+
should "be able to destroy using parent" do
|
148
|
+
john = DocSon.create(:name => 'John')
|
149
|
+
steph = DocDaughter.create(:name => 'Steph')
|
150
|
+
|
151
|
+
lambda {
|
152
|
+
DocParent.destroy_all
|
153
|
+
}.should change { DocParent.count }.by(-2)
|
154
|
+
end
|
155
|
+
|
156
|
+
should "be able to delete using parent" do
|
157
|
+
john = DocSon.create(:name => 'John')
|
158
|
+
steph = DocDaughter.create(:name => 'Steph')
|
159
|
+
|
160
|
+
lambda {
|
161
|
+
DocParent.delete_all
|
162
|
+
}.should change { DocParent.count }.by(-2)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
should "be able to reload single collection inherited parent class" do
|
167
|
+
brian = DocParent.create(:name => 'Brian')
|
168
|
+
brian.name = 'B-Dawg'
|
169
|
+
brian.reload
|
170
|
+
brian.name.should == 'Brian'
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context "Single collection inheritance (embedded document)" do
|
175
|
+
setup do
|
176
|
+
class ::Grandparent
|
177
|
+
include MongoMapper::EmbeddedDocument
|
178
|
+
key :grandparent, String
|
179
|
+
end
|
180
|
+
|
181
|
+
class ::Parent < ::Grandparent
|
182
|
+
include MongoMapper::EmbeddedDocument
|
183
|
+
key :parent, String
|
184
|
+
end
|
185
|
+
|
186
|
+
class ::Child < ::Parent
|
187
|
+
include MongoMapper::EmbeddedDocument
|
188
|
+
key :child, String
|
189
|
+
end
|
190
|
+
|
191
|
+
class ::OtherChild < ::Parent
|
192
|
+
include MongoMapper::EmbeddedDocument
|
193
|
+
key :other_child, String
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
teardown do
|
198
|
+
Object.send :remove_const, 'Grandparent' if defined?(::Grandparent)
|
199
|
+
Object.send :remove_const, 'Parent' if defined?(::Parent)
|
200
|
+
Object.send :remove_const, 'Child' if defined?(::Child)
|
201
|
+
Object.send :remove_const, 'OtherChild' if defined?(::OtherChild)
|
202
|
+
end
|
203
|
+
|
204
|
+
should "automatically add _type key" do
|
205
|
+
Grandparent.key?(:_type).should be_true
|
206
|
+
end
|
207
|
+
|
208
|
+
context ".single_collection_inherited?" do
|
209
|
+
should "be false if has not inherited" do
|
210
|
+
Grandparent.should_not be_single_collection_inherited
|
211
|
+
end
|
212
|
+
|
213
|
+
should "be true if inherited" do
|
214
|
+
Parent.should be_single_collection_inherited
|
215
|
+
Child.should be_single_collection_inherited
|
216
|
+
OtherChild.should be_single_collection_inherited
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
should "set _type on initialize" do
|
221
|
+
Parent.new._type.should == 'Parent'
|
222
|
+
Child.new._type.should == 'Child'
|
223
|
+
OtherChild.new._type.should == 'OtherChild'
|
224
|
+
end
|
225
|
+
|
226
|
+
should "set _type based on class and ignore assigned values" do
|
227
|
+
Child.new(:_type => 'OtherChild')._type.should == 'Child'
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ScopesTest < Test::Unit::TestCase
|
4
|
+
context "Scopes" do
|
5
|
+
setup do
|
6
|
+
@document = Doc() do
|
7
|
+
key :name, String
|
8
|
+
key :age, Integer
|
9
|
+
timestamps!
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "basic scopes" do
|
14
|
+
setup do
|
15
|
+
@document.class_eval do
|
16
|
+
scope :old, :age.gt => 60
|
17
|
+
scope :teens, :age.gte => 13, :age.lte => 19
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
should "know what scopes have been added" do
|
22
|
+
@document.scopes.size.should == 2
|
23
|
+
@document.scopes.keys.map(&:to_s).sort.should == %w(old teens)
|
24
|
+
end
|
25
|
+
|
26
|
+
should "return a plucky query" do
|
27
|
+
@document.old.should be_instance_of(Plucky::Query)
|
28
|
+
end
|
29
|
+
|
30
|
+
should "work" do
|
31
|
+
@document.create(:name => 'John', :age => 99)
|
32
|
+
@document.create(:name => 'Frank', :age => 15)
|
33
|
+
docs = @document.old.all
|
34
|
+
docs.size.should == 1
|
35
|
+
docs[0].name.should == 'John'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "dynamic scopes" do
|
40
|
+
setup do
|
41
|
+
@document.class_eval do
|
42
|
+
scope :age, lambda { |age| {:age => age} }
|
43
|
+
scope :ages, lambda { |low, high| {:age.gte => low, :age.lte => high} }
|
44
|
+
scope :ordered, lambda { |sort| sort(sort) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
should "work with single argument" do
|
49
|
+
@document.create(:name => 'John', :age => 60)
|
50
|
+
@document.create(:name => 'Frank', :age => 50)
|
51
|
+
docs = @document.age(60).all
|
52
|
+
docs.size.should == 1
|
53
|
+
docs.first.name.should == 'John'
|
54
|
+
end
|
55
|
+
|
56
|
+
should "work with multiple arguments" do
|
57
|
+
@document.create(:name => 'John', :age => 60)
|
58
|
+
@document.create(:name => 'Frank', :age => 50)
|
59
|
+
@document.create(:name => 'Bill', :age => 40)
|
60
|
+
docs = @document.ages(50, 70).all
|
61
|
+
docs.size.should == 2
|
62
|
+
docs.map(&:name).sort.should == %w(Frank John)
|
63
|
+
end
|
64
|
+
|
65
|
+
should "work with queries" do
|
66
|
+
john = @document.create(:name => 'John', :age => 60)
|
67
|
+
frank = @document.create(:name => 'Frank', :age => 50)
|
68
|
+
bill = @document.create(:name => 'Bill', :age => 40)
|
69
|
+
@document.ordered(:age).all.should == [bill, frank, john]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "query scopes" do
|
74
|
+
setup do
|
75
|
+
@document.class_eval do
|
76
|
+
scope :boomers, where(:age.gte => 60).sort(:age)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
should "work" do
|
81
|
+
todd = @document.create(:name => 'Todd', :age => 65)
|
82
|
+
john = @document.create(:name => 'John', :age => 60)
|
83
|
+
@document.create(:name => 'Frank', :age => 50)
|
84
|
+
@document.create(:name => 'Bill', :age => 40)
|
85
|
+
docs = @document.boomers.all
|
86
|
+
docs[0].should == john
|
87
|
+
docs[1].should == todd
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "chaining" do
|
92
|
+
setup do
|
93
|
+
@document.class_eval do
|
94
|
+
scope :by_age, lambda { |age| {:age => age} }
|
95
|
+
scope :by_name, lambda { |name| {:name => name} }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
should "work with scope methods" do
|
100
|
+
@document.create(:name => 'John', :age => 60)
|
101
|
+
@document.create(:name => 'Frank', :age => 60)
|
102
|
+
@document.create(:name => 'Bill', :age => 50)
|
103
|
+
docs = @document.by_age(60).by_name('John').all
|
104
|
+
docs.size.should == 1
|
105
|
+
docs.first.name.should == 'John'
|
106
|
+
end
|
107
|
+
|
108
|
+
should "work on query methods" do
|
109
|
+
@document.create(:name => 'John', :age => 60)
|
110
|
+
@document.create(:name => 'John', :age => 50)
|
111
|
+
@document.create(:name => 'Bill', :age => 50)
|
112
|
+
docs = @document.where(:name => 'John').by_age(50).all
|
113
|
+
docs.size.should == 1
|
114
|
+
docs.first.age.should == 50
|
115
|
+
end
|
116
|
+
|
117
|
+
context "with model methods" do
|
118
|
+
should "work if method returns a query" do
|
119
|
+
@document.create(:name => 'John', :age => 10)
|
120
|
+
@document.create(:name => 'John', :age => 20)
|
121
|
+
@document.class_eval do
|
122
|
+
def self.young
|
123
|
+
query(:age.lte => 12)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
docs = @document.by_name('John').young.all
|
127
|
+
docs.size.should == 1
|
128
|
+
docs.first.age.should == 10
|
129
|
+
end
|
130
|
+
|
131
|
+
should "not work if method does not return a query" do
|
132
|
+
@document.class_eval { def self.age; 20 end }
|
133
|
+
lambda { @document.by_name('John').age }.should raise_error(NoMethodError)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "with single collection inheritance" do
|
139
|
+
setup do
|
140
|
+
class ::Item
|
141
|
+
include MongoMapper::Document
|
142
|
+
scope :by_title, lambda { |title| {:title => title} }
|
143
|
+
scope :published, lambda { {:published_at.lte => Time.now.utc} }
|
144
|
+
|
145
|
+
key :title, String
|
146
|
+
key :published_at, Time
|
147
|
+
end
|
148
|
+
Item.collection.remove
|
149
|
+
|
150
|
+
class ::Page < ::Item; end
|
151
|
+
class ::Blog < ::Item; end
|
152
|
+
end
|
153
|
+
|
154
|
+
teardown do
|
155
|
+
Object.send :remove_const, 'Item' if defined?(::Item)
|
156
|
+
Object.send :remove_const, 'Page' if defined?(::Page)
|
157
|
+
Object.send :remove_const, 'Blog' if defined?(::Blog)
|
158
|
+
end
|
159
|
+
|
160
|
+
should "inherit scopes" do
|
161
|
+
Page.scopes.keys.map(&:to_s).sort.should == %w(by_title published)
|
162
|
+
end
|
163
|
+
|
164
|
+
should "work with _type" do
|
165
|
+
item = Item.create(:title => 'Home')
|
166
|
+
page = Page.create(:title => 'Home')
|
167
|
+
Page.by_title('Home').first.should == page
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|