mongoid 7.2.3 → 7.3.0

Sign up to get free protection for your applications and to get access to all the features.
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