pwnash-mongo_mapper 0.7.5 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/lib/mongo_mapper.rb +6 -8
  2. data/lib/mongo_mapper/document.rb +6 -281
  3. data/lib/mongo_mapper/embedded_document.rb +5 -45
  4. data/lib/mongo_mapper/extensions.rb +190 -0
  5. data/lib/mongo_mapper/plugins.rb +27 -18
  6. data/lib/mongo_mapper/plugins/associations.rb +7 -6
  7. data/lib/mongo_mapper/plugins/associations/base.rb +1 -0
  8. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +1 -0
  9. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +1 -0
  10. data/lib/mongo_mapper/plugins/associations/collection.rb +1 -0
  11. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +1 -0
  12. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +2 -1
  13. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +1 -0
  14. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +4 -4
  15. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +1 -0
  16. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +1 -0
  17. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +1 -0
  18. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +1 -0
  19. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +1 -0
  20. data/lib/mongo_mapper/plugins/associations/proxy.rb +1 -0
  21. data/lib/mongo_mapper/plugins/callbacks.rb +4 -3
  22. data/lib/mongo_mapper/plugins/clone.rb +1 -0
  23. data/lib/mongo_mapper/plugins/descendants.rb +1 -0
  24. data/lib/mongo_mapper/plugins/dirty.rb +1 -0
  25. data/lib/mongo_mapper/plugins/document.rb +40 -0
  26. data/lib/mongo_mapper/plugins/dynamic_querying.rb +42 -0
  27. data/lib/mongo_mapper/{support/find.rb → plugins/dynamic_querying/dynamic_finder.rb} +2 -36
  28. data/lib/mongo_mapper/plugins/embedded_document.rb +48 -0
  29. data/lib/mongo_mapper/plugins/equality.rb +1 -0
  30. data/lib/mongo_mapper/plugins/identity_map.rb +8 -11
  31. data/lib/mongo_mapper/plugins/indexes.rb +11 -0
  32. data/lib/mongo_mapper/plugins/inspect.rb +1 -0
  33. data/lib/mongo_mapper/plugins/keys.rb +7 -9
  34. data/lib/mongo_mapper/plugins/keys/key.rb +12 -2
  35. data/lib/mongo_mapper/plugins/logger.rb +1 -0
  36. data/lib/mongo_mapper/plugins/modifiers.rb +3 -2
  37. data/lib/mongo_mapper/plugins/pagination.rb +1 -0
  38. data/lib/mongo_mapper/plugins/pagination/proxy.rb +1 -0
  39. data/lib/mongo_mapper/plugins/persistence.rb +1 -0
  40. data/lib/mongo_mapper/plugins/protected.rb +1 -0
  41. data/lib/mongo_mapper/plugins/query_logger.rb +5 -10
  42. data/lib/mongo_mapper/plugins/querying.rb +236 -0
  43. data/lib/mongo_mapper/plugins/rails.rb +1 -0
  44. data/lib/mongo_mapper/plugins/sci.rb +31 -0
  45. data/lib/mongo_mapper/plugins/serialization.rb +1 -0
  46. data/lib/mongo_mapper/plugins/timestamps.rb +1 -0
  47. data/lib/mongo_mapper/plugins/userstamps.rb +1 -0
  48. data/lib/mongo_mapper/plugins/validations.rb +5 -1
  49. data/lib/mongo_mapper/query.rb +53 -120
  50. data/lib/mongo_mapper/support.rb +2 -213
  51. data/lib/mongo_mapper/support/descendant_appends.rb +3 -6
  52. data/lib/mongo_mapper/version.rb +2 -1
  53. metadata +156 -190
  54. data/.gitignore +0 -10
  55. data/Rakefile +0 -37
  56. data/mongo_mapper.gemspec +0 -216
  57. data/performance/read_write.rb +0 -52
  58. data/specs.watchr +0 -51
  59. data/test/NOTE_ON_TESTING +0 -1
  60. data/test/active_model_lint_test.rb +0 -13
  61. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +0 -63
  62. data/test/functional/associations/test_belongs_to_proxy.rb +0 -101
  63. data/test/functional/associations/test_in_array_proxy.rb +0 -325
  64. data/test/functional/associations/test_many_documents_as_proxy.rb +0 -229
  65. data/test/functional/associations/test_many_documents_proxy.rb +0 -536
  66. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +0 -176
  67. data/test/functional/associations/test_many_embedded_proxy.rb +0 -256
  68. data/test/functional/associations/test_many_polymorphic_proxy.rb +0 -302
  69. data/test/functional/associations/test_one_embedded_proxy.rb +0 -68
  70. data/test/functional/associations/test_one_proxy.rb +0 -196
  71. data/test/functional/test_associations.rb +0 -44
  72. data/test/functional/test_binary.rb +0 -27
  73. data/test/functional/test_callbacks.rb +0 -151
  74. data/test/functional/test_dirty.rb +0 -163
  75. data/test/functional/test_document.rb +0 -1219
  76. data/test/functional/test_embedded_document.rb +0 -210
  77. data/test/functional/test_identity_map.rb +0 -507
  78. data/test/functional/test_indexing.rb +0 -44
  79. data/test/functional/test_logger.rb +0 -20
  80. data/test/functional/test_modifiers.rb +0 -416
  81. data/test/functional/test_pagination.rb +0 -93
  82. data/test/functional/test_protected.rb +0 -163
  83. data/test/functional/test_string_id_compatibility.rb +0 -67
  84. data/test/functional/test_timestamps.rb +0 -64
  85. data/test/functional/test_userstamps.rb +0 -28
  86. data/test/functional/test_validations.rb +0 -342
  87. data/test/models.rb +0 -227
  88. data/test/support/custom_matchers.rb +0 -37
  89. data/test/support/timing.rb +0 -16
  90. data/test/test_helper.rb +0 -64
  91. data/test/unit/associations/test_base.rb +0 -212
  92. data/test/unit/associations/test_proxy.rb +0 -105
  93. data/test/unit/serializers/test_json_serializer.rb +0 -202
  94. data/test/unit/test_descendant_appends.rb +0 -71
  95. data/test/unit/test_document.rb +0 -225
  96. data/test/unit/test_dynamic_finder.rb +0 -123
  97. data/test/unit/test_embedded_document.rb +0 -657
  98. data/test/unit/test_keys.rb +0 -216
  99. data/test/unit/test_mongo_mapper.rb +0 -118
  100. data/test/unit/test_pagination.rb +0 -160
  101. data/test/unit/test_plugins.rb +0 -50
  102. data/test/unit/test_query.rb +0 -374
  103. data/test/unit/test_rails.rb +0 -181
  104. data/test/unit/test_rails_compatibility.rb +0 -52
  105. data/test/unit/test_serialization.rb +0 -51
  106. data/test/unit/test_support.rb +0 -390
  107. data/test/unit/test_time_zones.rb +0 -39
  108. data/test/unit/test_validations.rb +0 -544
@@ -1,123 +0,0 @@
1
- require 'test_helper'
2
-
3
- class DynamicFinderTest < Test::Unit::TestCase
4
- should "initialize with method" do
5
- finder = MongoMapper::Support::Find::DynamicFinder.new(:foobar)
6
- finder.method.should == :foobar
7
- end
8
-
9
- context "found?" do
10
- should "be true for find_by" do
11
- MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo).found?.should be_true
12
- end
13
-
14
- should "be true for find_by with !" do
15
- MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo!).found?.should be_true
16
- end
17
-
18
- should "be true for find_all_by" do
19
- MongoMapper::Support::Find::DynamicFinder.new(:find_all_by_foo).found?.should be_true
20
- end
21
-
22
- should "be true for find_or_initialize_by" do
23
- MongoMapper::Support::Find::DynamicFinder.new(:find_or_initialize_by_foo).found?.should be_true
24
- end
25
-
26
- should "be true for find_or_create_by" do
27
- MongoMapper::Support::Find::DynamicFinder.new(:find_or_create_by_foo).found?.should be_true
28
- end
29
-
30
- should "be false for anything else" do
31
- [:foobar, :bazwick].each do |method|
32
- MongoMapper::Support::Find::DynamicFinder.new(method).found?.should be_false
33
- end
34
- end
35
- end
36
-
37
- context "find_all_by" do
38
- should "parse one attribute" do
39
- MongoMapper::Support::Find::DynamicFinder.new(:find_all_by_foo).attributes.should == %w(foo)
40
- end
41
-
42
- should "parse multiple attributes" do
43
- MongoMapper::Support::Find::DynamicFinder.new(:find_all_by_foo_and_bar).attributes.should == %w(foo bar)
44
- MongoMapper::Support::Find::DynamicFinder.new(:find_all_by_foo_and_bar_and_baz).attributes.should == %w(foo bar baz)
45
- end
46
-
47
- should "set finder to :all" do
48
- MongoMapper::Support::Find::DynamicFinder.new(:find_all_by_foo_and_bar).finder.should == :all
49
- end
50
- end
51
-
52
- context "find_by" do
53
- should "parse one attribute" do
54
- MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo).attributes.should == %w(foo)
55
- end
56
-
57
- should "parse multiple attributes" do
58
- MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo_and_bar).attributes.should == %w(foo bar)
59
- end
60
-
61
- should "set finder to :first" do
62
- MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo).finder.should == :first
63
- end
64
-
65
- should "set bang to false" do
66
- MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo).bang.should be_false
67
- end
68
- end
69
-
70
- context "find_by with !" do
71
- should "parse one attribute" do
72
- MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo!).attributes.should == %w(foo)
73
- end
74
-
75
- should "parse multiple attributes" do
76
- MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo_and_bar!).attributes.should == %w(foo bar)
77
- end
78
-
79
- should "set finder to :first" do
80
- MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo!).finder.should == :first
81
- end
82
-
83
- should "set bang to true" do
84
- MongoMapper::Support::Find::DynamicFinder.new(:find_by_foo!).bang.should be_true
85
- end
86
- end
87
-
88
- context "find_or_initialize_by" do
89
- should "parse one attribute" do
90
- MongoMapper::Support::Find::DynamicFinder.new(:find_or_initialize_by_foo).attributes.should == %w(foo)
91
- end
92
-
93
- should "parse multiple attributes" do
94
- MongoMapper::Support::Find::DynamicFinder.new(:find_or_initialize_by_foo_and_bar).attributes.should == %w(foo bar)
95
- end
96
-
97
- should "set finder to :first" do
98
- MongoMapper::Support::Find::DynamicFinder.new(:find_or_initialize_by_foo).finder.should == :first
99
- end
100
-
101
- should "set instantiator to new" do
102
- MongoMapper::Support::Find::DynamicFinder.new(:find_or_initialize_by_foo).instantiator.should == :new
103
- end
104
- end
105
-
106
- context "find_or_create_by" do
107
- should "parse one attribute" do
108
- MongoMapper::Support::Find::DynamicFinder.new(:find_or_create_by_foo).attributes.should == %w(foo)
109
- end
110
-
111
- should "parse multiple attributes" do
112
- MongoMapper::Support::Find::DynamicFinder.new(:find_or_create_by_foo_and_bar).attributes.should == %w(foo bar)
113
- end
114
-
115
- should "set finder to :first" do
116
- MongoMapper::Support::Find::DynamicFinder.new(:find_or_create_by_foo).finder.should == :first
117
- end
118
-
119
- should "set instantiator to new" do
120
- MongoMapper::Support::Find::DynamicFinder.new(:find_or_create_by_foo).instantiator.should == :create
121
- end
122
- end
123
- end
@@ -1,657 +0,0 @@
1
- require 'test_helper'
2
-
3
- module KeyOverride
4
- def other_child
5
- self[:other_child] || "special result"
6
- end
7
-
8
- def other_child=(value)
9
- super(value + " modified")
10
- end
11
- end
12
-
13
- class EmbeddedDocumentTest < Test::Unit::TestCase
14
- context "EmbeddedDocuments" do
15
- setup do
16
- class ::Grandparent
17
- include MongoMapper::EmbeddedDocument
18
- key :grandparent, String
19
- end
20
-
21
- class ::Parent < ::Grandparent
22
- include MongoMapper::EmbeddedDocument
23
- key :parent, String
24
- end
25
-
26
- class ::Child < ::Parent
27
- include MongoMapper::EmbeddedDocument
28
- key :child, String
29
- end
30
-
31
- class ::OtherChild < ::Parent
32
- include MongoMapper::EmbeddedDocument
33
- include KeyOverride
34
-
35
- key :other_child, String
36
- end
37
- end
38
-
39
- teardown do
40
- Object.send :remove_const, 'Grandparent' if defined?(::Grandparent)
41
- Object.send :remove_const, 'Parent' if defined?(::Parent)
42
- Object.send :remove_const, 'Child' if defined?(::Child)
43
- Object.send :remove_const, 'OtherChild' if defined?(::OtherChild)
44
- end
45
-
46
- context "Including MongoMapper::EmbeddedDocument in a class" do
47
- setup do
48
- @klass = EDoc()
49
- end
50
-
51
- should "add _id key" do
52
- @klass.keys['_id'].should_not be_nil
53
- end
54
-
55
- should "know it is using object id" do
56
- @klass.using_object_id?.should be_true
57
- end
58
-
59
- should "know it is not using object id if _id type is changed" do
60
- @klass.key :_id, String
61
- @klass.using_object_id?.should be_false
62
- end
63
- end
64
-
65
- context "Class Methods" do
66
- should "include logger" do
67
- @klass = EDoc()
68
- @klass.logger.should == MongoMapper.logger
69
- @klass.logger.should be_instance_of(Logger)
70
- end
71
-
72
- should "return false for embeddable" do
73
- EDoc().embeddable?.should be_true
74
- end
75
-
76
- context "#to_mongo" do
77
- setup { @klass = EDoc() }
78
-
79
- should "be nil if nil" do
80
- @klass.to_mongo(nil).should be_nil
81
- end
82
-
83
- should "convert to_mongo for other values" do
84
- doc = @klass.new(:foo => 'bar')
85
- to_mongo = @klass.to_mongo(doc)
86
- to_mongo.is_a?(Hash).should be_true
87
- to_mongo['foo'].should == 'bar'
88
- end
89
- end
90
-
91
- context "#from_mongo" do
92
- setup { @klass = EDoc() }
93
-
94
- should "be nil if nil" do
95
- @klass.from_mongo(nil).should be_nil
96
- end
97
-
98
- should "be instance if instance of class" do
99
- doc = @klass.new
100
- @klass.from_mongo(doc).should == doc
101
- end
102
-
103
- should "be instance if hash of attributes" do
104
- doc = @klass.from_mongo({:foo => 'bar'})
105
- doc.instance_of?(@klass).should be_true
106
- doc.foo.should == 'bar'
107
- end
108
- end
109
-
110
- context "defining a key" do
111
- setup do
112
- @document = EDoc()
113
- end
114
-
115
- should "work with name" do
116
- key = @document.key(:name)
117
- key.name.should == 'name'
118
- end
119
-
120
- should "work with name and type" do
121
- key = @document.key(:name, String)
122
- key.name.should == 'name'
123
- key.type.should == String
124
- end
125
-
126
- should "work with name, type and options" do
127
- key = @document.key(:name, String, :required => true)
128
- key.name.should == 'name'
129
- key.type.should == String
130
- key.options[:required].should be_true
131
- end
132
-
133
- should "work with name and options" do
134
- key = @document.key(:name, :required => true)
135
- key.name.should == 'name'
136
- key.options[:required].should be_true
137
- end
138
-
139
- should "be tracked per document" do
140
- @document.key(:name, String)
141
- @document.key(:age, Integer)
142
- @document.keys['name'].name.should == 'name'
143
- @document.keys['name'].type.should == String
144
- @document.keys['age'].name.should == 'age'
145
- @document.keys['age'].type.should == Integer
146
- end
147
-
148
- should "be redefinable" do
149
- @document.key(:foo, String)
150
- @document.keys['foo'].type.should == String
151
- @document.key(:foo, Integer)
152
- @document.keys['foo'].type.should == Integer
153
- end
154
-
155
- should "create reader method" do
156
- @document.new.should_not respond_to(:foo)
157
- @document.key(:foo, String)
158
- @document.new.should respond_to(:foo)
159
- end
160
-
161
- should "create reader before typecast method" do
162
- @document.new.should_not respond_to(:foo_before_typecast)
163
- @document.key(:foo, String)
164
- @document.new.should respond_to(:foo_before_typecast)
165
- end
166
-
167
- should "create writer method" do
168
- @document.new.should_not respond_to(:foo=)
169
- @document.key(:foo, String)
170
- @document.new.should respond_to(:foo=)
171
- end
172
-
173
- should "create boolean 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
- end
179
-
180
- context "keys" do
181
- should "be inherited" do
182
- Grandparent.keys.keys.sort.should == ['_id', '_type', 'grandparent']
183
- Parent.keys.keys.sort.should == ['_id', '_type', 'grandparent', 'parent']
184
- Child.keys.keys.sort.should == ['_id', '_type', 'child', 'grandparent', 'parent']
185
- end
186
-
187
- should "propogate to descendants if key added after class definition" do
188
- Grandparent.key :foo, String
189
-
190
- Grandparent.keys.keys.sort.should == ['_id', '_type', 'foo', 'grandparent']
191
- Parent.keys.keys.sort.should == ['_id', '_type', 'foo', 'grandparent', 'parent']
192
- Child.keys.keys.sort.should == ['_id', '_type', 'child', 'foo', 'grandparent', 'parent']
193
- end
194
-
195
- should "not add anonymous objects to the ancestor tree" do
196
- OtherChild.ancestors.any? { |a| a.name.blank? }.should be_false
197
- end
198
-
199
- should "not include descendant keys" do
200
- lambda { Parent.new.other_child }.should raise_error
201
- end
202
- end
203
-
204
- context "descendants" do
205
- should "default to an empty array" do
206
- Child.descendants.should == []
207
- end
208
-
209
- should "be recorded" do
210
- Grandparent.descendants.should == [Parent]
211
- Parent.descendants.should == [Child, OtherChild]
212
- end
213
- end
214
- end
215
-
216
- context "An instance of an embedded document" do
217
- setup do
218
- @document = EDoc do
219
- key :name, String
220
- key :age, Integer
221
- end
222
- end
223
-
224
- should "have access to class logger" do
225
- doc = @document.new
226
- doc.logger.should == @document.logger
227
- doc.logger.should be_instance_of(Logger)
228
- end
229
-
230
- should "automatically have an _id key" do
231
- @document.keys.keys.should include('_id')
232
- end
233
-
234
- should "create id during initialization" do
235
- @document.new._id.should be_instance_of(BSON::ObjectID)
236
- end
237
-
238
- should "have id method returns _id" do
239
- id = BSON::ObjectID.new
240
- doc = @document.new(:_id => id)
241
- doc.id.should == id
242
- end
243
-
244
- should "convert string object id to mongo object id when assigning id with _id object id type" do
245
- id = BSON::ObjectID.new
246
- doc = @document.new(:id => id.to_s)
247
- doc._id.should == id
248
- doc.id.should == id
249
- doc = @document.new(:_id => id.to_s)
250
- doc._id.should == id
251
- doc.id.should == id
252
- end
253
-
254
- context "_parent_document" do
255
- should "default to nil" do
256
- @document.new._parent_document.should be_nil
257
- @document.new._root_document.should be_nil
258
- end
259
-
260
- should "set _root_document when setting _parent_document" do
261
- root = Doc().new
262
- doc = @document.new(:_parent_document => root)
263
- doc._parent_document.should be(root)
264
- doc._root_document.should be(root)
265
- end
266
-
267
- should "set _root_document when setting _parent_document on embedded many" do
268
- root = Doc().new
269
- klass = EDoc { many :children }
270
- parent = klass.new(:_parent_document => root, :children => [{}])
271
- child = parent.children.first
272
- child._parent_document.should be(parent)
273
- child._root_document.should be(root)
274
- end
275
- end
276
-
277
- context "being initialized" do
278
- should "accept a hash that sets keys and values" do
279
- doc = @document.new(:name => 'John', :age => 23)
280
- doc.attributes.keys.sort.should == ['_id', 'age', 'name']
281
- doc.attributes['name'].should == 'John'
282
- doc.attributes['age'].should == 23
283
- end
284
-
285
- should "be able to assign keys dynamically" do
286
- doc = @document.new(:name => 'John', :skills => ['ruby', 'rails'])
287
- doc.name.should == 'John'
288
- doc.skills.should == ['ruby', 'rails']
289
- end
290
-
291
- should "not throw error if initialized with nil" do
292
- assert_nothing_raised { @document.new(nil) }
293
- end
294
- end
295
-
296
- context "initialized when _type key present" do
297
- setup do
298
- @klass = EDoc('FooBar') { key :_type, String }
299
- end
300
-
301
- should "set _type to class name" do
302
- @klass.new._type.should == 'FooBar'
303
- end
304
-
305
- should "ignore _type attribute and always use class" do
306
- @klass.new(:_type => 'Foo')._type.should == 'FooBar'
307
- end
308
- end
309
-
310
- context "attributes=" do
311
- should "update values for keys provided" do
312
- doc = @document.new(:name => 'foobar', :age => 10)
313
- doc.attributes = {:name => 'new value', :age => 5}
314
- doc.attributes[:name].should == 'new value'
315
- doc.attributes[:age].should == 5
316
- end
317
-
318
- should "not update values for keys that were not provided" do
319
- doc = @document.new(:name => 'foobar', :age => 10)
320
- doc.attributes = {:name => 'new value'}
321
- doc.attributes[:name].should == 'new value'
322
- doc.attributes[:age].should == 10
323
- end
324
-
325
- should "work with pre-defined methods" do
326
- @document.class_eval do
327
- attr_writer :password
328
-
329
- def passwd
330
- @password
331
- end
332
- end
333
-
334
- doc = @document.new(:name => 'foobar', :password => 'secret')
335
- doc.passwd.should == 'secret'
336
- end
337
-
338
- should "typecast key values" do
339
- doc = @document.new(:name => 1234, :age => '21')
340
- doc.name.should == '1234'
341
- doc.age.should == 21
342
- end
343
- end
344
-
345
- context "attributes" do
346
- should "default to hash with all keys" do
347
- doc = @document.new
348
- doc.attributes.keys.sort.should == ['_id', 'age', 'name']
349
- end
350
-
351
- should "return all keys with values" do
352
- doc = @document.new(:name => 'string', :age => nil)
353
- doc.attributes.keys.sort.should == ['_id', 'age', 'name']
354
- doc.attributes.values.should include('string')
355
- doc.attributes.values.should include(nil)
356
- end
357
-
358
- should "have indifferent access" do
359
- doc = @document.new(:name => 'string')
360
- doc.attributes[:name].should == 'string'
361
- doc.attributes['name'].should == 'string'
362
- end
363
- end
364
-
365
- context "to_mongo" do
366
- should "default to hash with _id key" do
367
- doc = @document.new
368
- doc.to_mongo.keys.sort.should == ['_id', 'age', 'name']
369
- end
370
-
371
- should "return all keys" do
372
- doc = @document.new(:name => 'string', :age => nil)
373
- doc.to_mongo.keys.sort.should == ['_id', 'age', 'name']
374
- doc.to_mongo.values.should include('string')
375
- doc.to_mongo.values.should include(nil)
376
- end
377
- end
378
-
379
- context "clone" do
380
- should "regenerate the id" do
381
- doc = @document.new(:name => "foo", :age => 27)
382
- doc_id = doc.id
383
- clone = doc.clone
384
- clone_id = clone.id
385
- clone_id.should_not == doc_id
386
- end
387
-
388
- should "copy the attributes" do
389
- doc = @document.new(:name => "foo", :age => 27)
390
- clone = doc.clone
391
- clone.name.should == "foo"
392
- clone.age.should == 27
393
- end
394
- end
395
-
396
- context "key shorcut access" do
397
- context "[]" do
398
- should "work when key found" do
399
- doc = @document.new(:name => 'string')
400
- doc[:name].should == 'string'
401
- end
402
-
403
- should "raise exception when key not found" do
404
- doc = @document.new(:name => 'string')
405
- assert_raises(MongoMapper::KeyNotFound) { doc[:not_here] }
406
- end
407
- end
408
-
409
- context "[]=" do
410
- should "write key value for existing key" do
411
- doc = @document.new
412
- doc[:name] = 'string'
413
- doc[:name].should == 'string'
414
- end
415
-
416
- should "create key and write value for missing key" do
417
- doc = @document.new
418
- doc[:foo] = 'string'
419
- doc.class.keys.include?('foo').should be_true
420
- doc[:foo].should == 'string'
421
- end
422
-
423
- should "share the new key with the class" do
424
- doc = @document.new
425
- doc[:foo] = 'string'
426
- @document.keys.should include('foo')
427
- end
428
- end
429
- end
430
-
431
- context "reading a key" do
432
- should "work for defined keys" do
433
- doc = @document.new(:name => 'string')
434
- doc.name.should == 'string'
435
- end
436
-
437
- should "raise no method error for undefined keys" do
438
- doc = @document.new
439
- lambda { doc.fart }.should raise_error(NoMethodError)
440
- end
441
-
442
- should "be accessible for use in the model" do
443
- @document.class_eval do
444
- def name_and_age
445
- "#{self[:name]} (#{self[:age]})"
446
- end
447
- end
448
-
449
- doc = @document.new(:name => 'John', :age => 27)
450
- doc.name_and_age.should == 'John (27)'
451
- end
452
-
453
- should "set instance variable" do
454
- @document.key :foo, Array
455
- doc = @document.new
456
- doc.instance_variable_get("@foo").should be_nil
457
- doc.foo
458
- doc.instance_variable_get("@foo").should == []
459
- end
460
-
461
- should "be overrideable by modules" do
462
- @document = Doc do
463
- key :other_child, String
464
- end
465
-
466
- child = @document.new
467
- child.other_child.should be_nil
468
-
469
- @document.send :include, KeyOverride
470
-
471
- overriden_child = @document.new
472
- overriden_child.other_child.should == 'special result'
473
- end
474
- end
475
-
476
- context "reading a key before typcasting" do
477
- should "work for defined keys" do
478
- doc = @document.new(:name => 12)
479
- doc.name_before_typecast.should == 12
480
- end
481
-
482
- should "raise no method error for undefined keys" do
483
- doc = @document.new
484
- lambda { doc.foo_before_typecast }.should raise_error(NoMethodError)
485
- end
486
-
487
- should "be accessible for use in a document" do
488
- @document.class_eval do
489
- def untypcasted_name
490
- read_key_before_typecast(:name)
491
- end
492
- end
493
-
494
- doc = @document.new(:name => 12)
495
- doc.name.should == '12'
496
- doc.untypcasted_name.should == 12
497
- end
498
- end
499
-
500
- context "writing a key" do
501
- should "work for defined keys" do
502
- doc = @document.new
503
- doc.name = 'John'
504
- doc.name.should == 'John'
505
- end
506
-
507
- should "raise no method error for undefined keys" do
508
- doc = @document.new
509
- lambda { doc.fart = 'poof!' }.should raise_error(NoMethodError)
510
- end
511
-
512
- should "typecast value" do
513
- doc = @document.new
514
- doc.name = 1234
515
- doc.name.should == '1234'
516
- doc.age = '21'
517
- doc.age.should == 21
518
- end
519
-
520
- should "be accessible for use in the model" do
521
- @document.class_eval do
522
- def name_and_age=(new_value)
523
- new_value.match(/([^\(\s]+) \((.*)\)/)
524
- write_key :name, $1
525
- write_key :age, $2
526
- end
527
- end
528
-
529
- doc = @document.new
530
- doc.name_and_age = 'Frank (62)'
531
- doc.name.should == 'Frank'
532
- doc.age.should == 62
533
- end
534
-
535
- should "be overrideable by modules" do
536
- @document = Doc do
537
- key :other_child, String
538
- end
539
-
540
- child = @document.new(:other_child => 'foo')
541
- child.other_child.should == 'foo'
542
-
543
- @document.send :include, KeyOverride
544
-
545
- overriden_child = @document.new(:other_child => 'foo')
546
- overriden_child.other_child.should == 'foo modified'
547
- end
548
- end # writing a key
549
-
550
- context "checking if a keys value is present" do
551
- should "work for defined keys" do
552
- doc = @document.new
553
- doc.name?.should be_false
554
- doc.name = 'John'
555
- doc.name?.should be_true
556
- end
557
-
558
- should "raise no method error for undefined keys" do
559
- doc = @document.new
560
- lambda { doc.fart? }.should raise_error(NoMethodError)
561
- end
562
- end
563
-
564
- should "call inspect on the document's attributes instead of to_s when inspecting the document" do
565
- doc = @document.new(:animals => %w(dog cat))
566
- doc.inspect.should include(%(animals: ["dog", "cat"]))
567
- end
568
-
569
- context "equality" do
570
- setup do
571
- @oid = BSON::ObjectID.new
572
- end
573
-
574
- should "delegate hash to _id" do
575
- doc = @document.new
576
- doc.hash.should == doc._id.hash
577
- end
578
-
579
- should "delegate eql to ==" do
580
- doc = @document.new
581
- other = @document.new
582
- doc.eql?(other).should == (doc == other)
583
- doc.eql?(doc).should == (doc == doc)
584
- end
585
-
586
- should "know if same object as another" do
587
- doc = @document.new
588
- doc.should equal(doc)
589
- doc.should_not equal(@document.new)
590
- end
591
-
592
- should "allow set operations on array of documents" do
593
- doc = @document.new
594
- ([doc] & [doc]).should == [doc]
595
- end
596
-
597
- should "be equal if id and class are the same" do
598
- (@document.new('_id' => @oid) == @document.new('_id' => @oid)).should be_true
599
- end
600
-
601
- should "not be equal if class same but id different" do
602
- (@document.new('_id' => @oid) == @document.new('_id' => BSON::ObjectID.new)).should be_false
603
- end
604
-
605
- should "not be equal if id same but class different" do
606
- another_document = Doc()
607
- (@document.new('_id' => @oid) == another_document.new('_id' => @oid)).should be_false
608
- end
609
- end
610
-
611
- context "reading keys with default values" do
612
- setup do
613
- @document = EDoc do
614
- key :name, String, :default => 'foo'
615
- key :age, Integer, :default => 20
616
- key :net_worth, Float, :default => 100.00
617
- key :active, Boolean, :default => true
618
- key :smart, Boolean, :default => false
619
- key :skills, Array, :default => [1]
620
- key :options, Hash, :default => {'foo' => 'bar'}
621
- end
622
-
623
- @doc = @document.new
624
- end
625
-
626
- should "work for strings" do
627
- @doc.name.should == 'foo'
628
- end
629
-
630
- should "work for integers" do
631
- @doc.age.should == 20
632
- end
633
-
634
- should "work for floats" do
635
- @doc.net_worth.should == 100.00
636
- end
637
-
638
- should "work for booleans" do
639
- @doc.active.should == true
640
- @doc.smart.should == false
641
- end
642
-
643
- should "work for arrays" do
644
- @doc.skills.should == [1]
645
- @doc.skills << 2
646
- @doc.skills.should == [1, 2]
647
- end
648
-
649
- should "work for hashes" do
650
- @doc.options['foo'].should == 'bar'
651
- @doc.options['baz'] = 'wick'
652
- @doc.options['baz'].should == 'wick'
653
- end
654
- end
655
- end # instance of a embedded document
656
- end
657
- end