mongoid 6.2.1 → 6.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -76,13 +76,13 @@ describe Mongoid::Atomic do
76
76
  person.addresses.build(street: "Oxford St")
77
77
  end
78
78
 
79
- it "returns a $set and $pushAll for modifications" do
79
+ it "returns a $set and $push for modifications" do
80
80
  expect(person.atomic_updates).to eq(
81
81
  {
82
82
  "$set" => { "title" => "Sir" },
83
- "$pushAll" => { "addresses" => [
83
+ "$push" => { "addresses" => { '$each' => [
84
84
  { "_id" => "oxford-st", "street" => "Oxford St" }
85
- ]}
85
+ ]} }
86
86
  }
87
87
  )
88
88
  end
@@ -197,8 +197,8 @@ describe Mongoid::Atomic do
197
197
  "addresses.0.street" => "Bond St"
198
198
  },
199
199
  conflicts: {
200
- "$pushAll" => {
201
- "addresses.0.locations" => [{ "_id" => location.id, "name" => "Home" }]
200
+ "$push" => {
201
+ "addresses.0.locations" => { '$each' => [{ "_id" => location.id, "name" => "Home" }] }
202
202
  }
203
203
  }
204
204
  }
@@ -215,8 +215,8 @@ describe Mongoid::Atomic do
215
215
  "addresses.0.street" => "Bond St"
216
216
  },
217
217
  conflicts: {
218
- "$pushAll" => {
219
- "addresses.0.locations" => [{ "_id" => location.id, "name" => "Home" }]
218
+ "$push" => {
219
+ "addresses.0.locations" => { '$each' => [{ "_id" => location.id, "name" => "Home" }] }
220
220
  }
221
221
  }
222
222
  }
@@ -263,15 +263,15 @@ describe Mongoid::Atomic do
263
263
  "addresses.0.street" => "Bond St"
264
264
  },
265
265
  conflicts: {
266
- "$pushAll" => {
267
- "addresses" => [{
266
+ "$push" => {
267
+ "addresses" => { '$each' => [{
268
268
  "_id" => new_address.id,
269
269
  "street" => "Another",
270
270
  "locations" => [
271
271
  "_id" => location.id,
272
272
  "name" => "Home"
273
273
  ]
274
- }]
274
+ }] }
275
275
  }
276
276
  }
277
277
  }
@@ -310,15 +310,15 @@ describe Mongoid::Atomic do
310
310
  "$set" => {
311
311
  "title" => "Sir"
312
312
  },
313
- "$pushAll" => {
314
- "addresses" => [{
313
+ "$push" => {
314
+ "addresses" => { '$each' => [{
315
315
  "_id" => new_address.id,
316
316
  "street" => "Ipanema",
317
317
  "locations" => [
318
318
  "_id" => location.id,
319
319
  "name" => "Home"
320
320
  ]
321
- }]
321
+ }] }
322
322
  },
323
323
  conflicts: {
324
324
  "$set" => { "addresses.0.street"=>"Bond St" }
@@ -339,21 +339,21 @@ describe Mongoid::Atomic do
339
339
  address.locations.build(name: "Home")
340
340
  end
341
341
 
342
- it "returns the proper $sets and $pushAlls for all levels" do
342
+ it "returns the proper $sets and $pushes for all levels" do
343
343
  expect(person.atomic_updates).to eq(
344
344
  {
345
345
  "$set" => {
346
346
  "title" => "Sir",
347
347
  },
348
- "$pushAll" => {
349
- "addresses" => [{
348
+ "$push" => {
349
+ "addresses" => { '$each' => [{
350
350
  "_id" => address.id,
351
351
  "street" => "Another",
352
352
  "locations" => [
353
353
  "_id" => location.id,
354
354
  "name" => "Home"
355
355
  ]
356
- }]
356
+ }] }
357
357
  }
358
358
  }
359
359
  )
@@ -2094,6 +2094,41 @@ describe Mongoid::Contextual::Mongo do
2094
2094
  expect(context.update).to be false
2095
2095
  end
2096
2096
  end
2097
+
2098
+ context 'when provided array filters', if: array_filters_supported? do
2099
+
2100
+ before do
2101
+ Band.delete_all
2102
+ b = Band.new(name: 'Depeche Mode')
2103
+ b.labels << Label.new(name: 'Warner')
2104
+ b.labels << Label.new(name: 'Sony')
2105
+ b.labels << Label.new(name: 'Cbs')
2106
+ b.save
2107
+
2108
+ b = Band.new(name: 'FKA Twigs')
2109
+ b.labels << Label.new(name: 'Warner')
2110
+ b.labels << Label.new(name: 'Cbs')
2111
+ b.save
2112
+ end
2113
+
2114
+
2115
+ let(:criteria) do
2116
+ Band.where(name: 'Depeche Mode')
2117
+ end
2118
+
2119
+ let!(:update) do
2120
+ context.update({ '$set' => { 'labels.$[i].name' => 'Sony' } },
2121
+ array_filters: [{ 'i.name' => 'Cbs' }])
2122
+ end
2123
+
2124
+ it 'applies the array filters' do
2125
+ expect(Band.where(name: 'Depeche Mode').first.labels.collect(&:name)).to match_array(['Warner', 'Sony', 'Sony'])
2126
+ end
2127
+
2128
+ it 'does not affect other documents' do
2129
+ expect(Band.where(name: 'FKA Twigs').first.labels.collect(&:name)).to match_array(['Warner', 'Cbs'])
2130
+ end
2131
+ end
2097
2132
  end
2098
2133
 
2099
2134
  describe "#update_all" do
@@ -2231,6 +2266,41 @@ describe Mongoid::Contextual::Mongo do
2231
2266
  expect(context.update_all).to be false
2232
2267
  end
2233
2268
  end
2269
+
2270
+ context 'when provided array filters', if: array_filters_supported? do
2271
+
2272
+ before do
2273
+ Band.delete_all
2274
+ b = Band.new(name: 'Depeche Mode')
2275
+ b.labels << Label.new(name: 'Warner')
2276
+ b.labels << Label.new(name: 'Sony')
2277
+ b.labels << Label.new(name: 'Cbs')
2278
+ b.save
2279
+
2280
+ b = Band.new(name: 'FKA Twigs')
2281
+ b.labels << Label.new(name: 'Warner')
2282
+ b.labels << Label.new(name: 'Cbs')
2283
+ b.save
2284
+ end
2285
+
2286
+
2287
+ let(:criteria) do
2288
+ Band.all
2289
+ end
2290
+
2291
+ let!(:update) do
2292
+ context.update_all({ '$set' => { 'labels.$[i].name' => 'Sony' } },
2293
+ array_filters: [{ 'i.name' => 'Cbs' }])
2294
+ end
2295
+
2296
+ it 'applies the array filters' do
2297
+ expect(Band.where(name: 'Depeche Mode').first.labels.collect(&:name)).to match_array(['Warner', 'Sony', 'Sony'])
2298
+ end
2299
+
2300
+ it 'updates all documents' do
2301
+ expect(Band.where(name: 'FKA Twigs').first.labels.collect(&:name)).to match_array(['Warner', 'Sony'])
2302
+ end
2303
+ end
2234
2304
  end
2235
2305
 
2236
2306
  describe '#pipeline' do
@@ -88,6 +88,17 @@ describe Mongoid::Factory do
88
88
  expect(person.title).to eq("Sir")
89
89
  end
90
90
  end
91
+
92
+ context "when the type is a symbol" do
93
+
94
+ let(:person) do
95
+ described_class.build(Person, {:_type => "Doctor"})
96
+ end
97
+
98
+ it "instantiates the subclass" do
99
+ expect(person.class).to eq(Doctor)
100
+ end
101
+ end
91
102
  end
92
103
 
93
104
  describe ".from_db" do
@@ -189,8 +189,8 @@ describe Mongoid::Persistable::Savable do
189
189
  "title" => "King",
190
190
  "name.first_name" => "Ryan"
191
191
  },
192
- "$pushAll"=> {
193
- "addresses" => [ { "_id" => address.id, "street" => "Bond St" } ]
192
+ "$push"=> {
193
+ "addresses" => { '$each' => [ { "_id" => address.id, "street" => "Bond St" } ] }
194
194
  }
195
195
  })
196
196
  end
@@ -462,7 +462,7 @@ describe Mongoid::Persistable::Updatable do
462
462
 
463
463
  it "raises an error" do
464
464
  expect {
465
- person.update_attributes(map: { "bad.key" => "value" })
465
+ person.update_attributes(map: { "$bad.key" => "value" })
466
466
  }.to raise_error(Mongo::Error::OperationFailure)
467
467
  end
468
468
  end
@@ -498,7 +498,7 @@ describe Mongoid::Persistable::Updatable do
498
498
 
499
499
  it "raises an error" do
500
500
  expect {
501
- person.send(method, map: { "bad.key" => "value" })
501
+ person.send(method, map: { "$bad.key" => "value" })
502
502
  }.to raise_error(Mongo::Error::OperationFailure)
503
503
  end
504
504
  end
@@ -70,6 +70,20 @@ describe Mongoid::PersistenceContext do
70
70
  { collection: :other }
71
71
  end
72
72
 
73
+ context 'when the method throws an error' do
74
+
75
+ let!(:persistence_context) do
76
+ described_class.set(object, options).tap do |cxt|
77
+ allow(cxt).to receive(:client).and_raise(Mongoid::Errors::NoClientConfig.new('default'))
78
+ end
79
+ end
80
+
81
+ it 'clears the context anyway' do
82
+ begin; described_class.clear(object); rescue; end
83
+ expect(described_class.get(object)).to be(nil)
84
+ end
85
+ end
86
+
73
87
  context 'when there has been a persistence context set on the current thread' do
74
88
 
75
89
  let!(:persistence_context) do
@@ -17,8 +17,8 @@ describe Mongoid::Positional do
17
17
  "children.0.field" => "value",
18
18
  "children.0.children.1.children.3.field" => "value"
19
19
  },
20
- "$pushAll" => {
21
- "children.0.children.1.children.3.fields" => [ "value", "value" ]
20
+ "$push" => {
21
+ "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
22
22
  }
23
23
  }
24
24
  end
@@ -113,8 +113,8 @@ describe Mongoid::Positional do
113
113
  "children.$.field" => "value",
114
114
  "children.0.children.1.children.3.field" => "value"
115
115
  },
116
- "$pushAll" => {
117
- "children.0.children.1.children.3.fields" => [ "value", "value" ]
116
+ "$push" => {
117
+ "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
118
118
  }
119
119
  }
120
120
  end
@@ -141,8 +141,8 @@ describe Mongoid::Positional do
141
141
  "children.0.field" => "value",
142
142
  "children.0.children.1.children.3.field" => "value"
143
143
  },
144
- "$pushAll" => {
145
- "children.0.children.1.children.3.fields" => [ "value", "value" ]
144
+ "$push" => {
145
+ "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
146
146
  }
147
147
  }
148
148
  end
@@ -170,8 +170,8 @@ describe Mongoid::Positional do
170
170
  "children.$.field" => "value",
171
171
  "children.0.children.1.children.3.field" => "value"
172
172
  },
173
- "$pushAll" => {
174
- "children.0.children.1.children.3.fields" => [ "value", "value" ]
173
+ "$push" => {
174
+ "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
175
175
  }
176
176
  }
177
177
  end
@@ -203,8 +203,8 @@ describe Mongoid::Positional do
203
203
  "children.$.field" => "value",
204
204
  "children.0.children.1.children.3.field" => "value"
205
205
  },
206
- "$pushAll" => {
207
- "children.0.children.1.children.3.fields" => [ "value", "value" ]
206
+ "$push" => {
207
+ "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
208
208
  }
209
209
  }
210
210
  end
@@ -20,6 +20,26 @@ describe Mongoid::Relations::Macros do
20
20
  klass.validators.clear
21
21
  end
22
22
 
23
+ describe 'Model loading' do
24
+
25
+ let(:model_associations) do
26
+ class TestModel
27
+ include Mongoid::Document
28
+ field :associations
29
+ end
30
+ end
31
+
32
+ after do
33
+ Object.send(:remove_const, :TestModel)
34
+ end
35
+
36
+ it 'prohibits the use of :associations as an attribute' do
37
+ expect {
38
+ model_associations
39
+ }.to raise_exception(Mongoid::Errors::InvalidField)
40
+ end
41
+ end
42
+
23
43
  describe ".embedded_in" do
24
44
 
25
45
  it "defines the macro" do
@@ -928,6 +928,60 @@ describe Mongoid::Relations::Targets::Enumerable do
928
928
  end
929
929
  end
930
930
  end
931
+
932
+ context 'when the id_sort option is none' do
933
+
934
+ let(:person) do
935
+ Person.create
936
+ end
937
+
938
+ let(:criteria) do
939
+ Post.where(person_id: person.id)
940
+ end
941
+
942
+ let(:enumerable) do
943
+ described_class.new(criteria)
944
+ end
945
+
946
+ let!(:first_post) do
947
+ person.posts.create(title: "One")
948
+ end
949
+
950
+ let!(:second_post) do
951
+ person.posts.create(title: "Two")
952
+ end
953
+
954
+ it 'does not use the sort on id' do
955
+ expect(enumerable.first(id_sort: :none)).to eq(first_post)
956
+ end
957
+ end
958
+
959
+ context 'when the id_sort option is not provided' do
960
+
961
+ let(:person) do
962
+ Person.create
963
+ end
964
+
965
+ let(:criteria) do
966
+ Post.where(person_id: person.id)
967
+ end
968
+
969
+ let(:enumerable) do
970
+ described_class.new(criteria)
971
+ end
972
+
973
+ let!(:first_post) do
974
+ person.posts.create(title: "One")
975
+ end
976
+
977
+ let!(:second_post) do
978
+ person.posts.create(title: "Two")
979
+ end
980
+
981
+ it 'uses the sort on id' do
982
+ expect(enumerable.first).to eq(first_post)
983
+ end
984
+ end
931
985
  end
932
986
 
933
987
  describe "#include?" do
@@ -1344,6 +1398,60 @@ describe Mongoid::Relations::Targets::Enumerable do
1344
1398
  end
1345
1399
  end
1346
1400
  end
1401
+
1402
+ context 'when the id_sort option is none' do
1403
+
1404
+ let(:person) do
1405
+ Person.create
1406
+ end
1407
+
1408
+ let(:criteria) do
1409
+ Post.where(person_id: person.id)
1410
+ end
1411
+
1412
+ let(:enumerable) do
1413
+ described_class.new(criteria)
1414
+ end
1415
+
1416
+ let!(:first_post) do
1417
+ person.posts.create(title: "One")
1418
+ end
1419
+
1420
+ let!(:second_post) do
1421
+ person.posts.create(title: "Two")
1422
+ end
1423
+
1424
+ it 'does not use the sort on id' do
1425
+ expect(enumerable.last(id_sort: :none)).to eq(first_post)
1426
+ end
1427
+ end
1428
+
1429
+ context 'when the id_sort option is not provided' do
1430
+
1431
+ let(:person) do
1432
+ Person.create
1433
+ end
1434
+
1435
+ let(:criteria) do
1436
+ Post.where(person_id: person.id)
1437
+ end
1438
+
1439
+ let(:enumerable) do
1440
+ described_class.new(criteria)
1441
+ end
1442
+
1443
+ let!(:first_post) do
1444
+ person.posts.create(title: "One")
1445
+ end
1446
+
1447
+ let!(:second_post) do
1448
+ person.posts.create(title: "Two")
1449
+ end
1450
+
1451
+ it 'uses the sort on id' do
1452
+ expect(enumerable.last).to eq(second_post)
1453
+ end
1454
+ end
1347
1455
  end
1348
1456
 
1349
1457
  describe "#kind_of?" do