ign-mongo_mapper 0.8.6.1

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 (147) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +33 -0
  3. data/UPGRADES +7 -0
  4. data/bin/mmconsole +60 -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 +8 -0
  11. data/examples/keys.rb +40 -0
  12. data/examples/modifiers/set.rb +25 -0
  13. data/examples/plugins.rb +41 -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 +83 -0
  19. data/lib/mongo_mapper/connection.rb +83 -0
  20. data/lib/mongo_mapper/document.rb +41 -0
  21. data/lib/mongo_mapper/embedded_document.rb +31 -0
  22. data/lib/mongo_mapper/exceptions.rb +27 -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 +27 -0
  33. data/lib/mongo_mapper/extensions/object_id.rb +30 -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 +29 -0
  37. data/lib/mongo_mapper/middleware/identity_map.rb +16 -0
  38. data/lib/mongo_mapper/plugins.rb +15 -0
  39. data/lib/mongo_mapper/plugins/accessible.rb +44 -0
  40. data/lib/mongo_mapper/plugins/associations.rb +134 -0
  41. data/lib/mongo_mapper/plugins/associations/base.rb +124 -0
  42. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +29 -0
  43. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +24 -0
  44. data/lib/mongo_mapper/plugins/associations/collection.rb +27 -0
  45. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +40 -0
  46. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +151 -0
  47. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  48. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +109 -0
  49. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
  50. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
  51. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
  52. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +41 -0
  53. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
  54. data/lib/mongo_mapper/plugins/associations/proxy.rb +139 -0
  55. data/lib/mongo_mapper/plugins/caching.rb +21 -0
  56. data/lib/mongo_mapper/plugins/callbacks.rb +243 -0
  57. data/lib/mongo_mapper/plugins/clone.rb +22 -0
  58. data/lib/mongo_mapper/plugins/descendants.rb +17 -0
  59. data/lib/mongo_mapper/plugins/dirty.rb +124 -0
  60. data/lib/mongo_mapper/plugins/document.rb +41 -0
  61. data/lib/mongo_mapper/plugins/dynamic_querying.rb +43 -0
  62. data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
  63. data/lib/mongo_mapper/plugins/embedded_document.rb +48 -0
  64. data/lib/mongo_mapper/plugins/equality.rb +17 -0
  65. data/lib/mongo_mapper/plugins/identity_map.rb +128 -0
  66. data/lib/mongo_mapper/plugins/indexes.rb +12 -0
  67. data/lib/mongo_mapper/plugins/inspect.rb +15 -0
  68. data/lib/mongo_mapper/plugins/keys.rb +311 -0
  69. data/lib/mongo_mapper/plugins/keys/key.rb +65 -0
  70. data/lib/mongo_mapper/plugins/logger.rb +18 -0
  71. data/lib/mongo_mapper/plugins/modifiers.rb +112 -0
  72. data/lib/mongo_mapper/plugins/pagination.rb +14 -0
  73. data/lib/mongo_mapper/plugins/persistence.rb +69 -0
  74. data/lib/mongo_mapper/plugins/protected.rb +53 -0
  75. data/lib/mongo_mapper/plugins/querying.rb +176 -0
  76. data/lib/mongo_mapper/plugins/querying/decorator.rb +46 -0
  77. data/lib/mongo_mapper/plugins/querying/plucky_methods.rb +15 -0
  78. data/lib/mongo_mapper/plugins/rails.rb +58 -0
  79. data/lib/mongo_mapper/plugins/safe.rb +28 -0
  80. data/lib/mongo_mapper/plugins/sci.rb +32 -0
  81. data/lib/mongo_mapper/plugins/scopes.rb +21 -0
  82. data/lib/mongo_mapper/plugins/serialization.rb +76 -0
  83. data/lib/mongo_mapper/plugins/timestamps.rb +22 -0
  84. data/lib/mongo_mapper/plugins/userstamps.rb +15 -0
  85. data/lib/mongo_mapper/plugins/validations.rb +50 -0
  86. data/lib/mongo_mapper/support/descendant_appends.rb +45 -0
  87. data/lib/mongo_mapper/version.rb +4 -0
  88. data/rails/init.rb +15 -0
  89. data/test/_NOTE_ON_TESTING +1 -0
  90. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +64 -0
  91. data/test/functional/associations/test_belongs_to_proxy.rb +117 -0
  92. data/test/functional/associations/test_in_array_proxy.rb +349 -0
  93. data/test/functional/associations/test_many_documents_as_proxy.rb +229 -0
  94. data/test/functional/associations/test_many_documents_proxy.rb +615 -0
  95. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +176 -0
  96. data/test/functional/associations/test_many_embedded_proxy.rb +256 -0
  97. data/test/functional/associations/test_many_polymorphic_proxy.rb +303 -0
  98. data/test/functional/associations/test_one_embedded_proxy.rb +100 -0
  99. data/test/functional/associations/test_one_proxy.rb +206 -0
  100. data/test/functional/test_accessible.rb +168 -0
  101. data/test/functional/test_associations.rb +46 -0
  102. data/test/functional/test_binary.rb +27 -0
  103. data/test/functional/test_caching.rb +76 -0
  104. data/test/functional/test_callbacks.rb +151 -0
  105. data/test/functional/test_dirty.rb +163 -0
  106. data/test/functional/test_document.rb +272 -0
  107. data/test/functional/test_dynamic_querying.rb +75 -0
  108. data/test/functional/test_embedded_document.rb +210 -0
  109. data/test/functional/test_identity_map.rb +513 -0
  110. data/test/functional/test_indexes.rb +42 -0
  111. data/test/functional/test_logger.rb +20 -0
  112. data/test/functional/test_modifiers.rb +416 -0
  113. data/test/functional/test_pagination.rb +91 -0
  114. data/test/functional/test_protected.rb +175 -0
  115. data/test/functional/test_querying.rb +873 -0
  116. data/test/functional/test_safe.rb +76 -0
  117. data/test/functional/test_sci.rb +230 -0
  118. data/test/functional/test_scopes.rb +171 -0
  119. data/test/functional/test_string_id_compatibility.rb +67 -0
  120. data/test/functional/test_timestamps.rb +62 -0
  121. data/test/functional/test_userstamps.rb +27 -0
  122. data/test/functional/test_validations.rb +342 -0
  123. data/test/models.rb +233 -0
  124. data/test/test_active_model_lint.rb +13 -0
  125. data/test/test_helper.rb +102 -0
  126. data/test/unit/associations/test_base.rb +212 -0
  127. data/test/unit/associations/test_proxy.rb +105 -0
  128. data/test/unit/serializers/test_json_serializer.rb +217 -0
  129. data/test/unit/test_clone.rb +69 -0
  130. data/test/unit/test_descendant_appends.rb +71 -0
  131. data/test/unit/test_document.rb +208 -0
  132. data/test/unit/test_dynamic_finder.rb +125 -0
  133. data/test/unit/test_embedded_document.rb +639 -0
  134. data/test/unit/test_extensions.rb +376 -0
  135. data/test/unit/test_identity_map_middleware.rb +34 -0
  136. data/test/unit/test_inspect.rb +22 -0
  137. data/test/unit/test_key.rb +205 -0
  138. data/test/unit/test_keys.rb +89 -0
  139. data/test/unit/test_mongo_mapper.rb +110 -0
  140. data/test/unit/test_pagination.rb +11 -0
  141. data/test/unit/test_plugins.rb +50 -0
  142. data/test/unit/test_rails.rb +181 -0
  143. data/test/unit/test_rails_compatibility.rb +52 -0
  144. data/test/unit/test_serialization.rb +51 -0
  145. data/test/unit/test_time_zones.rb +39 -0
  146. data/test/unit/test_validations.rb +564 -0
  147. metadata +385 -0
@@ -0,0 +1,376 @@
1
+ require 'test_helper'
2
+
3
+ class SupportTest < Test::Unit::TestCase
4
+ context "Array.to_mongo" do
5
+ should "convert value to_a" do
6
+ Array.to_mongo([1, 2, 3, 4]).should == [1, 2, 3, 4]
7
+ Array.to_mongo('1').should == ['1']
8
+ Array.to_mongo({'1' => '2', '3' => '4'}).should == [['1', '2'], ['3', '4']]
9
+ end
10
+ end
11
+
12
+ context "Array.from_mongo" do
13
+ should "be array if array" do
14
+ Array.from_mongo([1, 2]).should == [1, 2]
15
+ end
16
+
17
+ should "be empty array if nil" do
18
+ Array.from_mongo(nil).should == []
19
+ end
20
+ end
21
+
22
+ context "Binary.to_mongo" do
23
+ should "convert to binary if not binary" do
24
+ Binary.to_mongo('asdfsadasdfs').is_a?(BSON::Binary).should be_true
25
+ end
26
+
27
+ should "be binary if binary" do
28
+ Binary.to_mongo(BSON::Binary.new('asdfsadasdfs')).is_a?(BSON::Binary).should be_true
29
+ end
30
+
31
+ should "be nil if nil" do
32
+ Binary.to_mongo(nil).should be_nil
33
+ end
34
+ end
35
+
36
+ context "Binary.from_mongo" do
37
+ should "return value" do
38
+ binary = BSON::Binary.new('asdfasdfasdf')
39
+ Binary.from_mongo(binary).to_s.should == binary.to_s
40
+ end
41
+ end
42
+
43
+ context "Boolean.to_mongo" do
44
+ should "be true for true" do
45
+ Boolean.to_mongo(true).should be_true
46
+ end
47
+
48
+ should "be false for false" do
49
+ Boolean.to_mongo(false).should be_false
50
+ end
51
+
52
+ should "handle odd assortment of other values" do
53
+ Boolean.to_mongo('true').should be_true
54
+ Boolean.to_mongo('t').should be_true
55
+ Boolean.to_mongo('1').should be_true
56
+ Boolean.to_mongo(1).should be_true
57
+
58
+ Boolean.to_mongo('false').should be_false
59
+ Boolean.to_mongo('f').should be_false
60
+ Boolean.to_mongo('0').should be_false
61
+ Boolean.to_mongo(0).should be_false
62
+ end
63
+
64
+ should "be nil for nil" do
65
+ Boolean.to_mongo(nil).should be_nil
66
+ end
67
+ end
68
+
69
+ context "Boolean.from_mongo" do
70
+ should "be true for true" do
71
+ Boolean.from_mongo(true).should be_true
72
+ end
73
+
74
+ should "be false for false" do
75
+ Boolean.from_mongo(false).should be_false
76
+ end
77
+
78
+ should "be nil for nil" do
79
+ Boolean.from_mongo(nil).should be_nil
80
+ end
81
+ end
82
+
83
+ context "Date.to_mongo" do
84
+ should "be time if string" do
85
+ date = Date.to_mongo('2009-10-01')
86
+ date.should == Time.utc(2009, 10, 1)
87
+ date.should == date
88
+ date.month.should == 10
89
+ date.day.should == 1
90
+ date.year.should == 2009
91
+ end
92
+
93
+ should "be time if date" do
94
+ Date.to_mongo(Date.new(2009, 10, 1)).should == Time.utc(2009, 10, 1)
95
+ end
96
+
97
+ should "be date if time" do
98
+ Date.to_mongo(Time.parse("2009-10-1T12:30:00")).should == Time.utc(2009, 10, 1)
99
+ end
100
+
101
+ should "be nil if bogus string" do
102
+ Date.to_mongo('jdsafop874').should be_nil
103
+ end
104
+
105
+ should "be nil if empty string" do
106
+ Date.to_mongo('').should be_nil
107
+ end
108
+ end
109
+
110
+ context "Date.from_mongo" do
111
+ should "be date if date" do
112
+ date = Date.new(2009, 10, 1)
113
+ from_date = Date.from_mongo(date)
114
+ from_date.should == date
115
+ from_date.month.should == 10
116
+ from_date.day.should == 1
117
+ from_date.year.should == 2009
118
+ end
119
+
120
+ should "be date if time" do
121
+ time = Time.now
122
+ Date.from_mongo(time).should == time.to_date
123
+ end
124
+
125
+ should "be nil if nil" do
126
+ Date.from_mongo(nil).should be_nil
127
+ end
128
+ end
129
+
130
+ context "Float.to_mongo" do
131
+ should "convert value to_f" do
132
+ [21, 21.0, '21'].each do |value|
133
+ Float.to_mongo(value).should == 21.0
134
+ end
135
+ end
136
+
137
+ should "leave nil values nil" do
138
+ Float.to_mongo(nil).should == nil
139
+ end
140
+ end
141
+
142
+ context "Hash.from_mongo" do
143
+ should "convert hash to hash with indifferent access" do
144
+ hash = Hash.from_mongo(:foo => 'bar')
145
+ hash[:foo].should == 'bar'
146
+ hash['foo'].should == 'bar'
147
+ end
148
+
149
+ should "be hash if nil" do
150
+ hash = Hash.from_mongo(nil)
151
+ hash.should == {}
152
+ hash.is_a?(HashWithIndifferentAccess).should be_true
153
+ end
154
+ end
155
+
156
+ context "Hash.to_mongo instance method" do
157
+ should "have instance method that returns self" do
158
+ hash = HashWithIndifferentAccess.new('foo' => 'bar')
159
+ hash.to_mongo.should == {'foo' => 'bar'}
160
+ end
161
+ end
162
+
163
+ context "Integer.to_mongo" do
164
+ should "convert value to integer" do
165
+ [21, 21.0, '21'].each do |value|
166
+ Integer.to_mongo(value).should == 21
167
+ end
168
+ end
169
+
170
+ should "work fine with big integers" do
171
+ [9223372036854775807, '9223372036854775807'].each do |value|
172
+ Integer.to_mongo(value).should == 9223372036854775807
173
+ end
174
+ end
175
+ end
176
+
177
+ context "NilClass#from_mongo" do
178
+ should "return nil" do
179
+ nil.from_mongo(nil).should be_nil
180
+ end
181
+ end
182
+
183
+ context "NilClass#to_mongo" do
184
+ should "return nil" do
185
+ nil.to_mongo(nil).should be_nil
186
+ end
187
+ end
188
+
189
+ context "ObjectId#to_mongo" do
190
+ should "call class to_mongo with self" do
191
+ object = Object.new
192
+ object.class.expects(:to_mongo).with(object)
193
+ object.to_mongo
194
+ end
195
+ end
196
+
197
+ context "ObjectId.to_mongo" do
198
+ should "return nil for nil" do
199
+ ObjectId.to_mongo(nil).should be_nil
200
+ end
201
+
202
+ should "return nil if blank string" do
203
+ ObjectId.to_mongo('').should be_nil
204
+ end
205
+
206
+ should "return value if object id" do
207
+ id = BSON::ObjectId.new
208
+ ObjectId.to_mongo(id).should be(id)
209
+ end
210
+
211
+ should "return value" do
212
+ Object.to_mongo(21).should == 21
213
+ Object.to_mongo('21').should == '21'
214
+ Object.to_mongo(9223372036854775807).should == 9223372036854775807
215
+ end
216
+ end
217
+
218
+ context "ObjectId.from_mongo" do
219
+ should "return value" do
220
+ Object.from_mongo(21).should == 21
221
+ Object.from_mongo('21').should == '21'
222
+ Object.from_mongo(9223372036854775807).should == 9223372036854775807
223
+
224
+ id = BSON::ObjectId.new
225
+ ObjectId.from_mongo(id).should == id
226
+ end
227
+ end
228
+
229
+ context "Set.to_mongo" do
230
+ should "convert value to_a" do
231
+ Set.to_mongo(Set.new([1,2,3])).should == [1,2,3]
232
+ end
233
+
234
+ should "convert to empty array if nil" do
235
+ Set.to_mongo(nil).should == []
236
+ end
237
+ end
238
+
239
+ context "Set.from_mongo" do
240
+ should "be a set if array" do
241
+ Set.from_mongo([1,2,3]).should == Set.new([1,2,3])
242
+ end
243
+
244
+ should "be empty set if nil" do
245
+ Set.from_mongo(nil).should == Set.new([])
246
+ end
247
+ end
248
+
249
+ context "String.to_mongo" do
250
+ should "convert value to_s" do
251
+ [21, '21'].each do |value|
252
+ String.to_mongo(value).should == '21'
253
+ end
254
+ end
255
+
256
+ should "be nil if nil" do
257
+ String.to_mongo(nil).should be_nil
258
+ end
259
+ end
260
+
261
+ context "String.from_mongo" do
262
+ should "be string if value present" do
263
+ String.from_mongo('Scotch! Scotch! Scotch!').should == 'Scotch! Scotch! Scotch!'
264
+ end
265
+
266
+ should "return nil if nil" do
267
+ String.from_mongo(nil).should be_nil
268
+ end
269
+
270
+ should "return empty string if blank" do
271
+ String.from_mongo('').should == ''
272
+ end
273
+ end
274
+
275
+ context "Time.to_mongo without Time.zone" do
276
+ setup do
277
+ Time.zone = nil
278
+ end
279
+
280
+ should "be time to milliseconds if string" do
281
+ Time.to_mongo('2000-01-01 01:01:01.123456').to_f.should == Time.local(2000, 1, 1, 1, 1, 1, 0).utc.to_f
282
+ end
283
+
284
+ should "be time in utc if time" do
285
+ Time.to_mongo(Time.local(2009, 8, 15, 0, 0, 0)).zone.should == 'UTC'
286
+ end
287
+
288
+ should "be nil if blank string" do
289
+ Time.to_mongo('').should be_nil
290
+ end
291
+
292
+ should "not be nil if nil" do
293
+ Time.to_mongo(nil).should be_nil
294
+ end
295
+ end
296
+
297
+ context "Time.to_mongo with Time.zone" do
298
+ should "be time to milliseconds if time" do
299
+ Time.zone = 'Hawaii'
300
+ Time.to_mongo(Time.zone.local(2009, 8, 15, 14, 0, 0, 123456)).to_f.should == Time.utc(2009, 8, 16, 0, 0, 0, 0).to_f
301
+ Time.zone = nil
302
+ end
303
+
304
+ should "be time to milliseconds if string" do
305
+ Time.zone = 'Hawaii'
306
+ Time.to_mongo('2009-08-15 14:00:00.123456').to_f.should == Time.utc(2009, 8, 16, 0, 0, 0, 0).to_f
307
+ Time.zone = nil
308
+ end
309
+
310
+ should "not round up times at the end of the month" do
311
+ Time.to_mongo(Time.now.end_of_month).to_i.should == Time.now.end_of_month.utc.to_i
312
+ end
313
+
314
+ should "be nil if blank string" do
315
+ Time.zone = 'Hawaii'
316
+ Time.to_mongo('').should be_nil
317
+ Time.zone = nil
318
+ end
319
+
320
+ should "be nil if nil" do
321
+ Time.zone = 'Hawaii'
322
+ Time.to_mongo(nil).should be_nil
323
+ Time.zone = nil
324
+ end
325
+ end
326
+
327
+ context "Time.from_mongo without Time.zone" do
328
+ should "be time" do
329
+ time = Time.now
330
+ Time.from_mongo(time).should == time
331
+ end
332
+
333
+ should "be nil if nil" do
334
+ Time.from_mongo(nil).should be_nil
335
+ end
336
+ end
337
+
338
+ context "Time.from_mongo with Time.zone" do
339
+ should "be time in Time.zone" do
340
+ Time.zone = 'Hawaii'
341
+
342
+ time = Time.from_mongo(Time.utc(2009, 10, 1))
343
+ time.should == Time.zone.local(2009, 9, 30, 14)
344
+ time.is_a?(ActiveSupport::TimeWithZone).should be_true
345
+
346
+ Time.zone = nil
347
+ end
348
+
349
+ should "be nil if nil" do
350
+ Time.zone = 'Hawaii'
351
+ Time.from_mongo(nil).should be_nil
352
+ Time.zone = nil
353
+ end
354
+ end
355
+
356
+ context "BSON::ObjectId" do
357
+ context "#as_json" do
358
+ should "convert object id to string" do
359
+ id = BSON::ObjectId.new
360
+ id.as_json.should == id.to_s
361
+ end
362
+ end
363
+
364
+ context "#to_json" do
365
+ should "convert object id to string" do
366
+ id = BSON::ObjectId.new
367
+ id.to_json.should == %Q("#{id}")
368
+ end
369
+
370
+ should "support ruby driver syntax also" do
371
+ id = BSON::ObjectId.new
372
+ id.original_to_json.should == %Q({"$oid": "#{id}"})
373
+ end
374
+ end
375
+ end
376
+ end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+ require 'rack/test'
3
+
4
+ class IdentityMapMiddlewareTest < Test::Unit::TestCase
5
+ include Rack::Test::Methods
6
+
7
+ def app
8
+ @app ||= Rack::Builder.new do
9
+ use MongoMapper::Middleware::IdentityMap
10
+ map "/" do
11
+ run lambda {|env| [200, {}, []] }
12
+ end
13
+ map "/fail" do
14
+ run lambda {|env| raise "FAIL!" }
15
+ end
16
+ end.to_app
17
+ end
18
+
19
+ context "with a successful request" do
20
+ should "clear the identity map" do
21
+ MongoMapper::Plugins::IdentityMap.expects(:clear).twice
22
+ get '/'
23
+ end
24
+ end
25
+
26
+ context "when the request raises an error" do
27
+ should "clear the identity map" do
28
+ MongoMapper::Plugins::IdentityMap.expects(:clear).twice
29
+ get '/fail' rescue nil
30
+ end
31
+ end
32
+
33
+
34
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+
3
+ class InspectTest < Test::Unit::TestCase
4
+ context "#inspect" do
5
+ setup do
6
+ @document = Doc('User') do
7
+ key :name, String
8
+ key :age, Integer
9
+ end
10
+
11
+ @doc = @document.new(:name => 'John', :age => 29)
12
+ end
13
+
14
+ should "print out attributes in alpha sorted order" do
15
+ @doc.inspect.should =~ /_id:.*, age: 29, name: "John"/
16
+ end
17
+
18
+ should "include class name" do
19
+ @doc.inspect.should =~ /^#<User/
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,205 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class FooType < Struct.new(:bar)
5
+ def self.to_mongo(value)
6
+ 'to_mongo'
7
+ end
8
+
9
+ def self.from_mongo(value)
10
+ 'from_mongo'
11
+ end
12
+ end
13
+
14
+ class KeyTest < Test::Unit::TestCase
15
+ include MongoMapper::Plugins::Keys
16
+
17
+ context "Initializing a new key" do
18
+ should "allow setting the name" do
19
+ Key.new(:foo, String).name.should == 'foo'
20
+ end
21
+
22
+ should "allow setting the type" do
23
+ Key.new(:foo, Integer).type.should be(Integer)
24
+ end
25
+
26
+ should "allow setting options" do
27
+ Key.new(:foo, Integer, :required => true).options[:required].should be(true)
28
+ end
29
+
30
+ should "default options to {}" do
31
+ Key.new(:foo, Integer, nil).options.should == {}
32
+ end
33
+
34
+ should "symbolize option keys" do
35
+ Key.new(:foo, Integer, 'required' => true).options[:required].should be(true)
36
+ end
37
+
38
+ should "work with just name" do
39
+ key = Key.new(:foo)
40
+ key.name.should == 'foo'
41
+ end
42
+
43
+ should "work with name and type" do
44
+ key = Key.new(:foo, String)
45
+ key.name.should == 'foo'
46
+ key.type.should == String
47
+ end
48
+
49
+ should "work with name, type, and options" do
50
+ key = Key.new(:foo, String, :required => true)
51
+ key.name.should == 'foo'
52
+ key.type.should == String
53
+ key.options[:required].should be_true
54
+ end
55
+
56
+ should "work with name and options" do
57
+ key = Key.new(:foo, :required => true)
58
+ key.name.should == 'foo'
59
+ key.options[:required].should be_true
60
+ end
61
+ end
62
+
63
+ context "A key" do
64
+ should "be equal to another key with same name and type" do
65
+ Key.new(:name, String).should == Key.new(:name, String)
66
+ end
67
+
68
+ should "not be equal to another key with different name" do
69
+ Key.new(:name, String).should_not == Key.new(:foo, String)
70
+ end
71
+
72
+ should "not be equal to another key with different type" do
73
+ Key.new(:name, String).should_not == Key.new(:name, Integer)
74
+ end
75
+
76
+ should "know if it is a embedded_document" do
77
+ Key.new(:name, EDoc()).embeddable?.should be_true
78
+ end
79
+
80
+ should "know if it is not a embedded_document" do
81
+ Key.new(:name, String).embeddable?.should be_false
82
+ end
83
+
84
+ should "know if it is a number" do
85
+ Key.new(:age, Integer).number?.should be_true
86
+ Key.new(:age, Float).number?.should be_true
87
+ end
88
+
89
+ should "know if it is not a number" do
90
+ Key.new(:age, String).number?.should be_false
91
+ end
92
+ end
93
+
94
+ context "for an array with :typecast option" do
95
+ setup { @key = Key.new(:user_ids, Array, :typecast => 'ObjectId') }
96
+ subject { @key }
97
+
98
+ should "cast each element correctly" do
99
+ ids = [BSON::ObjectId.new, BSON::ObjectId.new, BSON::ObjectId.new.to_s, BSON::ObjectId.new.to_s]
100
+ subject.set(ids).should == ids.map { |id| ObjectId.to_mongo(id) }
101
+ end
102
+ end
103
+
104
+ context "for an array with :typecast option of Date" do
105
+ setup { @key = Key.new(:dates, Array, :typecast => 'Date') }
106
+ subject { @key }
107
+
108
+ should "cast each element correctly when get" do
109
+ dates = [Date.yesterday, Date.today, Date.tomorrow.to_s]
110
+ subject.get(dates).should == dates.map { |date| Date.from_mongo(date) }
111
+ end
112
+
113
+ should "cast each element correctly when set" do
114
+ dates = [Date.yesterday, Date.today, Date.tomorrow.to_s]
115
+ subject.set(dates).should == dates.map { |date| Date.to_mongo(date) }
116
+ end
117
+ end
118
+
119
+ context "for a set with :typecast option" do
120
+ setup { @key = Key.new(:user_ids, Set, :typecast => 'ObjectId') }
121
+ subject { @key }
122
+
123
+ should "cast each element correctly" do
124
+ ids = [BSON::ObjectId.new, BSON::ObjectId.new, BSON::ObjectId.new.to_s, BSON::ObjectId.new.to_s]
125
+ subject.set(ids).should == ids.map { |id| ObjectId.to_mongo(id) }
126
+ end
127
+ end
128
+
129
+ context "setting a value with a custom type" do
130
+ should "correctly typecast" do
131
+ key = Key.new(:foo, FooType)
132
+ key.set("something").should == 'to_mongo'
133
+ end
134
+
135
+ should "correctly typecast if object of that type is given" do
136
+ key = Key.new(:foo, FooType)
137
+ key.set(FooType.new('something')).should == 'to_mongo'
138
+ end
139
+ end
140
+
141
+ context "getting a value with a custom type" do
142
+ should "use #from_mongo to convert back to custom type" do
143
+ key = Key.new(:foo, FooType)
144
+ key.get('something').should == 'from_mongo'
145
+ end
146
+ end
147
+
148
+ context "getting a value" do
149
+ should "work with a type" do
150
+ key = Key.new(:foo, String)
151
+ key.get('bar').should == 'bar'
152
+ end
153
+
154
+ should "work without type" do
155
+ key = Key.new(:foo)
156
+ key.get([1, '2']).should == [1, '2']
157
+ key.get(false).should == false
158
+ key.get({}).should == {}
159
+ end
160
+
161
+ context "for a embedded_document" do
162
+ should "default to nil" do
163
+ key = Key.new(:foo, Address)
164
+ key.get(nil).should be_nil
165
+ end
166
+
167
+ should "return instance if instance" do
168
+ address = Address.new(:city => 'South Bend', :state => 'IN', :zip => 46544)
169
+ key = Key.new(:foo, Address)
170
+ key.get(address).should == address
171
+ end
172
+ end
173
+ end
174
+
175
+ context "getting a value with a default set" do
176
+ setup do
177
+ @key = Key.new(:foo, String, :default => 'baz')
178
+ end
179
+
180
+ should "return default value if value nil" do
181
+ @key.get(nil).should == 'baz'
182
+ end
183
+
184
+ should "return a dup of the default value" do
185
+ @key.get(nil).replace('bar')
186
+ @key.get(nil).should == 'baz'
187
+ end
188
+
189
+ should "return value if not blank" do
190
+ @key.get('foobar').should == 'foobar'
191
+ end
192
+
193
+ should "work with Boolean type and false value" do
194
+ Key.new(:active, Boolean, :default => false).get(nil).should be_false
195
+ end
196
+
197
+ should "work with Boolean type and true value" do
198
+ Key.new(:active, Boolean, :default => true).get(nil).should be_true
199
+ end
200
+
201
+ should "work with procs" do
202
+ Key.new(:foo, String, :default => lambda { return 'hello world' }).get(nil).should == "hello world"
203
+ end
204
+ end
205
+ end # KeyTest