mongo_mapper-unstable 2010.3.8 → 2010.06.23

Sign up to get free protection for your applications and to get access to all the features.
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