mongoid 7.1.7 → 7.1.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +1 -1
  4. data/Rakefile +31 -0
  5. data/lib/config/locales/en.yml +13 -0
  6. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +1 -1
  7. data/lib/mongoid/association/proxy.rb +1 -1
  8. data/lib/mongoid/association/referenced/has_many/enumerable.rb +1 -1
  9. data/lib/mongoid/association/referenced/has_many/proxy.rb +1 -1
  10. data/lib/mongoid/attributes.rb +8 -1
  11. data/lib/mongoid/config/environment.rb +9 -1
  12. data/lib/mongoid/contextual/atomic.rb +7 -2
  13. data/lib/mongoid/contextual/none.rb +3 -0
  14. data/lib/mongoid/criteria/queryable/selectable.rb +2 -2
  15. data/lib/mongoid/criteria/queryable/storable.rb +4 -4
  16. data/lib/mongoid/criteria.rb +1 -1
  17. data/lib/mongoid/document.rb +3 -2
  18. data/lib/mongoid/errors/empty_config_file.rb +26 -0
  19. data/lib/mongoid/errors/invalid_config_file.rb +26 -0
  20. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  21. data/lib/mongoid/errors.rb +2 -0
  22. data/lib/mongoid/interceptable.rb +1 -1
  23. data/lib/mongoid/persistence_context.rb +3 -1
  24. data/lib/mongoid/reloadable.rb +5 -0
  25. data/lib/mongoid/tasks/database.rb +1 -1
  26. data/lib/mongoid/validatable/associated.rb +1 -1
  27. data/lib/mongoid/validatable/presence.rb +3 -3
  28. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  29. data/lib/mongoid/version.rb +1 -1
  30. data/lib/mongoid.rb +1 -0
  31. data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
  32. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
  33. data/spec/app/models/address.rb +4 -0
  34. data/spec/app/models/mop.rb +26 -0
  35. data/spec/app/models/person.rb +9 -0
  36. data/spec/integration/app_spec.rb +144 -87
  37. data/spec/integration/contextual/empty_spec.rb +142 -0
  38. data/spec/integration/document_spec.rb +21 -0
  39. data/spec/lite_spec_helper.rb +5 -5
  40. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +17 -4
  41. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +17 -0
  42. data/spec/mongoid/attributes_spec.rb +241 -0
  43. data/spec/mongoid/clients/factory_spec.rb +11 -0
  44. data/spec/mongoid/clients/options_spec.rb +11 -3
  45. data/spec/mongoid/config/environment_spec.rb +86 -8
  46. data/spec/mongoid/contextual/atomic_spec.rb +81 -29
  47. data/spec/mongoid/contextual/geo_near_spec.rb +1 -1
  48. data/spec/mongoid/criteria_spec.rb +4 -0
  49. data/spec/mongoid/document_query_spec.rb +51 -0
  50. data/spec/mongoid/document_spec.rb +21 -1
  51. data/spec/mongoid/errors/invalid_config_file_spec.rb +32 -0
  52. data/spec/mongoid/errors/mongoid_error_spec.rb +20 -8
  53. data/spec/mongoid/factory_spec.rb +2 -2
  54. data/spec/mongoid/persistable/savable_spec.rb +4 -4
  55. data/spec/mongoid/persistable/settable_spec.rb +30 -0
  56. data/spec/mongoid/persistable/updatable_spec.rb +2 -0
  57. data/spec/mongoid/persistable_spec.rb +2 -2
  58. data/spec/shared/bin/get-mongodb-download-url +17 -0
  59. data/spec/shared/bin/s3-copy +45 -0
  60. data/spec/shared/bin/s3-upload +69 -0
  61. data/spec/shared/lib/mrss/cluster_config.rb +19 -4
  62. data/spec/shared/lib/mrss/constraints.rb +67 -12
  63. data/spec/shared/lib/mrss/docker_runner.rb +10 -1
  64. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  65. data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
  66. data/spec/shared/lib/mrss/server_version_registry.rb +84 -33
  67. data/spec/shared/lib/mrss/spec_organizer.rb +32 -2
  68. data/spec/shared/lib/mrss/utils.rb +15 -0
  69. data/spec/shared/share/Dockerfile.erb +126 -32
  70. data/spec/shared/share/haproxy-1.conf +16 -0
  71. data/spec/shared/share/haproxy-2.conf +17 -0
  72. data/spec/shared/shlib/server.sh +123 -26
  73. data/spec/shared/shlib/set_env.sh +4 -1
  74. data/spec/spec_helper.rb +3 -1
  75. data/spec/support/constraints.rb +0 -226
  76. data/spec/support/spec_config.rb +8 -0
  77. data.tar.gz.sig +0 -0
  78. metadata +555 -503
  79. metadata.gz.sig +0 -0
  80. data/spec/support/child_process_helper.rb +0 -76
  81. data/spec/support/lite_constraints.rb +0 -22
@@ -68,7 +68,7 @@ module Mongoid
68
68
  # @since 2.4.10
69
69
  def add_error(document, attribute, value)
70
70
  document.errors.add(
71
- attribute, :taken, options.except(:case_sensitive, :scope).merge(value: value)
71
+ attribute, :taken, **options.except(:case_sensitive, :scope).merge(value: value)
72
72
  )
73
73
  end
74
74
 
@@ -2,5 +2,5 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  module Mongoid
5
- VERSION = "7.1.7"
5
+ VERSION = "7.1.11"
6
6
  end
data/lib/mongoid.rb CHANGED
@@ -6,6 +6,7 @@ require "support/ruby_version"
6
6
  require "forwardable"
7
7
  require "time"
8
8
  require "set"
9
+ require "ruby2_keywords"
9
10
 
10
11
  require "active_support"
11
12
  require "active_support/core_ext"
@@ -15,7 +15,14 @@ module Mongoid
15
15
  end
16
16
 
17
17
  def app_name
18
- Rails::Application.subclasses.first.parent.to_s.underscore
18
+ app_cls = Rails.application.class
19
+ parent = begin
20
+ # Rails 6.1+
21
+ app_cls.module_parent_name
22
+ rescue NoMethodError
23
+ app_cls.parent.to_s
24
+ end
25
+ parent.underscore
19
26
  end
20
27
 
21
28
  def create_config_file
@@ -57,7 +57,7 @@ development:
57
57
  # connect: :direct
58
58
 
59
59
  # Changes the default time in seconds the server monitors refresh their status
60
- # via ismaster commands. (default: 10)
60
+ # via hello commands. (default: 10)
61
61
  # heartbeat_frequency: 10
62
62
 
63
63
  # The time in seconds for selecting servers for a near read preference. (default: 0.015)
@@ -78,5 +78,9 @@ class Address
78
78
  def streets
79
79
  all.map(&:street)
80
80
  end
81
+
82
+ def city_and_state(city:, state:)
83
+ where(city: city, state: state)
84
+ end
81
85
  end
82
86
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ # This class is used for embedded matcher testing.
5
+ class Mop
6
+ include Mongoid::Document
7
+
8
+ # The dynamic attributes are used so that the tests can use various
9
+ # field names as makes sense for the particular operator.
10
+ include Mongoid::Attributes::Dynamic
11
+
12
+ # We need some fields of specific types because the query conditions are
13
+ # transformed differently based on the type of field being queried.
14
+ field :int_field, type: Integer
15
+ field :array_field, type: Array
16
+ field :date_field, type: Date
17
+ field :time_field, type: Time
18
+ field :datetime_field, type: DateTime
19
+ field :big_decimal_field, type: BigDecimal
20
+ field :decimal128_field, type: BSON::Decimal128
21
+ field :symbol_field, type: Symbol
22
+ field :bson_symbol_field, type: BSON::Symbol::Raw
23
+ field :regexp_field, type: Regexp
24
+ field :bson_regexp_field, type: BSON::Regexp::Raw
25
+ end
26
+
@@ -136,6 +136,10 @@ class Person
136
136
  scope :without_ssn, ->{ without(:ssn) }
137
137
  scope :search, ->(query){ any_of({ title: query }) }
138
138
 
139
+ def self.older_than(age:)
140
+ where(:age.gt => age)
141
+ end
142
+
139
143
  def score_with_rescoring=(score)
140
144
  @rescored = score.to_i + 20
141
145
  self.score_without_rescoring = score
@@ -206,6 +210,11 @@ class Person
206
210
  self.map_with_default["key"] = value
207
211
  end
208
212
 
213
+ def set_personal_data(ssn:, age:)
214
+ self.ssn = ssn
215
+ self.age = age
216
+ end
217
+
209
218
  reset_callbacks(:validate)
210
219
  reset_callbacks(:create)
211
220
  reset_callbacks(:save)
@@ -13,109 +13,131 @@ 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)
20
20
  end
21
21
 
22
- context 'demo application - sinatra' do
23
- it 'runs' do
24
- clone_application(
25
- 'https://github.com/mongoid/mongoid-demo',
26
- subdir: 'sinatra-minimal',
27
- ) do
22
+ context 'demo application' do
23
+ context 'sinatra' do
24
+ it 'runs' do
25
+ clone_application(
26
+ 'https://github.com/mongoid/mongoid-demo',
27
+ subdir: 'sinatra-minimal',
28
+ ) do
28
29
 
29
- process = ChildProcess.build(*%w(bundle exec ruby app.rb))
30
- process.environment.update(clean_env)
31
- process.io.inherit!
32
- process.start
33
-
34
- begin
35
30
  # JRuby needs a long timeout
36
- wait_for_port(4567, 20)
37
- sleep 1
38
-
39
- uri = URI.parse('http://localhost:4567/posts')
40
- resp = JSON.parse(uri.open.read)
41
- ensure
42
- Process.kill('TERM', process.pid)
43
- status = process.wait
44
- end
31
+ start_app(%w(bundle exec ruby app.rb), 4567, 40) do |port|
32
+ uri = URI.parse('http://localhost:4567/posts')
33
+ resp = JSON.parse(uri.open.read)
45
34
 
46
- resp.should == []
35
+ resp.should == []
47
36
 
48
- status.should == 0
37
+ end
38
+ end
49
39
  end
50
40
  end
51
- end
52
41
 
53
- context 'demo application - rails-api' do
54
- ['~> 6.0.0'].each do |rails_version|
55
- context "with rails #{rails_version}" do
56
- it 'runs' do
57
- clone_application(
58
- 'https://github.com/mongoid/mongoid-demo',
59
- subdir: 'rails-api',
60
- rails_version: rails_version,
61
- ) do
62
-
63
- process = ChildProcess.build(*%w(bundle exec rails s))
64
- process.environment.update(clean_env)
65
- process.io.inherit!
66
- process.start
67
-
68
- begin
69
- # JRuby needs a long timeout
70
- wait_for_port(3000, 30)
71
- sleep 1
72
-
73
- uri = URI.parse('http://localhost:3000/posts')
74
- resp = JSON.parse(uri.open.read)
75
- ensure
76
- Process.kill('TERM', process.pid)
77
- status = process.wait
78
- end
42
+ context 'rails-api' do
43
+ it 'runs' do
44
+ clone_application(
45
+ 'https://github.com/mongoid/mongoid-demo',
46
+ subdir: 'rails-api',
47
+ ) do
79
48
 
80
- resp.should == []
49
+ # JRuby needs a long timeout
50
+ start_app(%w(bundle exec rails s), 3000, 50) do |port|
51
+ uri = URI.parse('http://localhost:3000/posts')
52
+ resp = JSON.parse(uri.open.read)
81
53
 
82
- # 143 = 128 + 15
83
- [0, 15, 143].should include(status)
54
+ resp.should == []
84
55
  end
85
56
  end
86
57
  end
87
58
  end
88
59
  end
89
60
 
61
+ def start_app(cmd, port, timeout)
62
+ process = ChildProcess.build(*cmd)
63
+ process.environment.update(clean_env)
64
+ process.io.inherit!
65
+ process.start
66
+
67
+ begin
68
+ wait_for_port(port, timeout, process)
69
+ sleep 1
70
+
71
+ rv = yield port
72
+ ensure
73
+ # The process may have already died (due to an error exit) -
74
+ # in this case killing it will raise an exception.
75
+ Process.kill('TERM', process.pid) rescue nil
76
+ status = process.wait
77
+ end
78
+
79
+ # Exit should be either success or SIGTERM
80
+ [0, 15, 128 + 15].should include(status)
81
+
82
+ rv
83
+ end
84
+
90
85
  context 'new application - rails' do
91
- ['~> 5.1.0', '~> 5.2.0', '~> 6.0.0'].each do |rails_version|
92
- context "with rails #{rails_version}" do
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])
96
-
97
- Dir.chdir(TMP_BASE) do
98
- FileUtils.rm_rf('mongoid-test')
99
- ChildProcessHelper.check_call(%w(rails new mongoid-test --skip-spring --skip-active-record), env: clean_env)
100
-
101
- Dir.chdir('mongoid-test') do
102
- adjust_app_gemfile
103
- ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
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)
107
-
108
- # https://jira.mongodb.org/browse/MONGOID-4885
109
- comment_text = File.read('app/models/comment.rb')
110
- comment_text.should =~ /belongs_to :post/
111
- comment_text.should_not =~ /embedded_in :post/
112
- end
113
- end
86
+ it 'creates' do
87
+ install_rails
88
+
89
+ Dir.chdir(TMP_BASE) do
90
+ FileUtils.rm_rf('mongoid-test')
91
+ Mrss::ChildProcessHelper.check_call(%w(rails new mongoid-test --skip-spring --skip-active-record), env: clean_env)
92
+
93
+ Dir.chdir('mongoid-test') do
94
+ adjust_app_gemfile
95
+ Mrss::ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
96
+
97
+ Mrss::ChildProcessHelper.check_call(%w(rails g model post), env: clean_env)
98
+ Mrss::ChildProcessHelper.check_call(%w(rails g model comment post:belongs_to), env: clean_env)
99
+
100
+ # https://jira.mongodb.org/browse/MONGOID-4885
101
+ comment_text = File.read('app/models/comment.rb')
102
+ comment_text.should =~ /belongs_to :post/
103
+ comment_text.should_not =~ /embedded_in :post/
104
+ end
105
+ end
106
+ end
107
+
108
+ it 'generates Mongoid config' do
109
+ install_rails
110
+
111
+ Dir.chdir(TMP_BASE) do
112
+ FileUtils.rm_rf('mongoid-test-config')
113
+ Mrss::ChildProcessHelper.check_call(%w(rails new mongoid-test-config --skip-spring --skip-active-record), env: clean_env)
114
+
115
+ Dir.chdir('mongoid-test-config') do
116
+ adjust_app_gemfile
117
+ Mrss::ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
118
+
119
+ mongoid_config_file = File.join(TMP_BASE,'mongoid-test-config/config/mongoid.yml')
120
+
121
+ File.exist?(mongoid_config_file).should be false
122
+ Mrss::ChildProcessHelper.check_call(%w(rails g mongoid:config), env: clean_env)
123
+ File.exist?(mongoid_config_file).should be true
124
+
125
+ config_text = File.read(mongoid_config_file)
126
+ config_text.should =~ /mongoid_test_config_development/
127
+ config_text.should =~ /mongoid_test_config_test/
114
128
  end
115
129
  end
116
130
  end
117
131
  end
118
132
 
133
+ def install_rails
134
+ Mrss::ChildProcessHelper.check_call(%w(gem uni rails -a))
135
+ if (rails_version = SpecConfig.instance.rails_version) == 'master'
136
+ else
137
+ Mrss::ChildProcessHelper.check_call(%w(gem install rails --no-document -v) + [rails_version])
138
+ end
139
+ end
140
+
119
141
  context 'local test applications' do
120
142
  let(:client) { Mongoid.default_client }
121
143
 
@@ -136,7 +158,7 @@ describe 'Mongoid application tests' do
136
158
  before do
137
159
  Dir.chdir(APP_PATH) do
138
160
  remove_bundler_req
139
- ChildProcessHelper.check_call(%w(bundle install), env: env)
161
+ Mrss::ChildProcessHelper.check_call(%w(bundle install), env: env)
140
162
  write_mongoid_yml
141
163
  end
142
164
 
@@ -150,7 +172,7 @@ describe 'Mongoid application tests' do
150
172
  end
151
173
  index.should be nil
152
174
 
153
- ChildProcessHelper.check_call(%w(bundle exec rake db:mongoid:create_indexes),
175
+ Mrss::ChildProcessHelper.check_call(%w(bundle exec rake db:mongoid:create_indexes),
154
176
  cwd: APP_PATH, env: env)
155
177
 
156
178
  index = client['posts'].indexes.detect do |index|
@@ -165,13 +187,14 @@ describe 'Mongoid application tests' do
165
187
  end
166
188
  end
167
189
 
168
- def clone_application(repo_url, subdir: nil, rails_version: nil)
190
+ def clone_application(repo_url, subdir: nil)
169
191
  Dir.chdir(TMP_BASE) do
170
192
  FileUtils.rm_rf(File.basename(repo_url))
171
- ChildProcessHelper.check_call(%w(git clone) + [repo_url])
193
+ Mrss::ChildProcessHelper.check_call(%w(git clone) + [repo_url])
172
194
  Dir.chdir(File.join(*[File.basename(repo_url), subdir].compact)) do
173
- adjust_app_gemfile(rails_version: rails_version)
174
- ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
195
+ adjust_app_gemfile
196
+ adjust_rails_defaults
197
+ Mrss::ChildProcessHelper.check_call(%w(bundle install), env: clean_env)
175
198
  puts `git diff`
176
199
 
177
200
  write_mongoid_yml
@@ -226,7 +249,7 @@ describe 'Mongoid application tests' do
226
249
  end
227
250
  end
228
251
 
229
- def adjust_app_gemfile(rails_version: nil)
252
+ def adjust_app_gemfile(rails_version: SpecConfig.instance.rails_version)
230
253
  remove_bundler_req
231
254
 
232
255
  gemfile_lines = IO.readlines('Gemfile')
@@ -238,14 +261,45 @@ describe 'Mongoid application tests' do
238
261
  gemfile_lines.delete_if do |line|
239
262
  line =~ /rails/
240
263
  end
241
- gemfile_lines << "gem 'rails', '#{rails_version}'\n"
264
+ if rails_version == 'master'
265
+ gemfile_lines << "gem 'rails', git: 'https://github.com/rails/rails'\n"
266
+ else
267
+ gemfile_lines << "gem 'rails', '~> #{rails_version}.0'\n"
268
+ end
242
269
  end
243
270
  File.open('Gemfile', 'w') do |f|
244
271
  f << gemfile_lines.join
245
272
  end
246
273
  end
247
274
 
275
+ def adjust_rails_defaults(rails_version: SpecConfig.instance.rails_version)
276
+ if File.exist?('config/application.rb')
277
+ lines = IO.readlines('config/application.rb')
278
+ lines.each do |line|
279
+ line.gsub!(/config.load_defaults \d\.\d/, "config.load_defaults #{rails_version}")
280
+ end
281
+ File.open('config/application.rb', 'w') do |f|
282
+ f << lines.join
283
+ end
284
+ end
285
+
286
+ if rails_version == '5.1'
287
+ secrets = {
288
+ 'development' => {
289
+ 'secret_key_base' => 'abracadabra',
290
+ 'my_secret_token' => 'very_secret',
291
+ },
292
+ }
293
+ File.open('config/secrets.yml', 'w') do |f|
294
+ f << YAML.dump(secrets)
295
+ end
296
+ end
297
+ end
298
+
248
299
  def remove_bundler_req
300
+ return unless File.file?('Gemfile.lock')
301
+ # TODO: Remove this method completely when we get rid of .lock files in
302
+ # mongoid-demo apps.
249
303
  lock_lines = IO.readlines('Gemfile.lock')
250
304
  # Get rid of the bundled with line so that whatever bundler is installed
251
305
  # on the system is usable with the application.
@@ -263,14 +317,14 @@ describe 'Mongoid application tests' do
263
317
  # in `initialize': too long unix socket path (126bytes given but 108bytes max) (ArgumentError)
264
318
  # Is it trying to create unix sockets in current directory?
265
319
  # https://stackoverflow.com/questions/30302021/rails-runner-without-spring
266
- ChildProcessHelper.check_call(%w(bin/spring binstub --remove --all), env: clean_env)
320
+ Mrss::ChildProcessHelper.check_call(%w(bin/spring binstub --remove --all), env: clean_env)
267
321
  end
268
322
 
269
323
  def clean_env
270
324
  @clean_env ||= Hash[ENV.keys.grep(/BUNDLE|RUBYOPT/).map { |k| [k, nil ] }]
271
325
  end
272
326
 
273
- def wait_for_port(port, timeout)
327
+ def wait_for_port(port, timeout, process)
274
328
  deadline = Time.now + timeout
275
329
  loop do
276
330
  begin
@@ -278,6 +332,9 @@ describe 'Mongoid application tests' do
278
332
  return
279
333
  end
280
334
  rescue IOError, SystemCallError
335
+ unless process.alive?
336
+ raise "Process #{process} died while waiting for port #{port}"
337
+ end
281
338
  if Time.now > deadline
282
339
  raise
283
340
  end
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require 'spec_helper'
5
+
6
+ describe 'Contextual classes when dealing with empty result set' do
7
+ shared_examples 'behave as expected' do
8
+ context '#exists?' do
9
+ it 'is false' do
10
+ context.exists?.should be false
11
+ end
12
+ end
13
+
14
+ context '#count' do
15
+ it 'is 0' do
16
+ context.count.should == 0
17
+ end
18
+ end
19
+
20
+ context '#length' do
21
+ it 'is 0' do
22
+ context.length.should == 0
23
+ end
24
+ end
25
+
26
+ # #estimated_count only exists for Mongo
27
+
28
+ context '#distinct' do
29
+ it 'is empty array' do
30
+ context.distinct(:foo).should == []
31
+ end
32
+ end
33
+
34
+ context '#each' do
35
+ context 'with block' do
36
+ it 'does not invoke the block' do
37
+ called = false
38
+ context.each do
39
+ called = true
40
+ end
41
+ called.should be false
42
+ end
43
+ end
44
+
45
+ context 'without block' do
46
+ it 'returns Enumerable' do
47
+ context.each.should be_a(Enumerable)
48
+ end
49
+
50
+ it 'returns empty Enumerable' do
51
+ context.each.to_a.should == []
52
+ end
53
+ end
54
+ end
55
+
56
+ context '#map' do
57
+ context 'with block' do
58
+ it 'does not invoke the block' do
59
+ called = false
60
+ context.map do
61
+ called = true
62
+ end
63
+ called.should be false
64
+ end
65
+ end
66
+
67
+ context 'without block' do
68
+ it 'returns empty array' do
69
+ skip 'MONGOID-5148'
70
+
71
+ context.map(:field).should == []
72
+ end
73
+ end
74
+ end
75
+
76
+ context '#first' do
77
+ it 'is nil' do
78
+ context.first.should be nil
79
+ end
80
+ end
81
+
82
+ context '#find_first' do
83
+ it 'is nil' do
84
+ context.find_first.should be nil
85
+ end
86
+ end
87
+
88
+ context '#one' do
89
+ it 'is nil' do
90
+ context.one.should be nil
91
+ end
92
+ end
93
+
94
+ context '#last' do
95
+ it 'is nil' do
96
+ context.last.should be nil
97
+ end
98
+ end
99
+ end
100
+
101
+ let(:context) do
102
+ context_cls.new(criteria)
103
+ end
104
+
105
+ before do
106
+ # Create an object of the same class used in the Criteria instance
107
+ # to verify we are using the Contextual classes.
108
+ Mop.create!
109
+ end
110
+
111
+ context 'Mongo' do
112
+ let(:context_cls) { Mongoid::Contextual::Mongo }
113
+
114
+ let(:criteria) do
115
+ Mop.and(Mop.where(a: 1), Mop.where(a: 2))
116
+ end
117
+
118
+ include_examples 'behave as expected'
119
+ end
120
+
121
+ context 'Memory' do
122
+ let(:context_cls) { Mongoid::Contextual::Memory }
123
+
124
+ let(:criteria) do
125
+ Mop.all.tap do |criteria|
126
+ criteria.documents = []
127
+ end
128
+ end
129
+
130
+ include_examples 'behave as expected'
131
+ end
132
+
133
+ context 'None' do
134
+ let(:context_cls) { Mongoid::Contextual::None }
135
+
136
+ let(:criteria) do
137
+ Mop.none
138
+ end
139
+
140
+ include_examples 'behave as expected'
141
+ end
142
+ end