mongoid 7.0.7 → 7.0.8

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