lookout-mongo_mapper 0.11.3

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 (176) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +33 -0
  3. data/UPGRADES +26 -0
  4. data/bin/mmconsole +59 -0
  5. data/examples/attr_accessible.rb +22 -0
  6. data/examples/attr_protected.rb +22 -0
  7. data/examples/cache_key.rb +24 -0
  8. data/examples/custom_types.rb +24 -0
  9. data/examples/identity_map.rb +33 -0
  10. data/examples/identity_map/automatic.rb +2 -0
  11. data/examples/keys.rb +40 -0
  12. data/examples/modifiers/set.rb +25 -0
  13. data/examples/plugins.rb +38 -0
  14. data/examples/querying.rb +35 -0
  15. data/examples/safe.rb +43 -0
  16. data/examples/scopes.rb +52 -0
  17. data/examples/validating/embedded_docs.rb +29 -0
  18. data/lib/mongo_mapper.rb +94 -0
  19. data/lib/mongo_mapper/connection.rb +96 -0
  20. data/lib/mongo_mapper/document.rb +42 -0
  21. data/lib/mongo_mapper/embedded_document.rb +32 -0
  22. data/lib/mongo_mapper/exceptions.rb +30 -0
  23. data/lib/mongo_mapper/extensions/array.rb +19 -0
  24. data/lib/mongo_mapper/extensions/binary.rb +22 -0
  25. data/lib/mongo_mapper/extensions/boolean.rb +44 -0
  26. data/lib/mongo_mapper/extensions/date.rb +25 -0
  27. data/lib/mongo_mapper/extensions/float.rb +14 -0
  28. data/lib/mongo_mapper/extensions/hash.rb +14 -0
  29. data/lib/mongo_mapper/extensions/integer.rb +19 -0
  30. data/lib/mongo_mapper/extensions/kernel.rb +9 -0
  31. data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
  32. data/lib/mongo_mapper/extensions/object.rb +26 -0
  33. data/lib/mongo_mapper/extensions/object_id.rb +32 -0
  34. data/lib/mongo_mapper/extensions/set.rb +20 -0
  35. data/lib/mongo_mapper/extensions/string.rb +18 -0
  36. data/lib/mongo_mapper/extensions/time.rb +28 -0
  37. data/lib/mongo_mapper/locale/en.yml +5 -0
  38. data/lib/mongo_mapper/middleware/identity_map.rb +16 -0
  39. data/lib/mongo_mapper/plugins.rb +22 -0
  40. data/lib/mongo_mapper/plugins/accessible.rb +52 -0
  41. data/lib/mongo_mapper/plugins/active_model.rb +18 -0
  42. data/lib/mongo_mapper/plugins/associations.rb +90 -0
  43. data/lib/mongo_mapper/plugins/associations/base.rb +92 -0
  44. data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +54 -0
  45. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +34 -0
  46. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +52 -0
  47. data/lib/mongo_mapper/plugins/associations/collection.rb +27 -0
  48. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +44 -0
  49. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +133 -0
  50. data/lib/mongo_mapper/plugins/associations/many_association.rb +63 -0
  51. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  52. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +118 -0
  53. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
  54. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
  55. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
  56. data/lib/mongo_mapper/plugins/associations/one_as_proxy.rb +22 -0
  57. data/lib/mongo_mapper/plugins/associations/one_association.rb +48 -0
  58. data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
  59. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +44 -0
  60. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +95 -0
  61. data/lib/mongo_mapper/plugins/associations/proxy.rb +134 -0
  62. data/lib/mongo_mapper/plugins/associations/single_association.rb +46 -0
  63. data/lib/mongo_mapper/plugins/caching.rb +21 -0
  64. data/lib/mongo_mapper/plugins/callbacks.rb +29 -0
  65. data/lib/mongo_mapper/plugins/clone.rb +22 -0
  66. data/lib/mongo_mapper/plugins/dirty.rb +60 -0
  67. data/lib/mongo_mapper/plugins/document.rb +41 -0
  68. data/lib/mongo_mapper/plugins/dynamic_querying.rb +45 -0
  69. data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
  70. data/lib/mongo_mapper/plugins/embedded_callbacks.rb +56 -0
  71. data/lib/mongo_mapper/plugins/embedded_document.rb +53 -0
  72. data/lib/mongo_mapper/plugins/equality.rb +23 -0
  73. data/lib/mongo_mapper/plugins/identity_map.rb +128 -0
  74. data/lib/mongo_mapper/plugins/indexes.rb +13 -0
  75. data/lib/mongo_mapper/plugins/inspect.rb +16 -0
  76. data/lib/mongo_mapper/plugins/keys.rb +313 -0
  77. data/lib/mongo_mapper/plugins/keys/key.rb +61 -0
  78. data/lib/mongo_mapper/plugins/logger.rb +18 -0
  79. data/lib/mongo_mapper/plugins/modifiers.rb +134 -0
  80. data/lib/mongo_mapper/plugins/pagination.rb +16 -0
  81. data/lib/mongo_mapper/plugins/persistence.rb +69 -0
  82. data/lib/mongo_mapper/plugins/protected.rb +45 -0
  83. data/lib/mongo_mapper/plugins/querying.rb +165 -0
  84. data/lib/mongo_mapper/plugins/querying/decorator.rb +36 -0
  85. data/lib/mongo_mapper/plugins/rails.rb +58 -0
  86. data/lib/mongo_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
  87. data/lib/mongo_mapper/plugins/safe.rb +28 -0
  88. data/lib/mongo_mapper/plugins/sci.rb +36 -0
  89. data/lib/mongo_mapper/plugins/scopes.rb +27 -0
  90. data/lib/mongo_mapper/plugins/serialization.rb +109 -0
  91. data/lib/mongo_mapper/plugins/timestamps.rb +22 -0
  92. data/lib/mongo_mapper/plugins/touch.rb +18 -0
  93. data/lib/mongo_mapper/plugins/userstamps.rb +18 -0
  94. data/lib/mongo_mapper/plugins/validations.rb +86 -0
  95. data/lib/mongo_mapper/railtie.rb +48 -0
  96. data/lib/mongo_mapper/railtie/database.rake +65 -0
  97. data/lib/mongo_mapper/translation.rb +10 -0
  98. data/lib/mongo_mapper/version.rb +4 -0
  99. data/lib/rails/generators/mongo_mapper/config/config_generator.rb +24 -0
  100. data/lib/rails/generators/mongo_mapper/config/templates/mongo.yml +18 -0
  101. data/lib/rails/generators/mongo_mapper/model/model_generator.rb +23 -0
  102. data/lib/rails/generators/mongo_mapper/model/templates/model.rb +13 -0
  103. data/test/_NOTE_ON_TESTING +1 -0
  104. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +64 -0
  105. data/test/functional/associations/test_belongs_to_proxy.rb +238 -0
  106. data/test/functional/associations/test_in_array_proxy.rb +349 -0
  107. data/test/functional/associations/test_many_documents_as_proxy.rb +231 -0
  108. data/test/functional/associations/test_many_documents_proxy.rb +866 -0
  109. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +239 -0
  110. data/test/functional/associations/test_many_embedded_proxy.rb +289 -0
  111. data/test/functional/associations/test_many_polymorphic_proxy.rb +303 -0
  112. data/test/functional/associations/test_one_as_proxy.rb +491 -0
  113. data/test/functional/associations/test_one_embedded_polymorphic_proxy.rb +208 -0
  114. data/test/functional/associations/test_one_embedded_proxy.rb +100 -0
  115. data/test/functional/associations/test_one_proxy.rb +383 -0
  116. data/test/functional/test_accessible.rb +198 -0
  117. data/test/functional/test_associations.rb +46 -0
  118. data/test/functional/test_binary.rb +27 -0
  119. data/test/functional/test_caching.rb +77 -0
  120. data/test/functional/test_callbacks.rb +232 -0
  121. data/test/functional/test_dirty.rb +301 -0
  122. data/test/functional/test_document.rb +282 -0
  123. data/test/functional/test_dynamic_querying.rb +75 -0
  124. data/test/functional/test_embedded_document.rb +288 -0
  125. data/test/functional/test_equality.rb +20 -0
  126. data/test/functional/test_identity_map.rb +513 -0
  127. data/test/functional/test_indexes.rb +50 -0
  128. data/test/functional/test_logger.rb +20 -0
  129. data/test/functional/test_modifiers.rb +537 -0
  130. data/test/functional/test_pagination.rb +91 -0
  131. data/test/functional/test_protected.rb +201 -0
  132. data/test/functional/test_querying.rb +935 -0
  133. data/test/functional/test_safe.rb +76 -0
  134. data/test/functional/test_sci.rb +240 -0
  135. data/test/functional/test_scopes.rb +171 -0
  136. data/test/functional/test_timestamps.rb +62 -0
  137. data/test/functional/test_touch.rb +125 -0
  138. data/test/functional/test_userstamps.rb +44 -0
  139. data/test/functional/test_validations.rb +414 -0
  140. data/test/models.rb +261 -0
  141. data/test/support/railtie.rb +4 -0
  142. data/test/support/railtie/autoloaded.rb +2 -0
  143. data/test/support/railtie/not_autoloaded.rb +3 -0
  144. data/test/support/railtie/parent.rb +3 -0
  145. data/test/test_active_model_lint.rb +18 -0
  146. data/test/test_helper.rb +93 -0
  147. data/test/unit/associations/test_base.rb +146 -0
  148. data/test/unit/associations/test_belongs_to_association.rb +29 -0
  149. data/test/unit/associations/test_many_association.rb +63 -0
  150. data/test/unit/associations/test_one_association.rb +47 -0
  151. data/test/unit/associations/test_proxy.rb +100 -0
  152. data/test/unit/serializers/test_json_serializer.rb +216 -0
  153. data/test/unit/serializers/test_xml_serializer.rb +196 -0
  154. data/test/unit/test_clone.rb +69 -0
  155. data/test/unit/test_document.rb +249 -0
  156. data/test/unit/test_dynamic_finder.rb +125 -0
  157. data/test/unit/test_embedded_document.rb +682 -0
  158. data/test/unit/test_equality.rb +38 -0
  159. data/test/unit/test_exceptions.rb +12 -0
  160. data/test/unit/test_extensions.rb +380 -0
  161. data/test/unit/test_identity_map_middleware.rb +34 -0
  162. data/test/unit/test_inspect.rb +47 -0
  163. data/test/unit/test_key.rb +205 -0
  164. data/test/unit/test_keys.rb +65 -0
  165. data/test/unit/test_mongo_mapper.rb +143 -0
  166. data/test/unit/test_pagination.rb +11 -0
  167. data/test/unit/test_plugins.rb +89 -0
  168. data/test/unit/test_rails.rb +183 -0
  169. data/test/unit/test_rails_compatibility.rb +38 -0
  170. data/test/unit/test_rails_reflect_on_association.rb +118 -0
  171. data/test/unit/test_railtie.rb +66 -0
  172. data/test/unit/test_serialization.rb +166 -0
  173. data/test/unit/test_time_zones.rb +44 -0
  174. data/test/unit/test_translation.rb +27 -0
  175. data/test/unit/test_validations.rb +562 -0
  176. metadata +285 -0
@@ -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,240 @@
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
+ class ::DocGrandGrandSon < ::DocGrandSon; end
16
+
17
+ DocSon.many :children, :class_name => 'DocGrandSon'
18
+
19
+ @parent = DocParent.new({:name => "Daddy Warbucks"})
20
+ @daughter = DocDaughter.new({:name => "Little Orphan Annie"})
21
+ end
22
+
23
+ teardown do
24
+ Object.send :remove_const, 'DocParent' if defined?(::DocParent)
25
+ Object.send :remove_const, 'DocDaughter' if defined?(::DocDaughter)
26
+ Object.send :remove_const, 'DocSon' if defined?(::DocSon)
27
+ Object.send :remove_const, 'DocGrandSon' if defined?(::DocGrandSon)
28
+ Object.send :remove_const, 'DocGrandGrandSon' if defined?(::DocGrandGrandSon)
29
+ end
30
+
31
+ should "automatically add _type key to store class" do
32
+ DocParent.key?(:_type).should be_true
33
+ end
34
+
35
+ should "use the same collection in the subclass" do
36
+ DocDaughter.collection.name.should == DocParent.collection.name
37
+ end
38
+
39
+ context ".single_collection_inherited?" do
40
+ should "be false if has not inherited" do
41
+ DocParent.should_not be_single_collection_inherited
42
+ end
43
+
44
+ should "be true if inherited" do
45
+ DocDaughter.should be_single_collection_inherited
46
+ DocSon.should be_single_collection_inherited
47
+ DocGrandSon.should be_single_collection_inherited
48
+ end
49
+ end
50
+
51
+ should "set _type on initialize" do
52
+ DocDaughter.new._type.should == 'DocDaughter'
53
+ DocSon.new._type.should == 'DocSon'
54
+ DocGrandSon.new._type.should == 'DocGrandSon'
55
+ end
56
+
57
+ should "set _type based on class and ignore assigned values" do
58
+ DocSon.new(:_type => 'DocDaughter')._type.should == 'DocSon'
59
+ end
60
+
61
+ context "loading" do
62
+ should "be based on _type" do
63
+ @parent.save
64
+ @daughter.save
65
+
66
+ collection = DocParent.all
67
+ collection.size.should == 2
68
+ collection.first.should be_kind_of(DocParent)
69
+ collection.first.name.should == "Daddy Warbucks"
70
+ collection.last.should be_kind_of(DocDaughter)
71
+ collection.last.name.should == "Little Orphan Annie"
72
+ end
73
+
74
+ should "gracefully handle when _type cannot be constantized" do
75
+ doc = DocParent.new(:name => 'Nunes')
76
+ doc._type = 'FoobarBaz'
77
+ doc.save
78
+
79
+ collection = DocParent.all
80
+ collection.last.should == doc
81
+ collection.last.should be_kind_of(DocParent)
82
+ end
83
+ end
84
+
85
+ context "querying" do
86
+ should "find scoped to class" do
87
+ john = DocSon.create(:name => 'John')
88
+ steve = DocSon.create(:name => 'Steve')
89
+ steph = DocDaughter.create(:name => 'Steph')
90
+ carrie = DocDaughter.create(:name => 'Carrie')
91
+ boris = DocGrandSon.create(:name => 'Boris')
92
+
93
+ DocGrandGrandSon.all(:order => 'name').should == []
94
+ DocGrandSon.all(:order => 'name').should == [boris]
95
+ DocSon.all(:order => 'name').should == [boris, john, steve]
96
+ DocDaughter.all(:order => 'name').should == [carrie, steph]
97
+ DocParent.all(:order => 'name').should == [boris, carrie, john, steph, steve]
98
+
99
+ sigmund = DocGrandGrandSon.create(:name => 'Sigmund')
100
+
101
+ DocGrandSon.all(:order => 'name').should == [boris, sigmund]
102
+ DocSon.all(:order => 'name').should == [boris, john, sigmund, steve]
103
+ DocParent.all(:order => 'name').should == [boris, carrie, john, sigmund, steph, steve]
104
+ end
105
+
106
+ should "work with nested hash conditions" do
107
+ john = DocSon.create(:name => 'John')
108
+ steve = DocSon.create(:name => 'Steve')
109
+ DocSon.all(:name => {'$ne' => 'Steve'}).should == [john]
110
+ end
111
+
112
+ should "raise error if not found scoped to class" do
113
+ john = DocSon.create(:name => 'John')
114
+ steph = DocDaughter.create(:name => 'Steph')
115
+
116
+ lambda {
117
+ DocSon.find!(steph._id)
118
+ }.should raise_error(MongoMapper::DocumentNotFound)
119
+ end
120
+
121
+ should "not raise error for find with parent" do
122
+ john = DocSon.create(:name => 'John')
123
+
124
+ DocParent.find!(john._id).should == john
125
+ end
126
+
127
+ should "count scoped to class" do
128
+ john = DocSon.create(:name => 'John')
129
+ steve = DocSon.create(:name => 'Steve')
130
+ steph = DocDaughter.create(:name => 'Steph')
131
+ carrie = DocDaughter.create(:name => 'Carrie')
132
+
133
+ DocGrandSon.count.should == 0
134
+ DocSon.count.should == 2
135
+ DocDaughter.count.should == 2
136
+ DocParent.count.should == 4
137
+ end
138
+
139
+ should "not be able to destroy each other" do
140
+ john = DocSon.create(:name => 'John')
141
+ steph = DocDaughter.create(:name => 'Steph')
142
+
143
+ lambda {
144
+ DocSon.destroy(steph._id)
145
+ }.should raise_error(MongoMapper::DocumentNotFound)
146
+ end
147
+
148
+ should "not be able to delete each other" do
149
+ john = DocSon.create(:name => 'John')
150
+ steph = DocDaughter.create(:name => 'Steph')
151
+
152
+ lambda {
153
+ DocSon.delete(steph._id)
154
+ }.should_not change { DocParent.count }
155
+ end
156
+
157
+ should "be able to destroy using parent" do
158
+ john = DocSon.create(:name => 'John')
159
+ steph = DocDaughter.create(:name => 'Steph')
160
+
161
+ lambda {
162
+ DocParent.destroy_all
163
+ }.should change { DocParent.count }.by(-2)
164
+ end
165
+
166
+ should "be able to delete using parent" do
167
+ john = DocSon.create(:name => 'John')
168
+ steph = DocDaughter.create(:name => 'Steph')
169
+
170
+ lambda {
171
+ DocParent.delete_all
172
+ }.should change { DocParent.count }.by(-2)
173
+ end
174
+ end
175
+
176
+ should "be able to reload single collection inherited parent class" do
177
+ brian = DocParent.create(:name => 'Brian')
178
+ brian.name = 'B-Dawg'
179
+ brian.reload
180
+ brian.name.should == 'Brian'
181
+ end
182
+ end
183
+
184
+ context "Single collection inheritance (embedded document)" do
185
+ setup do
186
+ class ::Grandparent
187
+ include MongoMapper::EmbeddedDocument
188
+ key :grandparent, String
189
+ end
190
+
191
+ class ::Parent < ::Grandparent
192
+ include MongoMapper::EmbeddedDocument
193
+ key :parent, String
194
+ end
195
+
196
+ class ::Child < ::Parent
197
+ include MongoMapper::EmbeddedDocument
198
+ key :child, String
199
+ end
200
+
201
+ class ::OtherChild < ::Parent
202
+ include MongoMapper::EmbeddedDocument
203
+ key :other_child, String
204
+ end
205
+ end
206
+
207
+ teardown do
208
+ Object.send :remove_const, 'Grandparent' if defined?(::Grandparent)
209
+ Object.send :remove_const, 'Parent' if defined?(::Parent)
210
+ Object.send :remove_const, 'Child' if defined?(::Child)
211
+ Object.send :remove_const, 'OtherChild' if defined?(::OtherChild)
212
+ end
213
+
214
+ should "automatically add _type key" do
215
+ Grandparent.key?(:_type).should be_true
216
+ end
217
+
218
+ context ".single_collection_inherited?" do
219
+ should "be false if has not inherited" do
220
+ Grandparent.should_not be_single_collection_inherited
221
+ end
222
+
223
+ should "be true if inherited" do
224
+ Parent.should be_single_collection_inherited
225
+ Child.should be_single_collection_inherited
226
+ OtherChild.should be_single_collection_inherited
227
+ end
228
+ end
229
+
230
+ should "set _type on initialize" do
231
+ Parent.new._type.should == 'Parent'
232
+ Child.new._type.should == 'Child'
233
+ OtherChild.new._type.should == 'OtherChild'
234
+ end
235
+
236
+ should "set _type based on class and ignore assigned values" do
237
+ Child.new(:_type => 'OtherChild')._type.should == 'Child'
238
+ end
239
+ end
240
+ 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