mongoid 8.0.5 → 8.0.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53bba3a9611a89eaf77478beacbf4a8a3c6751503ecf1919407c7af05e134af0
4
- data.tar.gz: ebe8a6705c4c035e99720d1a37e8103948aa1cb61a66ab42b0d426dd7e10c135
3
+ metadata.gz: 51995917ca452899edfb1e432aecad879c476f89057c5377e55081a5c2a989ac
4
+ data.tar.gz: b01e8f7141b1f37d0ddfc51b5e4fa889f09b85988069af8cc8af7214a00a888c
5
5
  SHA512:
6
- metadata.gz: 15c3ecad78d34f2bdc3967042c0175b639d813aa44bcb2e6a5aa4ee5ec6d3adcb13e428accefb0edfa6b7dab59710829194e00cc17cb0f38ff5673957c97e6ce
7
- data.tar.gz: ba5f2a0a8cd2ddc48650d9e7b67c162d4071f254ea9de03070308a411aeda8db2ac40c3a548d9543bed2bad637aa001e2a4ed0fe039cb380a30a69d6b79164fd
6
+ metadata.gz: 7a011a2367c77d3e7abdc57a3781f45c97c71451afcaae7a3358a3e0173e8d3bc4ef09ef92d32f8d72c14ca89b5d8f3d9fccdf8b0a7b84ccb9a874329413b561
7
+ data.tar.gz: a868fc0217fc98cccfa8b6c3f9c0dccb4425354ddb4f23a1819f52dc539e2754e8dd8a508a804e05bddeeb8be73fe09ff6f027d141a22d3f479c3adc63097fcb
checksums.yaml.gz.sig CHANGED
Binary file
@@ -35,10 +35,15 @@ module Mongoid
35
35
  # @api private
36
36
  class_attribute :aliased_associations
37
37
 
38
+ # @return [ Set<String> ] The set of associations that are configured
39
+ # with :store_as parameter.
40
+ class_attribute :stored_as_associations
41
+
38
42
  self.embedded = false
39
43
  self.embedded_relations = BSON::Document.new
40
44
  self.relations = BSON::Document.new
41
45
  self.aliased_associations = {}
46
+ self.stored_as_associations = Set.new
42
47
  end
43
48
 
44
49
  # This is convenience for libraries still on the old API.
@@ -219,6 +224,7 @@ module Mongoid
219
224
  self.relations = self.relations.merge(name => assoc)
220
225
  if assoc.embedded? && assoc.respond_to?(:store_as) && assoc.store_as != name
221
226
  self.aliased_associations[assoc.store_as] = name
227
+ self.stored_as_associations << assoc.store_as
222
228
  end
223
229
  end
224
230
  end
@@ -43,22 +43,46 @@ module Mongoid
43
43
  # @return [ true | false ] True if pending, false if not.
44
44
  def pending_attribute?(key, value)
45
45
  name = key.to_s
46
-
47
46
  aliased = if aliased_associations.key?(name)
48
47
  aliased_associations[name]
49
48
  else
50
49
  name
51
50
  end
52
-
53
51
  if relations.has_key?(aliased)
54
- pending_relations[name] = value
52
+ set_pending_relation(name, aliased, value)
55
53
  return true
56
54
  end
57
55
  if nested_attributes.has_key?(aliased)
58
- pending_nested[name] = value
56
+ set_pending_nested(name, aliased, value)
59
57
  return true
60
58
  end
61
- return false
59
+ false
60
+ end
61
+
62
+ # Set value of the pending relation.
63
+ #
64
+ # @param [ Symbol ] name The name of the relation.
65
+ # @param [ Symbol ] aliased The aliased name of the relation.
66
+ # @param [ Object ] value The value of the relation.
67
+ def set_pending_relation(name, aliased, value)
68
+ if stored_as_associations.include?(name)
69
+ pending_relations[aliased] = value
70
+ else
71
+ pending_relations[name] = value
72
+ end
73
+ end
74
+
75
+ # Set value of the pending nested attribute.
76
+ #
77
+ # @param [ Symbol ] name The name of the nested attribute.
78
+ # @param [ Symbol ] aliased The aliased name of the nested attribute.
79
+ # @param [ Object ] value The value of the nested attribute.
80
+ def set_pending_nested(name, aliased, value)
81
+ if stored_as_associations.include?(name)
82
+ pending_nested[aliased] = value
83
+ else
84
+ pending_nested[name] = value
85
+ end
62
86
  end
63
87
 
64
88
  # Get all the pending associations that need to be set.
@@ -25,6 +25,8 @@ module Mongoid
25
25
  # @param [ Hash ] options Extras for the option.
26
26
  #
27
27
  # @option options [ Object ] :default The default value.
28
+ # @option options [ Proc | nil ] :on_change The callback to invoke when the
29
+ # setter is invoked.
28
30
  def option(name, options = {})
29
31
  defaults[name] = settings[name] = options[:default]
30
32
 
@@ -38,6 +40,7 @@ module Mongoid
38
40
 
39
41
  define_method("#{name}=") do |value|
40
42
  settings[name] = value
43
+ options[:on_change]&.call(value)
41
44
  end
42
45
 
43
46
  define_method("#{name}?") do
@@ -125,6 +125,23 @@ module Mongoid
125
125
  # always return a Hash.
126
126
  option :legacy_attributes, default: false
127
127
 
128
+ # Allow BSON::Decimal128 to be parsed and returned directly in
129
+ # field values. When BSON 5 is present and the this option is set to false
130
+ # (the default), BSON::Decimal128 values in the database will be returned
131
+ # as BigDecimal.
132
+ #
133
+ # @note this option only has effect when BSON 5+ is present. Otherwise,
134
+ # the setting is ignored.
135
+ option :allow_bson5_decimal128, default: false, on_change: -> (allow) do
136
+ if BSON::VERSION >= '5.0.0'
137
+ if allow
138
+ BSON::Registry.register(BSON::Decimal128::BSON_TYPE, BSON::Decimal128)
139
+ else
140
+ BSON::Registry.register(BSON::Decimal128::BSON_TYPE, BigDecimal)
141
+ end
142
+ end
143
+ end
144
+
128
145
  # Has Mongoid been configured? This is checking that at least a valid
129
146
  # client config exists.
130
147
  #
@@ -20,7 +20,7 @@ module Mongoid
20
20
  other.each_pair do |key, value|
21
21
  if value.is_a?(Hash) && self[key.to_s].is_a?(Hash)
22
22
  value = self[key.to_s].merge(value) do |_key, old_val, new_val|
23
- case _key
23
+ case _key.to_s
24
24
  when '$in'
25
25
  new_val & old_val
26
26
  when '$nin'
@@ -47,7 +47,7 @@ module Mongoid
47
47
  if value.is_a?(Hash) && selector[field].is_a?(Hash) &&
48
48
  value.keys.all? { |key|
49
49
  key_s = key.to_s
50
- key_s.start_with?('$') && !selector[field].key?(key_s)
50
+ key_s.start_with?('$') && !selector[field].keys.map(&:to_s).include?(key_s)
51
51
  }
52
52
  then
53
53
  # Multiple operators can be combined on the same field by
@@ -38,8 +38,12 @@ module Mongoid
38
38
  consolidated = {}
39
39
  each_pair do |key, value|
40
40
  if key =~ /\$/
41
- value.each_pair do |_key, _value|
42
- value[_key] = (key == "$rename") ? _value.to_s : mongoize_for(key, klass, _key, _value)
41
+ value.keys.each do |key2|
42
+ value2 = value[key2]
43
+ real_key = klass.database_field_name(key2)
44
+
45
+ value.delete(key2) if real_key != key2
46
+ value[real_key] = (key == "$rename") ? value2.to_s : mongoize_for(key, klass, real_key, value2)
43
47
  end
44
48
  consolidated[key] ||= {}
45
49
  consolidated[key].update(value)
@@ -764,33 +764,60 @@ module Mongoid
764
764
 
765
765
  def field_for(name, options)
766
766
  opts = options.merge(klass: self)
767
- type_mapping = TYPE_MAPPINGS[options[:type]]
768
- opts[:type] = type_mapping || unmapped_type(options)
769
- if !opts[:type].is_a?(Class)
770
- raise Errors::InvalidFieldType.new(self, name, options[:type])
771
- else
772
- if INVALID_BSON_CLASSES.include?(opts[:type])
773
- warn_message = "Using #{opts[:type]} as the field type is not supported. "
774
- if opts[:type] == BSON::Decimal128
775
- warn_message += "In BSON <= 4, the BSON::Decimal128 type will work as expected for both storing and querying, but will return a BigDecimal on query in BSON 5+."
776
- else
777
- warn_message += "Saving values of this type to the database will work as expected, however, querying them will return a value of the native Ruby Integer type."
778
- end
779
- Mongoid.logger.warn(warn_message)
780
- end
781
- end
767
+ opts[:type] = retrieve_and_validate_type(name, options[:type])
782
768
  return Fields::Localized.new(name, opts) if options[:localize]
783
769
  return Fields::ForeignKey.new(name, opts) if options[:identity]
784
770
  Fields::Standard.new(name, opts)
785
771
  end
786
772
 
787
- def unmapped_type(options)
788
- if "Boolean" == options[:type].to_s
773
+ # Get the class for the given type.
774
+ #
775
+ # @param [ Symbol ] name The name of the field.
776
+ # @param [ Symbol | Class ] type The type of the field.
777
+ #
778
+ # @return [ Class ] The type of the field.
779
+ #
780
+ # @raises [ Mongoid::Errors::InvalidFieldType ] if given an invalid field
781
+ # type.
782
+ #
783
+ # @api private
784
+ def retrieve_and_validate_type(name, type)
785
+ result = TYPE_MAPPINGS[type] || unmapped_type(type)
786
+ raise Errors::InvalidFieldType.new(self, name, type) if !result.is_a?(Class)
787
+
788
+ if unsupported_type?(result)
789
+ warn_message = "Using #{result} as the field type is not supported. "
790
+ if result == BSON::Decimal128
791
+ warn_message += 'In BSON <= 4, the BSON::Decimal128 type will work as expected for both storing and querying, but will return a BigDecimal on query in BSON 5+. To use literal BSON::Decimal128 fields with BSON 5, set Mongoid.allow_bson5_decimal128 to true.'
792
+ else
793
+ warn_message += 'Saving values of this type to the database will work as expected, however, querying them will return a value of the native Ruby Integer type.'
794
+ end
795
+ Mongoid.logger.warn(warn_message)
796
+ end
797
+
798
+ result
799
+ end
800
+
801
+ def unmapped_type(type)
802
+ if "Boolean" == type.to_s
789
803
  Mongoid::Boolean
790
804
  else
791
- options[:type] || Object
805
+ type || Object
792
806
  end
793
807
  end
808
+
809
+ # Queries whether or not the given type is permitted as a declared field
810
+ # type.
811
+ #
812
+ # @param [ Class ] type The type to query
813
+ #
814
+ # @return [ true | false ] whether or not the type is supported
815
+ #
816
+ # @api private
817
+ def unsupported_type?(type)
818
+ return !Mongoid::Config.allow_bson5_decimal128? if type == BSON::Decimal128
819
+ INVALID_BSON_CLASSES.include?(type)
820
+ end
794
821
  end
795
822
  end
796
823
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mongoid
4
- VERSION = "8.0.5"
4
+ VERSION = "8.0.6"
5
5
  end
@@ -2711,4 +2711,31 @@ describe Mongoid::Attributes do
2711
2711
  catalog.set_field.should == Set.new([ 1, 2 ])
2712
2712
  end
2713
2713
  end
2714
+
2715
+ context 'when an embedded field has a capitalized store_as name' do
2716
+ let(:person) { Person.new(Purse: { brand: 'Gucci' }) }
2717
+
2718
+ it 'sets the value' do
2719
+ expect(person.purse.brand).to eq('Gucci')
2720
+ end
2721
+
2722
+ it 'saves successfully' do
2723
+ expect(person.save!).to eq(true)
2724
+ end
2725
+
2726
+ context 'when persisted' do
2727
+ before do
2728
+ person.save!
2729
+ person.reload
2730
+ end
2731
+
2732
+ it 'persists the value' do
2733
+ expect(person.reload.purse.brand).to eq('Gucci')
2734
+ end
2735
+
2736
+ it 'uses the correct key in the database' do
2737
+ expect(person.collection.find(_id: person.id).first['Purse']['_id']).to eq(person.purse.id)
2738
+ end
2739
+ end
2740
+ end
2714
2741
  end
@@ -272,6 +272,15 @@ describe Mongoid::Config do
272
272
  it_behaves_like "a config option"
273
273
  end
274
274
 
275
+ context 'when setting the allow_bson5_decimal128 option in the config' do
276
+ min_bson_version '5.0'
277
+
278
+ let(:option) { :allow_bson5_decimal128 }
279
+ let(:default) { false }
280
+
281
+ it_behaves_like "a config option"
282
+ end
283
+
275
284
  context 'when setting the broken_updates option in the config' do
276
285
  let(:option) { :broken_updates }
277
286
  let(:default) { false }
@@ -1179,33 +1179,49 @@ describe Mongoid::Contextual::Mongo do
1179
1179
  let!(:person2) { Person.create!(ssn: BSON::Decimal128.new("1")) }
1180
1180
  let(:tally) { Person.tally("ssn") }
1181
1181
 
1182
+ let(:tallied_classes) do
1183
+ tally.keys.map(&:class).sort do |a, b|
1184
+ a.to_s.casecmp(b.to_s)
1185
+ end
1186
+ end
1187
+
1182
1188
  context "< BSON 5" do
1183
1189
  max_bson_version '4.99.99'
1184
1190
 
1185
1191
  it "stores the correct types in the database" do
1186
- Person.find(person1.id).attributes["ssn"].should be_a BSON::Regexp::Raw
1187
- Person.find(person2.id).attributes["ssn"].should be_a BSON::Decimal128
1192
+ expect(Person.find(person1.id).attributes["ssn"]).to be_a BSON::Regexp::Raw
1193
+ expect(Person.find(person2.id).attributes["ssn"]).to be_a BSON::Decimal128
1194
+ end
1195
+
1196
+ it "tallies the correct type" do
1197
+ expect(tallied_classes).to be == [ BSON::Decimal128, BSON::Regexp::Raw ]
1198
+ end
1199
+ end
1200
+
1201
+ context '>= BSON 5' do
1202
+ min_bson_version "5.0"
1203
+
1204
+ it "stores the correct types in the database" do
1205
+ expect(Person.find(person1.id).ssn).to be_a BSON::Regexp::Raw
1206
+ expect(Person.find(person2.id).ssn).to be_a BigDecimal
1188
1207
  end
1189
1208
 
1190
1209
  it "tallies the correct type" do
1191
- tally.keys.map(&:class).sort do |a,b|
1192
- a.to_s <=> b.to_s
1193
- end.should == [BSON::Decimal128, BSON::Regexp::Raw]
1210
+ expect(tallied_classes).to be == [ BigDecimal, BSON::Regexp::Raw ]
1194
1211
  end
1195
1212
  end
1196
1213
 
1197
- context ">= BSON 5" do
1214
+ context '>= BSON 5 with decimal128 allowed' do
1198
1215
  min_bson_version "5.0"
1216
+ config_override :allow_bson5_decimal128, true
1199
1217
 
1200
1218
  it "stores the correct types in the database" do
1201
- Person.find(person1.id).ssn.should be_a BSON::Regexp::Raw
1202
- Person.find(person2.id).ssn.should be_a BigDeimal
1219
+ expect(Person.find(person1.id).ssn).to be_a BSON::Regexp::Raw
1220
+ expect(Person.find(person2.id).ssn).to be_a BSON::Decimal128
1203
1221
  end
1204
1222
 
1205
1223
  it "tallies the correct type" do
1206
- tally.keys.map(&:class).sort do |a,b|
1207
- a.to_s <=> b.to_s
1208
- end.should == [BigDecimal, BSON::Regexp::Raw]
1224
+ expect(tallied_classes).to be == [ BSON::Decimal128, BSON::Regexp::Raw ]
1209
1225
  end
1210
1226
  end
1211
1227
  end
@@ -3560,6 +3576,20 @@ describe Mongoid::Contextual::Mongo do
3560
3576
  end
3561
3577
  end
3562
3578
 
3579
+ context 'when using aliased field names' do
3580
+ before do
3581
+ context.update_all('$set' => { years: 100 })
3582
+ end
3583
+
3584
+ it "updates the first matching document" do
3585
+ expect(depeche_mode.reload.years).to eq(100)
3586
+ end
3587
+
3588
+ it "updates the last matching document" do
3589
+ expect(new_order.reload.years).to eq(100)
3590
+ end
3591
+ end
3592
+
3563
3593
  context "when the attributes must be mongoized" do
3564
3594
 
3565
3595
  before do
@@ -44,7 +44,7 @@ describe Mongoid::Criteria::Queryable::Selector do
44
44
  end
45
45
  end
46
46
 
47
- context "when selector contains a $nin" do
47
+ context "when selector contains a $nin string" do
48
48
 
49
49
  let(:initial) do
50
50
  { "$nin" => ["foo"] }
@@ -72,7 +72,35 @@ describe Mongoid::Criteria::Queryable::Selector do
72
72
  end
73
73
  end
74
74
 
75
- context "when selector contains a $in" do
75
+ context "when selector contains a $nin symbol" do
76
+
77
+ let(:initial) do
78
+ { :$nin => ["foo"] }
79
+ end
80
+
81
+ before do
82
+ selector["field"] = initial
83
+ end
84
+
85
+ context "when merging in a new $nin" do
86
+
87
+ let(:other) do
88
+ { "field" => { :$nin => ["bar"] } }
89
+ end
90
+
91
+ before do
92
+ selector.merge!(other)
93
+ end
94
+
95
+ it "combines the two $nin queries into one" do
96
+ expect(selector).to eq({
97
+ "field" => { :$nin => ["foo", "bar"] }
98
+ })
99
+ end
100
+ end
101
+ end
102
+
103
+ context "when selector contains a $in string" do
76
104
 
77
105
  let(:initial) do
78
106
  { "$in" => [1, 2] }
@@ -117,6 +145,51 @@ describe Mongoid::Criteria::Queryable::Selector do
117
145
  end
118
146
  end
119
147
 
148
+ context "when selector contains a $in symbol" do
149
+
150
+ let(:initial) do
151
+ { :$in => [1, 2] }
152
+ end
153
+
154
+ before do
155
+ selector["field"] = initial
156
+ end
157
+
158
+ context "when merging in a new $in with an intersecting value" do
159
+
160
+ let(:other) do
161
+ { "field" => { :$in => [1] } }
162
+ end
163
+
164
+ before do
165
+ selector.merge!(other)
166
+ end
167
+
168
+ it "intersects the $in values" do
169
+ expect(selector).to eq({
170
+ "field" => { :$in => [1] }
171
+ })
172
+ end
173
+ end
174
+
175
+ context "when merging in a new $in with no intersecting values" do
176
+
177
+ let(:other) do
178
+ { "field" => { :$in => [3] } }
179
+ end
180
+
181
+ before do
182
+ selector.merge!(other)
183
+ end
184
+
185
+ it "intersects the $in values" do
186
+ expect(selector).to eq({
187
+ "field" => { :$in => [] }
188
+ })
189
+ end
190
+ end
191
+ end
192
+
120
193
  context "when selector is not nested" do
121
194
 
122
195
  before do
@@ -210,7 +210,79 @@ describe Mongoid::Criteria::Queryable::Storable do
210
210
  }
211
211
  end
212
212
  end
213
+
214
+ context 'when value is a hash combine values with different operator keys' do
215
+ let(:base) do
216
+ query.add_field_expression('foo', {'$in' => ['bar']})
217
+ end
218
+
219
+ let(:modified) do
220
+ base.add_field_expression('foo', {'$nin' => ['zoom']})
221
+ end
222
+
223
+ it 'combines the conditions using $and' do
224
+ modified.selector.should == {
225
+ 'foo' => {
226
+ '$in' => ['bar'],
227
+ '$nin' => ['zoom']
228
+ }
229
+ }
230
+ end
231
+ end
232
+
233
+ context 'when value is a hash with symbol operator key combine values with different operator keys' do
234
+ let(:base) do
235
+ query.add_field_expression('foo', {:$in => ['bar']})
236
+ end
237
+
238
+ let(:modified) do
239
+ base.add_field_expression('foo', {:$nin => ['zoom']})
240
+ end
241
+
242
+ it 'combines the conditions using $and' do
243
+ modified.selector.should == {
244
+ 'foo' => {
245
+ :$in => ['bar'],
246
+ :$nin => ['zoom']
247
+ }
248
+ }
249
+ end
250
+ end
251
+
252
+ context 'when value is a hash add values with same operator keys using $and' do
253
+ let(:base) do
254
+ query.add_field_expression('foo', {'$in' => ['bar']})
255
+ end
256
+
257
+ let(:modified) do
258
+ base.add_field_expression('foo', {'$in' => ['zoom']})
259
+ end
260
+
261
+ it 'adds the new condition using $and' do
262
+ modified.selector.should == {
263
+ 'foo' => {'$in' => ['bar']},
264
+ '$and' => ['foo' => {'$in' => ['zoom']}]
265
+ }
266
+ end
267
+ end
268
+
269
+ context 'when value is a hash with symbol operator key add values with same operator keys using $and' do
270
+ let(:base) do
271
+ query.add_field_expression('foo', {:$in => ['bar']})
272
+ end
273
+
274
+ let(:modified) do
275
+ base.add_field_expression('foo', {:$in => ['zoom']})
276
+ end
277
+
278
+ it 'adds the new condition using $and' do
279
+ modified.selector.should == {
280
+ 'foo' => {:$in => ['bar']},
281
+ '$and' => ['foo' => {:$in => ['zoom']}]
282
+ }
283
+ end
213
284
  end
285
+ end
214
286
 
215
287
  describe '#add_operator_expression' do
216
288
  let(:query_method) { :add_operator_expression }
@@ -178,7 +178,7 @@ describe Mongoid::Extensions::Hash do
178
178
 
179
179
  it "moves the non hash values under the provided key" do
180
180
  expect(consolidated).to eq({
181
- "$set" => { name: "Tool", likes: 10 }, "$inc" => { plays: 1 }
181
+ "$set" => { 'name' => "Tool", likes: 10 }, "$inc" => { 'plays' => 1 }
182
182
  })
183
183
  end
184
184
  end
@@ -195,7 +195,7 @@ describe Mongoid::Extensions::Hash do
195
195
 
196
196
  it "moves the non hash values under the provided key" do
197
197
  expect(consolidated).to eq({
198
- "$set" => { likes: 10, name: "Tool" }, "$inc" => { plays: 1 }
198
+ "$set" => { likes: 10, 'name' => "Tool" }, "$inc" => { 'plays' => 1 }
199
199
  })
200
200
  end
201
201
  end
@@ -213,7 +213,7 @@ describe Mongoid::Extensions::Hash do
213
213
 
214
214
  it "moves the non hash values under the provided key" do
215
215
  expect(consolidated).to eq({
216
- "$set" => { likes: 10, name: "Tool" }, "$inc" => { plays: 1 }
216
+ "$set" => { likes: 10, name: "Tool" }, "$inc" => { 'plays' => 1 }
217
217
  })
218
218
  end
219
219
  end
@@ -567,6 +567,49 @@ describe Mongoid::Fields do
567
567
  end
568
568
  end
569
569
  end
570
+
571
+ context 'when the field is declared as BSON::Decimal128' do
572
+ let(:document) { Mop.create!(decimal128_field: BSON::Decimal128.new(Math::PI.to_s)).reload }
573
+
574
+ shared_context 'BSON::Decimal128 is BigDecimal' do
575
+ it 'should return a BigDecimal' do
576
+ expect(document.decimal128_field).to be_a BigDecimal
577
+ end
578
+ end
579
+
580
+ shared_context 'BSON::Decimal128 is BSON::Decimal128' do
581
+ it 'should return a BSON::Decimal128' do
582
+ expect(document.decimal128_field).to be_a BSON::Decimal128
583
+ end
584
+ end
585
+
586
+ it 'is declared as BSON::Decimal128' do
587
+ expect(Mop.fields['decimal128_field'].type).to be == BSON::Decimal128
588
+ end
589
+
590
+ context 'when BSON version <= 4' do
591
+ max_bson_version '4.99.99'
592
+ it_behaves_like 'BSON::Decimal128 is BSON::Decimal128'
593
+ end
594
+
595
+ context 'when BSON version >= 5' do
596
+ min_bson_version '5.0.0'
597
+
598
+ context 'when allow_bson5_decimal128 is false' do
599
+ config_override :allow_bson5_decimal128, false
600
+ it_behaves_like 'BSON::Decimal128 is BigDecimal'
601
+ end
602
+
603
+ context 'when allow_bson5_decimal128 is true' do
604
+ config_override :allow_bson5_decimal128, true
605
+ it_behaves_like 'BSON::Decimal128 is BSON::Decimal128'
606
+ end
607
+
608
+ context 'when allow_bson5_decimal128 is default' do
609
+ it_behaves_like 'BSON::Decimal128 is BigDecimal'
610
+ end
611
+ end
612
+ end
570
613
  end
571
614
 
572
615
  describe "#getter_before_type_cast" do
@@ -84,22 +84,32 @@ module Mrss
84
84
 
85
85
  # Locates command stated events for the specified command name,
86
86
  # asserts that there is exactly one such event, and returns it.
87
- def single_command_started_event(command_name, include_auth: false)
87
+ def single_command_started_event(command_name, include_auth: false, database_name: nil)
88
88
  events = if include_auth
89
89
  started_events
90
90
  else
91
91
  non_auth_command_started_events
92
92
  end
93
- events.select! do |event|
94
- event.command[command_name]
93
+ get_one_event(events, command_name, 'started', database_name: database_name)
94
+ end
95
+
96
+ # Locates command succeeded events for the specified command name,
97
+ # asserts that there is exactly one such event, and returns it.
98
+ def single_command_succeeded_event(command_name, database_name: nil)
99
+ get_one_event(succeeded_events, command_name, 'succeeded', database_name: database_name)
100
+ end
101
+
102
+ def get_one_event(events, command_name, kind, database_name: nil)
103
+ events = events.select do |event|
104
+ event.command_name == command_name and
105
+ database_name.nil? || database_name == event.database_name
95
106
  end
96
107
  if events.length != 1
97
- raise "Expected a single #{command_name} event but we have #{events.length}"
108
+ raise "Expected a single '#{command_name}' #{kind} event#{database_name ? " for '#{database_name}'" : ''} but we have #{events.length}"
98
109
  end
99
110
  events.first
100
111
  end
101
112
 
102
-
103
113
  # Get the first succeeded event published for the name, and then delete it.
104
114
  #
105
115
  # @param [ String ] name The event name.
@@ -209,6 +209,14 @@ module Mrss
209
209
  end
210
210
  end
211
211
 
212
+ def require_no_fallbacks
213
+ before(:all) do
214
+ if %w(yes true 1).include?((ENV['TEST_I18N_FALLBACKS'] || '').downcase)
215
+ skip 'Set TEST_I18N_FALLBACKS=0 environment variable to run these tests'
216
+ end
217
+ end
218
+ end
219
+
212
220
  # This is a macro for retrying flaky tests on CI that occasionally fail.
213
221
  # Note that the tests will only be retried on CI.
214
222
  #
@@ -71,12 +71,12 @@ prepare_server_from_url() {
71
71
  export PATH="$BINDIR":$PATH
72
72
  }
73
73
 
74
- install_mlaunch_virtualenv() {
74
+ install_mlaunch_venv() {
75
75
  python3 -V || true
76
- if ! python3 -m virtualenv -h >/dev/null; then
76
+ if ! python3 -m venv -h >/dev/null; then
77
77
  # Current virtualenv fails with
78
78
  # https://github.com/pypa/virtualenv/issues/1630
79
- python3 -m pip install 'virtualenv<20' --user
79
+ python3 -m pip install venv --user
80
80
  fi
81
81
  if test "$USE_SYSTEM_PYTHON_PACKAGES" = 1 &&
82
82
  python3 -m pip list |grep mtools
@@ -85,13 +85,13 @@ install_mlaunch_virtualenv() {
85
85
  :
86
86
  else
87
87
  venvpath="$MONGO_ORCHESTRATION_HOME"/venv
88
- python3 -m virtualenv -p python3 $venvpath
88
+ python3 -m venv $venvpath
89
89
  . $venvpath/bin/activate
90
90
  # [mlaunch] does not work:
91
91
  # https://github.com/rueckstiess/mtools/issues/856
92
92
  # dateutil dependency is missing in mtools: https://github.com/rueckstiess/mtools/issues/864
93
93
  #pip install 'mtools==1.7' 'pymongo==4.1' python-dateutil psutil
94
-
94
+
95
95
  # dateutil dependency is missing in mtools: https://github.com/rueckstiess/mtools/issues/864
96
96
  pip install 'mtools-legacy[mlaunch]' 'pymongo<4' python-dateutil
97
97
  fi
@@ -70,6 +70,7 @@ class Person
70
70
  embeds_many :messages, validate: false
71
71
 
72
72
  embeds_one :passport, autobuild: true, store_as: :pass, validate: false
73
+ embeds_one :purse, store_as: "Purse"
73
74
  embeds_one :pet, class_name: "Animal", validate: false
74
75
  embeds_one :name, as: :namable, validate: false do
75
76
  def extension
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Purse
4
+ include Mongoid::Document
5
+
6
+ field :brand, type: String
7
+
8
+ embedded_in :person
9
+ end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.5
4
+ version: 8.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - The MongoDB Ruby Team
@@ -35,7 +35,7 @@ cert_chain:
35
35
  wkeAWhd5b+5JS0zgDL4SvGB8/W2IY+y0zELkojBMgJPyrpAWHL/WSsSBMuhyI2Pv
36
36
  xxaBVLklnJJ/qCCOZ3lG2MyVc/Nb0Mmq8ygWNsfwHmKKYuuWcviit0D0Tek=
37
37
  -----END CERTIFICATE-----
38
- date: 2023-07-11 00:00:00.000000000 Z
38
+ date: 2023-08-24 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: activemodel
@@ -1067,6 +1067,7 @@ files:
1067
1067
  - spec/support/models/publication/review.rb
1068
1068
  - spec/support/models/purchase.rb
1069
1069
  - spec/support/models/purchased_item.rb
1070
+ - spec/support/models/purse.rb
1070
1071
  - spec/support/models/question.rb
1071
1072
  - spec/support/models/quiz.rb
1072
1073
  - spec/support/models/rating.rb
@@ -1177,7 +1178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1177
1178
  - !ruby/object:Gem::Version
1178
1179
  version: 1.3.6
1179
1180
  requirements: []
1180
- rubygems_version: 3.4.12
1181
+ rubygems_version: 3.4.17
1181
1182
  signing_key:
1182
1183
  specification_version: 4
1183
1184
  summary: Elegant Persistence in Ruby for MongoDB.
@@ -1781,6 +1782,7 @@ test_files:
1781
1782
  - spec/support/models/publication.rb
1782
1783
  - spec/support/models/purchase.rb
1783
1784
  - spec/support/models/purchased_item.rb
1785
+ - spec/support/models/purse.rb
1784
1786
  - spec/support/models/question.rb
1785
1787
  - spec/support/models/quiz.rb
1786
1788
  - spec/support/models/rating.rb
metadata.gz.sig CHANGED
Binary file