mongo_mapper 0.13.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +1 -1
  3. data/README.md +61 -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 +7 -0
  10. data/lib/mongo_mapper/connection.rb +16 -37
  11. data/lib/mongo_mapper/document.rb +4 -0
  12. data/lib/mongo_mapper/extensions/array.rb +14 -6
  13. data/lib/mongo_mapper/extensions/hash.rb +15 -3
  14. data/lib/mongo_mapper/extensions/object.rb +4 -0
  15. data/lib/mongo_mapper/extensions/object_id.rb +5 -1
  16. data/lib/mongo_mapper/extensions/string.rb +13 -5
  17. data/lib/mongo_mapper/extensions/symbol.rb +18 -0
  18. data/lib/mongo_mapper/plugins/accessible.rb +15 -5
  19. data/lib/mongo_mapper/plugins/associations.rb +7 -6
  20. data/lib/mongo_mapper/plugins/associations/base.rb +27 -14
  21. data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +10 -1
  22. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +9 -8
  23. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +12 -11
  24. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +4 -4
  25. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +60 -29
  26. data/lib/mongo_mapper/plugins/associations/in_foreign_array_proxy.rb +136 -0
  27. data/lib/mongo_mapper/plugins/associations/many_association.rb +4 -2
  28. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +18 -16
  29. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +55 -48
  30. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +14 -13
  31. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +7 -6
  32. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +7 -5
  33. data/lib/mongo_mapper/plugins/associations/one_as_proxy.rb +14 -11
  34. data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +14 -13
  35. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +9 -9
  36. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +27 -26
  37. data/lib/mongo_mapper/plugins/associations/proxy.rb +36 -29
  38. data/lib/mongo_mapper/plugins/associations/single_association.rb +5 -4
  39. data/lib/mongo_mapper/plugins/callbacks.rb +13 -0
  40. data/lib/mongo_mapper/plugins/counter_cache.rb +97 -0
  41. data/lib/mongo_mapper/plugins/dirty.rb +29 -37
  42. data/lib/mongo_mapper/plugins/document.rb +1 -1
  43. data/lib/mongo_mapper/plugins/dynamic_querying.rb +10 -9
  44. data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +18 -17
  45. data/lib/mongo_mapper/plugins/embedded_callbacks.rb +2 -1
  46. data/lib/mongo_mapper/plugins/embedded_document.rb +1 -1
  47. data/lib/mongo_mapper/plugins/identity_map.rb +4 -2
  48. data/lib/mongo_mapper/plugins/indexes.rb +14 -7
  49. data/lib/mongo_mapper/plugins/keys.rb +170 -151
  50. data/lib/mongo_mapper/plugins/keys/key.rb +27 -16
  51. data/lib/mongo_mapper/plugins/keys/static.rb +45 -0
  52. data/lib/mongo_mapper/plugins/modifiers.rb +64 -38
  53. data/lib/mongo_mapper/plugins/partial_updates.rb +86 -0
  54. data/lib/mongo_mapper/plugins/persistence.rb +13 -8
  55. data/lib/mongo_mapper/plugins/protected.rb +6 -5
  56. data/lib/mongo_mapper/plugins/querying.rb +85 -42
  57. data/lib/mongo_mapper/plugins/querying/decorated_plucky_query.rb +20 -15
  58. data/lib/mongo_mapper/plugins/rails.rb +1 -0
  59. data/lib/mongo_mapper/plugins/safe.rb +10 -4
  60. data/lib/mongo_mapper/plugins/sci.rb +0 -0
  61. data/lib/mongo_mapper/plugins/scopes.rb +78 -7
  62. data/lib/mongo_mapper/plugins/stats.rb +17 -0
  63. data/lib/mongo_mapper/plugins/strong_parameters.rb +26 -0
  64. data/lib/mongo_mapper/plugins/timestamps.rb +1 -0
  65. data/lib/mongo_mapper/plugins/validations.rb +1 -1
  66. data/lib/mongo_mapper/railtie.rb +4 -3
  67. data/lib/mongo_mapper/utils.rb +2 -2
  68. data/lib/mongo_mapper/version.rb +1 -1
  69. data/lib/rails/generators/mongo_mapper/config/config_generator.rb +12 -13
  70. data/lib/rails/generators/mongo_mapper/model/model_generator.rb +9 -9
  71. data/spec/examples.txt +1717 -0
  72. data/spec/functional/accessible_spec.rb +19 -13
  73. data/spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb +13 -13
  74. data/spec/functional/associations/belongs_to_proxy_spec.rb +36 -20
  75. data/spec/functional/associations/in_array_proxy_spec.rb +145 -10
  76. data/spec/functional/associations/in_foreign_array_proxy_spec.rb +321 -0
  77. data/spec/functional/associations/many_documents_as_proxy_spec.rb +6 -6
  78. data/spec/functional/associations/many_documents_proxy_spec.rb +85 -14
  79. data/spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb +13 -13
  80. data/spec/functional/associations/many_embedded_proxy_spec.rb +1 -1
  81. data/spec/functional/associations/many_polymorphic_proxy_spec.rb +4 -4
  82. data/spec/functional/associations/one_as_proxy_spec.rb +10 -10
  83. data/spec/functional/associations/one_embedded_polymorphic_proxy_spec.rb +9 -9
  84. data/spec/functional/associations/one_embedded_proxy_spec.rb +3 -3
  85. data/spec/functional/associations/one_proxy_spec.rb +10 -10
  86. data/spec/functional/associations_spec.rb +3 -3
  87. data/spec/functional/binary_spec.rb +2 -2
  88. data/spec/functional/caching_spec.rb +8 -15
  89. data/spec/functional/callbacks_spec.rb +89 -2
  90. data/spec/functional/counter_cache_spec.rb +235 -0
  91. data/spec/functional/dirty_spec.rb +63 -46
  92. data/spec/functional/document_spec.rb +30 -5
  93. data/spec/functional/dumpable_spec.rb +1 -1
  94. data/spec/functional/embedded_document_spec.rb +17 -17
  95. data/spec/functional/identity_map_spec.rb +29 -16
  96. data/spec/functional/indexes_spec.rb +19 -18
  97. data/spec/functional/keys_spec.rb +86 -28
  98. data/spec/functional/logger_spec.rb +3 -3
  99. data/spec/functional/modifiers_spec.rb +81 -19
  100. data/spec/functional/partial_updates_spec.rb +577 -0
  101. data/spec/functional/protected_spec.rb +14 -14
  102. data/spec/functional/querying_spec.rb +77 -28
  103. data/spec/functional/safe_spec.rb +23 -27
  104. data/spec/functional/sci_spec.rb +9 -9
  105. data/spec/functional/scopes_spec.rb +235 -2
  106. data/spec/functional/static_keys_spec.rb +153 -0
  107. data/spec/functional/stats_spec.rb +86 -0
  108. data/spec/functional/strong_parameters_spec.rb +49 -0
  109. data/spec/functional/touch_spec.rb +1 -1
  110. data/spec/functional/validations_spec.rb +51 -57
  111. data/spec/quality_spec.rb +51 -0
  112. data/spec/spec_helper.rb +37 -9
  113. data/spec/support/matchers.rb +5 -14
  114. data/spec/unit/associations/base_spec.rb +12 -12
  115. data/spec/unit/associations/belongs_to_association_spec.rb +2 -2
  116. data/spec/unit/associations/many_association_spec.rb +2 -2
  117. data/spec/unit/associations/one_association_spec.rb +2 -2
  118. data/spec/unit/associations/proxy_spec.rb +19 -20
  119. data/spec/unit/clone_spec.rb +1 -1
  120. data/spec/unit/document_spec.rb +8 -8
  121. data/spec/unit/dynamic_finder_spec.rb +8 -8
  122. data/spec/unit/embedded_document_spec.rb +18 -19
  123. data/spec/unit/extensions_spec.rb +41 -17
  124. data/spec/unit/identity_map_middleware_spec.rb +65 -96
  125. data/spec/unit/key_spec.rb +28 -26
  126. data/spec/unit/keys_spec.rb +20 -11
  127. data/spec/unit/model_generator_spec.rb +0 -0
  128. data/spec/unit/mongo_mapper_spec.rb +38 -85
  129. data/spec/unit/rails_spec.rb +5 -0
  130. data/spec/unit/serialization_spec.rb +1 -1
  131. data/spec/unit/time_zones_spec.rb +2 -2
  132. data/spec/unit/validations_spec.rb +46 -33
  133. metadata +66 -37
  134. data/README.rdoc +0 -59
  135. data/lib/mongo_mapper/connections/10gen.rb +0 -0
  136. data/lib/mongo_mapper/connections/moped.rb +0 -0
  137. data/lib/mongo_mapper/extensions/ordered_hash.rb +0 -23
@@ -130,6 +130,34 @@ describe "Document" do
130
130
  end
131
131
  end
132
132
 
133
+ context "symbol key" do
134
+ before do
135
+ @document.key :foo, Symbol, :default => lambda { 123 }
136
+ end
137
+
138
+ it "should return default value" do
139
+ doc = @document.new
140
+ doc.foo.should == :'123'
141
+ end
142
+
143
+ it "should return symbol value" do
144
+ doc = @document.create :foo => 'qwerty'
145
+ doc.foo.should == :qwerty
146
+
147
+ doc.set :foo => 'poiuyt'
148
+ doc.reload
149
+ doc.foo.should == :poiuyt
150
+
151
+ doc.foo = 'asdf'
152
+ doc.foo.should == :asdf
153
+ end
154
+
155
+ it "should return typecasted value" do
156
+ doc = @document.new
157
+ (doc.foo = 'qwerty').should == 'qwerty'
158
+ end
159
+ end
160
+
133
161
  it "should have instance method for collection" do
134
162
  @document.new.collection.name.should == @document.collection.name
135
163
  end
@@ -229,9 +257,6 @@ describe "Document" do
229
257
  @instance.bar.should_not be_nil
230
258
  end
231
259
 
232
- it "should reset nil one association" do
233
- end
234
-
235
260
  it "should reinstantiate embedded associations" do
236
261
  @instance.reload
237
262
  @instance.bars.first.name.should == '1'
@@ -243,7 +268,7 @@ describe "Document" do
243
268
 
244
269
  it "should raise DocumentNotFound if not found" do
245
270
  @instance.destroy
246
- expect { @instance.reload }.to raise_error(MongoMapper::DocumentNotFound)
271
+ lambda { @instance.reload }.should raise_error(MongoMapper::DocumentNotFound)
247
272
  end
248
273
 
249
274
  it "should clear keys that were removed from the database" do
@@ -255,7 +280,7 @@ describe "Document" do
255
280
  context "database has keys not defined in model" do
256
281
  before do
257
282
  @id = BSON::ObjectId.new
258
- @document.collection.insert({
283
+ @document.collection.insert_one({
259
284
  :_id => @id,
260
285
  :first_name => 'John',
261
286
  :last_name => 'Nunemaker',
@@ -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
@@ -70,14 +70,14 @@ describe "EmbeddedDocument" do
70
70
  it "should be true until document is created" do
71
71
  address = @address_class.new(:city => 'South Bend', :state => 'IN')
72
72
  doc = @klass.new(:foo => address)
73
- address.new?.should be_true
73
+ address.new?.should be_truthy
74
74
  end
75
75
 
76
76
  it "should be false after document is saved" do
77
77
  address = @address_class.new(:city => 'South Bend', :state => 'IN')
78
78
  doc = @klass.new(:foo => address)
79
79
  doc.save
80
- doc.foo.new?.should be_false
80
+ doc.foo.new?.should be_falsey
81
81
  end
82
82
 
83
83
  it "should be false when loaded from database" do
@@ -86,7 +86,7 @@ describe "EmbeddedDocument" do
86
86
  doc.save
87
87
 
88
88
  doc.reload
89
- doc.foo.new?.should be_false
89
+ doc.foo.new?.should be_falsey
90
90
  end
91
91
  end
92
92
 
@@ -115,9 +115,9 @@ describe "EmbeddedDocument" do
115
115
  it "should be true until existing document is saved" do
116
116
  @doc.save
117
117
  pet = @doc.pets.build(:name => 'Rasmus')
118
- pet.new?.should be_true
118
+ pet.new?.should be_truthy
119
119
  @doc.save
120
- pet.new?.should be_false
120
+ pet.new?.should be_falsey
121
121
  end
122
122
  end
123
123
 
@@ -131,9 +131,9 @@ describe "EmbeddedDocument" do
131
131
 
132
132
  it "should be true until existing document is saved" do
133
133
  address = @doc.pets.first.addresses.build(:city => 'Holland', :state => 'MI')
134
- address.new?.should be_true
134
+ address.new?.should be_truthy
135
135
  @doc.save
136
- address.new?.should be_false
136
+ address.new?.should be_falsey
137
137
  end
138
138
  end
139
139
 
@@ -146,9 +146,9 @@ describe "EmbeddedDocument" do
146
146
  it "should be true until existing document is saved" do
147
147
  @doc.save
148
148
  @doc.build_address(:city => 'Holland', :state => 'MI')
149
- @doc.address.new?.should be_true
149
+ @doc.address.new?.should be_truthy
150
150
  @doc.save
151
- @doc.address.new?.should be_false
151
+ @doc.address.new?.should be_falsey
152
152
  end
153
153
  end
154
154
 
@@ -162,9 +162,9 @@ describe "EmbeddedDocument" do
162
162
 
163
163
  it "should be true until existing document is saved" do
164
164
  address = @doc.pets.first.build_address(:city => 'Holland', :stats => 'MI')
165
- address.new?.should be_true
165
+ address.new?.should be_truthy
166
166
  @doc.save
167
- address.new?.should be_false
167
+ address.new?.should be_falsey
168
168
  end
169
169
  end
170
170
 
@@ -248,7 +248,7 @@ describe "EmbeddedDocument" do
248
248
  person.reload
249
249
  pet = person.pets.first
250
250
 
251
- pet.update_attribute('name', 'koda').should be_true
251
+ pet.update_attribute('name', 'koda').should be_truthy
252
252
  person.reload
253
253
  person.pets.first._id.should == pet._id
254
254
  person.pets.first.name.should == 'koda'
@@ -260,7 +260,7 @@ describe "EmbeddedDocument" do
260
260
  person.reload
261
261
  pet = person.pets.first
262
262
 
263
- pet.update_attributes(:name => 'koda').should be_true
263
+ pet.update_attributes(:name => 'koda').should be_truthy
264
264
  person.reload
265
265
  person.pets.first._id.should == pet._id
266
266
  person.pets.first.name.should == 'koda'
@@ -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"
@@ -302,7 +302,7 @@ describe "EmbeddedDocument" do
302
302
  person.update_attributes!({"pets" => ["name" => "sparky", "flag" => "false"]})
303
303
  person.reload
304
304
  person.pets.first.name.should == "sparky"
305
- person.pets.first.flag.should be_false
305
+ person.pets.first.flag.should be_falsey
306
306
  end
307
307
 
308
308
  it "should update attributes with symbol keys" do
@@ -310,7 +310,7 @@ describe "EmbeddedDocument" do
310
310
  person.update_attributes!({:pets => [:name => "sparky", :flag => "false"]})
311
311
  person.reload
312
312
  person.pets.first.name.should == "sparky"
313
- person.pets.first.flag.should be_false
313
+ person.pets.first.flag.should be_falsey
314
314
  end
315
315
  end
316
316
  end
@@ -3,13 +3,13 @@ require 'spec_helper'
3
3
  describe "IdentityMap" do
4
4
  def assert_in_map(*resources)
5
5
  [resources].flatten.each do |resource|
6
- MongoMapper::Plugins::IdentityMap.include?(resource).should be_true
6
+ MongoMapper::Plugins::IdentityMap.include?(resource).should be_truthy
7
7
  end
8
8
  end
9
9
 
10
10
  def assert_not_in_map(*resources)
11
11
  [resources].flatten.each do |resource|
12
- MongoMapper::Plugins::IdentityMap.include?(resource).should be_false
12
+ MongoMapper::Plugins::IdentityMap.include?(resource).should be_falsey
13
13
  end
14
14
  end
15
15
 
@@ -19,7 +19,7 @@ describe "IdentityMap" do
19
19
  end
20
20
 
21
21
  def expects_one_query
22
- Mongo::Collection.any_instance.should_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
@@ -27,7 +27,7 @@ describe "IdentityMap" do
27
27
  end
28
28
 
29
29
  it "should default identity map to off" do
30
- MongoMapper::Plugins::IdentityMap.enabled?.should be_false
30
+ MongoMapper::Plugins::IdentityMap.enabled?.should be_falsey
31
31
  end
32
32
 
33
33
  context "Document" do
@@ -84,16 +84,16 @@ describe "IdentityMap" do
84
84
  MongoMapper::Plugins::IdentityMap.use do
85
85
  @person_class.find(@person.id)
86
86
  end
87
- MongoMapper::Plugins::IdentityMap.repository.empty?.should be_true
87
+ MongoMapper::Plugins::IdentityMap.repository.empty?.should be_truthy
88
88
  end
89
89
 
90
90
  it "should set enabled back to original status" do
91
91
  MongoMapper::Plugins::IdentityMap.enabled = false
92
- MongoMapper::Plugins::IdentityMap.enabled?.should be_false
92
+ MongoMapper::Plugins::IdentityMap.enabled?.should be_falsey
93
93
  MongoMapper::Plugins::IdentityMap.use do
94
- MongoMapper::Plugins::IdentityMap.enabled?.should be_true
94
+ MongoMapper::Plugins::IdentityMap.enabled?.should be_truthy
95
95
  end
96
- MongoMapper::Plugins::IdentityMap.enabled?.should be_false
96
+ MongoMapper::Plugins::IdentityMap.enabled?.should be_falsey
97
97
  end
98
98
  end
99
99
 
@@ -111,11 +111,11 @@ describe "IdentityMap" do
111
111
 
112
112
  it "should set enabled back to original value" do
113
113
  MongoMapper::Plugins::IdentityMap.enabled = true
114
- MongoMapper::Plugins::IdentityMap.enabled?.should be_true
114
+ MongoMapper::Plugins::IdentityMap.enabled?.should be_truthy
115
115
  MongoMapper::Plugins::IdentityMap.without do
116
- MongoMapper::Plugins::IdentityMap.enabled?.should be_false
116
+ MongoMapper::Plugins::IdentityMap.enabled?.should be_falsey
117
117
  end
118
- MongoMapper::Plugins::IdentityMap.enabled?.should be_true
118
+ MongoMapper::Plugins::IdentityMap.enabled?.should be_truthy
119
119
  end
120
120
  end
121
121
 
@@ -126,14 +126,14 @@ describe "IdentityMap" do
126
126
  it "should add key to map when saved" do
127
127
  person = @person_class.new
128
128
  assert_not_in_map(person)
129
- person.save.should be_true
129
+ person.save.should be_truthy
130
130
  assert_in_map(person)
131
131
  end
132
132
 
133
133
  it "should allow saving with options" do
134
134
  person = @person_class.new
135
135
  assert_not_in_map(person)
136
- person.save(:validate => false).should be_true
136
+ person.save(:validate => false).should be_truthy
137
137
  assert_in_map(person)
138
138
  end
139
139
 
@@ -178,6 +178,19 @@ describe "IdentityMap" do
178
178
  second_load = @person_class.load('_id' => @id, 'name' => 'Frank')
179
179
  first_load.should equal(second_load)
180
180
  end
181
+
182
+ it "should allow passing with_cast" do
183
+ person_with_time_class = Doc('PersonWithTime') do
184
+ key :name, String
185
+ key :created_at, Time
186
+ end
187
+
188
+ lambda do
189
+ loaded = person_with_time_class.load({'_id' => @id, 'name' => 'Frank', 'created_at' => '2014-12-07T20:36:45.529-08:00'}, true)
190
+ loaded.should be_present
191
+ loaded.created_at.should be_an_instance_of(Time)
192
+ end.should_not raise_error
193
+ end
181
194
  end
182
195
 
183
196
  context "#find (with one id)" do
@@ -407,7 +420,7 @@ describe "IdentityMap" do
407
420
  belongs_to :parent, :class_name => 'Item'
408
421
  one :blog, :class_name => 'Blog', :foreign_key => 'parent_id'
409
422
  end
410
- Item.collection.remove
423
+ Item.collection.drop
411
424
 
412
425
  class ::Blog < ::Item; end
413
426
 
@@ -448,7 +461,7 @@ describe "IdentityMap" do
448
461
 
449
462
  blog = Blog.create(:title => 'Jill', :parent => root)
450
463
  assert_in_map(blog)
451
- root.should equal(blog.parent.target)
464
+ root.should equal(blog.parent)
452
465
  end
453
466
 
454
467
  it "should work correctly with one proxy" do
@@ -457,7 +470,7 @@ describe "IdentityMap" do
457
470
 
458
471
  root = Item.create(:title => 'Root', :blog => blog)
459
472
  assert_in_map(root)
460
- blog.should equal(root.blog.target)
473
+ blog.should equal(root.blog)
461
474
  end
462
475
 
463
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
- @document.stub(: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
- @document.collection.should_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
- @document.collection.should_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
- @document.collection.should_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)
49
45
  end
50
46
  end
51
47
 
52
- it "should not mutate the model's state" do
53
- person = Person.new "Bob"
54
- doc = TypecastedKeyModel.new(:people => [person])
48
+ context "when persisting a typecast Array" do
49
+ typecast_key_model = Doc do
50
+ key :people, Array, :typecast => "Person"
51
+ end
55
52
 
56
- doc.save
53
+ it "should not mutate the model's state" do
54
+ person = Person.new "Bob"
55
+ doc = typecast_key_model.new(:people => [person])
57
56
 
58
- doc.people.should == [person]
57
+ doc.save!
58
+
59
+ doc.people.should == [person]
60
+ end
61
+ end
62
+
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]))
72
+
73
+ doc.save!
74
+
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
 
@@ -141,7 +159,7 @@ describe "Keys" do
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
 
@@ -151,7 +169,16 @@ describe "Keys" do
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)
173
+ end
174
+
175
+ it "should not create accessors for reserved keys" do
176
+ doc = Doc {}
177
+ doc.should_not_receive(:create_accessors_for)
178
+ doc.class_eval do
179
+ key :"class", :__dynamic => true
180
+ end
181
+ doc.new.class.should == doc
155
182
  end
156
183
 
157
184
  it "should create accessors for good keys" do
@@ -159,13 +186,13 @@ describe "Keys" do
159
186
  key :good_name
160
187
  }
161
188
  doc.new.good_name.should be_nil
162
- expect { doc.new.method("good_name") }.to_not raise_error
189
+ lambda { doc.new.method("good_name") }.should_not raise_error
163
190
  end
164
191
  end
165
192
 
166
193
  it "should handle loading dynamic fields from the database that have bad names" do
167
194
  doc = Doc {}
168
- doc.collection.insert("foo-bar" => "baz-bin")
195
+ doc.collection.insert_one("foo-bar" => "baz-bin")
169
196
 
170
197
  doc.first["foo-bar"].should == "baz-bin"
171
198
  end
@@ -186,7 +213,7 @@ describe "Keys" do
186
213
  end
187
214
 
188
215
  it "should serialize with aliased keys" do
189
- AliasedKeyModel.collection.find_one.keys.should =~ %w(_id f bar)
216
+ AliasedKeyModel.collection.find.first.keys.should =~ %w(_id f bar)
190
217
 
191
218
  AliasedKeyModel.first.tap do |d|
192
219
  d.foo.should == "whee!"
@@ -210,15 +237,15 @@ describe "Keys" do
210
237
  it "should permit dealiasing of atomic operations" do
211
238
  m = AliasedKeyModel.first
212
239
  m.set(:foo => 1)
213
- AliasedKeyModel.collection.find_one["f"].should == 1
214
- 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
215
242
  end
216
243
 
217
244
  it "should permit dealiasing of update operations" do
218
245
  m = AliasedKeyModel.first
219
246
  m.update_attributes(:foo => 1)
220
- AliasedKeyModel.collection.find_one["f"].should == 1
221
- 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
222
249
  end
223
250
 
224
251
  it "should not break when unaliasing non-keys" do
@@ -237,7 +264,7 @@ describe "Keys" do
237
264
  before { AliasedKeyModel.create(:with_underscores => "foobar") }
238
265
  it "should work" do
239
266
  AliasedKeyModel.first.with_underscores.should == "foobar"
240
- AliasedKeyModel.collection.find_one["with-hyphens"].should == "foobar"
267
+ AliasedKeyModel.collection.find.first["with-hyphens"].should == "foobar"
241
268
  end
242
269
  end
243
270
 
@@ -245,7 +272,7 @@ describe "Keys" do
245
272
  before { AliasedKeyModel.create(:field_name => "foobar") }
246
273
  it "should work" do
247
274
  AliasedKeyModel.first.field_name.should == "foobar"
248
- AliasedKeyModel.collection.find_one["alternate_field_name"].should == "foobar"
275
+ AliasedKeyModel.collection.find.first["alternate_field_name"].should == "foobar"
249
276
  end
250
277
  end
251
278
 
@@ -282,7 +309,7 @@ describe "Keys" do
282
309
  owner.reload
283
310
  owner.associated_documents.to_a.should =~ associated_documents.to_a
284
311
 
285
- AssociatedKeyWithAlias.collection.find_one.keys.should =~ %w(_id n aid)
312
+ AssociatedKeyWithAlias.collection.find.first.keys.should =~ %w(_id n aid)
286
313
  end
287
314
 
288
315
  it "should work with embedded documents" do
@@ -292,8 +319,39 @@ describe "Keys" do
292
319
 
293
320
  owner.reload
294
321
  owner.other_documents[0].embedded_name.should == "Underling"
295
- owner.collection.find_one["other_documents"][0]["en"].should == "Underling"
322
+ owner.collection.find.first["other_documents"][0]["en"].should == "Underling"
296
323
  end
297
324
  end
298
325
  end
326
+
327
+ describe "removing keys" do
328
+ DocWithRemovedKey = Doc do
329
+ key :something
330
+ validates_uniqueness_of :something
331
+ remove_key :something
332
+ end
333
+
334
+ it 'should remove the key' do
335
+ DocWithRemovedKey.keys.should_not have_key "_something"
336
+ end
337
+
338
+ it 'should remove validations' do
339
+ DocWithRemovedKey._validate_callbacks.should be_empty
340
+ end
341
+ end
342
+
343
+ describe "removing keys in the presence of a validation method" do
344
+ DocWithRemovedValidator = Doc do
345
+ key :something
346
+ validate :something_valid?
347
+ remove_key :something
348
+
349
+ def something_valid?; true; end
350
+ end
351
+
352
+ it 'should remove the key' do
353
+ DocWithRemovedKey.keys.should_not have_key "_something"
354
+ end
355
+
356
+ end
299
357
  end