mongoid 6.0.3 → 6.1.0.rc0

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 (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