mongoid 7.1.1 → 7.1.2

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 (63) 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/association/embedded/embeds_many.rb +2 -1
  5. data/lib/mongoid/association/embedded/embeds_one.rb +2 -1
  6. data/lib/mongoid/association/proxy.rb +1 -1
  7. data/lib/mongoid/atomic.rb +13 -3
  8. data/lib/mongoid/criteria.rb +7 -1
  9. data/lib/mongoid/criteria/modifiable.rb +2 -1
  10. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  11. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  12. data/lib/mongoid/criteria/queryable/mergeable.rb +75 -8
  13. data/lib/mongoid/criteria/queryable/selectable.rb +28 -8
  14. data/lib/mongoid/extensions/hash.rb +4 -2
  15. data/lib/mongoid/extensions/regexp.rb +1 -1
  16. data/lib/mongoid/fields.rb +2 -1
  17. data/lib/mongoid/matchable/regexp.rb +2 -2
  18. data/lib/mongoid/persistable/pushable.rb +4 -1
  19. data/lib/mongoid/persistence_context.rb +6 -6
  20. data/lib/mongoid/query_cache.rb +2 -1
  21. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  22. data/lib/mongoid/version.rb +1 -1
  23. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
  24. data/spec/integration/app_spec.rb +192 -0
  25. data/spec/integration/associations/embedded_spec.rb +54 -0
  26. data/spec/integration/criteria/logical_spec.rb +13 -0
  27. data/spec/lite_spec_helper.rb +11 -4
  28. data/spec/mongoid/association/embedded/embeds_many_models.rb +19 -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 +2 -2
  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 +22 -11
  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/queryable/mergeable_spec.rb +45 -12
  43. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +480 -198
  44. data/spec/mongoid/criteria_spec.rb +4 -2
  45. data/spec/mongoid/document_persistence_context_spec.rb +33 -0
  46. data/spec/mongoid/indexable_spec.rb +6 -4
  47. data/spec/mongoid/matchable/default_spec.rb +1 -1
  48. data/spec/mongoid/matchable/regexp_spec.rb +2 -2
  49. data/spec/mongoid/matchable_spec.rb +2 -2
  50. data/spec/mongoid/query_cache_spec.rb +2 -1
  51. data/spec/mongoid/relations/proxy_spec.rb +1 -1
  52. data/spec/mongoid/scopable_spec.rb +2 -1
  53. data/spec/mongoid/shardable_models.rb +1 -1
  54. data/spec/mongoid/shardable_spec.rb +2 -2
  55. data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
  56. data/spec/mongoid/tasks/database_spec.rb +1 -1
  57. data/spec/spec_helper.rb +0 -31
  58. data/spec/support/child_process_helper.rb +76 -0
  59. data/spec/support/cluster_config.rb +3 -3
  60. data/spec/support/constraints.rb +26 -10
  61. data/spec/support/spec_config.rb +12 -4
  62. metadata +8 -2
  63. metadata.gz.sig +0 -0
@@ -2337,7 +2337,7 @@ describe Mongoid::Criteria do
2337
2337
  end
2338
2338
 
2339
2339
  it "returns the map/reduce results" do
2340
- expect(map_reduce).to eq([
2340
+ expect(map_reduce.sort_by { |doc| doc['_id'] }).to eq([
2341
2341
  { "_id" => "Depeche Mode", "value" => { "likes" => 200 }},
2342
2342
  { "_id" => "Tool", "value" => { "likes" => 100 }}
2343
2343
  ])
@@ -3534,7 +3534,8 @@ describe Mongoid::Criteria do
3534
3534
  end
3535
3535
  end
3536
3536
 
3537
- context "when querying on a BSON::Decimal128", if: decimal128_supported? do
3537
+ context "when querying on a BSON::Decimal128" do
3538
+ min_server_version '3.4'
3538
3539
 
3539
3540
  let(:decimal) do
3540
3541
  BSON::Decimal128.new("0.0005")
@@ -3622,6 +3623,7 @@ describe Mongoid::Criteria do
3622
3623
  end
3623
3624
 
3624
3625
  context "when the code has scope" do
3626
+ max_server_version '4.2'
3625
3627
 
3626
3628
  let(:criteria) do
3627
3629
  Band.for_js("this.name == param", param: "Depeche Mode")
@@ -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
@@ -48,7 +48,7 @@ describe Mongoid::Indexable do
48
48
  end
49
49
  end
50
50
 
51
- context "when database specific options exist", if: non_legacy_server? do
51
+ context "when database specific options exist" do
52
52
 
53
53
  let(:klass) do
54
54
  Class.new do
@@ -98,7 +98,7 @@ describe Mongoid::Indexable do
98
98
  end
99
99
  end
100
100
 
101
- context "when database options are specified", if: non_legacy_server? do
101
+ context "when database options are specified" do
102
102
 
103
103
  let(:klass) do
104
104
  Class.new do
@@ -136,7 +136,8 @@ describe Mongoid::Indexable do
136
136
  end
137
137
  end
138
138
 
139
- context "when a collation option is specified", if: collation_supported? do
139
+ context "when a collation option is specified" do
140
+ min_server_version '3.4'
140
141
 
141
142
  let(:klass) do
142
143
  Class.new do
@@ -311,7 +312,8 @@ describe Mongoid::Indexable do
311
312
  end
312
313
  end
313
314
 
314
- context "when providing a collation option", if: collation_supported? do
315
+ context "when providing a collation option" do
316
+ min_server_version '3.4'
315
317
 
316
318
  before do
317
319
  klass.index({ name: 1 }, collation: { locale: 'en_US', strength: 2 })
@@ -71,7 +71,7 @@ describe Mongoid::Matchable::Default do
71
71
  context "when the value is a regexp" do
72
72
 
73
73
  it "returns true" do
74
- expect(matcher._matches?(/^Test[3-5]$/)).to be true
74
+ expect(matcher._matches?(/\ATest[3-5]\z/)).to be true
75
75
  end
76
76
  end
77
77
  end
@@ -18,7 +18,7 @@ describe Mongoid::Matchable::Regexp do
18
18
  context 'when a BSON::Regexp::Raw object is passed' do
19
19
 
20
20
  let(:regexp) do
21
- BSON::Regexp::Raw.new('^Em')
21
+ BSON::Regexp::Raw.new("\\AEm")
22
22
  end
23
23
 
24
24
  it 'compiles the regexp object to a native regexp for the matching' do
@@ -40,7 +40,7 @@ describe Mongoid::Matchable::Regexp do
40
40
  context 'when a native Regexp object is passed' do
41
41
 
42
42
  let(:regexp) do
43
- /^Em/
43
+ /\AEm/
44
44
  end
45
45
 
46
46
  it 'calls super with the native regexp' do
@@ -296,7 +296,7 @@ describe Mongoid::Matchable do
296
296
  context 'when a BSON::Regexp::Raw object is used' do
297
297
 
298
298
  let(:selector) do
299
- { street: BSON::Regexp::Raw.new("^Clarkenwell") }
299
+ { street: BSON::Regexp::Raw.new("\\AClarkenwell") }
300
300
  end
301
301
 
302
302
  it "returns true" do
@@ -307,7 +307,7 @@ describe Mongoid::Matchable do
307
307
  context 'when a native Regexp object is used' do
308
308
 
309
309
  let(:selector) do
310
- { street: /^Clarkenwell/ }
310
+ { street: /\AClarkenwell/ }
311
311
  end
312
312
 
313
313
  it "returns true" do
@@ -183,7 +183,8 @@ describe Mongoid::QueryCache do
183
183
  end
184
184
  end
185
185
 
186
- context 'when the first query has a collation', if: collation_supported? do
186
+ context 'when the first query has a collation' do
187
+ min_server_version '3.4'
187
188
 
188
189
  before do
189
190
  Band.where(name: 'DEPECHE MODE').collation(locale: 'en_US', strength: 2).to_a
@@ -5,7 +5,7 @@
5
5
  #
6
6
  # describe Mongoid::Relations::Proxy do
7
7
  #
8
- # describe '#with', if: non_legacy_server? do
8
+ # describe '#with' do
9
9
  #
10
10
  # let(:circus) do
11
11
  # Circus.new
@@ -230,7 +230,8 @@ describe Mongoid::Scopable do
230
230
 
231
231
  context "when provided a criteria" do
232
232
 
233
- context 'when a collation is defined on the criteria', if: collation_supported? do
233
+ context 'when a collation is defined on the criteria' do
234
+ min_server_version '3.4'
234
235
 
235
236
  before do
236
237
  Band.scope(:tests, ->{ Band.where(name: 'TESTING').collation(locale: 'en_US', strength: 2) })
@@ -19,7 +19,7 @@ class SmActor
19
19
 
20
20
  # This is not a usable shard configuration for the server.
21
21
  # We just have it for unit tests.
22
- shard_key age: 1, 'gender' => :hashed
22
+ shard_key age: 1, 'gender' => :hashed, 'hello' => :hashed
23
23
  end
24
24
 
25
25
  class SmAssistant
@@ -48,12 +48,12 @@ describe Mongoid::Shardable do
48
48
 
49
49
  context 'with string value' do
50
50
  it 'sets shard key fields to symbol value' do
51
- SmActor.shard_key_fields.should == %i(age gender)
51
+ SmActor.shard_key_fields.should == %i(age gender hello)
52
52
  end
53
53
 
54
54
  it 'sets shard config' do
55
55
  SmActor.shard_config.should == {
56
- key: {age: 1, gender: 'hashed'},
56
+ key: {age: 1, gender: 'hashed', hello: 'hashed'},
57
57
  options: {},
58
58
  }
59
59
  end
@@ -48,7 +48,7 @@ shared_context "rails rake task" do
48
48
  end
49
49
  end
50
50
 
51
- describe "db:drop", if: non_legacy_server? do
51
+ describe "db:drop" do
52
52
  include_context "rake task"
53
53
  include_context "rails rake task"
54
54
 
@@ -61,7 +61,7 @@ describe "db:drop", if: non_legacy_server? do
61
61
  end
62
62
  end
63
63
 
64
- describe "db:purge", if: non_legacy_server? do
64
+ describe "db:purge" do
65
65
  include_context "rake task"
66
66
  include_context "rails rake task"
67
67
 
@@ -74,7 +74,7 @@ describe "db:purge", if: non_legacy_server? do
74
74
  end
75
75
  end
76
76
 
77
- describe "db:seed", if: non_legacy_server? do
77
+ describe "db:seed" do
78
78
  include_context "rake task"
79
79
  include_context "rails rake task"
80
80
 
@@ -88,7 +88,7 @@ describe "db:seed", if: non_legacy_server? do
88
88
  end
89
89
  end
90
90
 
91
- describe "db:setup", if: non_legacy_server? do
91
+ describe "db:setup" do
92
92
  include_context "rake task"
93
93
  include_context "rails rake task"
94
94
 
@@ -120,7 +120,7 @@ describe "db:setup", if: non_legacy_server? do
120
120
  end
121
121
  end
122
122
 
123
- describe "db:reset", if: non_legacy_server? do
123
+ describe "db:reset" do
124
124
  include_context "rake task"
125
125
  include_context "rails rake task"
126
126
 
@@ -138,7 +138,7 @@ describe "db:reset", if: non_legacy_server? do
138
138
  end
139
139
  end
140
140
 
141
- describe "db:create", if: non_legacy_server? do
141
+ describe "db:create" do
142
142
  include_context "rake task"
143
143
  include_context "rails rake task"
144
144
 
@@ -147,7 +147,7 @@ describe "db:create", if: non_legacy_server? do
147
147
  end
148
148
  end
149
149
 
150
- describe "db:migrate", if: non_legacy_server? do
150
+ describe "db:migrate" do
151
151
  include_context "rake task"
152
152
  include_context "rails rake task"
153
153
 
@@ -156,7 +156,7 @@ describe "db:migrate", if: non_legacy_server? do
156
156
  end
157
157
  end
158
158
 
159
- describe "db:test:prepare", if: non_legacy_server? do
159
+ describe "db:test:prepare" do
160
160
  include_context "rake task"
161
161
  include_context "rails rake task"
162
162
 
@@ -177,7 +177,7 @@ describe "db:test:prepare", if: non_legacy_server? do
177
177
  end
178
178
  end
179
179
 
180
- describe "db:mongoid:create_indexes", if: non_legacy_server? do
180
+ describe "db:mongoid:create_indexes" do
181
181
  include_context "rake task"
182
182
 
183
183
  it_behaves_like "create_indexes"
@@ -201,7 +201,7 @@ describe "db:mongoid:create_indexes", if: non_legacy_server? do
201
201
  end
202
202
  end
203
203
 
204
- describe "db:mongoid:remove_undefined_indexes", if: non_legacy_server? do
204
+ describe "db:mongoid:remove_undefined_indexes" do
205
205
  include_context "rake task"
206
206
 
207
207
  it "receives remove_undefined_indexes" do
@@ -227,7 +227,7 @@ describe "db:mongoid:remove_undefined_indexes", if: non_legacy_server? do
227
227
  end
228
228
  end
229
229
 
230
- describe "db:mongoid:remove_indexes", if: non_legacy_server? do
230
+ describe "db:mongoid:remove_indexes" do
231
231
  include_context "rake task"
232
232
 
233
233
  it "receives remove_indexes" do
@@ -253,7 +253,7 @@ describe "db:mongoid:remove_indexes", if: non_legacy_server? do
253
253
  end
254
254
  end
255
255
 
256
- describe "db:mongoid:drop", if: non_legacy_server? do
256
+ describe "db:mongoid:drop" do
257
257
  include_context "rake task"
258
258
 
259
259
  it "works" do
@@ -269,7 +269,7 @@ describe "db:mongoid:drop", if: non_legacy_server? do
269
269
  end
270
270
  end
271
271
 
272
- describe "db:mongoid:purge", if: non_legacy_server? do
272
+ describe "db:mongoid:purge" do
273
273
  include_context "rake task"
274
274
 
275
275
  it "receives a purge" do
@@ -136,7 +136,7 @@ describe "Mongoid::Tasks::Database" do
136
136
  expect(removed_indexes).to be_empty
137
137
  end
138
138
 
139
- context 'when the index is a text index', if: non_legacy_server? do
139
+ context 'when the index is a text index' do
140
140
 
141
141
  before do
142
142
  class Band
@@ -77,37 +77,6 @@ CONFIG = {
77
77
  }
78
78
  }
79
79
 
80
- def non_legacy_server?
81
- Mongoid::Clients.default.cluster.servers.first.features.write_command_enabled?
82
- end
83
-
84
- def testing_replica_set?
85
- Mongoid::Clients.default.cluster.replica_set?
86
- end
87
-
88
- def collation_supported?
89
- Mongoid::Clients.default.cluster.next_primary.features.collation_enabled?
90
- end
91
- alias :decimal128_supported? :collation_supported?
92
-
93
- def array_filters_supported?
94
- Mongoid::Clients.default.cluster.next_primary.features.array_filters_enabled?
95
- end
96
- alias :sessions_supported? :array_filters_supported?
97
-
98
- def transactions_supported?
99
- features = Mongoid::Clients.default.cluster.next_primary.features
100
- features.respond_to?(:transactions_enabled?) && features.transactions_enabled?
101
- end
102
-
103
- def testing_transactions?
104
- transactions_supported? && if Gem::Version.new(ClusterConfig.instance.fcv_ish) >= Gem::Version.new('4.2')
105
- %i(replica_set sharded).include?(ClusterConfig.instance.topology)
106
- else
107
- ClusterConfig.instance.topology == :replica_set
108
- end
109
- end
110
-
111
80
  # Set the database that the spec suite connects to.
112
81
  Mongoid.configure do |config|
113
82
  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