mongoid-rspec 2.1.0 → 4.1.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 +5 -5
- data/LICENSE +1 -1
- data/README.md +222 -102
- data/Rakefile +8 -5
- data/lib/matchers/accept_nested_attributes.rb +22 -23
- data/lib/matchers/allow_mass_assignment.rb +12 -12
- data/lib/matchers/associations.rb +85 -49
- data/lib/matchers/be_dynamic_document.rb +26 -0
- data/lib/matchers/be_mongoid_document.rb +26 -0
- data/lib/matchers/be_stored_in.rb +55 -0
- data/lib/matchers/have_field.rb +90 -0
- data/lib/matchers/have_timestamps.rb +61 -0
- data/lib/matchers/indexes/have_index_for.rb +16 -0
- data/lib/matchers/indexes/v3/have_index_for.rb +59 -0
- data/lib/matchers/indexes/v4/have_index_for.rb +54 -0
- data/lib/matchers/validations.rb +30 -11
- data/lib/matchers/validations/absence_of.rb +11 -0
- data/lib/matchers/validations/associated.rb +1 -1
- data/lib/matchers/validations/confirmation_of.rb +7 -1
- data/lib/matchers/validations/custom_validation_of.rb +1 -4
- data/lib/matchers/validations/exclusion_of.rb +5 -5
- data/lib/matchers/validations/format_of.rb +2 -2
- data/lib/matchers/validations/inclusion_of.rb +5 -5
- data/lib/matchers/validations/length_of.rb +13 -35
- data/lib/matchers/validations/numericality_of.rb +32 -16
- data/lib/matchers/validations/presence_of.rb +1 -1
- data/lib/matchers/validations/uniqueness_of.rb +7 -10
- data/lib/mongoid-rspec.rb +1 -33
- data/lib/mongoid/rspec.rb +46 -0
- data/lib/mongoid/rspec/version.rb +5 -0
- data/spec/models/article.rb +9 -6
- data/spec/models/comment.rb +1 -1
- data/spec/models/log.rb +3 -3
- data/spec/models/message.rb +17 -0
- data/spec/models/movie_article.rb +1 -2
- data/spec/models/person.rb +1 -1
- data/spec/models/profile.rb +2 -2
- data/spec/models/record.rb +1 -1
- data/spec/models/site.rb +5 -1
- data/spec/models/user.rb +12 -10
- data/spec/spec_helper.rb +12 -10
- data/spec/unit/accept_nested_attributes_spec.rb +1 -1
- data/spec/unit/associations_spec.rb +19 -7
- data/spec/unit/be_dynamic_document_spec.rb +21 -0
- data/spec/unit/be_mongoid_document_spec.rb +25 -0
- data/spec/unit/be_stored_in.rb +54 -0
- data/spec/unit/document_spec.rb +5 -14
- data/spec/unit/have_index_for_spec.rb +46 -0
- data/spec/unit/have_timestamps_spec.rb +71 -0
- data/spec/unit/validations_spec.rb +23 -14
- data/spec/validators/ssn_validator.rb +6 -6
- metadata +119 -43
- data/.document +0 -5
- data/.gitignore +0 -6
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/.travis.yml +0 -10
- data/Gemfile +0 -4
- data/lib/matchers/collections.rb +0 -9
- data/lib/matchers/document.rb +0 -173
- data/lib/matchers/indexes.rb +0 -69
- data/lib/matchers/validations/with_message.rb +0 -27
- data/lib/mongoid-rspec/version.rb +0 -5
- data/mongoid-rspec.gemspec +0 -25
- data/spec/unit/collections_spec.rb +0 -7
- data/spec/unit/indexes_spec.rb +0 -17
@@ -2,8 +2,19 @@ module Mongoid
|
|
2
2
|
module Matchers
|
3
3
|
module Validations
|
4
4
|
class ValidateNumericalityOfMatcher < HaveValidationMatcher
|
5
|
-
|
6
|
-
|
5
|
+
ALLOWED_OPTIONS =
|
6
|
+
%i[
|
7
|
+
allow_nil
|
8
|
+
equal_to
|
9
|
+
even
|
10
|
+
greater_than
|
11
|
+
greater_than_or_equal_to
|
12
|
+
less_than
|
13
|
+
less_than_or_equal_to
|
14
|
+
nil
|
15
|
+
odd
|
16
|
+
only_integer
|
17
|
+
].freeze
|
7
18
|
|
8
19
|
def initialize(field)
|
9
20
|
super(field, :numericality)
|
@@ -12,9 +23,15 @@ module Mongoid
|
|
12
23
|
|
13
24
|
def to_allow(options)
|
14
25
|
options[:equal_to] = options if options.is_a?(Numeric)
|
15
|
-
options[:allow_nil] = options.delete(:nil) if options.
|
16
|
-
|
17
|
-
|
26
|
+
options[:allow_nil] = options.delete(:nil) if options.key?(:nil)
|
27
|
+
|
28
|
+
if !options.is_a?(Hash) || options.empty? || (options.keys - ALLOWED_OPTIONS).any?
|
29
|
+
message =
|
30
|
+
'validate_numericality_of#to_allow requires a Hash parameter containing' \
|
31
|
+
"any of the following keys: #{ALLOWED_OPTIONS.map(&:inspect).join(', ')}"
|
32
|
+
raise ArgumentError, message
|
33
|
+
end
|
34
|
+
|
18
35
|
@options.merge!(options)
|
19
36
|
self
|
20
37
|
end
|
@@ -22,11 +39,10 @@ module Mongoid
|
|
22
39
|
def matches?(actual)
|
23
40
|
return false unless result = super(actual)
|
24
41
|
|
25
|
-
|
26
|
-
|
27
|
-
result &= (@validator.options[comparator] == @options[comparator])
|
28
|
-
end
|
42
|
+
@options.each do |comparator, expected_value|
|
43
|
+
result &= (@validator.options[comparator] == expected_value)
|
29
44
|
end
|
45
|
+
|
30
46
|
@positive_result_message <<= options_message(@validator.options)
|
31
47
|
@negative_result_message <<= options_message(@validator.options)
|
32
48
|
result
|
@@ -45,19 +61,19 @@ module Mongoid
|
|
45
61
|
case key
|
46
62
|
when :allow_nil
|
47
63
|
when :only_integer
|
48
|
-
type_msg <<
|
64
|
+
type_msg << 'integer' if value
|
49
65
|
when :odd, :even
|
50
|
-
type_msg << "#{key
|
66
|
+
type_msg << "#{key}-numbered" if value
|
51
67
|
else
|
52
|
-
comp_msg << "#{key.to_s.
|
68
|
+
comp_msg << "#{key.to_s.tr('_', ' ')} #{value.inspect}"
|
53
69
|
end
|
54
70
|
end
|
55
|
-
allow_nil = (options[:allow_nil] ?
|
56
|
-
[
|
71
|
+
allow_nil = (options[:allow_nil] ? 'nil' : 'non-nil') if options.key?(:allow_nil)
|
72
|
+
['', 'allowing', allow_nil, type_msg.any? ? type_msg.to_sentence : nil, 'values', comp_msg.any? ? comp_msg.to_sentence : nil].compact.join(' ')
|
57
73
|
end
|
58
74
|
|
59
75
|
def method_missing(m, *args, &block)
|
60
|
-
if
|
76
|
+
if ALLOWED_OPTIONS.include?(m.to_sym)
|
61
77
|
raise ArgumentError, "wrong number of arguments (#{args.length} for 1)" if args.length > 1
|
62
78
|
send :to_allow, m.to_sym => args.first
|
63
79
|
else
|
@@ -71,4 +87,4 @@ module Mongoid
|
|
71
87
|
end
|
72
88
|
end
|
73
89
|
end
|
74
|
-
end
|
90
|
+
end
|
@@ -2,7 +2,6 @@ module Mongoid
|
|
2
2
|
module Matchers
|
3
3
|
module Validations
|
4
4
|
class ValidateUniquenessOfMatcher < HaveValidationMatcher
|
5
|
-
include WithMessage
|
6
5
|
def initialize(field)
|
7
6
|
super(field, :uniqueness)
|
8
7
|
end
|
@@ -11,7 +10,7 @@ module Mongoid
|
|
11
10
|
@scope = [scope].flatten.map(&:to_sym)
|
12
11
|
self
|
13
12
|
end
|
14
|
-
|
13
|
+
alias scoped_on scoped_to
|
15
14
|
|
16
15
|
def case_insensitive
|
17
16
|
@case_insensitive = true
|
@@ -29,7 +28,6 @@ module Mongoid
|
|
29
28
|
check_scope if @scope
|
30
29
|
check_allow_blank if @allow_blank
|
31
30
|
check_case_sensitivity if @case_insensitive
|
32
|
-
check_expected_message if @expected_message
|
33
31
|
|
34
32
|
@result
|
35
33
|
end
|
@@ -37,9 +35,8 @@ module Mongoid
|
|
37
35
|
def description
|
38
36
|
options_desc = []
|
39
37
|
options_desc << " scoped to #{@scope.inspect}" if @scope
|
40
|
-
options_desc <<
|
41
|
-
options_desc <<
|
42
|
-
options_desc << " with message '#{@expected_message}'" if @expected_message
|
38
|
+
options_desc << ' allowing blank values' if @allow_blank
|
39
|
+
options_desc << ' allowing case insensitive values' if @case_insensitive
|
43
40
|
super << options_desc.to_sentence
|
44
41
|
end
|
45
42
|
|
@@ -47,9 +44,9 @@ module Mongoid
|
|
47
44
|
|
48
45
|
def check_allow_blank
|
49
46
|
if @validator.options[:allow_blank] == @allow_blank
|
50
|
-
@positive_result_message <<
|
47
|
+
@positive_result_message << ' with blank values allowed'
|
51
48
|
else
|
52
|
-
@negative_result_message <<
|
49
|
+
@negative_result_message << ' with no blank values allowed'
|
53
50
|
@result = false
|
54
51
|
end
|
55
52
|
end
|
@@ -66,9 +63,9 @@ module Mongoid
|
|
66
63
|
|
67
64
|
def check_case_sensitivity
|
68
65
|
if @validator.options[:case_sensitive] == false
|
69
|
-
@positive_result_message <<
|
66
|
+
@positive_result_message << ' with case insensitive values'
|
70
67
|
else
|
71
|
-
@negative_result_message <<
|
68
|
+
@negative_result_message << ' without case insensitive values'
|
72
69
|
@result = false
|
73
70
|
end
|
74
71
|
end
|
data/lib/mongoid-rspec.rb
CHANGED
@@ -1,33 +1 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'mongoid'
|
4
|
-
require 'rspec/core'
|
5
|
-
require 'rspec/expectations'
|
6
|
-
require 'rspec/mocks'
|
7
|
-
require "active_model"
|
8
|
-
require 'matchers/document'
|
9
|
-
require 'matchers/associations'
|
10
|
-
require 'matchers/collections'
|
11
|
-
require 'matchers/indexes'
|
12
|
-
require 'matchers/allow_mass_assignment'
|
13
|
-
require 'matchers/accept_nested_attributes'
|
14
|
-
require 'matchers/validations'
|
15
|
-
require 'matchers/validations/with_message'
|
16
|
-
require 'matchers/validations/associated'
|
17
|
-
require 'matchers/validations/confirmation_of'
|
18
|
-
require 'matchers/validations/exclusion_of'
|
19
|
-
require 'matchers/validations/format_of'
|
20
|
-
require 'matchers/validations/inclusion_of'
|
21
|
-
require 'matchers/validations/length_of'
|
22
|
-
require 'matchers/validations/numericality_of'
|
23
|
-
require 'matchers/validations/presence_of'
|
24
|
-
require 'matchers/validations/uniqueness_of'
|
25
|
-
require 'matchers/validations/acceptance_of'
|
26
|
-
require 'matchers/validations/custom_validation_of'
|
27
|
-
|
28
|
-
module Mongoid
|
29
|
-
module Matchers
|
30
|
-
include Mongoid::Matchers::Associations
|
31
|
-
include Mongoid::Matchers::Validations
|
32
|
-
end
|
33
|
-
end
|
1
|
+
require 'mongoid/rspec'
|
@@ -0,0 +1,46 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'mongoid'
|
4
|
+
require 'mongoid-compatibility'
|
5
|
+
require 'rspec/core'
|
6
|
+
require 'rspec/expectations'
|
7
|
+
require 'rspec/mocks'
|
8
|
+
require 'active_support/core_ext/hash/keys'
|
9
|
+
require 'active_support/core_ext/hash/transform_values' if Mongoid::Compatibility::Version.mongoid4_or_newer? && ActiveSupport.version < Gem::Version.new('6')
|
10
|
+
require 'active_support/core_ext/object/blank'
|
11
|
+
require 'active_support/core_ext/string/inflections'
|
12
|
+
|
13
|
+
require 'matchers/associations'
|
14
|
+
require 'matchers/allow_mass_assignment'
|
15
|
+
require 'matchers/accept_nested_attributes'
|
16
|
+
require 'matchers/validations'
|
17
|
+
require 'matchers/validations/associated'
|
18
|
+
require 'matchers/validations/confirmation_of'
|
19
|
+
require 'matchers/validations/exclusion_of'
|
20
|
+
require 'matchers/validations/format_of'
|
21
|
+
require 'matchers/validations/inclusion_of'
|
22
|
+
require 'matchers/validations/length_of'
|
23
|
+
require 'matchers/validations/numericality_of'
|
24
|
+
require 'matchers/validations/presence_of'
|
25
|
+
require 'matchers/validations/uniqueness_of'
|
26
|
+
require 'matchers/validations/acceptance_of'
|
27
|
+
require 'matchers/validations/custom_validation_of'
|
28
|
+
require 'matchers/validations/absence_of'
|
29
|
+
require 'matchers/be_mongoid_document'
|
30
|
+
require 'matchers/be_dynamic_document'
|
31
|
+
require 'matchers/be_stored_in'
|
32
|
+
require 'matchers/have_field'
|
33
|
+
require 'matchers/indexes/have_index_for'
|
34
|
+
if Mongoid::Compatibility::Version.mongoid3?
|
35
|
+
require 'matchers/indexes/v3/have_index_for'
|
36
|
+
else
|
37
|
+
require 'matchers/indexes/v4/have_index_for'
|
38
|
+
end
|
39
|
+
require 'matchers/have_timestamps'
|
40
|
+
|
41
|
+
module Mongoid
|
42
|
+
module Matchers
|
43
|
+
include Mongoid::Matchers::Associations
|
44
|
+
include Mongoid::Matchers::Validations
|
45
|
+
end
|
46
|
+
end
|
data/spec/models/article.rb
CHANGED
@@ -8,22 +8,25 @@ class Article
|
|
8
8
|
field :allow_comments, type: Boolean, default: true
|
9
9
|
field :number_of_comments, type: Integer
|
10
10
|
field :status, type: Symbol
|
11
|
+
field :deletion_date, type: DateTime, default: nil
|
11
12
|
|
12
|
-
embeds_many :comments, cascade_callbacks: true
|
13
|
-
embeds_one :permalink
|
13
|
+
embeds_many :comments, cascade_callbacks: true, inverse_of: :article
|
14
|
+
embeds_one :permalink, inverse_of: :linkable
|
14
15
|
belongs_to :author, class_name: 'User', inverse_of: :articles, index: true
|
15
16
|
|
16
17
|
validates :title, presence: true
|
17
18
|
|
18
19
|
validates_inclusion_of :status, in: [:pending], on: :create
|
19
|
-
validates_inclusion_of :status, in: [
|
20
|
+
validates_inclusion_of :status, in: %i[approved rejected], on: :update
|
20
21
|
|
21
22
|
validates_length_of :title, within: 8..16
|
22
23
|
validates_length_of :content, minimum: 200
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
index({
|
25
|
+
validates_absence_of :deletion_date if Mongoid::Compatibility::Version.mongoid4_or_newer?
|
26
|
+
|
27
|
+
index({ title: 1 }, unique: true, background: true, drop_dups: true)
|
28
|
+
index(published: 1)
|
29
|
+
index('permalink._id' => 1)
|
27
30
|
|
28
31
|
accepts_nested_attributes_for :permalink
|
29
32
|
end
|
data/spec/models/comment.rb
CHANGED
data/spec/models/log.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
class Log
|
2
2
|
include Mongoid::Document
|
3
3
|
include Mongoid::Timestamps
|
4
|
-
include Mongoid::Attributes::Dynamic
|
4
|
+
include Mongoid::Attributes::Dynamic if Mongoid::Compatibility::Version.mongoid4_or_newer?
|
5
5
|
|
6
|
-
store_in collection:
|
6
|
+
store_in collection: 'logs'
|
7
7
|
|
8
|
-
index({ created_at: 1 },
|
8
|
+
index({ created_at: 1 }, bucket_size: 100, expire_after_seconds: 3600)
|
9
9
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Message
|
2
|
+
include Mongoid::Document
|
3
|
+
|
4
|
+
field :identifier
|
5
|
+
field :from
|
6
|
+
field :to
|
7
|
+
|
8
|
+
if Mongoid::Compatibility::Version.mongoid6_or_newer?
|
9
|
+
belongs_to :user, optional: true
|
10
|
+
else
|
11
|
+
belongs_to :user
|
12
|
+
end
|
13
|
+
|
14
|
+
validates :identifier, uniqueness: { message: 'uniqueness' }
|
15
|
+
validates :from, presence: { message: 'required' }
|
16
|
+
validates :to, format: { with: /[a-z]+/, message: 'format' }
|
17
|
+
end
|
@@ -1,8 +1,7 @@
|
|
1
1
|
class MovieArticle < Article
|
2
|
-
|
3
2
|
field :rating, type: Float
|
4
3
|
field :classification, type: Integer
|
5
4
|
|
6
5
|
validates :rating, numericality: { greater_than: 0, less_than_or_equal_to: 5 }
|
7
6
|
validates :classification, numericality: { even: true, only_integer: true, allow_nil: false }
|
8
|
-
end
|
7
|
+
end
|
data/spec/models/person.rb
CHANGED
data/spec/models/profile.rb
CHANGED
@@ -10,7 +10,7 @@ class Profile
|
|
10
10
|
|
11
11
|
validates :age, numericality: { greater_than: 0 }
|
12
12
|
validates :terms_of_service, acceptance: true
|
13
|
-
validates :hobbies, length: { minimum: 1, message:
|
13
|
+
validates :hobbies, length: { minimum: 1, message: 'requires at least one hobby' }
|
14
14
|
|
15
|
-
index(
|
15
|
+
index(first_name: 1, last_name: 1)
|
16
16
|
end
|
data/spec/models/record.rb
CHANGED
data/spec/models/site.rb
CHANGED
@@ -3,7 +3,11 @@ class Site
|
|
3
3
|
|
4
4
|
field :name
|
5
5
|
|
6
|
-
|
6
|
+
if Mongoid::Compatibility::Version.mongoid6_or_older?
|
7
|
+
has_many :users, inverse_of: :site, order: :email.desc, counter_cache: true
|
8
|
+
else
|
9
|
+
has_many :users, inverse_of: :site, order: :email.desc
|
10
|
+
end
|
7
11
|
|
8
12
|
validates :name, presence: true, uniqueness: true
|
9
13
|
end
|
data/spec/models/user.rb
CHANGED
@@ -13,20 +13,22 @@ class User
|
|
13
13
|
belongs_to :site, inverse_of: :users
|
14
14
|
has_many :articles, foreign_key: :author_id, order: :title
|
15
15
|
has_many :comments, dependent: :destroy, autosave: true
|
16
|
-
|
17
|
-
|
16
|
+
has_many :messages, dependent: :destroy
|
17
|
+
has_and_belongs_to_many :children, class_name: 'User'
|
18
|
+
has_one :record, autobuild: true, inverse_of: :user
|
18
19
|
|
19
|
-
embeds_one :profile
|
20
|
+
embeds_one :profile, inverse_of: :user
|
20
21
|
|
21
|
-
validates :login, presence: true, uniqueness: { scope: :site }, format: { with: /\A[\w\-]+\z/ }, exclusion: { in: [
|
22
|
-
validates :email, uniqueness: { case_sensitive: false, scope: :site, message:
|
23
|
-
validates :role, presence: true, inclusion: { in: [
|
22
|
+
validates :login, presence: true, uniqueness: { scope: :site }, format: { with: /\A[\w\-]+\z/ }, exclusion: { in: %w[super index edit] }
|
23
|
+
validates :email, uniqueness: { case_sensitive: false, scope: :site, message: 'is already taken' }, confirmation: true
|
24
|
+
validates :role, presence: true, inclusion: { in: %w[admin moderator member] }
|
24
25
|
validates :profile, presence: true, associated: true
|
25
|
-
validates :age, presence: true, numericality: true, inclusion: { in: 23..42 }, on: [
|
26
|
-
validates :password, presence: true, on: [
|
27
|
-
validates :password, exclusion: { in: ->(
|
26
|
+
validates :age, presence: true, numericality: true, inclusion: { in: 23..42 }, on: %i[create update]
|
27
|
+
validates :password, presence: true, on: %i[create update]
|
28
|
+
validates :password, exclusion: { in: ->(_user) { ['password'] } }
|
29
|
+
validates :password, confirmation: { message: 'Password confirmation must match given password' }
|
28
30
|
validates :provider_uid, presence: true
|
29
|
-
validates :locale, inclusion: { in: ->(
|
31
|
+
validates :locale, inclusion: { in: ->(_user) { %i[en ru] } }
|
30
32
|
|
31
33
|
accepts_nested_attributes_for :articles, :comments
|
32
34
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,24 +1,23 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__),
|
3
|
-
MODELS = File.join(File.dirname(__FILE__),
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
3
|
+
MODELS = File.join(File.dirname(__FILE__), 'models')
|
4
4
|
$LOAD_PATH.unshift(MODELS)
|
5
|
-
VALIDATORS = File.join(File.dirname(__FILE__),
|
5
|
+
VALIDATORS = File.join(File.dirname(__FILE__), 'validators')
|
6
6
|
$LOAD_PATH.unshift(VALIDATORS)
|
7
7
|
|
8
|
-
require
|
9
|
-
require
|
8
|
+
require 'rubygems'
|
9
|
+
require 'bundler'
|
10
10
|
Bundler.setup
|
11
11
|
|
12
12
|
require 'mongoid'
|
13
|
-
require 'rspec'
|
14
13
|
require 'rspec/core'
|
15
14
|
require 'rspec/expectations'
|
15
|
+
require 'mongoid/compatibility'
|
16
16
|
|
17
|
-
Mongoid.
|
18
|
-
|
19
|
-
end
|
17
|
+
Mongoid::Config.connect_to('mongoid-rspec-test') if Mongoid::Compatibility::Version.mongoid3_or_newer?
|
18
|
+
Mongo::Logger.logger.level = ::Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer?
|
20
19
|
|
21
|
-
Dir[
|
20
|
+
Dir[File.join(MODELS, '*.rb')].sort.each { |file| require File.basename(file) }
|
22
21
|
|
23
22
|
require 'mongoid-rspec'
|
24
23
|
|
@@ -29,5 +28,8 @@ RSpec.configure do |config|
|
|
29
28
|
config.after :all do
|
30
29
|
Mongoid::Config.purge!
|
31
30
|
end
|
31
|
+
config.after :suite do
|
32
|
+
print "\n# Mongoid v#{Mongoid::VERSION}"
|
33
|
+
end
|
32
34
|
config.disable_monkey_patching!
|
33
35
|
end
|