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.
Files changed (134) 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.rb +77 -97
  8. data/lib/mongo_mapper/connection.rb +83 -0
  9. data/lib/mongo_mapper/document.rb +10 -252
  10. data/lib/mongo_mapper/embedded_document.rb +7 -46
  11. data/lib/mongo_mapper/exceptions.rb +30 -0
  12. data/lib/mongo_mapper/extensions/array.rb +19 -0
  13. data/lib/mongo_mapper/extensions/binary.rb +22 -0
  14. data/lib/mongo_mapper/extensions/boolean.rb +44 -0
  15. data/lib/mongo_mapper/extensions/date.rb +25 -0
  16. data/lib/mongo_mapper/extensions/float.rb +14 -0
  17. data/lib/mongo_mapper/extensions/hash.rb +14 -0
  18. data/lib/mongo_mapper/extensions/integer.rb +19 -0
  19. data/lib/mongo_mapper/extensions/kernel.rb +9 -0
  20. data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
  21. data/lib/mongo_mapper/extensions/object.rb +27 -0
  22. data/lib/mongo_mapper/extensions/object_id.rb +30 -0
  23. data/lib/mongo_mapper/extensions/set.rb +20 -0
  24. data/lib/mongo_mapper/extensions/string.rb +18 -0
  25. data/lib/mongo_mapper/extensions/time.rb +29 -0
  26. data/lib/mongo_mapper/plugins.rb +1 -21
  27. data/lib/mongo_mapper/plugins/accessible.rb +44 -0
  28. data/lib/mongo_mapper/plugins/associations.rb +7 -24
  29. data/lib/mongo_mapper/plugins/associations/base.rb +1 -0
  30. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +5 -6
  31. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +5 -6
  32. data/lib/mongo_mapper/plugins/associations/collection.rb +1 -0
  33. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +2 -1
  34. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +22 -39
  35. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +4 -4
  36. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +22 -23
  37. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +1 -0
  38. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +1 -0
  39. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +1 -0
  40. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +2 -3
  41. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +6 -7
  42. data/lib/mongo_mapper/plugins/associations/proxy.rb +8 -6
  43. data/lib/mongo_mapper/plugins/caching.rb +21 -0
  44. data/lib/mongo_mapper/plugins/callbacks.rb +4 -3
  45. data/lib/mongo_mapper/plugins/clone.rb +10 -4
  46. data/lib/mongo_mapper/plugins/descendants.rb +1 -0
  47. data/lib/mongo_mapper/plugins/dirty.rb +1 -0
  48. data/lib/mongo_mapper/plugins/document.rb +41 -0
  49. data/lib/mongo_mapper/plugins/dynamic_querying.rb +41 -0
  50. data/lib/mongo_mapper/{support/find.rb → plugins/dynamic_querying/dynamic_finder.rb} +3 -36
  51. data/lib/mongo_mapper/plugins/embedded_document.rb +49 -0
  52. data/lib/mongo_mapper/plugins/equality.rb +3 -9
  53. data/lib/mongo_mapper/plugins/identity_map.rb +8 -10
  54. data/lib/mongo_mapper/plugins/indexes.rb +12 -0
  55. data/lib/mongo_mapper/plugins/inspect.rb +1 -0
  56. data/lib/mongo_mapper/plugins/keys.rb +15 -27
  57. data/lib/mongo_mapper/plugins/keys/key.rb +14 -3
  58. data/lib/mongo_mapper/plugins/logger.rb +1 -0
  59. data/lib/mongo_mapper/plugins/modifiers.rb +3 -2
  60. data/lib/mongo_mapper/plugins/pagination.rb +5 -15
  61. data/lib/mongo_mapper/plugins/persistence.rb +12 -11
  62. data/lib/mongo_mapper/plugins/protected.rb +8 -0
  63. data/lib/mongo_mapper/plugins/querying.rb +236 -0
  64. data/lib/mongo_mapper/plugins/querying/decorator.rb +46 -0
  65. data/lib/mongo_mapper/plugins/rails.rb +1 -0
  66. data/lib/mongo_mapper/plugins/safe.rb +28 -0
  67. data/lib/mongo_mapper/plugins/sci.rb +32 -0
  68. data/lib/mongo_mapper/plugins/scopes.rb +21 -0
  69. data/lib/mongo_mapper/plugins/serialization.rb +1 -0
  70. data/lib/mongo_mapper/plugins/timestamps.rb +1 -0
  71. data/lib/mongo_mapper/plugins/userstamps.rb +1 -0
  72. data/lib/mongo_mapper/plugins/validations.rb +5 -1
  73. data/lib/mongo_mapper/support/descendant_appends.rb +5 -6
  74. data/lib/mongo_mapper/version.rb +2 -1
  75. data/test/NOTE_ON_TESTING +1 -0
  76. data/test/active_model_lint_test.rb +13 -0
  77. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +63 -0
  78. data/test/functional/associations/test_belongs_to_proxy.rb +93 -0
  79. data/test/functional/associations/test_in_array_proxy.rb +319 -0
  80. data/test/functional/associations/test_many_documents_as_proxy.rb +229 -0
  81. data/test/functional/associations/test_many_documents_proxy.rb +536 -0
  82. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +176 -0
  83. data/test/functional/associations/test_many_embedded_proxy.rb +256 -0
  84. data/test/functional/associations/test_many_polymorphic_proxy.rb +302 -0
  85. data/test/functional/associations/test_one_embedded_proxy.rb +58 -0
  86. data/test/functional/associations/test_one_proxy.rb +182 -0
  87. data/test/functional/test_accessible.rb +168 -0
  88. data/test/functional/test_associations.rb +44 -0
  89. data/test/functional/test_binary.rb +27 -0
  90. data/test/functional/test_caching.rb +76 -0
  91. data/test/functional/test_callbacks.rb +151 -0
  92. data/test/functional/test_dirty.rb +163 -0
  93. data/test/functional/test_document.rb +253 -0
  94. data/test/functional/test_dynamic_querying.rb +75 -0
  95. data/test/functional/test_embedded_document.rb +210 -0
  96. data/test/functional/test_identity_map.rb +506 -0
  97. data/test/functional/test_indexes.rb +42 -0
  98. data/test/functional/test_logger.rb +20 -0
  99. data/test/functional/test_modifiers.rb +416 -0
  100. data/test/functional/test_pagination.rb +91 -0
  101. data/test/functional/test_protected.rb +175 -0
  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 +67 -0
  107. data/test/functional/test_timestamps.rb +62 -0
  108. data/test/functional/test_userstamps.rb +27 -0
  109. data/test/functional/test_validations.rb +342 -0
  110. data/test/models.rb +227 -0
  111. data/test/test_helper.rb +98 -0
  112. data/test/unit/associations/test_base.rb +212 -0
  113. data/test/unit/associations/test_proxy.rb +105 -0
  114. data/test/unit/serializers/test_json_serializer.rb +202 -0
  115. data/test/unit/test_clone.rb +69 -0
  116. data/test/unit/test_descendant_appends.rb +71 -0
  117. data/test/unit/test_document.rb +213 -0
  118. data/test/unit/test_dynamic_finder.rb +125 -0
  119. data/test/unit/test_embedded_document.rb +644 -0
  120. data/test/unit/test_extensions.rb +380 -0
  121. data/test/unit/test_key.rb +185 -0
  122. data/test/unit/test_keys.rb +55 -0
  123. data/test/unit/test_mongo_mapper.rb +110 -0
  124. data/test/unit/test_pagination.rb +11 -0
  125. data/test/unit/test_plugins.rb +50 -0
  126. data/test/unit/test_rails.rb +181 -0
  127. data/test/unit/test_rails_compatibility.rb +52 -0
  128. data/test/unit/test_serialization.rb +51 -0
  129. data/test/unit/test_time_zones.rb +39 -0
  130. data/test/unit/test_validations.rb +544 -0
  131. metadata +113 -44
  132. data/lib/mongo_mapper/plugins/pagination/proxy.rb +0 -72
  133. data/lib/mongo_mapper/query.rb +0 -23
  134. data/lib/mongo_mapper/support.rb +0 -196
@@ -0,0 +1,380 @@
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 byte buffer if not byte buffer" do
24
+ Binary.to_mongo('asdfsadasdfs').is_a?(BSON::ByteBuffer).should be_true
25
+ end
26
+
27
+ should "be byte buffer if byte buffer" do
28
+ Binary.to_mongo(BSON::ByteBuffer.new('asdfsadasdfs')).is_a?(BSON::ByteBuffer).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
+ buffer = BSON::ByteBuffer.new('asdfasdfasdf')
39
+ Binary.from_mongo(buffer).to_s.should == buffer.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
+
377
+ context "BSON::ObjectID.to_json" do
378
+
379
+ end
380
+ end
@@ -0,0 +1,185 @@
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 a set with :typecast option" do
105
+ setup { @key = Key.new(:user_ids, Set, :typecast => 'ObjectId') }
106
+ subject { @key }
107
+
108
+ should "cast each element correctly" do
109
+ ids = [BSON::ObjectID.new, BSON::ObjectID.new, BSON::ObjectID.new.to_s, BSON::ObjectID.new.to_s]
110
+ subject.set(ids).should == ids.map { |id| ObjectId.to_mongo(id) }
111
+ end
112
+ end
113
+
114
+ context "setting a value with a custom type" do
115
+ should "correctly typecast" do
116
+ key = Key.new(:foo, FooType)
117
+ key.set("something").should == 'to_mongo'
118
+ end
119
+
120
+ should "correctly typecast if object of that type is given" do
121
+ key = Key.new(:foo, FooType)
122
+ key.set(FooType.new('something')).should == 'to_mongo'
123
+ end
124
+ end
125
+
126
+ context "getting a value with a custom type" do
127
+ should "use #from_mongo to convert back to custom type" do
128
+ key = Key.new(:foo, FooType)
129
+ key.get('something').should == 'from_mongo'
130
+ end
131
+ end
132
+
133
+ context "getting a value" do
134
+ should "work with a type" do
135
+ key = Key.new(:foo, String)
136
+ key.get('bar').should == 'bar'
137
+ end
138
+
139
+ should "work without type" do
140
+ key = Key.new(:foo)
141
+ key.get([1, '2']).should == [1, '2']
142
+ key.get(false).should == false
143
+ key.get({}).should == {}
144
+ end
145
+
146
+ context "for a embedded_document" do
147
+ should "default to nil" do
148
+ key = Key.new(:foo, Address)
149
+ key.get(nil).should be_nil
150
+ end
151
+
152
+ should "return instance if instance" do
153
+ address = Address.new(:city => 'South Bend', :state => 'IN', :zip => 46544)
154
+ key = Key.new(:foo, Address)
155
+ key.get(address).should == address
156
+ end
157
+ end
158
+ end
159
+
160
+ context "getting a value with a default set" do
161
+ setup do
162
+ @key = Key.new(:foo, String, :default => 'baz')
163
+ end
164
+
165
+ should "return default value if value nil" do
166
+ @key.get(nil).should == 'baz'
167
+ end
168
+
169
+ should "return value if not blank" do
170
+ @key.get('foobar').should == 'foobar'
171
+ end
172
+
173
+ should "work with Boolean type and false value" do
174
+ Key.new(:active, Boolean, :default => false).get(nil).should be_false
175
+ end
176
+
177
+ should "work with Boolean type and true value" do
178
+ Key.new(:active, Boolean, :default => true).get(nil).should be_true
179
+ end
180
+
181
+ should "work with procs" do
182
+ Key.new(:foo, String, :default => lambda { return 'hello world' }).get(nil).should == "hello world"
183
+ end
184
+ end
185
+ end # KeyTest