mongoid 7.0.7 → 7.0.8

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 (59) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongoid.rb +1 -1
  5. data/lib/mongoid/association/embedded/embeds_many.rb +2 -1
  6. data/lib/mongoid/association/embedded/embeds_one.rb +2 -1
  7. data/lib/mongoid/association/proxy.rb +1 -1
  8. data/lib/mongoid/atomic.rb +13 -3
  9. data/lib/mongoid/criteria.rb +7 -1
  10. data/lib/mongoid/criteria/modifiable.rb +2 -1
  11. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  12. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  13. data/lib/mongoid/extensions/hash.rb +4 -2
  14. data/lib/mongoid/extensions/regexp.rb +1 -1
  15. data/lib/mongoid/fields.rb +2 -1
  16. data/lib/mongoid/matchable/regexp.rb +2 -2
  17. data/lib/mongoid/persistable/pushable.rb +4 -1
  18. data/lib/mongoid/persistence_context.rb +6 -6
  19. data/lib/mongoid/query_cache.rb +2 -1
  20. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  21. data/lib/mongoid/version.rb +1 -1
  22. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
  23. data/spec/app/models/delegating_patient.rb +16 -0
  24. data/spec/integration/app_spec.rb +192 -0
  25. data/spec/integration/associations/embedded_spec.rb +62 -0
  26. data/spec/integration/document_spec.rb +22 -0
  27. data/spec/lite_spec_helper.rb +11 -4
  28. data/spec/mongoid/association/embedded/embeds_many_models.rb +53 -0
  29. data/spec/mongoid/association/embedded/embeds_many_spec.rb +10 -0
  30. data/spec/mongoid/association/embedded/embeds_one_spec.rb +0 -2
  31. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +2 -1
  32. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +2 -1
  33. data/spec/mongoid/clients/options_spec.rb +4 -4
  34. data/spec/mongoid/clients/sessions_spec.rb +8 -4
  35. data/spec/mongoid/clients/transactions_spec.rb +20 -8
  36. data/spec/mongoid/clients_spec.rb +2 -2
  37. data/spec/mongoid/contextual/atomic_spec.rb +20 -10
  38. data/spec/mongoid/contextual/map_reduce_spec.rb +20 -5
  39. data/spec/mongoid/contextual/mongo_spec.rb +76 -53
  40. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +7 -7
  41. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +1 -1
  42. data/spec/mongoid/criteria_spec.rb +4 -2
  43. data/spec/mongoid/document_persistence_context_spec.rb +33 -0
  44. data/spec/mongoid/indexable_spec.rb +6 -4
  45. data/spec/mongoid/matchable/default_spec.rb +1 -1
  46. data/spec/mongoid/matchable/regexp_spec.rb +2 -2
  47. data/spec/mongoid/matchable_spec.rb +2 -2
  48. data/spec/mongoid/query_cache_spec.rb +2 -1
  49. data/spec/mongoid/relations/proxy_spec.rb +1 -1
  50. data/spec/mongoid/scopable_spec.rb +2 -1
  51. data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
  52. data/spec/mongoid/tasks/database_spec.rb +1 -1
  53. data/spec/spec_helper.rb +0 -31
  54. data/spec/support/child_process_helper.rb +76 -0
  55. data/spec/support/cluster_config.rb +3 -3
  56. data/spec/support/constraints.rb +29 -19
  57. data/spec/support/spec_config.rb +12 -4
  58. metadata +16 -2
  59. metadata.gz.sig +2 -2
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+
6
+ describe Mongoid::Document do
7
+
8
+ let(:klass) do
9
+ Person
10
+ end
11
+
12
+ let(:person) do
13
+ Person.new
14
+ end
15
+
16
+ describe '.client_name' do
17
+ it 'returns client name' do
18
+ Person.client_name.should == :default
19
+ end
20
+ end
21
+
22
+ describe '.database_name' do
23
+ it 'returns database name' do
24
+ Person.database_name.should == 'mongoid_test'
25
+ end
26
+ end
27
+
28
+ describe '.collection_name' do
29
+ it 'returns collection name' do
30
+ Person.collection_name.should == :people
31
+ end
32
+ end
33
+ end
@@ -45,7 +45,7 @@ describe Mongoid::Indexable do
45
45
  end
46
46
  end
47
47
 
48
- context "when database specific options exist", if: non_legacy_server? do
48
+ context "when database specific options exist" do
49
49
 
50
50
  let(:klass) do
51
51
  Class.new do
@@ -95,7 +95,7 @@ describe Mongoid::Indexable do
95
95
  end
96
96
  end
97
97
 
98
- context "when database options are specified", if: non_legacy_server? do
98
+ context "when database options are specified" do
99
99
 
100
100
  let(:klass) do
101
101
  Class.new do
@@ -133,7 +133,8 @@ describe Mongoid::Indexable do
133
133
  end
134
134
  end
135
135
 
136
- context "when a collation option is specified", if: collation_supported? do
136
+ context "when a collation option is specified" do
137
+ min_server_version '3.4'
137
138
 
138
139
  let(:klass) do
139
140
  Class.new do
@@ -308,7 +309,8 @@ describe Mongoid::Indexable do
308
309
  end
309
310
  end
310
311
 
311
- context "when providing a collation option", if: collation_supported? do
312
+ context "when providing a collation option" do
313
+ min_server_version '3.4'
312
314
 
313
315
  before do
314
316
  klass.index({ name: 1 }, collation: { locale: 'en_US', strength: 2 })
@@ -68,7 +68,7 @@ describe Mongoid::Matchable::Default do
68
68
  context "when the value is a regexp" do
69
69
 
70
70
  it "returns true" do
71
- expect(matcher._matches?(/^Test[3-5]$/)).to be true
71
+ expect(matcher._matches?(/\ATest[3-5]\z/)).to be true
72
72
  end
73
73
  end
74
74
  end
@@ -15,7 +15,7 @@ describe Mongoid::Matchable::Regexp do
15
15
  context 'when a BSON::Regexp::Raw object is passed' do
16
16
 
17
17
  let(:regexp) do
18
- BSON::Regexp::Raw.new('^Em')
18
+ BSON::Regexp::Raw.new("\\AEm")
19
19
  end
20
20
 
21
21
  it 'compiles the regexp object to a native regexp for the matching' do
@@ -37,7 +37,7 @@ describe Mongoid::Matchable::Regexp do
37
37
  context 'when a native Regexp object is passed' do
38
38
 
39
39
  let(:regexp) do
40
- /^Em/
40
+ /\AEm/
41
41
  end
42
42
 
43
43
  it 'calls super with the native regexp' do
@@ -293,7 +293,7 @@ describe Mongoid::Matchable do
293
293
  context 'when a BSON::Regexp::Raw object is used' do
294
294
 
295
295
  let(:selector) do
296
- { street: BSON::Regexp::Raw.new("^Clarkenwell") }
296
+ { street: BSON::Regexp::Raw.new("\\AClarkenwell") }
297
297
  end
298
298
 
299
299
  it "returns true" do
@@ -304,7 +304,7 @@ describe Mongoid::Matchable do
304
304
  context 'when a native Regexp object is used' do
305
305
 
306
306
  let(:selector) do
307
- { street: /^Clarkenwell/ }
307
+ { street: /\AClarkenwell/ }
308
308
  end
309
309
 
310
310
  it "returns true" do
@@ -180,7 +180,8 @@ describe Mongoid::QueryCache do
180
180
  end
181
181
  end
182
182
 
183
- context 'when the first query has a collation', if: collation_supported? do
183
+ context 'when the first query has a collation' do
184
+ min_server_version '3.4'
184
185
 
185
186
  before do
186
187
  Band.where(name: 'DEPECHE MODE').collation(locale: 'en_US', strength: 2).to_a
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # describe Mongoid::Relations::Proxy do
4
4
  #
5
- # describe '#with', if: non_legacy_server? do
5
+ # describe '#with' do
6
6
  #
7
7
  # let(:circus) do
8
8
  # Circus.new
@@ -227,7 +227,8 @@ describe Mongoid::Scopable do
227
227
 
228
228
  context "when provided a criteria" do
229
229
 
230
- context 'when a collation is defined on the criteria', if: collation_supported? do
230
+ context 'when a collation is defined on the criteria' do
231
+ min_server_version '3.4'
231
232
 
232
233
  before do
233
234
  Band.scope(:tests, ->{ Band.where(name: 'TESTING').collation(locale: 'en_US', strength: 2) })
@@ -45,7 +45,7 @@ shared_context "rails rake task" do
45
45
  end
46
46
  end
47
47
 
48
- describe "db:drop", if: non_legacy_server? do
48
+ describe "db:drop" do
49
49
  include_context "rake task"
50
50
  include_context "rails rake task"
51
51
 
@@ -58,7 +58,7 @@ describe "db:drop", if: non_legacy_server? do
58
58
  end
59
59
  end
60
60
 
61
- describe "db:purge", if: non_legacy_server? do
61
+ describe "db:purge" do
62
62
  include_context "rake task"
63
63
  include_context "rails rake task"
64
64
 
@@ -71,7 +71,7 @@ describe "db:purge", if: non_legacy_server? do
71
71
  end
72
72
  end
73
73
 
74
- describe "db:seed", if: non_legacy_server? do
74
+ describe "db:seed" do
75
75
  include_context "rake task"
76
76
  include_context "rails rake task"
77
77
 
@@ -85,7 +85,7 @@ describe "db:seed", if: non_legacy_server? do
85
85
  end
86
86
  end
87
87
 
88
- describe "db:setup", if: non_legacy_server? do
88
+ describe "db:setup" do
89
89
  include_context "rake task"
90
90
  include_context "rails rake task"
91
91
 
@@ -117,7 +117,7 @@ describe "db:setup", if: non_legacy_server? do
117
117
  end
118
118
  end
119
119
 
120
- describe "db:reset", if: non_legacy_server? do
120
+ describe "db:reset" do
121
121
  include_context "rake task"
122
122
  include_context "rails rake task"
123
123
 
@@ -135,7 +135,7 @@ describe "db:reset", if: non_legacy_server? do
135
135
  end
136
136
  end
137
137
 
138
- describe "db:create", if: non_legacy_server? do
138
+ describe "db:create" do
139
139
  include_context "rake task"
140
140
  include_context "rails rake task"
141
141
 
@@ -144,7 +144,7 @@ describe "db:create", if: non_legacy_server? do
144
144
  end
145
145
  end
146
146
 
147
- describe "db:migrate", if: non_legacy_server? do
147
+ describe "db:migrate" do
148
148
  include_context "rake task"
149
149
  include_context "rails rake task"
150
150
 
@@ -153,7 +153,7 @@ describe "db:migrate", if: non_legacy_server? do
153
153
  end
154
154
  end
155
155
 
156
- describe "db:test:prepare", if: non_legacy_server? do
156
+ describe "db:test:prepare" do
157
157
  include_context "rake task"
158
158
  include_context "rails rake task"
159
159
 
@@ -174,7 +174,7 @@ describe "db:test:prepare", if: non_legacy_server? do
174
174
  end
175
175
  end
176
176
 
177
- describe "db:mongoid:create_indexes", if: non_legacy_server? do
177
+ describe "db:mongoid:create_indexes" do
178
178
  include_context "rake task"
179
179
 
180
180
  it_behaves_like "create_indexes"
@@ -198,7 +198,7 @@ describe "db:mongoid:create_indexes", if: non_legacy_server? do
198
198
  end
199
199
  end
200
200
 
201
- describe "db:mongoid:remove_undefined_indexes", if: non_legacy_server? do
201
+ describe "db:mongoid:remove_undefined_indexes" do
202
202
  include_context "rake task"
203
203
 
204
204
  it "receives remove_undefined_indexes" do
@@ -224,7 +224,7 @@ describe "db:mongoid:remove_undefined_indexes", if: non_legacy_server? do
224
224
  end
225
225
  end
226
226
 
227
- describe "db:mongoid:remove_indexes", if: non_legacy_server? do
227
+ describe "db:mongoid:remove_indexes" do
228
228
  include_context "rake task"
229
229
 
230
230
  it "receives remove_indexes" do
@@ -250,7 +250,7 @@ describe "db:mongoid:remove_indexes", if: non_legacy_server? do
250
250
  end
251
251
  end
252
252
 
253
- describe "db:mongoid:drop", if: non_legacy_server? do
253
+ describe "db:mongoid:drop" do
254
254
  include_context "rake task"
255
255
 
256
256
  it "works" do
@@ -266,7 +266,7 @@ describe "db:mongoid:drop", if: non_legacy_server? do
266
266
  end
267
267
  end
268
268
 
269
- describe "db:mongoid:purge", if: non_legacy_server? do
269
+ describe "db:mongoid:purge" do
270
270
  include_context "rake task"
271
271
 
272
272
  it "receives a purge" do
@@ -133,7 +133,7 @@ describe "Mongoid::Tasks::Database" do
133
133
  expect(removed_indexes).to be_empty
134
134
  end
135
135
 
136
- context 'when the index is a text index', if: non_legacy_server? do
136
+ context 'when the index is a text index' do
137
137
 
138
138
  before do
139
139
  class Band
@@ -75,37 +75,6 @@ CONFIG = {
75
75
  }
76
76
  }
77
77
 
78
- def non_legacy_server?
79
- Mongoid::Clients.default.cluster.servers.first.features.write_command_enabled?
80
- end
81
-
82
- def testing_replica_set?
83
- Mongoid::Clients.default.cluster.replica_set?
84
- end
85
-
86
- def collation_supported?
87
- Mongoid::Clients.default.cluster.next_primary.features.collation_enabled?
88
- end
89
- alias :decimal128_supported? :collation_supported?
90
-
91
- def array_filters_supported?
92
- Mongoid::Clients.default.cluster.next_primary.features.array_filters_enabled?
93
- end
94
- alias :sessions_supported? :array_filters_supported?
95
-
96
- def transactions_supported?
97
- features = Mongoid::Clients.default.cluster.next_primary.features
98
- features.respond_to?(:transactions_enabled?) && features.transactions_enabled?
99
- end
100
-
101
- def testing_transactions?
102
- transactions_supported? && testing_replica_set?
103
- end
104
-
105
- def testing_locally?
106
- !(ENV['CI'] == 'travis')
107
- end
108
-
109
78
  # Set the database that the spec suite connects to.
110
79
  Mongoid.configure do |config|
111
80
  config.load_configuration(CONFIG)
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ autoload :ChildProcess, 'childprocess'
5
+ autoload :Tempfile, 'tempfile'
6
+
7
+ module ChildProcessHelper
8
+ module_function def call(cmd, env: nil, cwd: nil)
9
+ process = ChildProcess.new(*cmd)
10
+ process.io.inherit!
11
+ if cwd
12
+ process.cwd = cwd
13
+ end
14
+ if env
15
+ env.each do |k, v|
16
+ process.environment[k.to_s] = v
17
+ end
18
+ end
19
+ process.start
20
+ process.wait
21
+ process
22
+ end
23
+
24
+ module_function def check_call(cmd, env: nil, cwd: nil)
25
+ process = call(cmd, env: env, cwd: cwd)
26
+ unless process.exit_code == 0
27
+ raise "Failed to execute: #{cmd}"
28
+ end
29
+ end
30
+
31
+ module_function def get_output(cmd, env: nil, cwd: nil)
32
+ process = ChildProcess.new(*cmd)
33
+ process.io.inherit!
34
+ if cwd
35
+ process.cwd = cwd
36
+ end
37
+ if env
38
+ env.each do |k, v|
39
+ process.environment[k.to_s] = v
40
+ end
41
+ end
42
+
43
+ output = ''
44
+ r, w = IO.pipe
45
+
46
+ begin
47
+ process.io.stdout = w
48
+ process.start
49
+ w.close
50
+
51
+ thread = Thread.new do
52
+ begin
53
+ loop do
54
+ output << r.readpartial(16384)
55
+ end
56
+ rescue EOFError
57
+ end
58
+ end
59
+
60
+ process.wait
61
+ thread.join
62
+ ensure
63
+ r.close
64
+ end
65
+
66
+ [process, output]
67
+ end
68
+
69
+ module_function def check_output(*args)
70
+ process, output = get_output(*args)
71
+ unless process.exit_code == 0
72
+ raise "Failed to execute: #{args}"
73
+ end
74
+ output
75
+ end
76
+ end
@@ -99,7 +99,7 @@ class ClusterConfig
99
99
  if topology == :sharded
100
100
  shards = client.use(:admin).command(listShards: 1).first
101
101
  shard = shards['shards'].first
102
- address_str = shard['host'].sub(/^.*\//, '').sub(/,.*/, '')
102
+ address_str = shard['host'].sub(/\A.*\//, '').sub(/,.*/, '')
103
103
  client = ClusterTools.instance.direct_client(address_str,
104
104
  SpecConfig.instance.test_options.merge(SpecConfig.instance.auth_options).merge(connect: :direct))
105
105
  end
@@ -133,8 +133,8 @@ class ClusterConfig
133
133
 
134
134
  @topology ||= begin
135
135
  topology = client.cluster.topology.class.name.sub(/.*::/, '')
136
- topology = topology.gsub(/([A-Z])/) { |match| '_' + match.downcase }.sub(/^_/, '')
137
- if topology =~ /^replica_set/
136
+ topology = topology.gsub(/([A-Z])/) { |match| '_' + match.downcase }.sub(/\A_/, '')
137
+ if topology =~ /\Areplica_set/
138
138
  topology = 'replica_set'
139
139
  end
140
140
  topology.to_sym
@@ -2,11 +2,11 @@ module Constraints
2
2
  RAILS_VERSION = ActiveSupport.version.to_s.split('.')[0..1].join('.').freeze
3
3
 
4
4
  def min_rails_version(version)
5
- unless version =~ /^\d+\.\d+$/
5
+ unless version =~ /\A\d+\.\d+\z/
6
6
  raise ArgumentError, "Version can only be major.minor: #{version}"
7
7
  end
8
8
 
9
- before do
9
+ before(:all) do
10
10
  if version > RAILS_VERSION
11
11
  skip "Rails version #{version} or higher required, we have #{RAILS_VERSION}"
12
12
  end
@@ -14,11 +14,11 @@ module Constraints
14
14
  end
15
15
 
16
16
  def max_rails_version(version)
17
- unless version =~ /^\d+\.\d+$/
17
+ unless version =~ /\A\d+\.\d+\z/
18
18
  raise ArgumentError, "Version can only be major.minor: #{version}"
19
19
  end
20
20
 
21
- before do
21
+ before(:all) do
22
22
  if version < RAILS_VERSION
23
23
  skip "Rails version #{version} or lower required, we have #{RAILS_VERSION}"
24
24
  end
@@ -26,11 +26,11 @@ module Constraints
26
26
  end
27
27
 
28
28
  def min_server_version(version)
29
- unless version =~ /^\d+\.\d+$/
29
+ unless version =~ /\A\d+\.\d+\z/
30
30
  raise ArgumentError, "Version can only be major.minor: #{version}"
31
31
  end
32
32
 
33
- before do
33
+ before(:all) do
34
34
  if version > ClusterConfig.instance.server_version
35
35
  skip "Server version #{version} or higher required, we have #{ClusterConfig.instance.server_version}"
36
36
  end
@@ -38,11 +38,11 @@ module Constraints
38
38
  end
39
39
 
40
40
  def max_server_version(version)
41
- unless version =~ /^\d+\.\d+$/
41
+ unless version =~ /\A\d+\.\d+\z/
42
42
  raise ArgumentError, "Version can only be major.minor: #{version}"
43
43
  end
44
44
 
45
- before do
45
+ before(:all) do
46
46
  if version < ClusterConfig.instance.short_server_version
47
47
  skip "Server version #{version} or lower required, we have #{ClusterConfig.instance.server_version}"
48
48
  end
@@ -50,18 +50,14 @@ module Constraints
50
50
  end
51
51
 
52
52
  def require_topology(*topologies)
53
- topologies = topologies.map { |t| t.to_s }
54
- invalid_topologies = topologies - %w(single replica_set sharded)
53
+ invalid_topologies = topologies - [:single, :replica_set, :sharded]
54
+
55
55
  unless invalid_topologies.empty?
56
56
  raise ArgumentError, "Invalid topologies requested: #{invalid_topologies.join(', ')}"
57
57
  end
58
- before do
59
- topology = Mongoid.default_client.cluster.topology.class.name.sub(/.*::/, '')
60
- topology = topology.gsub(/([A-Z])/) { |match| '_' + match.downcase }.sub(/^_/, '')
61
- if topology =~ /^replica_set/
62
- topology = 'replica_set'
63
- end
64
- unless topologies.include?(topology)
58
+
59
+ before(:all) do
60
+ unless topologies.include?(topology = ClusterConfig.instance.topology)
65
61
  skip "Topology #{topologies.join(' or ')} required, we have #{topology}"
66
62
  end
67
63
  end
@@ -76,8 +72,22 @@ module Constraints
76
72
  end
77
73
 
78
74
  def require_transaction_support
79
- min_server_version '4.0'
80
- require_topology :replica_set
75
+ before(:all) do
76
+ case ClusterConfig.instance.topology
77
+ when :single
78
+ skip 'Transactions tests require a replica set (4.0+) or a sharded cluster (4.2+)'
79
+ when :replica_set
80
+ unless ClusterConfig.instance.server_version >= '4.0'
81
+ skip 'Transactions tests in a replica set topology require server 4.0+'
82
+ end
83
+ when :sharded
84
+ unless ClusterConfig.instance.server_version >= '4.2'
85
+ skip 'Transactions tests in a sharded cluster topology require server 4.2+'
86
+ end
87
+ else
88
+ raise NotImplementedError
89
+ end
90
+ end
81
91
  end
82
92
 
83
93
  def require_scram_sha_256_support