mongoid 7.2.0.rc1 → 7.2.0

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 (42) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +30 -11
  5. data/lib/mongoid/association/referenced/has_one/buildable.rb +8 -0
  6. data/lib/mongoid/association/referenced/has_one/proxy.rb +6 -1
  7. data/lib/mongoid/copyable.rb +5 -1
  8. data/lib/mongoid/extensions.rb +1 -0
  9. data/lib/mongoid/fields.rb +3 -0
  10. data/lib/mongoid/stringified_symbol.rb +53 -0
  11. data/lib/mongoid/version.rb +1 -1
  12. data/spec/README.md +19 -4
  13. data/spec/integration/app_spec.rb +12 -12
  14. data/spec/integration/associations/embeds_many_spec.rb +24 -0
  15. data/spec/integration/associations/embeds_one_spec.rb +24 -0
  16. data/spec/integration/associations/has_many_spec.rb +60 -0
  17. data/spec/integration/associations/has_one_spec.rb +60 -0
  18. data/spec/integration/stringified_symbol_field_spec.rb +190 -0
  19. data/spec/lite_spec_helper.rb +4 -3
  20. data/spec/mongoid/association/referenced/has_many_models.rb +12 -0
  21. data/spec/mongoid/association/referenced/has_one_models.rb +12 -0
  22. data/spec/mongoid/association/referenced/has_one_spec.rb +1 -1
  23. data/spec/mongoid/copyable_spec.rb +44 -17
  24. data/spec/mongoid/copyable_spec_models.rb +14 -0
  25. data/spec/mongoid/equality_spec.rb +0 -1
  26. data/spec/mongoid/extensions/stringified_symbol_spec.rb +85 -0
  27. data/spec/shared/LICENSE +20 -0
  28. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  29. data/spec/shared/lib/mrss/constraints.rb +303 -0
  30. data/spec/shared/lib/mrss/lite_constraints.rb +175 -0
  31. data/spec/shared/lib/mrss/spec_organizer.rb +149 -0
  32. data/spec/spec_helper.rb +2 -0
  33. data/spec/support/constraints.rb +0 -226
  34. data/spec/support/models/order.rb +11 -0
  35. data/spec/support/models/person.rb +2 -0
  36. data/spec/support/models/series.rb +1 -0
  37. data/spec/support/models/wiki_page.rb +1 -0
  38. metadata +512 -496
  39. metadata.gz.sig +0 -0
  40. data/spec/support/child_process_helper.rb +0 -79
  41. data/spec/support/lite_constraints.rb +0 -22
  42. data/spec/support/spec_organizer.rb +0 -130
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da086175f8b41ffc6991262225460da5577f7ea47d3c355f34e072ff5c78d5f1
4
- data.tar.gz: 7797a83ed15fd55f0ec8aba1a43569393f99f037a7f1013aeb0770f0aa4c3000
3
+ metadata.gz: 6a81d403f49ffcc37e06200c91ab90a6205604730f7169ceb4a07d057ae61193
4
+ data.tar.gz: 045ce8ed60ab931f1406e52f25f9e486d670ec1c76dff86ee3b299cbeca0adfe
5
5
  SHA512:
6
- metadata.gz: f18e6f9ca45ce9cc406a32983d031388c5f6a76100de18fcdf036163bf08c74f4f15a1e77a02c6445e37f2824ec6ecf549514bf78447f7876b8d52d2c2fb4947
7
- data.tar.gz: ca7b9fe36e273d4e2dab3680dbaa973450eb2b87ae58a9d462bba6ec95d27de1479255175a9d7971b32e61b5a43726d7b7855134c5ec733b75e126e6e51fb408
6
+ metadata.gz: bebd7b18d65049cd7d0793319a65bf1868f3c9addf09c21c7b4dbf315deb2fda27cf1a8f27be5288245ab2b1c830d21752de9042d01fb9b31579cab7536ccdcf
7
+ data.tar.gz: 4a4b231ce42eb8b5bf07eca5131ff4b9e5c838a0965996adcf9a529ad6c398f11e0c9e4e5d7cc005fe969e4851a50a2d6aab7c436af433a809c6090ff1927b9c
Binary file
data.tar.gz.sig CHANGED
Binary file
data/Rakefile CHANGED
@@ -4,8 +4,13 @@ require "bundler"
4
4
  require "bundler/gem_tasks"
5
5
  Bundler.setup
6
6
 
7
+ ROOT = File.expand_path(File.join(File.dirname(__FILE__)))
8
+
9
+ $: << File.join(ROOT, 'spec/shared/lib')
10
+
7
11
  require "rake"
8
12
  require "rspec/core/rake_task"
13
+ require 'mrss/spec_organizer'
9
14
 
10
15
  $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
11
16
  require "mongoid/version"
@@ -22,11 +27,8 @@ task :install => :build do
22
27
  system "sudo gem install mongoid-#{Mongoid::VERSION}.gem"
23
28
  end
24
29
 
25
- task :release => :build do
26
- system "git tag -a v#{Mongoid::VERSION} -m 'Tagging #{Mongoid::VERSION}'"
27
- system "git push --tags"
28
- system "gem push mongoid-#{Mongoid::VERSION}.gem"
29
- system "rm mongoid-#{Mongoid::VERSION}.gem"
30
+ task :release do
31
+ raise "Please use ./release.sh to release"
30
32
  end
31
33
 
32
34
  RSpec::Core::RakeTask.new("spec") do |spec|
@@ -38,11 +40,30 @@ RSpec::Core::RakeTask.new('spec:progress') do |spec|
38
40
  spec.pattern = "spec/**/*_spec.rb"
39
41
  end
40
42
 
41
- task :ci do
42
- $LOAD_PATH.push File.expand_path("../spec", __FILE__)
43
- require 'support/spec_organizer'
43
+ CLASSIFIERS = [
44
+ [%r,^mongoid/attribute,, :attributes],
45
+ [%r,^mongoid/association/[or],, :associations_referenced],
46
+ [%r,^mongoid/association,, :associations],
47
+ [%r,^mongoid,, :unit],
48
+ [%r,^integration,, :integration],
49
+ [%r,^rails,, :rails],
50
+ ]
51
+
52
+ RUN_PRIORITY = %i(
53
+ unit attributes associations_referenced associations
54
+ integration rails
55
+ )
56
+
57
+ def spec_organizer
58
+ Mrss::SpecOrganizer.new(
59
+ root: ROOT,
60
+ classifiers: CLASSIFIERS,
61
+ priority_order: RUN_PRIORITY,
62
+ )
63
+ end
44
64
 
45
- SpecOrganizer.new.run
65
+ task :ci do
66
+ spec_organizer.run
46
67
  end
47
68
 
48
69
  task :default => :spec
@@ -66,5 +87,3 @@ namespace :release do
66
87
  end
67
88
  end
68
89
  end
69
-
70
- task :release => ['release:check_private_key', 'release:do']
@@ -35,6 +35,14 @@ module Mongoid
35
35
  private
36
36
 
37
37
  def clear_associated(object)
38
+ unless inverse
39
+ raise Errors::InverseNotFound.new(
40
+ @owner_class,
41
+ name,
42
+ object.class,
43
+ foreign_key,
44
+ )
45
+ end
38
46
  if object && (associated = object.send(inverse))
39
47
  associated.substitute(nil)
40
48
  end
@@ -54,9 +54,14 @@ module Mongoid
54
54
  #
55
55
  # @since 2.0.0.rc.1
56
56
  def substitute(replacement)
57
+ # If the same object currently associated is being assigned,
58
+ # rebind the association and save the target but do not destroy
59
+ # the target.
60
+
57
61
  unbind_one
58
62
  if persistable?
59
- if _association.destructive?
63
+ # TODO can this entire method be skipped if self == replacement?
64
+ if _association.destructive? && self != replacement
60
65
  send(_association.dependent)
61
66
  else
62
67
  save if persisted?
@@ -23,8 +23,12 @@ module Mongoid
23
23
  # elsewhere.
24
24
  attrs = clone_document.except("_id", "id")
25
25
  dynamic_attrs = {}
26
+ _attribute_names = self.attribute_names
26
27
  attrs.reject! do |attr_name, value|
27
- dynamic_attrs.merge!(attr_name => value) unless self.attribute_names.include?(attr_name)
28
+ unless _attribute_names.include?(attr_name)
29
+ dynamic_attrs[attr_name] = value
30
+ true
31
+ end
28
32
  end
29
33
  self.class.new(attrs).tap do |object|
30
34
  dynamic_attrs.each do |attr_name, value|
@@ -38,6 +38,7 @@ require "mongoid/extensions/range"
38
38
  require "mongoid/extensions/regexp"
39
39
  require "mongoid/extensions/set"
40
40
  require "mongoid/extensions/string"
41
+ require "mongoid/stringified_symbol"
41
42
  require "mongoid/extensions/symbol"
42
43
  require "mongoid/extensions/time"
43
44
  require "mongoid/extensions/time_with_zone"
@@ -12,6 +12,8 @@ module Mongoid
12
12
  module Fields
13
13
  extend ActiveSupport::Concern
14
14
 
15
+ StringifiedSymbol = Mongoid::StringifiedSymbol
16
+
15
17
  # For fields defined with symbols use the correct class.
16
18
  #
17
19
  # @since 4.0.0
@@ -30,6 +32,7 @@ module Mongoid
30
32
  regexp: Regexp,
31
33
  set: Set,
32
34
  string: String,
35
+ stringified_symbol: StringifiedSymbol,
33
36
  symbol: Symbol,
34
37
  time: Time
35
38
  }.with_indifferent_access
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ # A class which sends values to the database as Strings but returns them to the user as Symbols.
5
+ module Mongoid
6
+ class StringifiedSymbol
7
+
8
+ class << self
9
+
10
+ # Convert the object from its mongo friendly ruby type to this type.
11
+ #
12
+ # @example Demongoize the object.
13
+ # Symbol.demongoize(object)
14
+ #
15
+ # @param [ Object ] object The object to demongoize.
16
+ #
17
+ # @return [ Symbol ] The object.
18
+ #
19
+ # @api private
20
+ def demongoize(object)
21
+ if object.nil?
22
+ object
23
+ else
24
+ object.to_s.to_sym
25
+ end
26
+ end
27
+
28
+ # Turn the object from the ruby type we deal with to a Mongo friendly
29
+ # type.
30
+ #
31
+ # @example Mongoize the object.
32
+ # Symbol.mongoize("123.11")
33
+ #
34
+ # @param [ Object ] object The object to mongoize.
35
+ #
36
+ # @return [ Symbol ] The object mongoized.
37
+ #
38
+ # @api private
39
+ def mongoize(object)
40
+ if object.nil?
41
+ object
42
+ else
43
+ object.to_s
44
+ end
45
+ end
46
+
47
+ # @api private
48
+ def evolve(object)
49
+ mongoize(object)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -2,5 +2,5 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  module Mongoid
5
- VERSION = "7.2.0.rc1"
5
+ VERSION = "7.2.0"
6
6
  end
@@ -1,8 +1,17 @@
1
1
  # Running Mongoid Tests
2
2
 
3
- ## Overview
4
- ### Quick Start
5
- Spin up a MongoDB deployment against which to run the Mongoid specs. Mongoid specs support a variety of MongoDB topologies, but the simplest is a single MongoDB instance:
3
+ ## Quick Start
4
+
5
+ The test suite requires shared tooling that is stored in a separate repository
6
+ and is referenced as a submodule. After checking out the desired driver
7
+ branch, check out the matching submodules:
8
+
9
+ git submodule init
10
+ git submodule update
11
+
12
+ Spin up a MongoDB deployment against which to run the Mongoid specs.
13
+ Mongoid specs support a variety of MongoDB topologies, but the simplest is
14
+ a single MongoDB instance:
6
15
 
7
16
  # Launch mongod in one terminal
8
17
  mkdir /tmp/mdb
@@ -14,5 +23,11 @@ Run the test suite in a separate terminal:
14
23
 
15
24
 
16
25
  ## Caveats
26
+
17
27
  ### "Too many open files" error
18
- On MacOS, you may encounter a "Too many open files" error on the MongoDB server when running the tests. If this happens, stop the server, run the command `ulimit -n 10000` in the same terminal session as the server, and restart the server. This will increase the number of files that can be opened. Then, re-run the tests.
28
+
29
+ On MacOS, you may encounter a "Too many open files" error on the MongoDB server
30
+ when running the tests. If this happens, stop the server, run the command
31
+ `ulimit -n 10000` in the same terminal session as the server, and restart
32
+ the server. This will increase the number of files that can be opened.
33
+ Then, re-run the tests.
@@ -13,7 +13,7 @@ describe 'Mongoid application tests' do
13
13
  end
14
14
 
15
15
  require 'fileutils'
16
- require 'support/child_process_helper'
16
+ require 'mrss/child_process_helper'
17
17
  require 'open-uri'
18
18
 
19
19
  FileUtils.mkdir_p(TMP_BASE)
@@ -91,19 +91,19 @@ describe 'Mongoid application tests' do
91
91
  ['~> 5.1.0', '~> 5.2.0', '~> 6.0.0'].each do |rails_version|
92
92
  context "with rails #{rails_version}" do
93
93
  it 'creates' do
94
- ChildProcessHelper.check_call(%w(gem uni rails -a))
95
- ChildProcessHelper.check_call(%w(gem install rails --no-document -v) + [rails_version])
94
+ Mrss::ChildProcessHelper.check_call(%w(gem uni rails -a))
95
+ Mrss::ChildProcessHelper.check_call(%w(gem install rails --no-document -v) + [rails_version])
96
96
 
97
97
  Dir.chdir(TMP_BASE) do
98
98
  FileUtils.rm_rf('mongoid-test')
99
- ChildProcessHelper.check_call(%w(rails new mongoid-test --skip-spring --skip-active-record), env: clean_env)
99
+ Mrss::ChildProcessHelper.check_call(%w(rails new mongoid-test --skip-spring --skip-active-record), env: clean_env)
100
100
 
101
101
  Dir.chdir('mongoid-test') do
102
102
  adjust_app_gemfile
103
- ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
103
+ Mrss::ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
104
104
 
105
- ChildProcessHelper.check_call(%w(rails g model post), env: clean_env)
106
- ChildProcessHelper.check_call(%w(rails g model comment post:belongs_to), env: clean_env)
105
+ Mrss::ChildProcessHelper.check_call(%w(rails g model post), env: clean_env)
106
+ Mrss::ChildProcessHelper.check_call(%w(rails g model comment post:belongs_to), env: clean_env)
107
107
 
108
108
  # https://jira.mongodb.org/browse/MONGOID-4885
109
109
  comment_text = File.read('app/models/comment.rb')
@@ -136,7 +136,7 @@ describe 'Mongoid application tests' do
136
136
  before do
137
137
  Dir.chdir(APP_PATH) do
138
138
  remove_bundler_req
139
- ChildProcessHelper.check_call(%w(bundle install), env: env)
139
+ Mrss::ChildProcessHelper.check_call(%w(bundle install), env: env)
140
140
  write_mongoid_yml
141
141
  end
142
142
 
@@ -150,7 +150,7 @@ describe 'Mongoid application tests' do
150
150
  end
151
151
  index.should be nil
152
152
 
153
- ChildProcessHelper.check_call(%w(rake db:mongoid:create_indexes),
153
+ Mrss::ChildProcessHelper.check_call(%w(rake db:mongoid:create_indexes),
154
154
  cwd: APP_PATH, env: env)
155
155
 
156
156
  index = client['posts'].indexes.detect do |index|
@@ -168,10 +168,10 @@ describe 'Mongoid application tests' do
168
168
  def clone_application(repo_url, subdir: nil, rails_version: nil)
169
169
  Dir.chdir(TMP_BASE) do
170
170
  FileUtils.rm_rf(File.basename(repo_url))
171
- ChildProcessHelper.check_call(%w(git clone) + [repo_url])
171
+ Mrss::ChildProcessHelper.check_call(%w(git clone) + [repo_url])
172
172
  Dir.chdir(File.join(*[File.basename(repo_url), subdir].compact)) do
173
173
  adjust_app_gemfile(rails_version: rails_version)
174
- ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
174
+ Mrss::ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
175
175
  puts `git diff`
176
176
 
177
177
  write_mongoid_yml
@@ -230,7 +230,7 @@ describe 'Mongoid application tests' do
230
230
  # in `initialize': too long unix socket path (126bytes given but 108bytes max) (ArgumentError)
231
231
  # Is it trying to create unix sockets in current directory?
232
232
  # https://stackoverflow.com/questions/30302021/rails-runner-without-spring
233
- ChildProcessHelper.check_call(%w(bin/spring binstub --remove --all), env: clean_env)
233
+ Mrss::ChildProcessHelper.check_call(%w(bin/spring binstub --remove --all), env: clean_env)
234
234
  end
235
235
 
236
236
  def clean_env
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require 'spec_helper'
5
+
6
+ describe 'embeds_many associations' do
7
+
8
+ context 're-associating the same object' do
9
+ context 'with dependent: destroy' do
10
+ let(:canvas) do
11
+ Canvas.create!(shapes: [Shape.new])
12
+ end
13
+
14
+ let!(:shape) { canvas.shapes.first }
15
+
16
+ it 'does not destroy the dependent object' do
17
+ canvas.shapes = [shape]
18
+ canvas.save!
19
+ canvas.reload
20
+ canvas.shapes.should == [shape]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require 'spec_helper'
5
+
6
+ describe 'embeds_one associations' do
7
+
8
+ context 're-associating the same object' do
9
+ context 'with dependent: destroy' do
10
+ let(:canvas) do
11
+ Canvas.create!(palette: Palette.new)
12
+ end
13
+
14
+ let!(:palette) { canvas.palette }
15
+
16
+ it 'does not destroy the dependent object' do
17
+ canvas.palette = canvas.palette
18
+ canvas.save!
19
+ canvas.reload
20
+ canvas.palette.should == palette
21
+ end
22
+ end
23
+ end
24
+ end
@@ -66,4 +66,64 @@ describe 'has_many associations' do
66
66
  end
67
67
  end
68
68
  end
69
+
70
+ context 'when child does not have parent association' do
71
+ context 'Child.new' do
72
+ it 'creates a child instance' do
73
+ HmmBusSeat.new.should be_a(HmmBusSeat)
74
+ end
75
+ end
76
+
77
+ context 'assignment to child in parent' do
78
+ let(:parent) { HmmBus.new }
79
+
80
+ it 'raises InverseNotFound' do
81
+ lambda do
82
+ parent.seats << HmmBusSeat.new
83
+ end.should raise_error(Mongoid::Errors::InverseNotFound)
84
+ end
85
+ end
86
+ end
87
+
88
+ context 're-associating the same object' do
89
+ context 'with dependent: destroy' do
90
+ let(:wiki_page) do
91
+ WikiPage.create!
92
+ end
93
+
94
+ let!(:comment) do
95
+ Comment.create!(wiki_page: wiki_page, title: 'hi') do
96
+ wiki_page.reload
97
+ end
98
+ end
99
+
100
+ it 'does not destroy the dependent object' do
101
+ wiki_page.comments.should == [comment]
102
+ wiki_page.comments = [comment]
103
+ wiki_page.save!
104
+ wiki_page.reload
105
+ wiki_page.comments.should == [comment]
106
+ end
107
+ end
108
+
109
+ context 'without dependent: destroy' do
110
+ let(:series) do
111
+ Series.create!
112
+ end
113
+
114
+ let!(:book) do
115
+ Book.create!(series: series).tap do
116
+ series.reload
117
+ end
118
+ end
119
+
120
+ it 'does not destroy the dependent object' do
121
+ series.books.should == [book]
122
+ series.books = [book]
123
+ series.save!
124
+ series.reload
125
+ series.books.should == [book]
126
+ end
127
+ end
128
+ end
69
129
  end
@@ -66,4 +66,64 @@ describe 'has_one associations' do
66
66
  end
67
67
  end
68
68
  end
69
+
70
+ context 'when child does not have parent association' do
71
+ context 'Child.new' do
72
+ it 'creates a child instance' do
73
+ HomBusDriver.new.should be_a(HomBusDriver)
74
+ end
75
+ end
76
+
77
+ context 'assignment to child in parent' do
78
+ let(:parent) { HomBus.new }
79
+
80
+ it 'raises InverseNotFound' do
81
+ lambda do
82
+ parent.driver = HomBusDriver.new
83
+ end.should raise_error(Mongoid::Errors::InverseNotFound)
84
+ end
85
+ end
86
+ end
87
+
88
+ context 're-associating the same object' do
89
+ context 'with dependent: destroy' do
90
+ let(:person) do
91
+ Person.create!
92
+ end
93
+
94
+ let!(:game) do
95
+ Game.create!(person: person) do
96
+ person.reload
97
+ end
98
+ end
99
+
100
+ it 'does not destroy the dependent object' do
101
+ person.game.should == game
102
+ person.game = person.game
103
+ person.save!
104
+ person.reload
105
+ person.game.should == game
106
+ end
107
+ end
108
+
109
+ context 'without dependent: destroy' do
110
+ let(:person) do
111
+ Person.create!
112
+ end
113
+
114
+ let!(:account) do
115
+ Account.create!(person: person, name: 'foo').tap do
116
+ person.reload
117
+ end
118
+ end
119
+
120
+ it 'does not destroy the dependent object' do
121
+ person.account.should == account
122
+ person.account = person.account
123
+ person.save!
124
+ person.reload
125
+ person.account.should == account
126
+ end
127
+ end
128
+ end
69
129
  end