mongoid-rspec 4.1.0 → 4.3.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.
- checksums.yaml +4 -4
- data/README.md +54 -7
- data/Rakefile +3 -4
- data/lib/matchers/accept_nested_attributes.rb +2 -0
- data/lib/matchers/allow_mass_assignment.rb +2 -0
- data/lib/matchers/associations.rb +25 -8
- data/lib/matchers/be_dynamic_document.rb +2 -0
- data/lib/matchers/be_mongoid_document.rb +2 -0
- data/lib/matchers/be_stored_in.rb +2 -0
- data/lib/matchers/have_field.rb +5 -3
- data/lib/matchers/have_timestamps.rb +5 -3
- data/lib/matchers/indexes/have_index_for.rb +2 -0
- data/lib/matchers/indexes/v3/have_index_for.rb +4 -2
- data/lib/matchers/indexes/v4/have_index_for.rb +3 -1
- data/lib/matchers/validations/absence_of.rb +2 -0
- data/lib/matchers/validations/acceptance_of.rb +2 -0
- data/lib/matchers/validations/associated.rb +2 -0
- data/lib/matchers/validations/confirmation_of.rb +2 -0
- data/lib/matchers/validations/custom_validation_of.rb +4 -2
- data/lib/matchers/validations/exclusion_of.rb +5 -3
- data/lib/matchers/validations/format_of.rb +2 -0
- data/lib/matchers/validations/inclusion_of.rb +2 -0
- data/lib/matchers/validations/length_of.rb +2 -0
- data/lib/matchers/validations/numericality_of.rb +2 -0
- data/lib/matchers/validations/presence_of.rb +2 -0
- data/lib/matchers/validations/uniqueness_of.rb +2 -0
- data/lib/matchers/validations.rb +43 -7
- data/lib/mongoid/rspec/version.rb +3 -1
- data/lib/mongoid/rspec.rb +2 -0
- data/lib/mongoid-rspec.rb +2 -0
- metadata +58 -95
- data/spec/models/article.rb +0 -32
- data/spec/models/comment.rb +0 -6
- data/spec/models/log.rb +0 -9
- data/spec/models/message.rb +0 -17
- data/spec/models/movie_article.rb +0 -7
- data/spec/models/permalink.rb +0 -5
- data/spec/models/person.rb +0 -10
- data/spec/models/profile.rb +0 -16
- data/spec/models/record.rb +0 -5
- data/spec/models/site.rb +0 -13
- data/spec/models/user.rb +0 -38
- data/spec/spec_helper.rb +0 -35
- data/spec/unit/accept_nested_attributes_spec.rb +0 -12
- data/spec/unit/associations_spec.rb +0 -54
- data/spec/unit/be_dynamic_document_spec.rb +0 -21
- data/spec/unit/be_mongoid_document_spec.rb +0 -25
- data/spec/unit/be_stored_in.rb +0 -54
- data/spec/unit/document_spec.rb +0 -17
- data/spec/unit/have_index_for_spec.rb +0 -46
- data/spec/unit/have_timestamps_spec.rb +0 -71
- data/spec/unit/validations_spec.rb +0 -61
- data/spec/validators/ssn_validator.rb +0 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0ff9e91940ac839c482f01b93f825a4f30ed64dcf3f4210053a5cac6a490cbbc
|
|
4
|
+
data.tar.gz: 73b94988e7950e2097427412e1c4af87a1413cf891085a53a71924bbae9466ca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 14504bfe14678c3c4df1eb85438438ab5b705f22ad36bc209bfd15d1bbeb4cc59ab09c0e8227682f8960f8db6cadc7c8731e8ab617d7f1d075e98f06a1085bdc
|
|
7
|
+
data.tar.gz: 4ae265834c188a9236e6c697345f70c5e16fc27c250076c72486030ae3ebc3cb62f1da00df5fefbf5bfd8dabb4e8dd29c26d80d26a1638e9a7e58d8824c2aa03
|
data/README.md
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
# [mongoid-rspec](https://github.com/mongoid/mongoid-rspec "A collection of RSpec-compatible matchers that help to test Mongoid documents.")
|
|
2
2
|
|
|
3
|
-
[](https://travis-ci.org/mongoid/mongoid-rspec)
|
|
4
3
|
[](https://badge.fury.io/rb/mongoid-rspec)
|
|
4
|
+
[](https://github.com/mongoid/mongoid-rspec/actions/workflows/rspec.yml?query=branch%3Amaster)
|
|
5
|
+
[](https://github.com/mongoid/mongoid-rspec/actions/workflows/rubocop.yml?query=branch%3Amaster)
|
|
6
|
+
[](https://coveralls.io/github/mongoid/mongoid-rspec?branch=master)
|
|
7
|
+
|
|
8
|
+
CI collects SimpleCov coverage on Ruby 3.4 with Mongoid 9 and MongoDB 8.0 and submits one report to Coveralls using GitHub's workflow token. To generate a local report, run `COVERAGE=true BUNDLE_GEMFILE=gemfiles/mongoid_9.gemfile bundle install` followed by `COVERAGE=true BUNDLE_GEMFILE=gemfiles/mongoid_9.gemfile bundle exec rake spec`. Reports are written to `coverage/`.
|
|
5
9
|
|
|
6
10
|
The mongoid-rspec library provides a collection of RSpec-compatible matchers that help to test Mongoid documents.
|
|
7
11
|
|
|
12
|
+
[Tested](https://github.com/mongoid/mongoid-rspec/actions/workflows/rspec.yml) against:
|
|
13
|
+
- MRI: `2.6.x`, `2.7.x`, `3.0.x`, `3.1.x`, `3.2.x`
|
|
14
|
+
- Mongoid: `4`, `5`, `6`, `7`, `8`, `9`
|
|
15
|
+
|
|
16
|
+
See [.github/workflows/rspec.yml](.github/workflows/rspec.yml) for the latest test matrix.
|
|
17
|
+
|
|
8
18
|
## Installation
|
|
9
19
|
|
|
10
20
|
Drop this line into your Gemfile:
|
|
@@ -18,7 +28,7 @@ end
|
|
|
18
28
|
|
|
19
29
|
## Compatibility
|
|
20
30
|
|
|
21
|
-
This gem is compatible with Mongoid 3, 4, 5, 6
|
|
31
|
+
This gem is compatible with Mongoid 3, 4, 5, 6, 7, 8, 9.
|
|
22
32
|
|
|
23
33
|
## Configuration
|
|
24
34
|
|
|
@@ -181,7 +191,7 @@ end
|
|
|
181
191
|
|
|
182
192
|
```ruby
|
|
183
193
|
class Article
|
|
184
|
-
index({ title: 1 }, { unique: true, background: true
|
|
194
|
+
index({ title: 1 }, { unique: true, background: true })
|
|
185
195
|
index({ title: 1, created_at: -1 })
|
|
186
196
|
index({ category: 1 })
|
|
187
197
|
end
|
|
@@ -190,7 +200,7 @@ RSpec.describe Article, type: :model do
|
|
|
190
200
|
it do
|
|
191
201
|
is_expected
|
|
192
202
|
.to have_index_for(title: 1)
|
|
193
|
-
.with_options(unique: true, background: true
|
|
203
|
+
.with_options(unique: true, background: true)
|
|
194
204
|
end
|
|
195
205
|
it { is_expected.to have_index_for(title: 1, created_at: -1) }
|
|
196
206
|
it { is_expected.to have_index_for(category: 1) }
|
|
@@ -201,9 +211,9 @@ end
|
|
|
201
211
|
|
|
202
212
|
```ruby
|
|
203
213
|
RSpec.describe Article do
|
|
204
|
-
it { is_expected.to have_field(:published).of_type(Boolean).with_default_value_of(false) }
|
|
205
|
-
it { is_expected.to have_field(:allow_comments).of_type(Boolean).with_default_value_of(true) }
|
|
206
|
-
it { is_expected.not_to have_field(:allow_comments).of_type(Boolean).with_default_value_of(false) }
|
|
214
|
+
it { is_expected.to have_field(:published).of_type(Mongoid::Boolean).with_default_value_of(false) }
|
|
215
|
+
it { is_expected.to have_field(:allow_comments).of_type(Mongoid::Boolean).with_default_value_of(true) }
|
|
216
|
+
it { is_expected.not_to have_field(:allow_comments).of_type(Mongoid::Boolean).with_default_value_of(false) }
|
|
207
217
|
it { is_expected.not_to have_field(:number_of_comments).of_type(Integer).with_default_value_of(1) }
|
|
208
218
|
end
|
|
209
219
|
|
|
@@ -249,6 +259,27 @@ RSpec.describe Article do
|
|
|
249
259
|
it { is_expected.to embed_many(:comments) }
|
|
250
260
|
end
|
|
251
261
|
|
|
262
|
+
# when the touch option is provided, then we can also verify that it is set
|
|
263
|
+
|
|
264
|
+
# by default, with_touch matches true when no parameters are provided
|
|
265
|
+
describe Article do
|
|
266
|
+
it { is_expected.to belong_to(:author).of_type(User).as_inverse_of(:articles).with_index.with_touch }
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# parameters are supported for explicit matching
|
|
270
|
+
describe Comment do
|
|
271
|
+
it { is_expected.to be_embedded_in(:article).as_inverse_of(:comments).with_polymorphism.with_touch(true) }
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
describe Permalink do
|
|
275
|
+
it { is_expected.to be_embedded_in(:linkable).as_inverse_of(:link).with_touch(false) }
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
# touch can also take a symbol representing a field on the parent to touch
|
|
279
|
+
describe Record do
|
|
280
|
+
it { is_expected.to belong_to(:user).as_inverse_of(:record).with_touch(:record_updated_at) }
|
|
281
|
+
end
|
|
282
|
+
|
|
252
283
|
RSpec.describe Comment do
|
|
253
284
|
it { is_expected.to be_embedded_in(:article).as_inverse_of(:comments) }
|
|
254
285
|
it { is_expected.to belong_to(:user).as_inverse_of(:comments) }
|
|
@@ -315,6 +346,22 @@ RSpec.describe Person do
|
|
|
315
346
|
# should redefine the kind method to return :custom, i.e. "def self.kind() :custom end"
|
|
316
347
|
it { is_expected.to custom_validate(:ssn).with_validator(SsnValidator) }
|
|
317
348
|
end
|
|
349
|
+
|
|
350
|
+
# If you're using validators with if/unless conditionals, spec subject must be object instance
|
|
351
|
+
# This is supported on Mongoid 4 and newer
|
|
352
|
+
Rspec.describe User do
|
|
353
|
+
context 'when user has `admin` role' do
|
|
354
|
+
subject { User.new(role: 'admin') }
|
|
355
|
+
|
|
356
|
+
it { is_expected.to validate_length_of(:password).greater_than(20) }
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
context 'when user does not have `admin` role' do
|
|
360
|
+
subject { User.new(role: 'member') }
|
|
361
|
+
|
|
362
|
+
it { is_expected.not_to validate_length_of(:password) }
|
|
363
|
+
end
|
|
364
|
+
end
|
|
318
365
|
```
|
|
319
366
|
|
|
320
367
|
### Mass Assignment Matcher
|
data/Rakefile
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
|
2
4
|
|
|
3
5
|
require 'bundler'
|
|
@@ -14,7 +16,4 @@ RSpec::Core::RakeTask.new(:rcov) do |spec|
|
|
|
14
16
|
spec.rcov = true
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
RuboCop::RakeTask.new(:rubocop)
|
|
19
|
-
|
|
20
|
-
task default: %i[rubocop spec]
|
|
19
|
+
task default: %i[spec]
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
|
2
4
|
require 'mongoid/association'
|
|
3
5
|
else
|
|
@@ -30,7 +32,7 @@ module Mongoid
|
|
|
30
32
|
@association = {}
|
|
31
33
|
@association[:name] = name.to_s
|
|
32
34
|
@association[:type] = association_type
|
|
33
|
-
@expectation_message = "#{type_description} #{@association[:name].inspect}"
|
|
35
|
+
@expectation_message = +"#{type_description} #{@association[:name].inspect}"
|
|
34
36
|
@expectation_message << " of type #{@association[:class].inspect}" unless @association[:class].nil?
|
|
35
37
|
end
|
|
36
38
|
|
|
@@ -119,6 +121,12 @@ module Mongoid
|
|
|
119
121
|
self
|
|
120
122
|
end
|
|
121
123
|
|
|
124
|
+
def with_touch(touch = true)
|
|
125
|
+
@association[:touch] = touch
|
|
126
|
+
@expectation_message << " which specifies touch as #{@association[:touch]}"
|
|
127
|
+
self
|
|
128
|
+
end
|
|
129
|
+
|
|
122
130
|
def with_optional
|
|
123
131
|
@association[:optional] = true
|
|
124
132
|
@expectation_message << " which specifies optional as #{@association[:optional]}"
|
|
@@ -272,6 +280,15 @@ module Mongoid
|
|
|
272
280
|
end
|
|
273
281
|
end
|
|
274
282
|
|
|
283
|
+
unless @association[:touch].nil?
|
|
284
|
+
if metadata.options[:touch] != @association[:touch]
|
|
285
|
+
@negative_result_message = "#{@positive_result_message} which sets touch as #{metadata.options[:touch].inspect}"
|
|
286
|
+
return false
|
|
287
|
+
else
|
|
288
|
+
@positive_result_message = "#{@positive_result_message} which sets touch as #{metadata.options[:touch].inspect}"
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
275
292
|
if @association[:optional]
|
|
276
293
|
if metadata.options[:optional] != true
|
|
277
294
|
@negative_result_message = "#{@positive_result_message} which did not set optional"
|
|
@@ -303,19 +320,19 @@ module Mongoid
|
|
|
303
320
|
type ||= @association[:type]
|
|
304
321
|
case type.name
|
|
305
322
|
when EMBEDS_ONE.name
|
|
306
|
-
(passive ? 'embed' : 'embeds') << ' one'
|
|
323
|
+
+(passive ? 'embed' : 'embeds') << ' one'
|
|
307
324
|
when EMBEDS_MANY.name
|
|
308
|
-
(passive ? 'embed' : 'embeds') << ' many'
|
|
325
|
+
+(passive ? 'embed' : 'embeds') << ' many'
|
|
309
326
|
when EMBEDDED_IN.name
|
|
310
|
-
(passive ? 'be' : 'is') << ' embedded in'
|
|
327
|
+
+(passive ? 'be' : 'is') << ' embedded in'
|
|
311
328
|
when HAS_ONE.name
|
|
312
|
-
(passive ? 'reference' : 'references') << ' one'
|
|
329
|
+
+(passive ? 'reference' : 'references') << ' one'
|
|
313
330
|
when HAS_MANY.name
|
|
314
|
-
(passive ? 'reference' : 'references') << ' many'
|
|
331
|
+
+(passive ? 'reference' : 'references') << ' many'
|
|
315
332
|
when HAS_AND_BELONGS_TO_MANY.name
|
|
316
|
-
(passive ? 'reference' : 'references') << ' and referenced in many'
|
|
333
|
+
+(passive ? 'reference' : 'references') << ' and referenced in many'
|
|
317
334
|
when BELONGS_TO.name
|
|
318
|
-
(passive ? 'be referenced in' : 'referenced in')
|
|
335
|
+
+(passive ? 'be referenced in' : 'referenced in')
|
|
319
336
|
else
|
|
320
337
|
raise format("Unknown association type '%s'", type)
|
|
321
338
|
end
|
data/lib/matchers/have_field.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Mongoid
|
|
2
4
|
module Matchers
|
|
3
5
|
class HaveField # :nodoc:
|
|
@@ -30,7 +32,7 @@ module Mongoid
|
|
|
30
32
|
@errors = []
|
|
31
33
|
@attributes.each do |attr|
|
|
32
34
|
if @klass.fields.include?(attr)
|
|
33
|
-
error = ''
|
|
35
|
+
error = +''
|
|
34
36
|
if @type && (@klass.fields[attr].type != @type)
|
|
35
37
|
error << " of type #{@klass.fields[attr].type}"
|
|
36
38
|
end
|
|
@@ -47,7 +49,7 @@ module Mongoid
|
|
|
47
49
|
error << " with alias #{@klass.fields[attr].options[:as]}"
|
|
48
50
|
end
|
|
49
51
|
|
|
50
|
-
@errors.push("field #{attr.inspect}"
|
|
52
|
+
@errors.push("field #{attr.inspect}#{error}") unless error.blank?
|
|
51
53
|
|
|
52
54
|
if @localized
|
|
53
55
|
unless @klass.fields[attr].localized?
|
|
@@ -74,7 +76,7 @@ module Mongoid
|
|
|
74
76
|
alias failure_message_when_negated failure_message_for_should_not
|
|
75
77
|
|
|
76
78
|
def description
|
|
77
|
-
desc = "have #{@attributes.size > 1 ? 'fields' : 'field'} named #{@attributes.collect(&:inspect).to_sentence}"
|
|
79
|
+
desc = +"have #{@attributes.size > 1 ? 'fields' : 'field'} named #{@attributes.collect(&:inspect).to_sentence}"
|
|
78
80
|
desc << " of type #{@type.inspect}" if @type
|
|
79
81
|
desc << " with alias #{@field_alias}" if @field_alias
|
|
80
82
|
desc << " with default value of #{@default.inspect}" unless @default.nil?
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Mongoid
|
|
2
4
|
module Matchers
|
|
3
5
|
def have_timestamps
|
|
@@ -6,7 +8,7 @@ module Mongoid
|
|
|
6
8
|
|
|
7
9
|
class HaveTimestamps
|
|
8
10
|
def initialize
|
|
9
|
-
@root_module = 'Mongoid::Timestamps'
|
|
11
|
+
@root_module = +'Mongoid::Timestamps'
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def matches?(actual)
|
|
@@ -15,7 +17,7 @@ module Mongoid
|
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def for(phase)
|
|
18
|
-
raise('You\'ve already declared
|
|
20
|
+
raise('You\'ve already declared timestamp\'s sub-module via "for" clause') if @submodule
|
|
19
21
|
|
|
20
22
|
case @phase = phase.to_sym
|
|
21
23
|
when :creating then @submodule = 'Created'
|
|
@@ -33,7 +35,7 @@ module Mongoid
|
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def description
|
|
36
|
-
desc = 'be a Mongoid document with'
|
|
38
|
+
desc = +'be a Mongoid document with'
|
|
37
39
|
desc << ' shorted' if @shortened
|
|
38
40
|
desc << " #{@phase}" if @phase
|
|
39
41
|
desc << ' timestamps'
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Mongoid
|
|
2
4
|
module Matchers
|
|
3
5
|
def have_index_for(index_key)
|
|
@@ -36,7 +38,7 @@ module Mongoid
|
|
|
36
38
|
alias failure_message_when_negated failure_message_for_should_not
|
|
37
39
|
|
|
38
40
|
def description
|
|
39
|
-
desc = "have an index for #{index_key.inspect}"
|
|
41
|
+
desc = +"have an index for #{index_key.inspect}"
|
|
40
42
|
desc << " with options of #{index_options.inspect}" if index_options
|
|
41
43
|
desc
|
|
42
44
|
end
|
|
@@ -44,7 +46,7 @@ module Mongoid
|
|
|
44
46
|
private
|
|
45
47
|
|
|
46
48
|
MAPPINGS = {
|
|
47
|
-
dropDups: :drop_dups
|
|
49
|
+
dropDups: :drop_dups # Deprecated from MongoDB 3.0
|
|
48
50
|
}.freeze
|
|
49
51
|
|
|
50
52
|
def denormalising_options(opts)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Mongoid
|
|
2
4
|
module Matchers
|
|
3
5
|
def have_index_for(index_key)
|
|
@@ -15,7 +17,7 @@ module Mongoid
|
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def failure_message
|
|
18
|
-
message = "Expected #{model.inspect} to #{description},"
|
|
20
|
+
message = +"Expected #{model.inspect} to #{description},"
|
|
19
21
|
message << if actual_index.nil?
|
|
20
22
|
' found no index'
|
|
21
23
|
else
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Mongoid
|
|
2
4
|
module Matchers
|
|
3
5
|
module Validations
|
|
@@ -19,9 +21,9 @@ module Mongoid
|
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
def description
|
|
22
|
-
options_desc =
|
|
24
|
+
options_desc = +"validate field #{@field.inspect}"
|
|
23
25
|
options_desc << " with custom validator #{@custom_validator.name}" if @validator
|
|
24
|
-
|
|
26
|
+
options_desc
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
private
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Mongoid
|
|
2
4
|
module Matchers
|
|
3
5
|
module Validations
|
|
@@ -12,7 +14,7 @@ module Mongoid
|
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
def matches?(actual)
|
|
15
|
-
return false unless result = super(actual)
|
|
17
|
+
return false unless (result = super(actual))
|
|
16
18
|
|
|
17
19
|
if @not_allowed_values
|
|
18
20
|
raw_validator_not_allowed_values = @validator.options[:in]
|
|
@@ -24,9 +26,9 @@ module Mongoid
|
|
|
24
26
|
|
|
25
27
|
allowed_values = @not_allowed_values - validator_not_allowed_values
|
|
26
28
|
if allowed_values.empty?
|
|
27
|
-
@positive_result_message
|
|
29
|
+
@positive_result_message << ' not allowing all values mentioned'
|
|
28
30
|
else
|
|
29
|
-
@negative_result_message
|
|
31
|
+
@negative_result_message << " allowing the following the ff. values: #{allowed_values.inspect}"
|
|
30
32
|
result = false
|
|
31
33
|
end
|
|
32
34
|
end
|
data/lib/matchers/validations.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Mongoid
|
|
2
4
|
module Matchers
|
|
3
5
|
module Validations
|
|
@@ -12,14 +14,15 @@ module Mongoid
|
|
|
12
14
|
@klass = actual.is_a?(Class) ? actual : actual.class
|
|
13
15
|
|
|
14
16
|
@validator = @klass.validators_on(@field).detect do |v|
|
|
15
|
-
(v.kind.to_s == @type) && (!v.options[:on] || on_options_matches?(v))
|
|
17
|
+
(v.kind.to_s == @type) && (!v.options[:on] || on_options_matches?(v)) &&
|
|
18
|
+
if_condition_matches?(actual, v) && unless_condition_matches?(actual, v)
|
|
16
19
|
end
|
|
17
20
|
|
|
18
21
|
if @validator
|
|
19
|
-
@negative_result_message = "#{@type.inspect} validator on #{@field.inspect}"
|
|
20
|
-
@positive_result_message = "#{@type.inspect} validator on #{@field.inspect}"
|
|
22
|
+
@negative_result_message = +"#{@type.inspect} validator on #{@field.inspect}"
|
|
23
|
+
@positive_result_message = +"#{@type.inspect} validator on #{@field.inspect}"
|
|
21
24
|
else
|
|
22
|
-
@negative_result_message = "no #{@type.inspect} validator on #{@field.inspect}"
|
|
25
|
+
@negative_result_message = +"no #{@type.inspect} validator on #{@field.inspect}"
|
|
23
26
|
return false
|
|
24
27
|
end
|
|
25
28
|
@result = true
|
|
@@ -40,10 +43,9 @@ module Mongoid
|
|
|
40
43
|
alias failure_message_when_negated failure_message_for_should_not
|
|
41
44
|
|
|
42
45
|
def description
|
|
43
|
-
desc = "have #{@type.inspect} validator on #{@field.inspect}"
|
|
46
|
+
desc = +"have #{@type.inspect} validator on #{@field.inspect}"
|
|
44
47
|
desc << " on #{@options[:on]}" if @options[:on]
|
|
45
48
|
desc << " with message #{@expected_message.inspect}" if @expected_message
|
|
46
|
-
|
|
47
49
|
desc
|
|
48
50
|
end
|
|
49
51
|
|
|
@@ -57,13 +59,47 @@ module Mongoid
|
|
|
57
59
|
self
|
|
58
60
|
end
|
|
59
61
|
|
|
62
|
+
def check_conditions
|
|
63
|
+
@check_conditions = true
|
|
64
|
+
self
|
|
65
|
+
end
|
|
66
|
+
|
|
60
67
|
private
|
|
61
68
|
|
|
69
|
+
def if_condition_matches?(actual, validator)
|
|
70
|
+
return true unless @check_conditions
|
|
71
|
+
return true unless validator.options[:if]
|
|
72
|
+
|
|
73
|
+
check_condition(actual, validator.options[:if])
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def unless_condition_matches?(actual, validator)
|
|
77
|
+
return true unless @check_conditions
|
|
78
|
+
return true unless validator.options[:unless]
|
|
79
|
+
|
|
80
|
+
!check_condition(actual, validator.options[:unless])
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def check_condition(actual, filter)
|
|
84
|
+
raise ArgumentError, 'Spec subject must be an instance when using .check_conditions' if actual.is_a?(Class)
|
|
85
|
+
|
|
86
|
+
case filter
|
|
87
|
+
when Symbol
|
|
88
|
+
actual.send(filter)
|
|
89
|
+
when ::Proc
|
|
90
|
+
filter.arity.zero? ? actual.instance_exec(&filter) : filter.call(actual)
|
|
91
|
+
when Array
|
|
92
|
+
filter.all? { |f| check_condition(actual, f) }
|
|
93
|
+
else
|
|
94
|
+
raise ArgumentError, "Unexpected filter: #{filter.inspect}"
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
62
98
|
def check_on
|
|
63
99
|
validator_on_methods = [@validator.options[:on]].flatten
|
|
64
100
|
|
|
65
101
|
if validator_on_methods.any?
|
|
66
|
-
message = " on methods: #{validator_on_methods}"
|
|
102
|
+
message = +" on methods: #{validator_on_methods}"
|
|
67
103
|
|
|
68
104
|
if on_options_covered_by?(@validator)
|
|
69
105
|
@positive_result_message << message
|
data/lib/mongoid/rspec.rb
CHANGED
data/lib/mongoid-rspec.rb
CHANGED