mongo_mapper-unstable 2010.3.8 → 2010.06.23

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 (143) hide show
  1. data/README.rdoc +4 -8
  2. data/bin/mmconsole +1 -1
  3. data/examples/keys.rb +37 -0
  4. data/examples/plugins.rb +41 -0
  5. data/examples/querying.rb +35 -0
  6. data/examples/scopes.rb +52 -0
  7. data/lib/mongo_mapper/connection.rb +83 -0
  8. data/lib/mongo_mapper/document.rb +11 -329
  9. data/lib/mongo_mapper/embedded_document.rb +9 -38
  10. data/lib/mongo_mapper/exceptions.rb +30 -0
  11. data/lib/mongo_mapper/extensions/array.rb +19 -0
  12. data/lib/mongo_mapper/extensions/binary.rb +22 -0
  13. data/lib/mongo_mapper/extensions/boolean.rb +44 -0
  14. data/lib/mongo_mapper/extensions/date.rb +25 -0
  15. data/lib/mongo_mapper/extensions/float.rb +14 -0
  16. data/lib/mongo_mapper/extensions/hash.rb +14 -0
  17. data/lib/mongo_mapper/extensions/integer.rb +19 -0
  18. data/lib/mongo_mapper/extensions/kernel.rb +9 -0
  19. data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
  20. data/lib/mongo_mapper/extensions/object.rb +27 -0
  21. data/lib/mongo_mapper/extensions/object_id.rb +30 -0
  22. data/lib/mongo_mapper/extensions/set.rb +20 -0
  23. data/lib/mongo_mapper/extensions/string.rb +18 -0
  24. data/lib/mongo_mapper/extensions/time.rb +29 -0
  25. data/lib/mongo_mapper/plugins/accessible.rb +44 -0
  26. data/lib/mongo_mapper/plugins/associations/base.rb +7 -6
  27. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +5 -6
  28. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +5 -6
  29. data/lib/mongo_mapper/plugins/associations/collection.rb +1 -0
  30. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +2 -1
  31. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +25 -39
  32. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +4 -4
  33. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +36 -46
  34. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +1 -0
  35. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +5 -4
  36. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +1 -0
  37. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +40 -0
  38. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +7 -7
  39. data/lib/mongo_mapper/plugins/associations/proxy.rb +16 -8
  40. data/lib/mongo_mapper/plugins/associations.rb +14 -22
  41. data/lib/mongo_mapper/plugins/caching.rb +21 -0
  42. data/lib/mongo_mapper/plugins/callbacks.rb +17 -5
  43. data/lib/mongo_mapper/plugins/clone.rb +10 -4
  44. data/lib/mongo_mapper/plugins/descendants.rb +3 -2
  45. data/lib/mongo_mapper/plugins/dirty.rb +1 -0
  46. data/lib/mongo_mapper/plugins/document.rb +41 -0
  47. data/lib/mongo_mapper/{support/find.rb → plugins/dynamic_querying/dynamic_finder.rb} +3 -36
  48. data/lib/mongo_mapper/plugins/dynamic_querying.rb +43 -0
  49. data/lib/mongo_mapper/plugins/embedded_document.rb +49 -0
  50. data/lib/mongo_mapper/plugins/equality.rb +4 -10
  51. data/lib/mongo_mapper/plugins/identity_map.rb +29 -23
  52. data/lib/mongo_mapper/plugins/indexes.rb +12 -0
  53. data/lib/mongo_mapper/plugins/inspect.rb +1 -0
  54. data/lib/mongo_mapper/plugins/keys/key.rb +55 -0
  55. data/lib/mongo_mapper/plugins/keys.rb +85 -110
  56. data/lib/mongo_mapper/plugins/logger.rb +1 -0
  57. data/lib/mongo_mapper/plugins/modifiers.rb +41 -16
  58. data/lib/mongo_mapper/plugins/pagination.rb +5 -15
  59. data/lib/mongo_mapper/plugins/persistence.rb +69 -0
  60. data/lib/mongo_mapper/plugins/protected.rb +9 -1
  61. data/lib/mongo_mapper/plugins/querying/decorator.rb +46 -0
  62. data/lib/mongo_mapper/plugins/querying/plucky_methods.rb +15 -0
  63. data/lib/mongo_mapper/plugins/querying.rb +176 -0
  64. data/lib/mongo_mapper/plugins/rails.rb +6 -1
  65. data/lib/mongo_mapper/plugins/safe.rb +28 -0
  66. data/lib/mongo_mapper/plugins/sci.rb +32 -0
  67. data/lib/mongo_mapper/plugins/scopes.rb +21 -0
  68. data/lib/mongo_mapper/plugins/serialization.rb +5 -4
  69. data/lib/mongo_mapper/plugins/timestamps.rb +2 -1
  70. data/lib/mongo_mapper/plugins/userstamps.rb +1 -0
  71. data/lib/mongo_mapper/plugins/validations.rb +9 -5
  72. data/lib/mongo_mapper/plugins.rb +1 -20
  73. data/lib/mongo_mapper/support/descendant_appends.rb +5 -6
  74. data/lib/mongo_mapper/version.rb +4 -0
  75. data/lib/mongo_mapper.rb +71 -128
  76. data/test/{NOTE_ON_TESTING → _NOTE_ON_TESTING} +0 -0
  77. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +5 -5
  78. data/test/functional/associations/test_belongs_to_proxy.rb +13 -21
  79. data/test/functional/associations/test_in_array_proxy.rb +7 -9
  80. data/test/functional/associations/test_many_documents_as_proxy.rb +5 -5
  81. data/test/functional/associations/test_many_documents_proxy.rb +186 -64
  82. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +22 -22
  83. data/test/functional/associations/test_many_embedded_proxy.rb +32 -32
  84. data/test/functional/associations/test_many_polymorphic_proxy.rb +47 -47
  85. data/test/functional/associations/test_one_embedded_proxy.rb +67 -0
  86. data/test/functional/associations/test_one_proxy.rb +70 -49
  87. data/test/functional/test_accessible.rb +168 -0
  88. data/test/functional/test_associations.rb +11 -11
  89. data/test/functional/test_binary.rb +5 -5
  90. data/test/functional/test_caching.rb +76 -0
  91. data/test/functional/test_callbacks.rb +104 -34
  92. data/test/functional/test_dirty.rb +16 -16
  93. data/test/functional/test_document.rb +12 -924
  94. data/test/functional/test_dynamic_querying.rb +75 -0
  95. data/test/functional/test_embedded_document.rb +88 -8
  96. data/test/functional/test_identity_map.rb +41 -43
  97. data/test/functional/{test_indexing.rb → test_indexes.rb} +3 -5
  98. data/test/functional/test_logger.rb +1 -1
  99. data/test/functional/test_modifiers.rb +275 -181
  100. data/test/functional/test_pagination.rb +13 -15
  101. data/test/functional/test_protected.rb +25 -11
  102. data/test/functional/test_querying.rb +873 -0
  103. data/test/functional/test_safe.rb +76 -0
  104. data/test/functional/test_sci.rb +230 -0
  105. data/test/functional/test_scopes.rb +171 -0
  106. data/test/functional/test_string_id_compatibility.rb +11 -11
  107. data/test/functional/test_timestamps.rb +0 -2
  108. data/test/functional/test_userstamps.rb +0 -1
  109. data/test/functional/test_validations.rb +44 -31
  110. data/test/models.rb +18 -17
  111. data/test/{active_model_lint_test.rb → test_active_model_lint.rb} +3 -1
  112. data/test/test_helper.rb +59 -16
  113. data/test/unit/associations/test_base.rb +47 -42
  114. data/test/unit/associations/test_proxy.rb +15 -15
  115. data/test/unit/serializers/test_json_serializer.rb +29 -29
  116. data/test/unit/test_clone.rb +69 -0
  117. data/test/unit/test_descendant_appends.rb +3 -3
  118. data/test/unit/test_document.rb +49 -67
  119. data/test/unit/test_dynamic_finder.rb +53 -51
  120. data/test/unit/test_embedded_document.rb +19 -38
  121. data/test/unit/{test_support.rb → test_extensions.rb} +136 -122
  122. data/test/unit/test_key.rb +185 -0
  123. data/test/unit/test_keys.rb +29 -147
  124. data/test/unit/test_mongo_mapper.rb +3 -48
  125. data/test/unit/test_pagination.rb +1 -150
  126. data/test/unit/test_rails.rb +77 -19
  127. data/test/unit/test_rails_compatibility.rb +12 -12
  128. data/test/unit/test_serialization.rb +5 -5
  129. data/test/unit/test_time_zones.rb +9 -9
  130. data/test/unit/test_validations.rb +46 -46
  131. metadata +157 -155
  132. data/.gitignore +0 -10
  133. data/Rakefile +0 -55
  134. data/VERSION +0 -1
  135. data/lib/mongo_mapper/plugins/pagination/proxy.rb +0 -72
  136. data/lib/mongo_mapper/query.rb +0 -130
  137. data/lib/mongo_mapper/support.rb +0 -215
  138. data/mongo_mapper.gemspec +0 -196
  139. data/performance/read_write.rb +0 -52
  140. data/specs.watchr +0 -51
  141. data/test/support/custom_matchers.rb +0 -55
  142. data/test/support/timing.rb +0 -16
  143. data/test/unit/test_query.rb +0 -340
@@ -1,16 +0,0 @@
1
- class Test::Unit::TestCase
2
- def run_with_test_timing(*args, &block)
3
- begin_time = Time.now
4
- run_without_test_timing(*args, &block)
5
- end_time = Time.now
6
-
7
- duration = end_time - begin_time
8
- threshold = 5.0
9
-
10
- if duration > threshold
11
- puts "\nSLOW TEST: #{duration} - #{self.name}"
12
- end
13
- end
14
-
15
- alias_method_chain :run, :test_timing unless method_defined?(:run_without_test_timing)
16
- end
@@ -1,340 +0,0 @@
1
- require 'test_helper'
2
- require 'models'
3
-
4
- class QueryTest < Test::Unit::TestCase
5
- include MongoMapper
6
-
7
- should "raise error if provided something other than a hash" do
8
- lambda { Query.new(Room) }.should raise_error(ArgumentError)
9
- lambda { Query.new(Room, 1) }.should raise_error(ArgumentError)
10
- end
11
-
12
- should "symbolize the keys of the hash provided" do
13
- Query.new(Room, 'offset' => 1).options.keys.map do |key|
14
- key.should be_instance_of(Symbol)
15
- end
16
- end
17
-
18
- context "Converting conditions to criteria" do
19
- should "not add _type to query if model does not have superclass that is single collection inherited" do
20
- Query.new(Message, :foo => 'bar').criteria.should == {
21
- :foo => 'bar'
22
- }
23
- end
24
-
25
- should "not add _type to nested conditions" do
26
- Query.new(Enter, :foo => 'bar', :age => {'$gt' => 21}).criteria.should == {
27
- :foo => 'bar',
28
- :age => {'$gt' => 21},
29
- :_type => 'Enter'
30
- }
31
- end
32
-
33
- should "automatically add _type to query if model is single collection inherited" do
34
- Query.new(Enter, :foo => 'bar').criteria.should == {
35
- :foo => 'bar',
36
- :_type => 'Enter'
37
- }
38
- end
39
-
40
- %w{gt lt gte lte ne in nin mod all size where exists}.each do |operator|
41
- next if operator == 'size' && RUBY_VERSION >= '1.9.1' # 1.9 defines Symbol#size
42
-
43
- should "convert #{operator} conditions" do
44
- Query.new(Room, :age.send(operator) => 21).criteria.should == {
45
- :age => {"$#{operator}" => 21}
46
- }
47
- end
48
- end
49
-
50
- should "normalize value when using symbol operators" do
51
- time = Time.now.in_time_zone('Indiana (East)')
52
- criteria = Query.new(Room, :created_at.gt => time).criteria
53
- criteria[:created_at]['$gt'].should be_utc
54
- end
55
-
56
- should "work with simple criteria" do
57
- Query.new(Room, :foo => 'bar').criteria.should == {
58
- :foo => 'bar'
59
- }
60
-
61
- Query.new(Room, :foo => 'bar', :baz => 'wick').criteria.should == {
62
- :foo => 'bar',
63
- :baz => 'wick'
64
- }
65
- end
66
-
67
- should "convert id to _id" do
68
- id = Mongo::ObjectID.new
69
- Query.new(Room, :id => id).criteria.should == {:_id => id}
70
- end
71
-
72
- should "convert id with symbol operator to _id with modifier" do
73
- id = Mongo::ObjectID.new
74
- Query.new(Room, :id.ne => id).criteria.should == {
75
- :_id => {'$ne' => id}
76
- }
77
- end
78
-
79
- should "make sure that _id's are object ids" do
80
- id = Mongo::ObjectID.new
81
- Query.new(Room, :_id => id.to_s).criteria.should == {:_id => id}
82
- end
83
-
84
- should "work fine with _id's that are object ids" do
85
- id = Mongo::ObjectID.new
86
- Query.new(Room, :_id => id).criteria.should == {:_id => id}
87
- end
88
-
89
- should "make sure other object id typed keys get converted" do
90
- id = Mongo::ObjectID.new
91
- Query.new(Message, :room_id => id.to_s).criteria.should == {:room_id => id}
92
- end
93
-
94
- should "work fine with object ids for object id typed keys" do
95
- id = Mongo::ObjectID.new
96
- Query.new(Message, :room_id => id).criteria.should == {:room_id => id}
97
- end
98
-
99
- should "convert times to utc if they aren't already" do
100
- time = Time.now.in_time_zone('Indiana (East)')
101
- criteria = Query.new(Room, :created_at => time).criteria
102
- criteria[:created_at].utc?.should be_true
103
- end
104
-
105
- should "not funk with times already in utc" do
106
- time = Time.now.utc
107
- criteria = Query.new(Room, :created_at => time).criteria
108
- criteria[:created_at].utc?.should be_true
109
- criteria[:created_at].should == time
110
- end
111
-
112
- should "use $in for arrays" do
113
- Query.new(Room, :foo => [1,2,3]).criteria.should == {
114
- :foo => {'$in' => [1,2,3]}
115
- }
116
- end
117
-
118
- should "not use $in for arrays if already using array operator" do
119
- Query.new(Room, :foo => {'$all' => [1,2,3]}).criteria.should == {
120
- :foo => {'$all' => [1,2,3]}
121
- }
122
-
123
- Query.new(Room, :foo => {'$any' => [1,2,3]}).criteria.should == {
124
- :foo => {'$any' => [1,2,3]}
125
- }
126
- end
127
-
128
- should "work arbitrarily deep" do
129
- Query.new(Room, :foo => {:bar => [1,2,3]}).criteria.should == {
130
- :foo => {:bar => {'$in' => [1,2,3]}}
131
- }
132
-
133
- Query.new(Room, :foo => {:bar => {'$any' => [1,2,3]}}).criteria.should == {
134
- :foo => {:bar => {'$any' => [1,2,3]}}
135
- }
136
- end
137
- end
138
-
139
- context "ordering" do
140
- should "single field with ascending direction" do
141
- sort = [['foo', 1]]
142
- Query.new(Room, :order => 'foo asc').options[:sort].should == sort
143
- Query.new(Room, :order => 'foo ASC').options[:sort].should == sort
144
- end
145
-
146
- should "single field with descending direction" do
147
- sort = [['foo', -1]]
148
- Query.new(Room, :order => 'foo desc').options[:sort].should == sort
149
- Query.new(Room, :order => 'foo DESC').options[:sort].should == sort
150
- end
151
-
152
- should "convert order operators to mongo sort" do
153
- Query.new(Room, :order => :foo.asc).options[:sort].should == [['foo', 1]]
154
- Query.new(Room, :order => :foo.desc).options[:sort].should == [['foo', -1]]
155
- end
156
-
157
- should "convert array of order operators to mongo sort" do
158
- Query.new(Room, :order => [:foo.asc, :bar.desc]).options[:sort].should == [['foo', 1], ['bar', -1]]
159
- end
160
-
161
- should "convert field without direction to ascending" do
162
- sort = [['foo', 1]]
163
- Query.new(Room, :order => 'foo').options[:sort].should == sort
164
- end
165
-
166
- should "convert multiple fields with directions" do
167
- sort = [['foo', -1], ['bar', 1], ['baz', -1]]
168
- Query.new(Room, :order => 'foo desc, bar asc, baz desc').options[:sort].should == sort
169
- end
170
-
171
- should "convert multiple fields with some missing directions" do
172
- sort = [['foo', -1], ['bar', 1], ['baz', 1]]
173
- Query.new(Room, :order => 'foo desc, bar, baz').options[:sort].should == sort
174
- end
175
-
176
- should "just use sort if sort and order are present" do
177
- sort = [['$natural', 1]]
178
- Query.new(Room, :sort => sort, :order => 'foo asc').options[:sort].should == sort
179
- end
180
-
181
- should "normalize id to _id" do
182
- Query.new(Room, :order => :id.asc).options[:sort].should == [['_id', 1]]
183
- end
184
-
185
- should "convert natural in order to proper" do
186
- sort = [['$natural', 1]]
187
- Query.new(Room, :order => '$natural asc').options[:sort].should == sort
188
- sort = [['$natural', -1]]
189
- Query.new(Room, :order => '$natural desc').options[:sort].should == sort
190
- end
191
-
192
- should "work for natural order ascending" do
193
- Query.new(Room, :sort => {'$natural' => 1}).options[:sort]['$natural'].should == 1
194
- end
195
-
196
- should "work for natural order descending" do
197
- Query.new(Room, :sort => {'$natural' => -1}).options[:sort]['$natural'].should == -1
198
- end
199
- end
200
-
201
- context "skip" do
202
- should "default to 0" do
203
- Query.new(Room, {}).options[:skip].should == 0
204
- end
205
-
206
- should "use skip provided" do
207
- Query.new(Room, :skip => 2).options[:skip].should == 2
208
- end
209
-
210
- should "covert string to integer" do
211
- Query.new(Room, :skip => '2').options[:skip].should == 2
212
- end
213
-
214
- should "convert offset to skip" do
215
- Query.new(Room, :offset => 1).options[:skip].should == 1
216
- end
217
- end
218
-
219
- context "limit" do
220
- should "default to 0" do
221
- Query.new(Room, {}).options[:limit].should == 0
222
- end
223
-
224
- should "use limit provided" do
225
- Query.new(Room, :limit => 2).options[:limit].should == 2
226
- end
227
-
228
- should "covert string to integer" do
229
- Query.new(Room, :limit => '2').options[:limit].should == 2
230
- end
231
- end
232
-
233
- context "fields" do
234
- should "default to nil" do
235
- Query.new(Room, {}).options[:fields].should be(nil)
236
- end
237
-
238
- should "be converted to nil if empty string" do
239
- Query.new(Room, :fields => '').options[:fields].should be(nil)
240
- end
241
-
242
- should "be converted to nil if []" do
243
- Query.new(Room, :fields => []).options[:fields].should be(nil)
244
- end
245
-
246
- should "should work with array" do
247
- Query.new(Room, {:fields => %w(a b)}).options[:fields].should == %w(a b)
248
- end
249
-
250
- should "convert comma separated list to array" do
251
- Query.new(Room, {:fields => 'a, b'}).options[:fields].should == %w(a b)
252
- end
253
-
254
- should "also work as select" do
255
- Query.new(Room, :select => %w(a b)).options[:fields].should == %w(a b)
256
- end
257
-
258
- should "also work with select as array of symbols" do
259
- Query.new(Room, :select => [:a, :b]).options[:fields].should == [:a, :b]
260
- end
261
- end
262
-
263
- context "Condition auto-detection" do
264
- should "know :conditions are criteria" do
265
- finder = Query.new(Room, :conditions => {:foo => 'bar'})
266
- finder.criteria.should == {:foo => 'bar'}
267
- finder.options.keys.should_not include(:conditions)
268
- end
269
-
270
- should "know fields is an option" do
271
- finder = Query.new(Room, :fields => ['foo'])
272
- finder.options[:fields].should == ['foo']
273
- finder.criteria.keys.should_not include(:fields)
274
- end
275
-
276
- # select gets converted to fields so just checking keys
277
- should "know select is an option" do
278
- finder = Query.new(Room, :select => 'foo')
279
- finder.options.keys.should include(:sort)
280
- finder.criteria.keys.should_not include(:select)
281
- finder.criteria.keys.should_not include(:fields)
282
- end
283
-
284
- should "know skip is an option" do
285
- finder = Query.new(Room, :skip => 10)
286
- finder.options[:skip].should == 10
287
- finder.criteria.keys.should_not include(:skip)
288
- end
289
-
290
- # offset gets converted to skip so just checking keys
291
- should "know offset is an option" do
292
- finder = Query.new(Room, :offset => 10)
293
- finder.options.keys.should include(:skip)
294
- finder.criteria.keys.should_not include(:skip)
295
- finder.criteria.keys.should_not include(:offset)
296
- end
297
-
298
- should "know limit is an option" do
299
- finder = Query.new(Room, :limit => 10)
300
- finder.options[:limit].should == 10
301
- finder.criteria.keys.should_not include(:limit)
302
- end
303
-
304
- should "know sort is an option" do
305
- finder = Query.new(Room, :sort => [['foo', 1]])
306
- finder.options[:sort].should == [['foo', 1]]
307
- finder.criteria.keys.should_not include(:sort)
308
- end
309
-
310
- # order gets converted to sort so just checking keys
311
- should "know order is an option" do
312
- finder = Query.new(Room, :order => 'foo')
313
- finder.options.keys.should include(:sort)
314
- finder.criteria.keys.should_not include(:sort)
315
- end
316
-
317
- should "work with full range of things" do
318
- query_options = Query.new(Room, {
319
- :foo => 'bar',
320
- :baz => true,
321
- :sort => [['foo', 1]],
322
- :fields => ['foo', 'baz'],
323
- :limit => 10,
324
- :skip => 10,
325
- })
326
-
327
- query_options.criteria.should == {
328
- :foo => 'bar',
329
- :baz => true,
330
- }
331
-
332
- query_options.options.should == {
333
- :sort => [['foo', 1]],
334
- :fields => ['foo', 'baz'],
335
- :limit => 10,
336
- :skip => 10,
337
- }
338
- end
339
- end
340
- end