mongoid 7.2.3 → 7.3.0

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 (152) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +16 -0
  5. data/lib/config/locales/en.yml +2 -2
  6. data/lib/mongoid/association/accessors.rb +1 -1
  7. data/lib/mongoid/association/constrainable.rb +1 -1
  8. data/lib/mongoid/association/depending.rb +4 -4
  9. data/lib/mongoid/association/embedded/batchable.rb +1 -1
  10. data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
  11. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +10 -3
  12. data/lib/mongoid/association/nested/many.rb +1 -1
  13. data/lib/mongoid/association/nested/one.rb +4 -2
  14. data/lib/mongoid/association/proxy.rb +6 -1
  15. data/lib/mongoid/association/referenced/auto_save.rb +2 -2
  16. data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -495
  17. data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
  18. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
  19. data/lib/mongoid/attributes.rb +24 -13
  20. data/lib/mongoid/attributes/projector.rb +120 -0
  21. data/lib/mongoid/cacheable.rb +2 -2
  22. data/lib/mongoid/clients.rb +1 -1
  23. data/lib/mongoid/clients/factory.rb +22 -8
  24. data/lib/mongoid/config.rb +19 -2
  25. data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
  26. data/lib/mongoid/copyable.rb +1 -1
  27. data/lib/mongoid/criteria.rb +4 -5
  28. data/lib/mongoid/criteria/findable.rb +1 -1
  29. data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
  30. data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
  31. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  32. data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
  33. data/lib/mongoid/criteria/queryable/selectable.rb +8 -8
  34. data/lib/mongoid/document.rb +1 -15
  35. data/lib/mongoid/errors/delete_restriction.rb +8 -9
  36. data/lib/mongoid/evolvable.rb +1 -1
  37. data/lib/mongoid/extensions/boolean.rb +1 -2
  38. data/lib/mongoid/extensions/false_class.rb +1 -1
  39. data/lib/mongoid/extensions/hash.rb +2 -2
  40. data/lib/mongoid/extensions/true_class.rb +1 -1
  41. data/lib/mongoid/fields.rb +43 -5
  42. data/lib/mongoid/inspectable.rb +1 -1
  43. data/lib/mongoid/matcher.rb +7 -0
  44. data/lib/mongoid/matcher/bits.rb +41 -0
  45. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  46. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  47. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  48. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  49. data/lib/mongoid/matcher/expression.rb +4 -0
  50. data/lib/mongoid/matcher/field_operator.rb +6 -0
  51. data/lib/mongoid/matcher/mod.rb +17 -0
  52. data/lib/mongoid/matcher/type.rb +99 -0
  53. data/lib/mongoid/persistable/deletable.rb +1 -2
  54. data/lib/mongoid/persistable/destroyable.rb +8 -2
  55. data/lib/mongoid/persistable/updatable.rb +27 -2
  56. data/lib/mongoid/query_cache.rb +35 -29
  57. data/lib/mongoid/selectable.rb +5 -7
  58. data/lib/mongoid/shardable.rb +21 -5
  59. data/lib/mongoid/touchable.rb +23 -4
  60. data/lib/mongoid/version.rb +1 -1
  61. data/spec/integration/associations/embeds_many_spec.rb +44 -0
  62. data/spec/integration/associations/has_one_spec.rb +48 -0
  63. data/spec/integration/criteria/date_field_spec.rb +1 -1
  64. data/spec/integration/document_spec.rb +9 -0
  65. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  66. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  67. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  68. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  69. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  70. data/spec/integration/matcher_operator_data/in.yml +16 -0
  71. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  72. data/spec/integration/matcher_operator_data/type.yml +70 -0
  73. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  74. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  75. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  76. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  77. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  78. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  79. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  80. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  81. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  82. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  83. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  84. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  85. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  86. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  87. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  88. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  89. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  90. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  91. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  92. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  93. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  94. data/spec/lite_spec_helper.rb +2 -0
  95. data/spec/mongoid/association/depending_spec.rb +391 -352
  96. data/spec/mongoid/association/nested/one_spec.rb +18 -14
  97. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -8
  98. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
  99. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
  100. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -1
  101. data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
  102. data/spec/mongoid/atomic/paths_spec.rb +64 -12
  103. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  104. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  105. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  106. data/spec/mongoid/attributes_spec.rb +98 -6
  107. data/spec/mongoid/clients/factory_spec.rb +48 -0
  108. data/spec/mongoid/config_spec.rb +32 -0
  109. data/spec/mongoid/contextual/mongo_spec.rb +2 -2
  110. data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
  111. data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
  112. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
  113. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
  114. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +229 -24
  115. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  116. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
  117. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  118. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  119. data/spec/mongoid/criteria_spec.rb +0 -275
  120. data/spec/mongoid/document_spec.rb +13 -13
  121. data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
  122. data/spec/mongoid/extensions/false_class_spec.rb +1 -1
  123. data/spec/mongoid/extensions/string_spec.rb +5 -5
  124. data/spec/mongoid/extensions/true_class_spec.rb +1 -1
  125. data/spec/mongoid/fields/localized_spec.rb +4 -4
  126. data/spec/mongoid/fields_spec.rb +4 -4
  127. data/spec/mongoid/inspectable_spec.rb +12 -4
  128. data/spec/mongoid/persistable/deletable_spec.rb +175 -1
  129. data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
  130. data/spec/mongoid/persistable/savable_spec.rb +3 -5
  131. data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
  132. data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
  133. data/spec/mongoid/reloadable_spec.rb +18 -1
  134. data/spec/mongoid/shardable_spec.rb +44 -0
  135. data/spec/mongoid/touchable_spec.rb +104 -16
  136. data/spec/mongoid/touchable_spec_models.rb +52 -0
  137. data/spec/mongoid/validatable_spec.rb +1 -1
  138. data/spec/spec_helper.rb +6 -2
  139. data/spec/support/client_registry.rb +9 -0
  140. data/spec/support/models/bolt.rb +8 -0
  141. data/spec/support/models/hole.rb +13 -0
  142. data/spec/support/models/mop.rb +0 -1
  143. data/spec/support/models/nut.rb +8 -0
  144. data/spec/support/models/person.rb +6 -0
  145. data/spec/support/models/sealer.rb +8 -0
  146. data/spec/support/models/shirt.rb +12 -0
  147. data/spec/support/models/spacer.rb +8 -0
  148. data/spec/support/models/threadlocker.rb +8 -0
  149. data/spec/support/models/washer.rb +8 -0
  150. metadata +97 -3
  151. metadata.gz.sig +5 -3
  152. data/spec/support/cluster_config.rb +0 -158
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+
6
+ describe Mongoid::Attributes::Projector do
7
+ Dir[File.join(File.dirname(__FILE__), 'projector_data', '*.yml')].sort.each do |path|
8
+ context File.basename(path) do
9
+ specs = YAML.load(File.read(path))
10
+
11
+ specs.each do |spec|
12
+ context spec['name'] do
13
+
14
+ if spec['pending']
15
+ pending spec['pending'].to_s
16
+ end
17
+
18
+ let(:projection) do
19
+ spec['projection']
20
+ end
21
+
22
+ let(:projector) do
23
+ Mongoid::Attributes::Projector.new(projection)
24
+ end
25
+
26
+ spec.fetch('queries').each do |query_spec|
27
+ context query_spec.fetch('query').inspect do
28
+ let(:query) { query_spec['query'] }
29
+
30
+ context 'attribute_or_path_allowed?' do
31
+ it "is #{query_spec.fetch('allowed')}" do
32
+ projector.attribute_or_path_allowed?(query).should be query_spec['allowed']
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -96,6 +96,49 @@ describe Mongoid::Attributes do
96
96
  it "does not raise an error" do
97
97
  expect(from_db.map).to eq(map)
98
98
  end
99
+
100
+ context 'when only one of the hash fields is projected' do
101
+
102
+ let(:map) do
103
+ { 'dates' => { 'y' => { '2016' => 'Berlin', '2017' => 'Munich' } } }
104
+ end
105
+
106
+ let(:expected) do
107
+ { 'dates' => { 'y' => {
108
+ '2016' => 'Berlin',
109
+ } } }
110
+ end
111
+
112
+ it 'retrieves only the projected fields' do
113
+ expect(from_db.map).to eq(expected)
114
+ end
115
+ end
116
+
117
+ context 'when several of the hash fields is projected' do
118
+
119
+ let(:map) do
120
+ { 'dates' => { 'y' => {
121
+ '2016' => 'Berlin',
122
+ '2017' => 'Munich',
123
+ '2018' => 'Krakow',
124
+ } } }
125
+ end
126
+
127
+ let(:expected) do
128
+ { 'dates' => { 'y' => {
129
+ '2016' => 'Berlin',
130
+ '2018' => 'Krakow',
131
+ } } }
132
+ end
133
+
134
+ let(:from_db) do
135
+ Person.only('map.dates.y.2016', 'map.dates.y.2018').first
136
+ end
137
+
138
+ it 'retrieves only the projected fields' do
139
+ expect(from_db.map).to eq(expected)
140
+ end
141
+ end
99
142
  end
100
143
  end
101
144
 
@@ -298,16 +341,12 @@ describe Mongoid::Attributes do
298
341
  context 'when retrieving a field of the association using the dot notation' do
299
342
 
300
343
  it 'retrieves the field' do
301
- pending 'MONGOID-5032, fixed in 7.3'
302
-
303
344
  expect(from_db['name.first_name']).to eq 'Jose'
304
345
  end
305
346
  end
306
347
 
307
348
  context 'when retrieving a field of a nested association using the dot notation' do
308
349
  it 'retrieves the field' do
309
- pending 'MONGOID-5032, fixed in 7.3'
310
-
311
350
  expect(from_db['name.language.name']).to eq 'es'
312
351
  end
313
352
  end
@@ -320,8 +359,6 @@ describe Mongoid::Attributes do
320
359
 
321
360
  context 'when retrieving a field under the projected sub-association' do
322
361
  it 'retrieves the field' do
323
- pending 'MONGOID-5032, fixed in 7.3'
324
-
325
362
  expect(from_db['name.language.name']).to eq 'es'
326
363
  end
327
364
  end
@@ -1892,6 +1929,61 @@ describe Mongoid::Attributes do
1892
1929
  end
1893
1930
  end
1894
1931
 
1932
+ describe '#unalias_attribute' do
1933
+ let(:shirt) { Shirt.new }
1934
+ let(:id) { '1234' }
1935
+
1936
+ context 'when creating object' do
1937
+ let(:shirt) { Shirt.new(id: id) }
1938
+
1939
+ it 'id and _id are not the same' do
1940
+ expect(shirt.id).to eq(id)
1941
+ expect(shirt._id).not_to eq(id)
1942
+ end
1943
+ end
1944
+
1945
+ context 'update' do
1946
+ before do
1947
+ shirt.update(id: id)
1948
+ end
1949
+
1950
+ it 'updates id but not_id' do
1951
+ expect(shirt.id).to eq(id)
1952
+ expect(shirt._id).not_to eq(id)
1953
+ end
1954
+ end
1955
+
1956
+ context 'id=' do
1957
+ before do
1958
+ shirt.id = id
1959
+ end
1960
+
1961
+ it 'sets id and not _id' do
1962
+ expect(shirt.id).to eq(id)
1963
+ expect(shirt._id).not_to eq(id)
1964
+ end
1965
+ end
1966
+
1967
+ context 'id?' do
1968
+ context 'with null id' do
1969
+ it 'returns false' do
1970
+ expect(shirt.id?).to be false
1971
+ expect(shirt._id?).to be true
1972
+ end
1973
+ end
1974
+
1975
+ context 'with id' do
1976
+ before do
1977
+ shirt.id = id
1978
+ end
1979
+
1980
+ it 'returns true' do
1981
+ expect(shirt.id?).to be true
1982
+ end
1983
+ end
1984
+ end
1985
+ end
1986
+
1895
1987
  describe "#alias_attribute" do
1896
1988
 
1897
1989
  let(:product) do
@@ -47,6 +47,7 @@ describe Mongoid::Clients::Factory do
47
47
 
48
48
  before do
49
49
  Mongoid::Config.send(:clients=, config)
50
+ # TODO: We should restore overwritten configuration in after block
50
51
  end
51
52
 
52
53
  after do
@@ -124,6 +125,7 @@ describe Mongoid::Clients::Factory do
124
125
 
125
126
  before do
126
127
  Mongoid::Config.send(:clients=, config)
128
+ # TODO: We should restore overwritten configuration in after block
127
129
  end
128
130
 
129
131
  after do
@@ -168,6 +170,7 @@ describe Mongoid::Clients::Factory do
168
170
 
169
171
  before do
170
172
  Mongoid::Config.send(:clients=, config)
173
+ # TODO: We should restore overwritten configuration in after block
171
174
  end
172
175
 
173
176
  after do
@@ -206,6 +209,7 @@ describe Mongoid::Clients::Factory do
206
209
 
207
210
  before do
208
211
  Mongoid::Config.send(:clients=, config)
212
+ # TODO: We should restore overwritten configuration in after block
209
213
  end
210
214
 
211
215
  after do
@@ -253,6 +257,7 @@ describe Mongoid::Clients::Factory do
253
257
 
254
258
  before do
255
259
  Mongoid::Config.send(:clients=, config)
260
+ # TODO: We should restore overwritten configuration in after block
256
261
  end
257
262
 
258
263
  after do
@@ -284,6 +289,7 @@ describe Mongoid::Clients::Factory do
284
289
 
285
290
  before do
286
291
  Mongoid.clients[:default] = nil
292
+ # TODO: We should restore overwritten configuration in after block
287
293
  end
288
294
 
289
295
  it "raises NoClientsConfig error" do
@@ -300,6 +306,7 @@ describe Mongoid::Clients::Factory do
300
306
 
301
307
  before do
302
308
  Mongoid::Config.send(:clients=, config)
309
+ # TODO: We should restore overwritten configuration in after block
303
310
  end
304
311
 
305
312
  after do
@@ -342,6 +349,7 @@ describe Mongoid::Clients::Factory do
342
349
 
343
350
  before do
344
351
  Mongoid::Config.send(:clients=, config)
352
+ # TODO: We should restore overwritten configuration in after block
345
353
  end
346
354
 
347
355
  after do
@@ -378,4 +386,44 @@ describe Mongoid::Clients::Factory do
378
386
  expect(client.options[:platform]).to eq(Mongoid::PLATFORM_DETAILS)
379
387
  end
380
388
  end
389
+
390
+ context "unexpected config options" do
391
+ let(:unknown_opts) do
392
+ {
393
+ bad_one: 1,
394
+ another_one: "here"
395
+ }
396
+ end
397
+
398
+ let(:config) do
399
+ {
400
+ default: { hosts: SpecConfig.instance.addresses, database: database_id },
401
+ good_one: { hosts: [ "127.0.0.1:1234" ], database: database_id},
402
+ bad_one: { hosts: [ "127.0.0.1:1234" ], database: database_id}.merge(unknown_opts),
403
+ good_two: { uri: "mongodb://127.0.0.1:1234,127.0.0.1:5678/#{database_id}" },
404
+ bad_two: { uri: "mongodb://127.0.0.1:1234,127.0.0.1:5678/#{database_id}" }.merge(unknown_opts)
405
+ }
406
+ end
407
+
408
+ around(:each) do |example|
409
+ old_config = Mongoid::Config.clients
410
+ Mongoid::Config.send(:clients=, config)
411
+ example.run
412
+ Mongoid::Config.send(:clients=, old_config)
413
+ end
414
+
415
+ [:bad_one, :bad_two].each do |env|
416
+ it 'does not log a warning if none' do
417
+ expect(described_class.send(:default_logger)).not_to receive(:warn)
418
+ described_class.create(env).close
419
+ end
420
+ end
421
+
422
+ [:bad_one, :bad_two].each do |env|
423
+ it 'logs a warning if some' do
424
+ expect(described_class.send(:default_logger)).not_to receive(:warn)
425
+ described_class.create(env).close
426
+ end
427
+ end
428
+ end
381
429
  end
@@ -545,4 +545,36 @@ describe Mongoid::Config do
545
545
  expect(Mongoid::Config.log_level).to eq(2)
546
546
  end
547
547
  end
548
+
549
+ context "with an overridden database" do
550
+ let(:database) do
551
+ "test_purge_#{Time.now.to_i}"
552
+ end
553
+
554
+ before do
555
+ Mongoid.override_database(database)
556
+ end
557
+
558
+ after do
559
+ Mongoid.override_database(nil)
560
+ end
561
+
562
+ describe "#purge!" do
563
+ it 'respects persistence context overrides' do
564
+ House.create!(name: '1', model: 'Big')
565
+ expect(House.count).to eq(1)
566
+ Mongoid.purge!
567
+ expect(House.count).to eq(0)
568
+ end
569
+ end
570
+
571
+ describe "#truncate!" do
572
+ it 'respects persistence context overrides' do
573
+ House.create!(name: '1', model: 'Big')
574
+ expect(House.count).to eq(1)
575
+ Mongoid.truncate!
576
+ expect(House.count).to eq(0)
577
+ end
578
+ end
579
+ end
548
580
  end
@@ -1442,8 +1442,8 @@ describe Mongoid::Contextual::Mongo do
1442
1442
  describe "##{method}" do
1443
1443
 
1444
1444
  before do
1445
- Band.create(name: "Depeche Mode")
1446
- Band.create(name: "New Order")
1445
+ Band.create!(name: "Depeche Mode")
1446
+ Band.create!(name: "New Order")
1447
1447
  end
1448
1448
 
1449
1449
  context "when the criteria has a limit" do
@@ -705,7 +705,7 @@ describe Mongoid::Criteria::Modifiable do
705
705
  end
706
706
 
707
707
  it 'uses the values from the attributes' do
708
- expect(document.map).to eq({ foo: :bar })
708
+ expect(document.map).to eq('foo' => :bar )
709
709
  end
710
710
  end
711
711
 
@@ -9,79 +9,6 @@ describe Mongoid::Criteria::Queryable::Expandable do
9
9
  Mongoid::Query.new
10
10
  end
11
11
 
12
- describe '#expand_condition' do
13
-
14
- let(:expanded) do
15
- query.send(:expand_condition, condition)
16
- end
17
-
18
- context 'field name => value' do
19
- shared_examples_for 'expands' do
20
-
21
- it 'expands' do
22
- expanded.should == {'foo' => 'bar'}
23
- end
24
- end
25
-
26
- context 'string key' do
27
- let(:condition) do
28
- {'foo' => 'bar'}
29
- end
30
-
31
- it_behaves_like 'expands'
32
- end
33
-
34
- context 'symbol key' do
35
- let(:condition) do
36
- {foo: 'bar'}
37
- end
38
-
39
- it_behaves_like 'expands'
40
- end
41
- end
42
-
43
- context 'Key instance => value' do
44
- let(:key) do
45
- Mongoid::Criteria::Queryable::Key.new(:foo, :__override__, '$gt')
46
- end
47
-
48
- let(:condition) do
49
- {key => 'bar'}
50
- end
51
-
52
- it 'expands' do
53
- expanded.should == {'foo' => {'$gt' => 'bar'}}
54
- end
55
- end
56
-
57
- =begin
58
- context 'operator => operator value expression' do
59
- shared_examples_for 'expands' do
60
-
61
- it 'expands' do
62
- expanded.should == {'foo' => 'bar'}
63
- end
64
- end
65
-
66
- context 'string key' do
67
- let(:condition) do
68
- {'$in' => %w(bar)}
69
- end
70
-
71
- it_behaves_like 'expands'
72
- end
73
-
74
- context 'symbol key' do
75
- let(:condition) do
76
- {:$in => %w(bar)}
77
- end
78
-
79
- it_behaves_like 'expands'
80
- end
81
- end
82
- =end
83
- end
84
-
85
12
  describe '#expand_condition_to_array_values' do
86
13
  shared_examples_for 'expands' do
87
14
 
@@ -3,7 +3,7 @@
3
3
 
4
4
  require "spec_helper"
5
5
 
6
- describe Boolean do
6
+ describe Mongoid::Boolean do
7
7
 
8
8
  describe ".evolve" do
9
9
 
@@ -44,7 +44,7 @@ describe Mongoid::Criteria::Queryable::Mergeable do
44
44
 
45
45
  describe '#_mongoid_expand_keys' do
46
46
  it 'expands simple keys' do
47
- query.send(:_mongoid_expand_keys, {a: 1}).should == {a: 1}
47
+ query.send(:_mongoid_expand_keys, {a: 1}).should == {'a' => 1}
48
48
  end
49
49
 
50
50
  let(:gt) do
@@ -68,18 +68,116 @@ describe Mongoid::Criteria::Queryable::Mergeable do
68
68
  'age' => {'$gt' => 42, '$lt' => 50}}
69
69
  end
70
70
 
71
- it 'expands simple and Key instances on the same field' do
72
- query.send(:_mongoid_expand_keys, {'age' => 42, lt => 50}).should == {
73
- 'age' => {'$eq' => 42, '$lt' => 50}}
71
+ context 'given implicit equality and Key instance on the same field' do
72
+ [42, 'infinite', [nil]].each do |value|
73
+ context "for non-regular expression value #{value}" do
74
+ context 'implicit equality then Key instance' do
75
+ it 'expands implicit equality with $eq and combines with Key operator' do
76
+ query.send(:_mongoid_expand_keys, {'age' => value, lt => 50}).should == {
77
+ 'age' => {'$eq' => value, '$lt' => 50}}
78
+ end
79
+ end
80
+
81
+ context 'symbol operator then implicit equality' do
82
+ it 'expands implicit equality with $eq and combines with Key operator' do
83
+ query.send(:_mongoid_expand_keys, {gt => 42, 'age' => value}).should == {
84
+ 'age' => {'$gt' => 42, '$eq' => value}}
85
+ end
86
+ end
87
+ end
88
+ end
74
89
  end
75
90
 
76
- it 'expands Key and simple instances on the same field' do
77
- query.send(:_mongoid_expand_keys, {gt => 42, 'age' => 50}).should == {
78
- 'age' => {'$gt' => 42, '$eq' => 50}}
91
+ context 'given implicit equality with Regexp argument and Key instance on the same field' do
92
+ [/42/, BSON::Regexp::Raw.new('42')].each do |value|
93
+ context "for regular expression value #{value}" do
94
+ context 'implicit equality then Key instance' do
95
+ it 'expands implicit equality with $eq and combines with Key operator' do
96
+ query.send(:_mongoid_expand_keys, {'age' => value, lt => 50}).should == {
97
+ 'age' => {'$regex' => value, '$lt' => 50}}
98
+ end
99
+ end
100
+
101
+ context 'Key instance then implicit equality' do
102
+ it 'expands implicit equality with $eq and combines with Key operator' do
103
+ query.send(:_mongoid_expand_keys, {gt => 50, 'age' => value}).should == {
104
+ 'age' => {'$gt' => 50, '$regex' => value}}
105
+ end
106
+ end
107
+ end
108
+ end
79
109
  end
80
110
 
81
111
  it 'Ruby does not allow same symbol operator with different values' do
82
112
  {gt => 42, gtp => 50}.should == {gtp => 50}
83
113
  end
114
+
115
+ let(:expanded) do
116
+ query.send(:_mongoid_expand_keys, condition)
117
+ end
118
+
119
+ context 'field name => value' do
120
+ shared_examples_for 'expands' do
121
+
122
+ it 'expands' do
123
+ expanded.should == {'foo' => 'bar'}
124
+ end
125
+ end
126
+
127
+ context 'string key' do
128
+ let(:condition) do
129
+ {'foo' => 'bar'}
130
+ end
131
+
132
+ it_behaves_like 'expands'
133
+ end
134
+
135
+ context 'symbol key' do
136
+ let(:condition) do
137
+ {foo: 'bar'}
138
+ end
139
+
140
+ it_behaves_like 'expands'
141
+ end
142
+ end
143
+
144
+ context 'Key instance => value' do
145
+ let(:key) do
146
+ Mongoid::Criteria::Queryable::Key.new(:foo, :__override__, '$gt')
147
+ end
148
+
149
+ let(:condition) do
150
+ {key => 'bar'}
151
+ end
152
+
153
+ it 'expands' do
154
+ expanded.should == {'foo' => {'$gt' => 'bar'}}
155
+ end
156
+ end
157
+
158
+ context 'operator => operator value expression' do
159
+ shared_examples_for 'expands' do
160
+
161
+ it 'expands' do
162
+ expanded.should == {'foo' => {'$in' => ['bar']}}
163
+ end
164
+ end
165
+
166
+ context 'string key' do
167
+ let(:condition) do
168
+ {foo: {'$in' => %w(bar)}}
169
+ end
170
+
171
+ it_behaves_like 'expands'
172
+ end
173
+
174
+ context 'symbol key' do
175
+ let(:condition) do
176
+ {foo: {:$in => %w(bar)}}
177
+ end
178
+
179
+ it_behaves_like 'expands'
180
+ end
181
+ end
84
182
  end
85
183
  end