mongo_mapper 0.14.0 → 0.15.4

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 (120) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +1 -1
  3. data/README.md +72 -0
  4. data/examples/keys.rb +1 -1
  5. data/examples/modifiers/set.rb +1 -1
  6. data/examples/querying.rb +1 -1
  7. data/examples/safe.rb +2 -2
  8. data/examples/scopes.rb +1 -1
  9. data/lib/mongo_mapper.rb +19 -17
  10. data/lib/mongo_mapper/connection.rb +16 -38
  11. data/lib/mongo_mapper/extensions/array.rb +1 -1
  12. data/lib/mongo_mapper/extensions/binary.rb +1 -1
  13. data/lib/mongo_mapper/extensions/date.rb +1 -1
  14. data/lib/mongo_mapper/extensions/float.rb +1 -1
  15. data/lib/mongo_mapper/extensions/hash.rb +1 -1
  16. data/lib/mongo_mapper/extensions/nil_class.rb +2 -2
  17. data/lib/mongo_mapper/extensions/object.rb +1 -1
  18. data/lib/mongo_mapper/extensions/object_id.rb +6 -2
  19. data/lib/mongo_mapper/extensions/set.rb +1 -1
  20. data/lib/mongo_mapper/extensions/string.rb +1 -1
  21. data/lib/mongo_mapper/plugins/accessible.rb +1 -1
  22. data/lib/mongo_mapper/plugins/associations/base.rb +10 -2
  23. data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +1 -1
  24. data/lib/mongo_mapper/plugins/associations/many_association.rb +6 -5
  25. data/lib/mongo_mapper/plugins/associations/{belongs_to_polymorphic_proxy.rb → proxy/belongs_to_polymorphic_proxy.rb} +0 -0
  26. data/lib/mongo_mapper/plugins/associations/{belongs_to_proxy.rb → proxy/belongs_to_proxy.rb} +6 -0
  27. data/lib/mongo_mapper/plugins/associations/proxy/collection.rb +55 -0
  28. data/lib/mongo_mapper/plugins/associations/{embedded_collection.rb → proxy/embedded_collection.rb} +0 -0
  29. data/lib/mongo_mapper/plugins/associations/{in_array_proxy.rb → proxy/in_array_proxy.rb} +36 -6
  30. data/lib/mongo_mapper/plugins/associations/proxy/in_foreign_array_proxy.rb +136 -0
  31. data/lib/mongo_mapper/plugins/associations/{many_documents_as_proxy.rb → proxy/many_documents_as_proxy.rb} +0 -0
  32. data/lib/mongo_mapper/plugins/associations/{many_documents_proxy.rb → proxy/many_documents_proxy.rb} +0 -4
  33. data/lib/mongo_mapper/plugins/associations/{many_embedded_polymorphic_proxy.rb → proxy/many_embedded_polymorphic_proxy.rb} +0 -0
  34. data/lib/mongo_mapper/plugins/associations/{many_embedded_proxy.rb → proxy/many_embedded_proxy.rb} +0 -0
  35. data/lib/mongo_mapper/plugins/associations/{many_polymorphic_proxy.rb → proxy/many_polymorphic_proxy.rb} +0 -0
  36. data/lib/mongo_mapper/plugins/associations/{one_as_proxy.rb → proxy/one_as_proxy.rb} +0 -0
  37. data/lib/mongo_mapper/plugins/associations/{one_embedded_polymorphic_proxy.rb → proxy/one_embedded_polymorphic_proxy.rb} +0 -0
  38. data/lib/mongo_mapper/plugins/associations/{one_embedded_proxy.rb → proxy/one_embedded_proxy.rb} +3 -1
  39. data/lib/mongo_mapper/plugins/associations/{one_proxy.rb → proxy/one_proxy.rb} +0 -0
  40. data/lib/mongo_mapper/plugins/associations/proxy/proxy.rb +164 -0
  41. data/lib/mongo_mapper/plugins/associations/single_association.rb +5 -13
  42. data/lib/mongo_mapper/plugins/dirty.rb +29 -37
  43. data/lib/mongo_mapper/plugins/document.rb +1 -1
  44. data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +1 -1
  45. data/lib/mongo_mapper/plugins/embedded_callbacks.rb +1 -0
  46. data/lib/mongo_mapper/plugins/embedded_document.rb +2 -2
  47. data/lib/mongo_mapper/plugins/identity_map.rb +3 -1
  48. data/lib/mongo_mapper/plugins/indexes.rb +13 -6
  49. data/lib/mongo_mapper/plugins/keys.rb +12 -7
  50. data/lib/mongo_mapper/plugins/keys/key.rb +21 -13
  51. data/lib/mongo_mapper/plugins/modifiers.rb +39 -14
  52. data/lib/mongo_mapper/plugins/persistence.rb +6 -2
  53. data/lib/mongo_mapper/plugins/querying.rb +9 -3
  54. data/lib/mongo_mapper/plugins/querying/decorated_plucky_query.rb +6 -6
  55. data/lib/mongo_mapper/plugins/safe.rb +10 -4
  56. data/lib/mongo_mapper/plugins/scopes.rb +19 -3
  57. data/lib/mongo_mapper/plugins/stats.rb +1 -3
  58. data/lib/mongo_mapper/plugins/strong_parameters.rb +26 -0
  59. data/lib/mongo_mapper/plugins/validations.rb +1 -1
  60. data/lib/mongo_mapper/railtie.rb +1 -0
  61. data/lib/mongo_mapper/utils.rb +2 -2
  62. data/lib/mongo_mapper/version.rb +1 -1
  63. data/spec/examples.txt +1731 -0
  64. data/spec/functional/accessible_spec.rb +7 -1
  65. data/spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb +2 -2
  66. data/spec/functional/associations/belongs_to_proxy_spec.rb +55 -5
  67. data/spec/functional/associations/in_array_proxy_spec.rb +149 -14
  68. data/spec/functional/associations/in_foreign_array_proxy_spec.rb +321 -0
  69. data/spec/functional/associations/many_documents_as_proxy_spec.rb +6 -6
  70. data/spec/functional/associations/many_documents_proxy_spec.rb +22 -22
  71. data/spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb +2 -2
  72. data/spec/functional/associations/many_polymorphic_proxy_spec.rb +4 -4
  73. data/spec/functional/associations/one_as_proxy_spec.rb +8 -8
  74. data/spec/functional/associations/one_embedded_proxy_spec.rb +28 -0
  75. data/spec/functional/associations/one_proxy_spec.rb +19 -9
  76. data/spec/functional/associations_spec.rb +3 -3
  77. data/spec/functional/binary_spec.rb +2 -2
  78. data/spec/functional/caching_spec.rb +15 -22
  79. data/spec/functional/callbacks_spec.rb +2 -2
  80. data/spec/functional/counter_cache_spec.rb +10 -10
  81. data/spec/functional/dirty_spec.rb +48 -10
  82. data/spec/functional/dirty_with_callbacks_spec.rb +59 -0
  83. data/spec/functional/document_spec.rb +5 -8
  84. data/spec/functional/dumpable_spec.rb +1 -1
  85. data/spec/functional/embedded_document_spec.rb +5 -5
  86. data/spec/functional/identity_map_spec.rb +8 -8
  87. data/spec/functional/indexes_spec.rb +19 -18
  88. data/spec/functional/keys_spec.rb +64 -33
  89. data/spec/functional/logger_spec.rb +2 -2
  90. data/spec/functional/modifiers_spec.rb +81 -19
  91. data/spec/functional/partial_updates_spec.rb +8 -8
  92. data/spec/functional/protected_spec.rb +1 -1
  93. data/spec/functional/querying_spec.rb +70 -22
  94. data/spec/functional/safe_spec.rb +23 -27
  95. data/spec/functional/sci_spec.rb +7 -7
  96. data/spec/functional/scopes_spec.rb +89 -1
  97. data/spec/functional/static_keys_spec.rb +2 -2
  98. data/spec/functional/stats_spec.rb +28 -12
  99. data/spec/functional/strong_parameters_spec.rb +49 -0
  100. data/spec/functional/validations_spec.rb +8 -16
  101. data/spec/quality_spec.rb +1 -1
  102. data/spec/spec_helper.rb +39 -8
  103. data/spec/support/matchers.rb +1 -1
  104. data/spec/unit/associations/proxy_spec.rb +18 -10
  105. data/spec/unit/clone_spec.rb +1 -1
  106. data/spec/unit/document_spec.rb +3 -3
  107. data/spec/unit/embedded_document_spec.rb +4 -5
  108. data/spec/unit/extensions_spec.rb +12 -7
  109. data/spec/unit/identity_map_middleware_spec.rb +65 -96
  110. data/spec/unit/inspect_spec.rb +1 -1
  111. data/spec/unit/key_spec.rb +23 -18
  112. data/spec/unit/keys_spec.rb +17 -8
  113. data/spec/unit/mongo_mapper_spec.rb +41 -88
  114. data/spec/unit/rails_spec.rb +2 -2
  115. data/spec/unit/validations_spec.rb +18 -18
  116. metadata +70 -38
  117. data/README.rdoc +0 -56
  118. data/lib/mongo_mapper/extensions/ordered_hash.rb +0 -23
  119. data/lib/mongo_mapper/plugins/associations/collection.rb +0 -29
  120. data/lib/mongo_mapper/plugins/associations/proxy.rb +0 -141
@@ -148,11 +148,11 @@ describe "Callbacks" do
148
148
  @root_class.define_callbacks :after_publish
149
149
  @root_class.after_save { |d| d.run_callbacks(:after_publish) }
150
150
 
151
- expect {
151
+ lambda {
152
152
  child = @child_class.new(:name => 'Child')
153
153
  root = @root_class.create(:name => 'Parent', :children => [child])
154
154
  child.history.should_not include(:after_publish)
155
- }.to_not raise_error
155
+ }.should_not raise_error
156
156
  end
157
157
  end
158
158
 
@@ -171,42 +171,42 @@ describe MongoMapper::Plugins::CounterCache do
171
171
  end
172
172
 
173
173
  it "should update the counter cache on save" do
174
- expect {
174
+ lambda {
175
175
  @comment.save!
176
176
  @article.reload
177
- }.to change(@article, :commentable_count).by(1)
177
+ }.should change(@article, :commentable_count).by(1)
178
178
  end
179
179
 
180
180
  it "should increment with a second object" do
181
181
  @comment.save!
182
182
 
183
- expect {
183
+ lambda {
184
184
  second_comment = CounterCacheFixtureModels::Comment.new
185
185
  second_comment.commentable = @article
186
186
  second_comment.save!
187
187
  @article.reload
188
- }.to change(@article, :commentable_count).by(1)
188
+ }.should change(@article, :commentable_count).by(1)
189
189
  end
190
190
 
191
191
  it "should decrement the counter cache on destroy" do
192
192
  @comment.save!
193
193
 
194
- expect {
194
+ lambda {
195
195
  @comment.destroy
196
196
  @article.reload
197
- }.to change(@article, :commentable_count).by(-1)
197
+ }.should change(@article, :commentable_count).by(-1)
198
198
  end
199
199
 
200
200
  it "should increment with a different type of object" do
201
201
  @comment.save!
202
202
 
203
- expect {
203
+ lambda {
204
204
  second_comment = CounterCacheFixtureModels::Comment.new
205
205
  second_comment.commentable = @article
206
206
  second_comment.save!
207
207
 
208
208
  @article.reload
209
- }.to change(@article, :commentable_count).by(1)
209
+ }.should change(@article, :commentable_count).by(1)
210
210
  end
211
211
 
212
212
  describe "without a counter cache field" do
@@ -226,9 +226,9 @@ describe MongoMapper::Plugins::CounterCache do
226
226
  it "should raise at save (runtime) if there is no counter cache field" do
227
227
  @comment.commentable = @obj
228
228
 
229
- expect {
229
+ lambda {
230
230
  @comment.save!
231
- }.to raise_error(MongoMapper::Plugins::CounterCache::InvalidCounterCacheError)
231
+ }.should raise_error(MongoMapper::Plugins::CounterCache::InvalidCounterCacheError)
232
232
  end
233
233
  end
234
234
  end
@@ -9,6 +9,13 @@ describe "Dirty" do
9
9
  end
10
10
 
11
11
  context "marking changes" do
12
+ it "should have the changed? methods" do
13
+ obj = @document.new
14
+ obj.should respond_to(:changed?)
15
+ obj.should respond_to(:phrase_changed?)
16
+ obj.should respond_to(:paragraph_changed?)
17
+ end
18
+
12
19
  it "should not happen if there are none" do
13
20
  doc = @document.new
14
21
  doc.phrase_changed?.should be_falsey
@@ -48,8 +55,8 @@ describe "Dirty" do
48
55
 
49
56
  it "should not happen when loading from database" do
50
57
  doc = @document.create(:phrase => 'Foo')
51
- expect_any_instance_of(@document).to receive(:attribute_will_change!).never
52
- expect_any_instance_of(@document).to receive(:attribute_changed?).never
58
+ @document.any_instance.should_receive(:attribute_will_change!).never
59
+ @document.any_instance.should_receive(:attribute_changed?).never
53
60
  doc = @document.find(doc.id)
54
61
  doc.changed?.should be_falsey
55
62
  end
@@ -220,19 +227,25 @@ describe "Dirty" do
220
227
  doc.a = "d"
221
228
  doc.a_change.should == ["b","d"]
222
229
  end
223
- it "should reset changes when set back to the original value" do
224
- doc = @document.create(:a=>"b")
225
- doc.a = "c"
226
- doc.a = "b"
227
- doc.changed?.should be_falsey
228
- end
230
+
231
+ # TODO: ? Is this consistent with how ActiveRecord now works with changes?
232
+ # it "should reset changes when set back to the original value" do
233
+ # doc = @document.create(:a=>"b")
234
+ # doc.a = "c"
235
+ # doc.a = "b"
236
+ # doc.changed?.should be_falsey
237
+ # end
229
238
  end
230
239
 
231
240
  context "reset_attribute!" do
232
241
  it "should reset the attribute back to the previous value" do
233
242
  doc = @document.create(:a=>"b")
234
243
  doc.a = "c"
235
- doc.reset_a!
244
+ if doc.respond_to?(:restore_a!)
245
+ doc.restore_a!
246
+ else
247
+ doc.reset_a!
248
+ end
236
249
  doc.changed?.should be_falsey
237
250
  doc.a.should == "b"
238
251
  end
@@ -241,7 +254,11 @@ describe "Dirty" do
241
254
  doc.a = "c"
242
255
  doc.a = "d"
243
256
  doc.a = "e"
244
- doc.reset_a!
257
+ if doc.respond_to?(:restore_a!)
258
+ doc.restore_a!
259
+ else
260
+ doc.reset_a!
261
+ end
245
262
  doc.changed?.should be_falsey
246
263
  doc.a.should == "b"
247
264
  end
@@ -263,6 +280,27 @@ describe "Dirty" do
263
280
  end
264
281
  end
265
282
 
283
+ context "Document having Array key with typecast option" do
284
+ before do
285
+ @author_id = BSON::ObjectId.new
286
+ @doc = Doc('Book') { key :author_ids, Array, typecast: "ObjectId" }
287
+ @doc.plugin MongoMapper::Plugins::Dirty
288
+ @book = @doc.create!(author_ids: [@author_id])
289
+ end
290
+
291
+ context "changed" do
292
+ it "should be empty if assigned the same array" do
293
+ @book.author_ids = [@author_id]
294
+ @book.changed.should be_empty
295
+ end
296
+
297
+ it "should be empty if assigned the same but before-typecasted array" do
298
+ @book.author_ids = [@author_id.to_s]
299
+ @book.changed.should be_empty
300
+ end
301
+ end
302
+ end
303
+
266
304
  context "Embedded documents" do
267
305
  before do
268
306
  @edoc = EDoc('Duck') { key :name, String }
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'DirtyWithCallbacks' do
4
+ it 'should update its changes/previous_changes before after_create/after_update callbacks' do
5
+ history = {}
6
+
7
+ document = Doc {
8
+ key :x, String
9
+
10
+ after_save {
11
+ history[:after_save] = {
12
+ changes: changes,
13
+ previous_changes: previous_changes,
14
+ }
15
+ }
16
+ after_create {
17
+ history[:after_create] = {
18
+ changes: changes,
19
+ previous_changes: previous_changes,
20
+ }
21
+ }
22
+ after_update {
23
+ history[:after_update] = {
24
+ changes: changes,
25
+ previous_changes: previous_changes,
26
+ }
27
+ }
28
+ }
29
+
30
+ d = document.new(x: 'hello')
31
+ d.save
32
+
33
+ history.should == {
34
+ after_save: {
35
+ changes: {},
36
+ previous_changes: {'x' => [nil, 'hello']},
37
+ },
38
+ after_create: {
39
+ changes: {},
40
+ previous_changes: {'x' => [nil, 'hello']},
41
+ },
42
+ }
43
+ history.clear
44
+
45
+ d.x = 'world'
46
+ d.save!
47
+
48
+ history.should == {
49
+ after_save: {
50
+ changes: {},
51
+ previous_changes: {'x' => ['hello', 'world']},
52
+ },
53
+ after_update: {
54
+ changes: {},
55
+ previous_changes: {'x' => ['hello', 'world']},
56
+ },
57
+ }
58
+ end
59
+ end
@@ -240,8 +240,8 @@ describe "Document" do
240
240
  end
241
241
 
242
242
  it "should reset many associations" do
243
- expect(@instance.foos).to receive(:reset).at_least(1).times
244
- expect(@instance.bars).to receive(:reset).at_least(1).times
243
+ @instance.foos.should_receive(:reset).at_least(1).times
244
+ @instance.bars.should_receive(:reset).at_least(1).times
245
245
  @instance.reload
246
246
  end
247
247
 
@@ -257,9 +257,6 @@ describe "Document" do
257
257
  @instance.bar.should_not be_nil
258
258
  end
259
259
 
260
- it "should reset nil one association" do
261
- end
262
-
263
260
  it "should reinstantiate embedded associations" do
264
261
  @instance.reload
265
262
  @instance.bars.first.name.should == '1'
@@ -271,7 +268,7 @@ describe "Document" do
271
268
 
272
269
  it "should raise DocumentNotFound if not found" do
273
270
  @instance.destroy
274
- expect { @instance.reload }.to raise_error(MongoMapper::DocumentNotFound)
271
+ lambda { @instance.reload }.should raise_error(MongoMapper::DocumentNotFound)
275
272
  end
276
273
 
277
274
  it "should clear keys that were removed from the database" do
@@ -283,7 +280,7 @@ describe "Document" do
283
280
  context "database has keys not defined in model" do
284
281
  before do
285
282
  @id = BSON::ObjectId.new
286
- @document.collection.insert({
283
+ @document.collection.insert_one({
287
284
  :_id => @id,
288
285
  :first_name => 'John',
289
286
  :last_name => 'Nunemaker',
@@ -304,7 +301,7 @@ describe "Document" do
304
301
  end
305
302
 
306
303
  it "should not walk ObjectSpace when creating a model" do
307
- expect(ObjectSpace).to receive(:each_object).never
304
+ ObjectSpace.should_receive(:each_object).never
308
305
  Doc()
309
306
  end
310
307
  end
@@ -7,7 +7,7 @@ describe "Documents with the Dumpable plugin" do
7
7
  let(:store) { ActiveSupport::Cache::MemoryStore.new(:size => 1.megabyte) }
8
8
 
9
9
  it "should be able to be marshalled" do
10
- expect { Marshal.dump(answer) }.to_not raise_error
10
+ lambda { Marshal.dump(answer) }.should_not raise_error
11
11
  end
12
12
 
13
13
  it "should be able to be unmarshalled" do
@@ -227,7 +227,7 @@ describe "EmbeddedDocument" do
227
227
  person.pets << pet
228
228
  pet.should be_new
229
229
 
230
- expect(person).to receive(:save!)
230
+ person.should_receive(:save!)
231
231
  pet.save!
232
232
  end
233
233
 
@@ -272,8 +272,8 @@ describe "EmbeddedDocument" do
272
272
  pet = person.pets.first
273
273
 
274
274
  attributes = {:name => 'koda'}
275
- expect(pet).to receive(:attributes=).with(attributes)
276
- expect(pet).to receive(:save!)
275
+ pet.should_receive(:attributes=).with(attributes)
276
+ pet.should_receive(:save!)
277
277
  pet.update_attributes!(attributes)
278
278
  end
279
279
 
@@ -288,8 +288,8 @@ describe "EmbeddedDocument" do
288
288
  end
289
289
 
290
290
  it "should not fail if the source document contains nils in the embedded document list" do
291
- @klass.collection.insert(:pets => [nil, {:name => "Sasha"}])
292
- expect { @klass.all.first.pets }.to_not raise_error
291
+ @klass.collection.insert_one(:pets => [nil, {:name => "Sasha"}])
292
+ lambda { @klass.all.first.pets }.should_not raise_error
293
293
  @klass.all.first.pets.tap do |pets|
294
294
  pets.length.should == 1
295
295
  pets[0].name.should == "Sasha"
@@ -14,12 +14,12 @@ describe "IdentityMap" do
14
14
  end
15
15
 
16
16
  def expect_no_queries
17
- expect_any_instance_of(Mongo::Collection).to receive(:find_one).never
18
- expect_any_instance_of(Mongo::Collection).to receive(:find).never
17
+ Mongo::Collection.any_instance.should_receive(:find_one).never
18
+ Mongo::Collection.any_instance.should_receive(:find).never
19
19
  end
20
20
 
21
21
  def expects_one_query
22
- expect_any_instance_of(Mongo::Collection).to receive(:find_one).once.and_return({})
22
+ Mongo::Collection.any_instance.should_receive(:find).once.and_call_original
23
23
  end
24
24
 
25
25
  def clear_identity_map
@@ -185,11 +185,11 @@ describe "IdentityMap" do
185
185
  key :created_at, Time
186
186
  end
187
187
 
188
- expect do
188
+ lambda do
189
189
  loaded = person_with_time_class.load({'_id' => @id, 'name' => 'Frank', 'created_at' => '2014-12-07T20:36:45.529-08:00'}, true)
190
190
  loaded.should be_present
191
191
  loaded.created_at.should be_an_instance_of(Time)
192
- end.to_not raise_error
192
+ end.should_not raise_error
193
193
  end
194
194
  end
195
195
 
@@ -420,7 +420,7 @@ describe "IdentityMap" do
420
420
  belongs_to :parent, :class_name => 'Item'
421
421
  one :blog, :class_name => 'Blog', :foreign_key => 'parent_id'
422
422
  end
423
- Item.collection.remove
423
+ Item.collection.drop
424
424
 
425
425
  class ::Blog < ::Item; end
426
426
 
@@ -461,7 +461,7 @@ describe "IdentityMap" do
461
461
 
462
462
  blog = Blog.create(:title => 'Jill', :parent => root)
463
463
  assert_in_map(blog)
464
- root.should equal(blog.parent.target)
464
+ root.should equal(blog.parent)
465
465
  end
466
466
 
467
467
  it "should work correctly with one proxy" do
@@ -470,7 +470,7 @@ describe "IdentityMap" do
470
470
 
471
471
  root = Item.create(:title => 'Root', :blog => blog)
472
472
  assert_in_map(root)
473
- blog.should equal(root.blog.target)
473
+ blog.should equal(root.blog)
474
474
  end
475
475
 
476
476
  it "should work correctly with one proxy create" do
@@ -13,22 +13,25 @@ describe "Indexing" do
13
13
 
14
14
  context "against a known collection" do
15
15
  before do
16
- allow(@document).to receive(:collection).and_return(double(:name => :foo))
16
+ @document.stub(:collection).and_return(double(:name => :foo, :indexes => double()))
17
17
  end
18
- [:create_index, :ensure_index].each do |method|
19
- it "should delegate #{method} to collection" do
20
- expect(@document.collection).to receive(method).with(:arg, {})
21
- @document.send(method, :arg)
22
- end
18
+
19
+ it "should delegate create_index to collection#create_one" do
20
+ @document.collection.indexes.should_receive(:create_one).with({:arg => 1}, {})
21
+ @document.create_index(:arg)
23
22
  end
24
23
 
24
+ it "should delegate ensure_index to collection#create_one" do
25
+ @document.collection.indexes.should_receive(:create_one).with({:arg => 1}, {})
26
+ @document.create_index(:arg)
27
+ end
25
28
  it "should delegate drop_index to collection" do
26
- expect(@document.collection).to receive(:drop_index).with(:arg)
29
+ @document.collection.indexes.should_receive(:drop_one).with(:arg)
27
30
  @document.drop_index(:arg)
28
31
  end
29
32
 
30
33
  it "should delegate drop_indexes to collection" do
31
- expect(@document.collection).to receive(:drop_indexes)
34
+ @document.collection.indexes.should_receive(:drop_all)
32
35
  @document.drop_indexes
33
36
  end
34
37
  end
@@ -48,6 +51,11 @@ describe "Indexing" do
48
51
  @document.should have_index('last_name_1')
49
52
  end
50
53
 
54
+ it "should allow specifying as a hash" do
55
+ @document.ensure_index({last_name: -1})
56
+ @document.should have_index('last_name_-1')
57
+ end
58
+
51
59
  it "should allow creating unique index for a key" do
52
60
  @document.ensure_index :first_name, :unique => true
53
61
  @document.should have_index('fn_1')
@@ -55,18 +63,11 @@ describe "Indexing" do
55
63
 
56
64
  it "should allow creating index on multiple keys" do
57
65
  @document.ensure_index [[:first_name, 1], [:last_name, -1]]
58
-
59
- # order is different for different versions of ruby so instead of
60
- # just checking have_index('first_name_1_last_name_-1') I'm checking
61
- # the values of the indexes to make sure the index creation was successful
62
- @document.collection.index_information.detect do |index|
63
- keys = index[0]
64
- keys.include?('fn_1') && keys.include?('last_name_-1')
65
- end.should_not be_nil
66
+ @document.should have_index('fn_1_last_name_-1')
66
67
  end
67
68
 
68
69
  it "should work with :index shortcut when defining key" do
69
- silence_stderr { @document.key :father, String, :index => true }
70
+ suppress_stderr { @document.key :father, String, :index => true }
70
71
  @document.should have_index('father_1')
71
72
  end
72
- end
73
+ end
@@ -34,28 +34,46 @@ describe "Keys" do
34
34
  instance.foo.should == 'baz'
35
35
  end
36
36
 
37
- context "when persisting an typecasted array" do
38
- TypecastedKeyModel = Doc do
39
- key :people, Array, :typecast => "Person"
40
- end
41
-
37
+ context "when persisting typecasts" do
42
38
  Person = Struct.new(:name) do
43
39
  def self.to_mongo(value)
44
40
  value.name
45
41
  end
46
42
 
47
43
  def self.from_mongo(value)
48
- Person.new value
44
+ new(value)
45
+ end
46
+ end
47
+
48
+ context "when persisting a typecast Array" do
49
+ typecast_key_model = Doc do
50
+ key :people, Array, :typecast => "Person"
51
+ end
52
+
53
+ it "should not mutate the model's state" do
54
+ person = Person.new "Bob"
55
+ doc = typecast_key_model.new(:people => [person])
56
+
57
+ doc.save!
58
+
59
+ doc.people.should == [person]
49
60
  end
50
61
  end
51
62
 
52
- it "should not mutate the model's state" do
53
- person = Person.new "Bob"
54
- doc = TypecastedKeyModel.new(:people => [person])
63
+ context "when persisting a typecast Set" do
64
+ typecast_key_model = Doc do
65
+ key :people, Set, :typecast => "Person"
66
+ end
67
+
68
+ it "should not mutate the model's state" do
69
+ person = Person.new "Bob"
70
+
71
+ doc = typecast_key_model.new(:people => Set.new([person]))
55
72
 
56
- doc.save
73
+ doc.save!
57
74
 
58
- doc.people.should == [person]
75
+ doc.people.should == Set.new([person])
76
+ end
59
77
  end
60
78
  end
61
79
 
@@ -70,7 +88,7 @@ describe "Keys" do
70
88
  end
71
89
  end
72
90
 
73
- expect { doc.new }.to_not raise_error
91
+ lambda { doc.new }.should_not raise_error
74
92
  end
75
93
 
76
94
  it "should not bomb if a key is read before Keys#initialize gets to get called" do
@@ -84,7 +102,7 @@ describe "Keys" do
84
102
  end
85
103
  end
86
104
 
87
- expect { doc.new }.to_not raise_error
105
+ lambda { doc.new }.should_not raise_error
88
106
  end
89
107
 
90
108
  it "should permit for key overrides" do
@@ -93,7 +111,7 @@ describe "Keys" do
93
111
  key :class, String, :accessors => :skip
94
112
  end
95
113
 
96
- doc.collection.insert('class' => 'String')
114
+ doc.collection.insert_one('class' => 'String')
97
115
  doc.all.first.tap do |d|
98
116
  d.class.should == doc
99
117
  d["class"].should == "String"
@@ -109,7 +127,7 @@ describe "Keys" do
109
127
  }
110
128
 
111
129
  before do
112
- doc.collection.insert(:dynamic => "foo")
130
+ doc.collection.insert_one(:dynamic => "foo")
113
131
  doc.first
114
132
  end
115
133
 
@@ -129,7 +147,7 @@ describe "Keys" do
129
147
  describe "with invalid names" do
130
148
  it "should warn when key names start with an uppercase letter" do
131
149
  doc = Doc {}
132
- expect(Kernel).to receive(:warn).once.with(/may not start with uppercase letters/)
150
+ Kernel.should_receive(:warn).once.with(/may not start with uppercase letters/)
133
151
  doc.class_eval do
134
152
  key :NotConstant
135
153
  end
@@ -137,30 +155,30 @@ describe "Keys" do
137
155
 
138
156
  it "should handle keys that start with uppercase letters by translating their first letter to lowercase" do
139
157
  doc = Doc {}
140
- allow(Kernel).to receive(:warn)
158
+ Kernel.stub(:warn)
141
159
  doc.class_eval do
142
160
  key :NotConstant
143
161
  end
144
- doc.collection.insert("NotConstant" => "Just data!")
162
+ doc.collection.insert_one("NotConstant" => "Just data!")
145
163
  doc.first.notConstant.should == "Just data!"
146
164
  end
147
165
 
148
166
  it "should not create accessors for bad keys" do
149
167
  doc = Doc {}
150
- expect(doc).to_not receive(:create_accessors_for)
168
+ doc.should_not_receive(:create_accessors_for)
151
169
  doc.class_eval do
152
170
  key :"bad-name", :__dynamic => true
153
171
  end
154
- expect { doc.new.method(:"bad-name") }.to raise_error(NameError)
172
+ lambda { doc.new.method(:"bad-name") }.should raise_error(NameError)
155
173
  end
156
174
 
157
175
  it "should not create accessors for reserved keys" do
158
176
  doc = Doc {}
159
- expect(doc).to_not receive(:create_accessors_for)
177
+ doc.should_not_receive(:create_accessors_for)
160
178
  doc.class_eval do
161
179
  key :"class", :__dynamic => true
162
180
  end
163
- expect(doc.new.class).to eq doc
181
+ doc.new.class.should == doc
164
182
  end
165
183
 
166
184
  it "should create accessors for good keys" do
@@ -168,13 +186,13 @@ describe "Keys" do
168
186
  key :good_name
169
187
  }
170
188
  doc.new.good_name.should be_nil
171
- expect { doc.new.method("good_name") }.to_not raise_error
189
+ lambda { doc.new.method("good_name") }.should_not raise_error
172
190
  end
173
191
  end
174
192
 
175
193
  it "should handle loading dynamic fields from the database that have bad names" do
176
194
  doc = Doc {}
177
- doc.collection.insert("foo-bar" => "baz-bin")
195
+ doc.collection.insert_one("foo-bar" => "baz-bin")
178
196
 
179
197
  doc.first["foo-bar"].should == "baz-bin"
180
198
  end
@@ -195,7 +213,7 @@ describe "Keys" do
195
213
  end
196
214
 
197
215
  it "should serialize with aliased keys" do
198
- AliasedKeyModel.collection.find_one.keys.should =~ %w(_id f bar)
216
+ AliasedKeyModel.collection.find.first.keys.should =~ %w(_id f bar)
199
217
 
200
218
  AliasedKeyModel.first.tap do |d|
201
219
  d.foo.should == "whee!"
@@ -219,15 +237,15 @@ describe "Keys" do
219
237
  it "should permit dealiasing of atomic operations" do
220
238
  m = AliasedKeyModel.first
221
239
  m.set(:foo => 1)
222
- AliasedKeyModel.collection.find_one["f"].should == 1
223
- AliasedKeyModel.collection.find_one["foo"].should be_nil
240
+ AliasedKeyModel.collection.find.first["f"].should == 1
241
+ AliasedKeyModel.collection.find.first["foo"].should be_nil
224
242
  end
225
243
 
226
244
  it "should permit dealiasing of update operations" do
227
245
  m = AliasedKeyModel.first
228
246
  m.update_attributes(:foo => 1)
229
- AliasedKeyModel.collection.find_one["f"].should == 1
230
- AliasedKeyModel.collection.find_one["foo"].should be_nil
247
+ AliasedKeyModel.collection.find.first["f"].should == 1
248
+ AliasedKeyModel.collection.find.first["foo"].should be_nil
231
249
  end
232
250
 
233
251
  it "should not break when unaliasing non-keys" do
@@ -246,7 +264,7 @@ describe "Keys" do
246
264
  before { AliasedKeyModel.create(:with_underscores => "foobar") }
247
265
  it "should work" do
248
266
  AliasedKeyModel.first.with_underscores.should == "foobar"
249
- AliasedKeyModel.collection.find_one["with-hyphens"].should == "foobar"
267
+ AliasedKeyModel.collection.find.first["with-hyphens"].should == "foobar"
250
268
  end
251
269
  end
252
270
 
@@ -254,7 +272,7 @@ describe "Keys" do
254
272
  before { AliasedKeyModel.create(:field_name => "foobar") }
255
273
  it "should work" do
256
274
  AliasedKeyModel.first.field_name.should == "foobar"
257
- AliasedKeyModel.collection.find_one["alternate_field_name"].should == "foobar"
275
+ AliasedKeyModel.collection.find.first["alternate_field_name"].should == "foobar"
258
276
  end
259
277
  end
260
278
 
@@ -291,7 +309,7 @@ describe "Keys" do
291
309
  owner.reload
292
310
  owner.associated_documents.to_a.should =~ associated_documents.to_a
293
311
 
294
- AssociatedKeyWithAlias.collection.find_one.keys.should =~ %w(_id n aid)
312
+ AssociatedKeyWithAlias.collection.find.first.keys.should =~ %w(_id n aid)
295
313
  end
296
314
 
297
315
  it "should work with embedded documents" do
@@ -301,7 +319,7 @@ describe "Keys" do
301
319
 
302
320
  owner.reload
303
321
  owner.other_documents[0].embedded_name.should == "Underling"
304
- owner.collection.find_one["other_documents"][0]["en"].should == "Underling"
322
+ owner.collection.find.first["other_documents"][0]["en"].should == "Underling"
305
323
  end
306
324
  end
307
325
  end
@@ -334,6 +352,19 @@ describe "Keys" do
334
352
  it 'should remove the key' do
335
353
  DocWithRemovedKey.keys.should_not have_key "_something"
336
354
  end
355
+ end
337
356
 
357
+ describe "default with no type" do
358
+ it "should work (regression)" do
359
+ doc = Doc do
360
+ key :a_num, default: 0
361
+ end
362
+
363
+ instance = doc.new
364
+ instance.a_num.should == 0
365
+
366
+ instance = doc.new(a_num: 10)
367
+ instance.a_num.should == 10
368
+ end
338
369
  end
339
370
  end