mongoid 6.0.3 → 6.1.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +3 -2
  4. data/lib/config/locales/en.yml +15 -0
  5. data/lib/mongoid.rb +5 -0
  6. data/lib/mongoid/clients.rb +10 -2
  7. data/lib/mongoid/clients/factory.rb +2 -0
  8. data/lib/mongoid/config.rb +1 -0
  9. data/lib/mongoid/contextual/map_reduce.rb +20 -115
  10. data/lib/mongoid/contextual/memory.rb +1 -0
  11. data/lib/mongoid/contextual/mongo.rb +16 -13
  12. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  13. data/lib/mongoid/criteria/queryable/optional.rb +14 -0
  14. data/lib/mongoid/errors.rb +1 -0
  15. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +20 -0
  16. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  17. data/lib/mongoid/extensions.rb +1 -0
  18. data/lib/mongoid/extensions/decimal128.rb +39 -0
  19. data/lib/mongoid/indexable/validators/options.rb +2 -1
  20. data/lib/mongoid/persistable/deletable.rb +3 -7
  21. data/lib/mongoid/query_cache.rb +2 -2
  22. data/lib/mongoid/relations/metadata.rb +3 -3
  23. data/lib/mongoid/relations/referenced/many.rb +2 -2
  24. data/lib/mongoid/version.rb +1 -1
  25. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -0
  26. data/spec/app/models/band.rb +1 -0
  27. data/spec/config/mongoid.yml +19 -0
  28. data/spec/mongoid/clients/factory_spec.rb +8 -0
  29. data/spec/mongoid/clients_spec.rb +69 -0
  30. data/spec/mongoid/config_spec.rb +34 -2
  31. data/spec/mongoid/contextual/atomic_spec.rb +342 -76
  32. data/spec/mongoid/contextual/map_reduce_spec.rb +102 -135
  33. data/spec/mongoid/contextual/memory_spec.rb +316 -56
  34. data/spec/mongoid/contextual/mongo_spec.rb +366 -4
  35. data/spec/mongoid/criteria/queryable/optional_spec.rb +13 -0
  36. data/spec/mongoid/criteria_spec.rb +19 -0
  37. data/spec/mongoid/extensions/boolean_spec.rb +14 -0
  38. data/spec/mongoid/extensions/decimal128_spec.rb +44 -0
  39. data/spec/mongoid/indexable_spec.rb +43 -0
  40. data/spec/mongoid/query_cache_spec.rb +34 -0
  41. data/spec/mongoid/relations/metadata_spec.rb +0 -1
  42. data/spec/mongoid/relations/referenced/many_spec.rb +11 -0
  43. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +11 -0
  44. data/spec/mongoid/scopable_spec.rb +12 -0
  45. data/spec/spec_helper.rb +9 -0
  46. metadata +17 -7
  47. metadata.gz.sig +0 -0
@@ -27,6 +27,7 @@ require "mongoid/extensions/big_decimal"
27
27
  require "mongoid/extensions/boolean"
28
28
  require "mongoid/extensions/date"
29
29
  require "mongoid/extensions/date_time"
30
+ require "mongoid/extensions/decimal128"
30
31
  require "mongoid/extensions/false_class"
31
32
  require "mongoid/extensions/float"
32
33
  require "mongoid/extensions/hash"
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Extensions
4
+ module Decimal128
5
+
6
+ # Evolve the decimal128.
7
+ #
8
+ # @example Evolve the decimal128.
9
+ # decimal128.__evolve_decimal128__
10
+ #
11
+ # @return [ BSON::Decimal128 ] self.
12
+ #
13
+ # @since 6.1.0
14
+ def __evolve_decimal128__
15
+ self
16
+ end
17
+
18
+ module ClassMethods
19
+
20
+ # Evolve the object into a mongo-friendly value to query with.
21
+ #
22
+ # @example Evolve the object.
23
+ # Decimal128.evolve(dec)
24
+ #
25
+ # @param [ Object ] object The object to evolve.
26
+ #
27
+ # @return [ BSON::Decimal128 ] The decimal128.
28
+ #
29
+ # @since 6.1.0
30
+ def evolve(object)
31
+ object.__evolve_decimal128__
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ BSON::Decimal128.__send__(:include, Mongoid::Extensions::Decimal128)
39
+ BSON::Decimal128.extend(Mongoid::Extensions::Decimal128::ClassMethods)
@@ -27,7 +27,8 @@ module Mongoid
27
27
  :sphere_version,
28
28
  :text_version,
29
29
  :version,
30
- :partial_filter_expression
30
+ :partial_filter_expression,
31
+ :collation
31
32
  ]
32
33
 
33
34
  VALID_TYPES = [
@@ -135,13 +135,9 @@ module Mongoid
135
135
  # @return [ Integer ] The number of documents deleted.
136
136
  #
137
137
  # @since 1.0.0
138
- def delete_all(conditions = nil)
139
- selector = conditions || {}
140
- selector.merge!(_type: name) if hereditary?
141
- coll = collection
142
- deleted = coll.find(selector).count
143
- coll.find(selector).delete_many
144
- deleted
138
+ def delete_all(conditions = {})
139
+ selector = hereditary? ? conditions.merge(_type: name) : conditions
140
+ collection.find(selector).delete_many.deleted_count
145
141
  end
146
142
  end
147
143
  end
@@ -237,7 +237,7 @@ module Mongoid
237
237
 
238
238
  def cached_cursor
239
239
  if limit
240
- key = [ collection.namespace, selector, nil, skip, sort, projection ]
240
+ key = [ collection.namespace, selector, nil, skip, sort, projection, collation ]
241
241
  cursor = QueryCache.cache_table[key]
242
242
  if cursor
243
243
  limited_docs = cursor.to_a[0...limit.abs]
@@ -248,7 +248,7 @@ module Mongoid
248
248
  end
249
249
 
250
250
  def cache_key
251
- [ collection.namespace, selector, limit, skip, sort, projection ]
251
+ [ collection.namespace, selector, limit, skip, sort, projection, collation ]
252
252
  end
253
253
 
254
254
  def system_collection?
@@ -778,10 +778,10 @@ module Mongoid
778
778
  #
779
779
  # @since 2.0.0.rc.1
780
780
  def validate?
781
- unless self[:validate].nil?
782
- self[:validate]
783
- else
781
+ if self[:validate].nil?
784
782
  self[:validate] = relation.validation_default
783
+ else
784
+ self[:validate]
785
785
  end
786
786
  end
787
787
 
@@ -803,8 +803,8 @@ module Mongoid
803
803
  # @since 3.0.0
804
804
  def with_inverse_field_criterion(criteria, metadata)
805
805
  inverse_metadata = metadata.inverse_metadata(metadata.klass)
806
- if inverse_metadata.try(:inverse_of_field)
807
- criteria.any_in(inverse_metadata.inverse_of_field => [ metadata.name, nil ])
806
+ if inverse_metadata.try(:inverse_of)
807
+ criteria.any_in(inverse_metadata.inverse_of => [ metadata.name, nil ])
808
808
  else
809
809
  criteria
810
810
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid
3
- VERSION = "6.0.3"
3
+ VERSION = "6.1.0.rc0"
4
4
  end
@@ -131,6 +131,10 @@ development:
131
131
  # environment. The Mongoid logger will be set to the Rails logger
132
132
  # otherwise.(default: :info)
133
133
  # log_level: :info
134
+
135
+ # Application name that is printed to the mongodb logs upon establishing a
136
+ # connection in server versions >= 3.4. Note that the name cannot exceed 128 bytes.
137
+ # app_name: MyApplicationName
134
138
  test:
135
139
  clients:
136
140
  default:
@@ -13,6 +13,7 @@ class Band
13
13
  field :upserted, type: Mongoid::Boolean, default: false
14
14
  field :created, type: DateTime
15
15
  field :sales, type: BigDecimal
16
+ field :decimal, type: BSON::Decimal128
16
17
  field :y, as: :years, type: Integer
17
18
  field :founded, type: Date
18
19
  field :deleted, type: Boolean
@@ -13,6 +13,14 @@ test:
13
13
  tag_sets:
14
14
  - use: web
15
15
  max_pool_size: 1
16
+ reports:
17
+ database: reports
18
+ hosts:
19
+ - <%=ENV["MONGOID_SPEC_HOST"]%>:<%=ENV["MONGOID_SPEC_PORT"]%>
20
+ options:
21
+ user: "mongoid-user"
22
+ password: "password"
23
+ auth_source: "admin"
16
24
  options:
17
25
  include_root_in_json: false
18
26
  include_type_for_serialization: false
@@ -23,3 +31,14 @@ test:
23
31
  use_utc: false
24
32
  log_level: :warn
25
33
  belongs_to_required_by_default: false
34
+ app_name: 'testing'
35
+ test_with_max_staleness:
36
+ clients:
37
+ default:
38
+ database: mongoid_test
39
+ hosts:
40
+ - <%=ENV["MONGOID_SPEC_HOST"]%>:<%=ENV["MONGOID_SPEC_PORT"]%>
41
+ options:
42
+ read:
43
+ mode: :primary_preferred
44
+ max_staleness: 100
@@ -40,6 +40,10 @@ describe Mongoid::Clients::Factory do
40
40
  it "sets the cluster's seeds" do
41
41
  expect(cluster.addresses.first.to_s).to eq("127.0.0.1:27017")
42
42
  end
43
+
44
+ it "sets the platform to Mongoid's platform constant" do
45
+ expect(client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
46
+ end
43
47
  end
44
48
 
45
49
  context "when the configuration has no ports" do
@@ -308,5 +312,9 @@ describe Mongoid::Clients::Factory do
308
312
  it "sets the write concern" do
309
313
  expect(client.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
310
314
  end
315
+
316
+ it "sets the platform to Mongoid's platform constant" do
317
+ expect(client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
318
+ end
311
319
  end
312
320
  end
@@ -524,6 +524,14 @@ describe Mongoid::Clients do
524
524
  it "returns the default client" do
525
525
  expect(mongo_client.options[:database].to_s).to eq(database_id)
526
526
  end
527
+
528
+ it "sets the platform to Mongoid's platform constant" do
529
+ expect(mongo_client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
530
+ end
531
+
532
+ it "sets the app_name to the config value" do
533
+ expect(mongo_client.options[:app_name]).to eq('testing')
534
+ end
527
535
  end
528
536
 
529
537
  context "when no client exists with the key" do
@@ -542,6 +550,59 @@ describe Mongoid::Clients do
542
550
  }.to raise_error(Mongoid::Errors::NoClientConfig)
543
551
  end
544
552
  end
553
+
554
+ context "when getting a client by name" do
555
+
556
+ let(:file) do
557
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
558
+ end
559
+
560
+ before do
561
+ described_class.clear
562
+ Mongoid.load!(file, :test)
563
+ Band.store_in(client: :reports)
564
+ end
565
+
566
+ after do
567
+ mongo_client.close
568
+ Mongoid::Config.reset
569
+ Band.reset_storage_options!
570
+ end
571
+
572
+ let(:mongo_client) do
573
+ Band.new.mongo_client
574
+ end
575
+
576
+ it "uses the reports client" do
577
+ expect(mongo_client.options[:database].to_s).to eq('reports')
578
+ end
579
+
580
+ it "sets the platform to Mongoid's platform constant" do
581
+ expect(mongo_client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
582
+ end
583
+
584
+ it "sets the app_name to the config value" do
585
+ expect(mongo_client.options[:app_name]).to eq('testing')
586
+ end
587
+ end
588
+
589
+ context 'when the app_name is not set in the config' do
590
+
591
+ before do
592
+ Mongoid::Config.reset
593
+ Mongoid.configure do |config|
594
+ config.load_configuration(CONFIG)
595
+ end
596
+ end
597
+
598
+ let(:mongo_client) do
599
+ Band.new.mongo_client
600
+ end
601
+
602
+ it 'does not set the Mongoid.app_name option' do
603
+ expect(mongo_client.options.has_key?(:app_name)).to be(false)
604
+ end
605
+ end
545
606
  end
546
607
 
547
608
  describe ".mongo_client" do
@@ -580,6 +641,14 @@ describe Mongoid::Clients do
580
641
  it "returns the default client" do
581
642
  expect(mongo_client.options[:database].to_s).to eq(database_id)
582
643
  end
644
+
645
+ it "sets the platform to Mongoid's platform constant" do
646
+ expect(mongo_client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
647
+ end
648
+
649
+ it "sets the app_name to the config value" do
650
+ expect(mongo_client.options[:app_name]).to eq('testing')
651
+ end
583
652
  end
584
653
 
585
654
  context "when no client exists with the key" do
@@ -128,6 +128,7 @@ describe Mongoid::Config do
128
128
  end
129
129
 
130
130
  before do
131
+ Mongoid::Config.reset
131
132
  Mongoid.configure do |config|
132
133
  config.load_configuration(conf)
133
134
  end
@@ -139,6 +140,37 @@ describe Mongoid::Config do
139
140
  end
140
141
  end
141
142
 
143
+ context 'when the app_name is set in the config' do
144
+
145
+ let(:conf) do
146
+ CONFIG.merge(options: { app_name: 'admin-reporting' })
147
+ end
148
+
149
+ before do
150
+ Mongoid.configure do |config|
151
+ config.load_configuration(conf)
152
+ end
153
+ end
154
+
155
+ it 'sets the Mongoid.app_name to the provided value' do
156
+ expect(Mongoid.app_name).to eq('admin-reporting')
157
+ end
158
+ end
159
+
160
+ context 'when the app_name is not set in the config' do
161
+
162
+ before do
163
+ Mongoid::Config.reset
164
+ Mongoid.configure do |config|
165
+ config.load_configuration(CONFIG)
166
+ end
167
+ end
168
+
169
+ it 'does not set the Mongoid.app_name option' do
170
+ expect(Mongoid.app_name).to be_nil
171
+ end
172
+ end
173
+
142
174
  describe "#load!" do
143
175
 
144
176
  before(:all) do
@@ -306,7 +338,7 @@ describe Mongoid::Config do
306
338
  context "when a default is provided" do
307
339
 
308
340
  before do
309
- described_class.load!(file)
341
+ described_class.load!(file, :test_with_max_staleness)
310
342
  end
311
343
 
312
344
  let(:default) do
@@ -325,7 +357,7 @@ describe Mongoid::Config do
325
357
 
326
358
  it "sets the read option" do
327
359
  expect(options["read"]).to eq({ "mode" => :primary_preferred,
328
- "tag_sets" => [{ "use" => "web" }]})
360
+ "max_staleness" => 100 })
329
361
  end
330
362
  end
331
363
  end
@@ -73,6 +73,29 @@ describe Mongoid::Contextual::Atomic do
73
73
  expect(smiths.reload.members).to eq([ "Dave" ])
74
74
  end
75
75
  end
76
+
77
+ context 'when the criteria has a collation', if: collation_supported? do
78
+
79
+ let(:criteria) do
80
+ Band.where(members: [ "DAVE" ]).collation(locale: 'en_US', strength: 2)
81
+ end
82
+
83
+ let(:context) do
84
+ Mongoid::Contextual::Mongo.new(criteria)
85
+ end
86
+
87
+ before do
88
+ context.add_to_set(members: "Dave", genres: "Electro")
89
+ end
90
+
91
+ it "does not add duplicates" do
92
+ expect(depeche_mode.reload.members).to eq([ "Dave" ])
93
+ end
94
+
95
+ it "adds multiple operations" do
96
+ expect(depeche_mode.reload.genres).to eq([ "Electro" ])
97
+ end
98
+ end
76
99
  end
77
100
 
78
101
  describe "#bit" do
@@ -121,6 +144,29 @@ describe Mongoid::Contextual::Atomic do
121
144
  expect(depeche_mode.reload.likes).to eq(14)
122
145
  end
123
146
  end
147
+
148
+ context 'when the criteria has a collation', if: collation_supported? do
149
+
150
+ let!(:depeche_mode) do
151
+ Band.create(members: [ "Dave" ], likes: 60)
152
+ end
153
+
154
+ let(:criteria) do
155
+ Band.where(members: [ "DAVE" ]).collation(locale: 'en_US', strength: 2)
156
+ end
157
+
158
+ let(:context) do
159
+ Mongoid::Contextual::Mongo.new(criteria)
160
+ end
161
+
162
+ before do
163
+ context.bit(likes: { and: 13, or: 10 })
164
+ end
165
+
166
+ it "performs the bitwise operation on initialized fields" do
167
+ expect(depeche_mode.reload.likes).to eq(14)
168
+ end
169
+ end
124
170
  end
125
171
 
126
172
  describe "#inc" do
@@ -177,6 +223,29 @@ describe Mongoid::Contextual::Atomic do
177
223
  expect(beatles.reload.y).to eq(3)
178
224
  end
179
225
  end
226
+
227
+ context 'when the criteria has a collation', if: collation_supported? do
228
+
229
+ let!(:depeche_mode) do
230
+ Band.create(members: [ "Dave" ])
231
+ end
232
+
233
+ let(:criteria) do
234
+ Band.where(members: [ "DAVE" ]).collation(locale: 'en_US', strength: 2)
235
+ end
236
+
237
+ let(:context) do
238
+ Mongoid::Contextual::Mongo.new(criteria)
239
+ end
240
+
241
+ before do
242
+ context.inc(years: 1)
243
+ end
244
+
245
+ it "incs the value and read from alias" do
246
+ expect(depeche_mode.reload.years).to eq(1)
247
+ end
248
+ end
180
249
  end
181
250
 
182
251
  describe "#pop" do
@@ -226,6 +295,29 @@ describe Mongoid::Contextual::Atomic do
226
295
  expect(smiths.reload.members).to be_nil
227
296
  end
228
297
  end
298
+
299
+ context 'when the criteria has a collation', if: collation_supported? do
300
+
301
+ let!(:depeche_mode) do
302
+ Band.create(members: [ "Dave" ])
303
+ end
304
+
305
+ let(:criteria) do
306
+ Band.where(members: [ "DAVE" ]).collation(locale: 'en_US', strength: 2)
307
+ end
308
+
309
+ let(:context) do
310
+ Mongoid::Contextual::Mongo.new(criteria)
311
+ end
312
+
313
+ before do
314
+ context.pop(members: 1)
315
+ end
316
+
317
+ it "pops the last element off the array" do
318
+ expect(depeche_mode.reload.members).to be_empty
319
+ end
320
+ end
229
321
  end
230
322
 
231
323
  describe "#pull" do
@@ -257,129 +349,276 @@ describe Mongoid::Contextual::Atomic do
257
349
  it "does not error on non existent fields" do
258
350
  expect(smiths.reload.members).to be_nil
259
351
  end
352
+
353
+ context 'when the criteria has a collation', if: collation_supported? do
354
+
355
+ let!(:depeche_mode) do
356
+ Band.create(members: [ "Dave" ])
357
+ end
358
+
359
+ let(:criteria) do
360
+ Band.where(members: [ "DAVE" ]).collation(locale: 'en_US', strength: 2)
361
+ end
362
+
363
+ let(:context) do
364
+ Mongoid::Contextual::Mongo.new(criteria)
365
+ end
366
+
367
+ before do
368
+ context.pull(members: "DAVE")
369
+ end
370
+
371
+ it "pulls when the value is found" do
372
+ expect(depeche_mode.reload.members).to be_empty
373
+ end
374
+ end
260
375
  end
261
376
 
262
377
  describe "#pull_all" do
263
378
 
264
- let!(:depeche_mode) do
265
- Band.create(members: [ "Dave", "Alan", "Fletch" ])
266
- end
379
+ context 'when the criteria does not have a collation' do
267
380
 
268
- let!(:smiths) do
269
- Band.create
270
- end
381
+ let!(:depeche_mode) do
382
+ Band.create(members: [ "Dave", "Alan", "Fletch" ])
383
+ end
271
384
 
272
- let(:criteria) do
273
- Band.all
274
- end
385
+ let!(:smiths) do
386
+ Band.create
387
+ end
275
388
 
276
- let(:context) do
277
- Mongoid::Contextual::Mongo.new(criteria)
278
- end
389
+ let(:criteria) do
390
+ Band.all
391
+ end
279
392
 
280
- before do
281
- context.pull_all(members: [ "Alan", "Dave" ])
282
- end
393
+ let(:context) do
394
+ Mongoid::Contextual::Mongo.new(criteria)
395
+ end
396
+
397
+ before do
398
+ context.pull_all(members: [ "Alan", "Dave" ])
399
+ end
283
400
 
284
- it "pulls when the values are found" do
285
- expect(depeche_mode.reload.members).to eq([ "Fletch" ])
401
+ it "pulls when the values are found" do
402
+ expect(depeche_mode.reload.members).to eq([ "Fletch" ])
403
+ end
404
+
405
+ it "does not error on non existent fields" do
406
+ expect(smiths.reload.members).to be_nil
407
+ end
286
408
  end
287
409
 
288
- it "does not error on non existent fields" do
289
- expect(smiths.reload.members).to be_nil
410
+ context 'when the criteria has a collation', if: collation_supported? do
411
+
412
+ let!(:depeche_mode) do
413
+ Band.create(members: [ "Dave", "Alan", "Fletch" ])
414
+ end
415
+
416
+ let(:criteria) do
417
+ Band.all.collation(locale: 'en_US', strength: 2)
418
+ end
419
+
420
+ let(:context) do
421
+ Mongoid::Contextual::Mongo.new(criteria)
422
+ end
423
+
424
+ before do
425
+ context.pull_all(members: [ "ALAN", "DAVE" ])
426
+ end
427
+
428
+ it "pulls when the value is found" do
429
+ expect(depeche_mode.reload.members).to eq([ "Fletch" ])
430
+ end
290
431
  end
291
432
  end
292
433
 
293
434
  describe "#push" do
294
435
 
295
- let!(:depeche_mode) do
296
- Band.create(members: [ "Dave" ])
297
- end
436
+ context 'when the criteria does not have a collation' do
298
437
 
299
- let!(:smiths) do
300
- Band.create
301
- end
438
+ let!(:depeche_mode) do
439
+ Band.create(members: [ "Dave" ])
440
+ end
302
441
 
303
- let(:criteria) do
304
- Band.all
305
- end
442
+ let!(:smiths) do
443
+ Band.create
444
+ end
306
445
 
307
- let(:context) do
308
- Mongoid::Contextual::Mongo.new(criteria)
309
- end
446
+ let(:criteria) do
447
+ Band.all
448
+ end
310
449
 
311
- before do
312
- context.push(members: "Alan")
313
- end
450
+ let(:context) do
451
+ Mongoid::Contextual::Mongo.new(criteria)
452
+ end
453
+
454
+ before do
455
+ context.push(members: "Alan")
456
+ end
457
+
458
+ it "pushes the value to existing arrays" do
459
+ expect(depeche_mode.reload.members).to eq([ "Dave", "Alan" ])
460
+ end
314
461
 
315
- it "pushes the value to existing arrays" do
316
- expect(depeche_mode.reload.members).to eq([ "Dave", "Alan" ])
462
+ it "pushes to non existent fields" do
463
+ expect(smiths.reload.members).to eq([ "Alan" ])
464
+ end
317
465
  end
318
466
 
319
- it "pushes to non existent fields" do
320
- expect(smiths.reload.members).to eq([ "Alan" ])
467
+ context 'when the criteria has a collation', if: collation_supported? do
468
+
469
+ let!(:depeche_mode) do
470
+ Band.create(members: [ "Dave" ])
471
+ end
472
+
473
+ let!(:smiths) do
474
+ Band.create
475
+ end
476
+
477
+ let(:criteria) do
478
+ Band.where(members: ['DAVE']).collation(locale: 'en_US', strength: 2)
479
+ end
480
+
481
+ let(:context) do
482
+ Mongoid::Contextual::Mongo.new(criteria)
483
+ end
484
+
485
+ before do
486
+ context.push(members: "Alan")
487
+ end
488
+
489
+ it "pushes the value to existing arrays" do
490
+ expect(depeche_mode.reload.members).to eq([ "Dave", "Alan" ])
491
+ end
492
+
493
+ it "pushes to non existent fields" do
494
+ expect(smiths.reload.members).to be_nil
495
+ end
321
496
  end
322
497
  end
323
498
 
324
499
  describe "#push_all" do
325
500
 
326
- let!(:depeche_mode) do
327
- Band.create(members: [ "Dave" ])
328
- end
501
+ context 'when the criteria does not have a collation' do
329
502
 
330
- let!(:smiths) do
331
- Band.create
332
- end
503
+ let!(:depeche_mode) do
504
+ Band.create(members: [ "Dave" ])
505
+ end
333
506
 
334
- let(:criteria) do
335
- Band.all
336
- end
507
+ let!(:smiths) do
508
+ Band.create
509
+ end
337
510
 
338
- let(:context) do
339
- Mongoid::Contextual::Mongo.new(criteria)
340
- end
511
+ let(:criteria) do
512
+ Band.all
513
+ end
341
514
 
342
- before do
343
- context.push_all(members: [ "Alan", "Fletch" ])
344
- end
515
+ let(:context) do
516
+ Mongoid::Contextual::Mongo.new(criteria)
517
+ end
518
+
519
+ before do
520
+ context.push_all(members: [ "Alan", "Fletch" ])
521
+ end
345
522
 
346
- it "pushes the values to existing arrays" do
347
- expect(depeche_mode.reload.members).to eq([ "Dave", "Alan", "Fletch" ])
523
+ it "pushes the values to existing arrays" do
524
+ expect(depeche_mode.reload.members).to eq([ "Dave", "Alan", "Fletch" ])
525
+ end
526
+
527
+ it "pushes to non existent fields" do
528
+ expect(smiths.reload.members).to eq([ "Alan", "Fletch" ])
529
+ end
348
530
  end
349
531
 
350
- it "pushes to non existent fields" do
351
- expect(smiths.reload.members).to eq([ "Alan", "Fletch" ])
532
+ context 'when the criteria has a collation', if: collation_supported? do
533
+
534
+ let!(:depeche_mode) do
535
+ Band.create(members: [ "Dave" ])
536
+ end
537
+
538
+ let!(:smiths) do
539
+ Band.create
540
+ end
541
+
542
+ let(:criteria) do
543
+ Band.where(members: ['DAVE']).collation(locale: 'en_US', strength: 2)
544
+ end
545
+
546
+ let(:context) do
547
+ Mongoid::Contextual::Mongo.new(criteria)
548
+ end
549
+
550
+ before do
551
+ context.push_all(members: [ "Alan", "Fletch" ])
552
+ end
553
+
554
+ it "pushes the values to existing arrays" do
555
+ expect(depeche_mode.reload.members).to eq([ "Dave", "Alan", "Fletch" ])
556
+ end
352
557
  end
353
558
  end
354
559
 
355
560
  describe "#rename" do
356
561
 
357
- let!(:depeche_mode) do
358
- Band.create(members: [ "Dave" ])
359
- end
562
+ context 'when the criteria does not have a collation' do
360
563
 
361
- let!(:smiths) do
362
- Band.create
363
- end
564
+ let!(:depeche_mode) do
565
+ Band.create(members: [ "Dave" ])
566
+ end
364
567
 
365
- let(:criteria) do
366
- Band.all
367
- end
568
+ let!(:smiths) do
569
+ Band.create
570
+ end
368
571
 
369
- let(:context) do
370
- Mongoid::Contextual::Mongo.new(criteria)
371
- end
572
+ let(:criteria) do
573
+ Band.all
574
+ end
372
575
 
373
- before do
374
- context.rename(members: :artists)
375
- end
576
+ let(:context) do
577
+ Mongoid::Contextual::Mongo.new(criteria)
578
+ end
376
579
 
377
- it "renames existing fields" do
378
- expect(depeche_mode.reload.artists).to eq([ "Dave" ])
580
+ before do
581
+ context.rename(members: :artists)
582
+ end
583
+
584
+ it "renames existing fields" do
585
+ expect(depeche_mode.reload.artists).to eq([ "Dave" ])
586
+ end
587
+
588
+ it "does not rename non existent fields" do
589
+ expect(smiths.reload).to_not respond_to(:artists)
590
+ end
379
591
  end
380
592
 
381
- it "does not rename non existent fields" do
382
- expect(smiths.reload).to_not respond_to(:artists)
593
+ context 'when the criteria has a collation', if: collation_supported? do
594
+
595
+ let!(:depeche_mode) do
596
+ Band.create(members: [ "Dave" ])
597
+ end
598
+
599
+ let!(:smiths) do
600
+ Band.create
601
+ end
602
+
603
+ let(:criteria) do
604
+ Band.where(members: ['DAVE']).collation(locale: 'en_US', strength: 2)
605
+ end
606
+
607
+ let(:context) do
608
+ Mongoid::Contextual::Mongo.new(criteria)
609
+ end
610
+
611
+ before do
612
+ context.rename(members: :artists)
613
+ end
614
+
615
+ it "renames existing fields" do
616
+ expect(depeche_mode.reload.artists).to eq([ "Dave" ])
617
+ end
618
+
619
+ it "does not rename non existent fields" do
620
+ expect(smiths.reload).to_not respond_to(:artists)
621
+ end
383
622
  end
384
623
  end
385
624
 
@@ -509,5 +748,32 @@ describe Mongoid::Contextual::Atomic do
509
748
  end
510
749
  end
511
750
  end
751
+
752
+ context 'when the criteria has a collation', if: collation_supported? do
753
+
754
+ let!(:depeche_mode) do
755
+ Band.create(name: "Depeche Mode", years: 10)
756
+ end
757
+
758
+ let!(:new_order) do
759
+ Band.create(name: "New Order", years: 10)
760
+ end
761
+
762
+ let(:criteria) do
763
+ Band.where(name: 'DEPECHE MODE').collation(locale: 'en_US', strength: 2)
764
+ end
765
+
766
+ let(:context) do
767
+ Mongoid::Contextual::Mongo.new(criteria)
768
+ end
769
+
770
+ before do
771
+ context.unset(:name)
772
+ end
773
+
774
+ it "unsets the unaliased field" do
775
+ expect(depeche_mode.reload.name).to be_nil
776
+ end
777
+ end
512
778
  end
513
779
  end