mongo_mapper-unstable 2010.1.6 → 2010.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/VERSION +1 -1
  2. data/lib/mongo_mapper/descendant_appends.rb +44 -0
  3. data/lib/mongo_mapper/document.rb +54 -98
  4. data/lib/mongo_mapper/embedded_document.rb +28 -348
  5. data/lib/mongo_mapper/finder_options.rb +15 -33
  6. data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
  7. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +28 -0
  8. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +23 -0
  9. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  10. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +49 -0
  11. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
  12. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  13. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
  14. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  15. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  16. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  17. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +66 -0
  18. data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
  19. data/lib/mongo_mapper/plugins/associations.rb +104 -0
  20. data/lib/mongo_mapper/plugins/callbacks.rb +65 -0
  21. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  22. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  23. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  24. data/lib/mongo_mapper/plugins/equality.rb +11 -0
  25. data/lib/mongo_mapper/plugins/identity_map.rb +66 -0
  26. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  27. data/lib/mongo_mapper/plugins/keys.rb +295 -0
  28. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  29. data/lib/mongo_mapper/plugins/pagination.rb +85 -0
  30. data/lib/mongo_mapper/plugins/rails.rb +45 -0
  31. data/lib/mongo_mapper/plugins/serialization.rb +109 -0
  32. data/lib/mongo_mapper/plugins/validations.rb +48 -0
  33. data/lib/mongo_mapper/plugins.rb +19 -0
  34. data/lib/mongo_mapper/support.rb +36 -15
  35. data/lib/mongo_mapper.rb +23 -22
  36. data/performance/read_write.rb +52 -0
  37. data/specs.watchr +23 -2
  38. data/test/functional/associations/test_belongs_to_proxy.rb +1 -1
  39. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +58 -39
  40. data/test/functional/associations/test_many_embedded_proxy.rb +103 -69
  41. data/test/functional/test_dirty.rb +1 -1
  42. data/test/functional/test_document.rb +25 -25
  43. data/test/functional/test_embedded_document.rb +66 -63
  44. data/test/functional/test_identity_map.rb +233 -0
  45. data/test/functional/test_modifiers.rb +14 -0
  46. data/test/functional/test_string_id_compatibility.rb +4 -4
  47. data/test/functional/test_validations.rb +13 -0
  48. data/test/models.rb +0 -39
  49. data/test/test_helper.rb +8 -2
  50. data/test/unit/associations/test_base.rb +1 -1
  51. data/test/unit/associations/test_proxy.rb +3 -3
  52. data/test/unit/test_descendant_appends.rb +71 -0
  53. data/test/unit/test_document.rb +35 -46
  54. data/test/unit/test_embedded_document.rb +218 -271
  55. data/test/unit/{test_key.rb → test_keys.rb} +0 -0
  56. data/test/unit/test_pagination.rb +10 -2
  57. data/test/unit/test_plugins.rb +42 -0
  58. data/test/unit/test_rails.rb +123 -0
  59. data/test/unit/{test_serializations.rb → test_serialization.rb} +0 -0
  60. data/test/unit/test_support.rb +10 -6
  61. data/test/unit/test_time_zones.rb +2 -2
  62. metadata +44 -31
  63. data/lib/mongo_mapper/associations/base.rb +0 -119
  64. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +0 -26
  65. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +0 -21
  66. data/lib/mongo_mapper/associations/collection.rb +0 -19
  67. data/lib/mongo_mapper/associations/in_array_proxy.rb +0 -137
  68. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +0 -26
  69. data/lib/mongo_mapper/associations/many_documents_proxy.rb +0 -115
  70. data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +0 -31
  71. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +0 -54
  72. data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +0 -11
  73. data/lib/mongo_mapper/associations/one_proxy.rb +0 -64
  74. data/lib/mongo_mapper/associations/proxy.rb +0 -116
  75. data/lib/mongo_mapper/associations.rb +0 -78
  76. data/lib/mongo_mapper/callbacks.rb +0 -61
  77. data/lib/mongo_mapper/dirty.rb +0 -117
  78. data/lib/mongo_mapper/key.rb +0 -36
  79. data/lib/mongo_mapper/mongo_mapper.rb +0 -125
  80. data/lib/mongo_mapper/pagination.rb +0 -66
  81. data/lib/mongo_mapper/rails_compatibility/document.rb +0 -15
  82. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +0 -28
  83. data/lib/mongo_mapper/serialization.rb +0 -54
  84. data/lib/mongo_mapper/serializers/json_serializer.rb +0 -48
  85. data/lib/mongo_mapper/validations.rb +0 -39
  86. data/test/functional/test_rails_compatibility.rb +0 -25
@@ -17,7 +17,7 @@ end
17
17
 
18
18
  module KeyOverride
19
19
  def other_child
20
- read_attribute(:other_child) || "special result"
20
+ self[:other_child] || "special result"
21
21
  end
22
22
 
23
23
  def other_child=(value)
@@ -32,17 +32,12 @@ class OtherChild < Parent
32
32
  key :other_child, String
33
33
  end
34
34
 
35
- class EmbeddedDocumentTest < Test::Unit::TestCase
35
+ class EmbeddedDocumentTest < Test::Unit::TestCase
36
36
  context "Including MongoMapper::EmbeddedDocument in a class" do
37
37
  setup do
38
38
  @klass = EDoc()
39
39
  end
40
40
 
41
- should "give class access to logger" do
42
- @klass.logger.should == MongoMapper.logger
43
- @klass.logger.should be_instance_of(Logger)
44
- end
45
-
46
41
  should "add _id key" do
47
42
  @klass.keys['_id'].should_not be_nil
48
43
  end
@@ -55,8 +50,22 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
55
50
  @klass.key :_id, String
56
51
  @klass.using_object_id?.should be_false
57
52
  end
53
+ end
54
+
55
+ context "Class Methods" do
56
+ should "include logger" do
57
+ @klass = EDoc()
58
+ @klass.logger.should == MongoMapper.logger
59
+ @klass.logger.should be_instance_of(Logger)
60
+ end
61
+
62
+ should "return false for embeddable" do
63
+ EDoc().embeddable?.should be_true
64
+ end
58
65
 
59
66
  context "#to_mongo" do
67
+ setup { @klass = EDoc() }
68
+
60
69
  should "be nil if nil" do
61
70
  @klass.to_mongo(nil).should be_nil
62
71
  end
@@ -70,6 +79,8 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
70
79
  end
71
80
 
72
81
  context "#from_mongo" do
82
+ setup { @klass = EDoc() }
83
+
73
84
  should "be nil if nil" do
74
85
  @klass.from_mongo(nil).should be_nil
75
86
  end
@@ -85,195 +96,110 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
85
96
  doc.foo.should == 'bar'
86
97
  end
87
98
  end
88
- end
89
-
90
- context "parent_model" do
91
- should "be nil if none of parents ancestors include EmbeddedDocument" do
92
- parent = Class.new
93
- document = Class.new(parent) { include MongoMapper::EmbeddedDocument }
94
- document.parent_model.should be_nil
95
- end
96
99
 
97
- should "work when other modules have been included" do
98
- grandparent = Class.new
99
- parent = Class.new(grandparent) { include MongoMapper::EmbeddedDocument }
100
-
101
- example_module = Module.new
102
- document = Class.new(parent) do
103
- include MongoMapper::EmbeddedDocument
104
- include example_module
100
+ context "defining a key" do
101
+ setup do
102
+ @document = EDoc()
105
103
  end
106
-
107
- document.parent_model.should == parent
108
- end
109
-
110
- should "find parent" do
111
- Parent.parent_model.should == Grandparent
112
- Child.parent_model.should == Parent
113
- end
114
- end
115
-
116
- context "defining a key" do
117
- setup do
118
- @document = EDoc()
119
- end
120
-
121
- should "work with name" do
122
- key = @document.key(:name)
123
- key.name.should == 'name'
124
- end
125
-
126
- should "work with name and type" do
127
- key = @document.key(:name, String)
128
- key.name.should == 'name'
129
- key.type.should == String
130
- end
131
-
132
- should "work with name, type and options" do
133
- key = @document.key(:name, String, :required => true)
134
- key.name.should == 'name'
135
- key.type.should == String
136
- key.options[:required].should be_true
137
- end
138
-
139
- should "work with name and options" do
140
- key = @document.key(:name, :required => true)
141
- key.name.should == 'name'
142
- key.options[:required].should be_true
143
- end
144
-
145
- should "be tracked per document" do
146
- @document.key(:name, String)
147
- @document.key(:age, Integer)
148
- @document.keys['name'].name.should == 'name'
149
- @document.keys['name'].type.should == String
150
- @document.keys['age'].name.should == 'age'
151
- @document.keys['age'].type.should == Integer
152
- end
153
-
154
- should "be redefinable" do
155
- @document.key(:foo, String)
156
- @document.keys['foo'].type.should == String
157
- @document.key(:foo, Integer)
158
- @document.keys['foo'].type.should == Integer
159
- end
160
-
161
- should "create reader method" do
162
- @document.new.should_not respond_to(:foo)
163
- @document.key(:foo, String)
164
- @document.new.should respond_to(:foo)
165
- end
166
-
167
- should "create reader before typecast method" do
168
- @document.new.should_not respond_to(:foo_before_typecast)
169
- @document.key(:foo, String)
170
- @document.new.should respond_to(:foo_before_typecast)
171
- end
172
-
173
- should "create writer method" do
174
- @document.new.should_not respond_to(:foo=)
175
- @document.key(:foo, String)
176
- @document.new.should respond_to(:foo=)
177
- end
178
-
179
- should "create boolean method" do
180
- @document.new.should_not respond_to(:foo?)
181
- @document.key(:foo, String)
182
- @document.new.should respond_to(:foo?)
183
- end
184
- end
185
-
186
- context "keys" do
187
- should "be inherited" do
188
- Grandparent.keys.keys.sort.should == ['_id', 'grandparent']
189
- Parent.keys.keys.sort.should == ['_id', 'grandparent', 'parent']
190
- Child.keys.keys.sort.should == ['_id', 'child', 'grandparent', 'parent']
191
- end
192
-
193
- should "propogate to subclasses if key added after class definition" do
194
- Grandparent.key :_type, String
195
-
196
- Grandparent.keys.keys.sort.should == ['_id', '_type', 'grandparent']
197
- Parent.keys.keys.sort.should == ['_id', '_type', 'grandparent', 'parent']
198
- Child.keys.keys.sort.should == ['_id', '_type', 'child', 'grandparent', 'parent']
199
- end
200
104
 
201
- should "not add anonymous objects to the ancestor tree" do
202
- OtherChild.ancestors.any? { |a| a.name.blank? }.should be_false
203
- end
105
+ should "work with name" do
106
+ key = @document.key(:name)
107
+ key.name.should == 'name'
108
+ end
204
109
 
205
- should "not include descendant keys" do
206
- lambda { Parent.new.other_child }.should raise_error
207
- end
208
- end
110
+ should "work with name and type" do
111
+ key = @document.key(:name, String)
112
+ key.name.should == 'name'
113
+ key.type.should == String
114
+ end
209
115
 
210
- context "#inspect" do
211
- setup do
212
- @document = Doc do
213
- key :animals
116
+ should "work with name, type and options" do
117
+ key = @document.key(:name, String, :required => true)
118
+ key.name.should == 'name'
119
+ key.type.should == String
120
+ key.options[:required].should be_true
214
121
  end
215
- end
216
122
 
217
- should "call inspect on the document's attributes instead of to_s" do
218
- doc = @document.new
219
- doc.animals = %w(dog cat)
220
- doc.inspect.should include(%(animals: ["dog", "cat"]))
221
- end
222
- end
223
-
224
- context "subclasses" do
225
- should "default to nil" do
226
- Child.subclasses.should be_nil
227
- end
228
-
229
- should "be recorded" do
230
- Grandparent.subclasses.should == [Parent]
231
- Parent.subclasses.should == [Child, OtherChild]
232
- end
233
- end
234
-
235
- context "Applying default values for keys" do
236
- setup do
237
- @document = EDoc do
238
- key :name, String, :default => 'foo'
239
- key :age, Integer, :default => 20
240
- key :net_worth, Float, :default => 100.00
241
- key :active, Boolean, :default => true
242
- key :smart, Boolean, :default => false
243
- key :skills, Array, :default => [1]
244
- key :options, Hash, :default => {'foo' => 'bar'}
123
+ should "work with name and options" do
124
+ key = @document.key(:name, :required => true)
125
+ key.name.should == 'name'
126
+ key.options[:required].should be_true
127
+ end
128
+
129
+ should "be tracked per document" do
130
+ @document.key(:name, String)
131
+ @document.key(:age, Integer)
132
+ @document.keys['name'].name.should == 'name'
133
+ @document.keys['name'].type.should == String
134
+ @document.keys['age'].name.should == 'age'
135
+ @document.keys['age'].type.should == Integer
136
+ end
137
+
138
+ should "be redefinable" do
139
+ @document.key(:foo, String)
140
+ @document.keys['foo'].type.should == String
141
+ @document.key(:foo, Integer)
142
+ @document.keys['foo'].type.should == Integer
143
+ end
144
+
145
+ should "create reader method" do
146
+ @document.new.should_not respond_to(:foo)
147
+ @document.key(:foo, String)
148
+ @document.new.should respond_to(:foo)
149
+ end
150
+
151
+ should "create reader before typecast method" do
152
+ @document.new.should_not respond_to(:foo_before_typecast)
153
+ @document.key(:foo, String)
154
+ @document.new.should respond_to(:foo_before_typecast)
155
+ end
156
+
157
+ should "create writer method" do
158
+ @document.new.should_not respond_to(:foo=)
159
+ @document.key(:foo, String)
160
+ @document.new.should respond_to(:foo=)
161
+ end
162
+
163
+ should "create boolean method" do
164
+ @document.new.should_not respond_to(:foo?)
165
+ @document.key(:foo, String)
166
+ @document.new.should respond_to(:foo?)
245
167
  end
246
-
247
- @doc = @document.new
248
- end
249
-
250
- should "work for strings" do
251
- @doc.name.should == 'foo'
252
- end
253
-
254
- should "work for integers" do
255
- @doc.age.should == 20
256
- end
257
-
258
- should "work for floats" do
259
- @doc.net_worth.should == 100.00
260
- end
261
-
262
- should "work for booleans" do
263
- @doc.active.should == true
264
- @doc.smart.should == false
265
168
  end
266
169
 
267
- should "work for arrays" do
268
- @doc.skills.should == [1]
269
- @doc.skills << 2
270
- @doc.skills.should == [1, 2]
170
+ context "keys" do
171
+ should "be inherited" do
172
+ Grandparent.keys.keys.sort.should == ['_id', 'grandparent']
173
+ Parent.keys.keys.sort.should == ['_id', 'grandparent', 'parent']
174
+ Child.keys.keys.sort.should == ['_id', 'child', 'grandparent', 'parent']
175
+ end
176
+
177
+ should "propogate to descendants if key added after class definition" do
178
+ Grandparent.key :_type, String
179
+
180
+ Grandparent.keys.keys.sort.should == ['_id', '_type', 'grandparent']
181
+ Parent.keys.keys.sort.should == ['_id', '_type', 'grandparent', 'parent']
182
+ Child.keys.keys.sort.should == ['_id', '_type', 'child', 'grandparent', 'parent']
183
+ end
184
+
185
+ should "not add anonymous objects to the ancestor tree" do
186
+ OtherChild.ancestors.any? { |a| a.name.blank? }.should be_false
187
+ end
188
+
189
+ should "not include descendant keys" do
190
+ lambda { Parent.new.other_child }.should raise_error
191
+ end
271
192
  end
272
193
 
273
- should "work for hashes" do
274
- @doc.options['foo'].should == 'bar'
275
- @doc.options['baz'] = 'wick'
276
- @doc.options['baz'].should == 'wick'
194
+ context "descendants" do
195
+ should "default to nil" do
196
+ Child.descendants.should be_nil
197
+ end
198
+
199
+ should "be recorded" do
200
+ Grandparent.descendants.should == [Parent]
201
+ Parent.descendants.should == [Child, OtherChild]
202
+ end
277
203
  end
278
204
  end
279
205
 
@@ -301,47 +227,47 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
301
227
  @document.keys.keys.should include('_id')
302
228
  end
303
229
 
230
+ should "create id during initialization" do
231
+ @document.new._id.should be_instance_of(Mongo::ObjectID)
232
+ end
233
+
304
234
  should "have id method returns _id" do
305
235
  id = Mongo::ObjectID.new
306
236
  doc = @document.new(:_id => id)
307
237
  doc.id.should == id
308
238
  end
309
239
 
310
- context "assigning id with _id ObjectId type" do
311
- should "not set custom id flag" do
312
- doc = @document.new
313
- doc.using_custom_id?.should be_false
314
- doc.id = Mongo::ObjectID.new
315
- doc.using_custom_id?.should be_false
316
- end
240
+ should "convert string object id to mongo object id when assigning id with _id object id type" do
241
+ id = Mongo::ObjectID.new
317
242
 
318
- should "convert string object id to mongo object id" do
319
- id = Mongo::ObjectID.new
320
- doc = @document.new(:id => id.to_s)
321
- doc._id.should == id
322
- doc.id.should == id
323
- doc.using_custom_id?.should be_false
324
- end
243
+ doc = @document.new(:id => id.to_s)
244
+ doc._id.should == id
245
+ doc.id.should == id
246
+
247
+ doc = @document.new(:_id => id.to_s)
248
+ doc._id.should == id
249
+ doc.id.should == id
325
250
  end
326
251
 
327
- context "setting custom id" do
328
- should "set _id" do
329
- @document.key :_id, String
330
- doc = @document.new(:id => '1234')
331
- doc._id.should == '1234'
252
+ context "_root_document" do
253
+ should "default to nil" do
254
+ @document.new._root_document.should be_nil
332
255
  end
333
-
334
- should "know that custom id is set" do
335
- @document.key :_id, String
336
- doc = @document.new
337
- doc.using_custom_id?.should be_false
338
- doc.id = '1234'
339
- doc.using_custom_id?.should be_true
256
+
257
+ should "allow setting when initialized" do
258
+ root = Doc().new
259
+ doc = @document.new :_root_document => root
260
+
261
+ doc._root_document.should be(root)
340
262
  end
341
- end
342
263
 
343
- should "have a nil _root_document" do
344
- @document.new._root_document.should be_nil
264
+ should "also be set on many embedded documents" do
265
+ root = Doc().new
266
+ klass = EDoc { many :children }
267
+ doc = klass.new(:_root_document => root, :children => [{}])
268
+
269
+ doc.children.first._root_document.should == root
270
+ end
345
271
  end
346
272
 
347
273
  context "being initialized" do
@@ -358,43 +284,26 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
358
284
  doc.skills.should == ['ruby', 'rails']
359
285
  end
360
286
 
361
- should "set the root on embedded documents" do
362
- document = Class.new(@document) do
363
- many :children
364
- end
365
-
366
- doc = document.new :_root_document => 'document', 'children' => [{}]
367
- doc.children.first._root_document.should == 'document'
368
- end
369
-
370
287
  should "not throw error if initialized with nil" do
371
- lambda {
372
- @document.new(nil)
373
- }.should_not raise_error
288
+ assert_nothing_raised { @document.new(nil) }
374
289
  end
375
290
  end
376
291
 
377
292
  context "initialized when _type key present" do
378
293
  setup do
379
- ::FooBar = EDoc do
380
- key :_type, String
381
- end
382
- end
383
-
384
- teardown do
385
- Object.send(:remove_const, :FooBar)
294
+ @klass = EDoc('FooBar') { key :_type, String }
386
295
  end
387
296
 
388
297
  should "set _type to class name" do
389
- FooBar.new._type.should == 'FooBar'
298
+ @klass.new._type.should == 'FooBar'
390
299
  end
391
300
 
392
301
  should "not change _type if already set" do
393
- FooBar.new(:_type => 'Foo')._type.should == 'Foo'
302
+ @klass.new(:_type => 'Foo')._type.should == 'Foo'
394
303
  end
395
304
  end
396
305
 
397
- context "mass assigning keys" do
306
+ context "attributes=" do
398
307
  should "update values for keys provided" do
399
308
  doc = @document.new(:name => 'foobar', :age => 10)
400
309
  doc.attributes = {:name => 'new value', :age => 5}
@@ -409,7 +318,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
409
318
  doc.attributes[:age].should == 10
410
319
  end
411
320
 
412
- should "not ignore keys that have methods defined" do
321
+ should "work with pre-defined methods" do
413
322
  @document.class_eval do
414
323
  attr_writer :password
415
324
 
@@ -441,29 +350,27 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
441
350
  doc.attributes.values.should include('string')
442
351
  doc.attributes.values.should include(nil)
443
352
  end
353
+
354
+ should "have indifferent access" do
355
+ doc = @document.new(:name => 'string')
356
+ doc.attributes[:name].should == 'string'
357
+ doc.attributes['name'].should == 'string'
358
+ end
444
359
  end
445
360
 
446
361
  context "to_mongo" do
447
362
  should "default to hash with _id key" do
448
363
  doc = @document.new
449
- doc.to_mongo.keys.should == ['_id']
364
+ doc.to_mongo.keys.sort.should == ['_id', 'age', 'name']
450
365
  end
451
366
 
452
- should "return all keys with non nil values" do
367
+ should "return all keys" do
453
368
  doc = @document.new(:name => 'string', :age => nil)
454
- doc.to_mongo.keys.sort.should == ['_id', 'name']
369
+ doc.to_mongo.keys.sort.should == ['_id', 'age', 'name']
455
370
  doc.to_mongo.values.should include('string')
456
- doc.to_mongo.values.should_not include(nil)
371
+ doc.to_mongo.values.should include(nil)
457
372
  end
458
373
  end
459
-
460
- should "convert dates into times" do
461
- document = Class.new(@document) do
462
- key :start_date, Date
463
- end
464
- doc = document.new :start_date => "12/05/2009"
465
- doc.start_date.should == Date.new(2009, 12, 05)
466
- end
467
374
 
468
375
  context "clone" do
469
376
  should "regenerate the id" do
@@ -491,9 +398,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
491
398
 
492
399
  should "raise exception when key not found" do
493
400
  doc = @document.new(:name => 'string')
494
- lambda {
495
- doc[:not_here]
496
- }.should raise_error(MongoMapper::KeyNotFound)
401
+ assert_raises(MongoMapper::KeyNotFound) { doc[:not_here] }
497
402
  end
498
403
  end
499
404
 
@@ -507,27 +412,19 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
507
412
  should "create key and write value for missing key" do
508
413
  doc = @document.new
509
414
  doc[:foo] = 'string'
510
- doc.metaclass.keys.include?('foo').should be_true
415
+ doc.class.keys.include?('foo').should be_true
511
416
  doc[:foo].should == 'string'
512
417
  end
513
418
 
514
- should "not share the new key" do
419
+ should "share the new key with the class" do
515
420
  doc = @document.new
516
421
  doc[:foo] = 'string'
517
- @document.keys.should_not include('foo')
422
+ @document.keys.should include('foo')
518
423
  end
519
424
  end
520
425
  end
521
-
522
- context "indifferent access" do
523
- should "be enabled for keys" do
524
- doc = @document.new(:name => 'string')
525
- doc.attributes[:name].should == 'string'
526
- doc.attributes['name'].should == 'string'
527
- end
528
- end
529
426
 
530
- context "reading an attribute" do
427
+ context "reading a key" do
531
428
  should "work for defined keys" do
532
429
  doc = @document.new(:name => 'string')
533
430
  doc.name.should == 'string'
@@ -541,7 +438,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
541
438
  should "be accessible for use in the model" do
542
439
  @document.class_eval do
543
440
  def name_and_age
544
- "#{read_attribute(:name)} (#{read_attribute(:age)})"
441
+ "#{self[:name]} (#{self[:age]})"
545
442
  end
546
443
  end
547
444
 
@@ -572,7 +469,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
572
469
  end
573
470
  end
574
471
 
575
- context "reading an attribute before typcasting" do
472
+ context "reading a key before typcasting" do
576
473
  should "work for defined keys" do
577
474
  doc = @document.new(:name => 12)
578
475
  doc.name_before_typecast.should == 12
@@ -586,7 +483,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
586
483
  should "be accessible for use in a document" do
587
484
  @document.class_eval do
588
485
  def untypcasted_name
589
- read_attribute_before_typecast(:name)
486
+ read_key_before_typecast(:name)
590
487
  end
591
488
  end
592
489
 
@@ -596,7 +493,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
596
493
  end
597
494
  end
598
495
 
599
- context "writing an attribute" do
496
+ context "writing a key" do
600
497
  should "work for defined keys" do
601
498
  doc = @document.new
602
499
  doc.name = 'John'
@@ -620,8 +517,8 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
620
517
  @document.class_eval do
621
518
  def name_and_age=(new_value)
622
519
  new_value.match(/([^\(\s]+) \((.*)\)/)
623
- write_attribute :name, $1
624
- write_attribute :age, $2
520
+ write_key :name, $1
521
+ write_key :age, $2
625
522
  end
626
523
  end
627
524
 
@@ -644,9 +541,9 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
644
541
  overriden_child = @document.new(:other_child => 'foo')
645
542
  overriden_child.other_child.should == 'foo modified'
646
543
  end
647
- end # writing an attribute
544
+ end # writing a key
648
545
 
649
- context "checking if an attributes value is present" do
546
+ context "checking if a keys value is present" do
650
547
  should "work for defined keys" do
651
548
  doc = @document.new
652
549
  doc.name?.should be_false
@@ -660,6 +557,11 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
660
557
  end
661
558
  end
662
559
 
560
+ should "call inspect on the document's attributes instead of to_s when inspecting the document" do
561
+ doc = @document.new(:animals => %w(dog cat))
562
+ doc.inspect.should include(%(animals: ["dog", "cat"]))
563
+ end
564
+
663
565
  context "equality" do
664
566
  setup do
665
567
  @oid = Mongo::ObjectID.new
@@ -677,5 +579,50 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
677
579
  (@document.new('_id' => @oid) == another_document.new('_id' => @oid)).should be_false
678
580
  end
679
581
  end
582
+
583
+ context "reading keys with default values" do
584
+ setup do
585
+ @document = EDoc do
586
+ key :name, String, :default => 'foo'
587
+ key :age, Integer, :default => 20
588
+ key :net_worth, Float, :default => 100.00
589
+ key :active, Boolean, :default => true
590
+ key :smart, Boolean, :default => false
591
+ key :skills, Array, :default => [1]
592
+ key :options, Hash, :default => {'foo' => 'bar'}
593
+ end
594
+
595
+ @doc = @document.new
596
+ end
597
+
598
+ should "work for strings" do
599
+ @doc.name.should == 'foo'
600
+ end
601
+
602
+ should "work for integers" do
603
+ @doc.age.should == 20
604
+ end
605
+
606
+ should "work for floats" do
607
+ @doc.net_worth.should == 100.00
608
+ end
609
+
610
+ should "work for booleans" do
611
+ @doc.active.should == true
612
+ @doc.smart.should == false
613
+ end
614
+
615
+ should "work for arrays" do
616
+ @doc.skills.should == [1]
617
+ @doc.skills << 2
618
+ @doc.skills.should == [1, 2]
619
+ end
620
+
621
+ should "work for hashes" do
622
+ @doc.options['foo'].should == 'bar'
623
+ @doc.options['baz'] = 'wick'
624
+ @doc.options['baz'].should == 'wick'
625
+ end
626
+ end
680
627
  end # instance of a embedded document
681
628
  end
File without changes