mongoid-rspec 1.4.5 → 1.4.6
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.
- data/.travis.yml +2 -5
- data/README.md +5 -0
- data/lib/matchers/allow_mass_assignment.rb +101 -0
- data/lib/matchers/collections.rb +1 -1
- data/lib/matchers/validations/custom_validation_of.rb +64 -0
- data/lib/matchers/validations/uniqueness_of.rb +1 -1
- data/lib/mongoid-rspec.rb +3 -0
- data/lib/mongoid-rspec/version.rb +1 -1
- data/mongoid-rspec.gemspec +1 -1
- data/spec/models/article.rb +2 -2
- data/spec/models/log.rb +1 -1
- data/spec/models/person.rb +13 -0
- data/spec/models/profile.rb +1 -6
- data/spec/models/user.rb +3 -0
- data/spec/spec_helper.rb +5 -5
- data/spec/unit/allow_mass_assignment_spec.rb +14 -0
- data/spec/unit/indexes_spec.rb +3 -3
- data/spec/unit/validations_spec.rb +5 -0
- data/spec/validators/ssn_validator.rb +14 -0
- metadata +17 -9
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -78,6 +78,11 @@ Validation Matchers
|
|
78
78
|
it { should validate_numericality_of(:classification).to_allow(:even => true, :only_integer => true, :nil => false) }
|
79
79
|
end
|
80
80
|
|
81
|
+
describe Person do
|
82
|
+
# in order to be able to use the custom_validate matcher, the custom validator class (in this case SsnValidator)
|
83
|
+
# should redefine the kind method to return :custom, i.e. "def self.kind() :custom end"
|
84
|
+
it { should custom_validate(:ssn).with_validator(SsnValidator) }
|
85
|
+
end
|
81
86
|
Others
|
82
87
|
-
|
83
88
|
describe User do
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# this code is totally extracted from shoulda-matchers gem.
|
2
|
+
module Mongoid
|
3
|
+
module Matchers
|
4
|
+
class AllowMassAssignmentOfMatcher # :nodoc:
|
5
|
+
attr_reader :failure_message, :negative_failure_message
|
6
|
+
|
7
|
+
def initialize(attribute)
|
8
|
+
@attribute = attribute.to_s
|
9
|
+
@options = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def as(role)
|
13
|
+
if active_model_less_than_3_1?
|
14
|
+
raise "You can specify role only in Rails 3.1 or greater"
|
15
|
+
end
|
16
|
+
@options[:role] = role
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def matches?(klass)
|
21
|
+
@klass = klass
|
22
|
+
if attr_mass_assignable?
|
23
|
+
if whitelisting?
|
24
|
+
@negative_failure_message = "#{@attribute} was made accessible"
|
25
|
+
else
|
26
|
+
if protected_attributes.empty?
|
27
|
+
@negative_failure_message = "no attributes were protected"
|
28
|
+
else
|
29
|
+
@negative_failure_message = "#{class_name} is protecting " <<
|
30
|
+
"#{protected_attributes.to_a.to_sentence}, " <<
|
31
|
+
"but not #{@attribute}."
|
32
|
+
end
|
33
|
+
end
|
34
|
+
true
|
35
|
+
else
|
36
|
+
if whitelisting?
|
37
|
+
@failure_message = "Expected #{@attribute} to be accessible"
|
38
|
+
else
|
39
|
+
@failure_message = "Did not expect #{@attribute} to be protected"
|
40
|
+
end
|
41
|
+
false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def description
|
46
|
+
"allow mass assignment of #{@attribute}"
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def role
|
52
|
+
@options[:role] || :default
|
53
|
+
end
|
54
|
+
|
55
|
+
def protected_attributes
|
56
|
+
@protected_attributes ||= (@klass.class.protected_attributes || [])
|
57
|
+
end
|
58
|
+
|
59
|
+
def accessible_attributes
|
60
|
+
@accessible_attributes ||= (@klass.class.accessible_attributes || [])
|
61
|
+
end
|
62
|
+
|
63
|
+
def whitelisting?
|
64
|
+
authorizer.kind_of?(::ActiveModel::MassAssignmentSecurity::WhiteList)
|
65
|
+
end
|
66
|
+
|
67
|
+
def attr_mass_assignable?
|
68
|
+
!authorizer.deny?(@attribute)
|
69
|
+
end
|
70
|
+
|
71
|
+
def authorizer
|
72
|
+
if active_model_less_than_3_1?
|
73
|
+
@klass.class.active_authorizer
|
74
|
+
else
|
75
|
+
@klass.class.active_authorizer[role]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def class_name
|
80
|
+
@klass.class.name
|
81
|
+
end
|
82
|
+
|
83
|
+
def active_model_less_than_3_1?
|
84
|
+
::ActiveModel::VERSION::STRING.to_f < 3.1
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Ensures that the attribute can be set on mass update.
|
89
|
+
#
|
90
|
+
# it { should_not allow_mass_assignment_of(:password) }
|
91
|
+
# it { should allow_mass_assignment_of(:first_name) }
|
92
|
+
#
|
93
|
+
# In Rails 3.1 you can check role as well:
|
94
|
+
#
|
95
|
+
# it { should allow_mass_assignment_of(:first_name).as(:admin) }
|
96
|
+
#
|
97
|
+
def allow_mass_assignment_of(value)
|
98
|
+
AllowMassAssignmentOfMatcher.new(value)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/matchers/collections.rb
CHANGED
@@ -0,0 +1,64 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchers
|
3
|
+
module Validations
|
4
|
+
class ValidateWithCustomValidatorMatcher < HaveValidationMatcher
|
5
|
+
def initialize(field)
|
6
|
+
super(field, :custom)
|
7
|
+
end
|
8
|
+
|
9
|
+
def with_validator(custom_validator)
|
10
|
+
@custom_validator = custom_validator
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def with_message(message)
|
15
|
+
@expected_message = message
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def matches?(actual)
|
20
|
+
return false unless (@result = super(actual))
|
21
|
+
check_custom_validator if @custom_validator
|
22
|
+
check_expected_message if @expected_message
|
23
|
+
|
24
|
+
@result
|
25
|
+
end
|
26
|
+
|
27
|
+
def description
|
28
|
+
options_desc = []
|
29
|
+
options_desc << " with custom validator #{@custom_validator.name}" if @validator
|
30
|
+
options_desc << " with message '#{@expected_message}'" if @expected_message
|
31
|
+
"validate field #{@field.inspect}" << options_desc.to_sentence
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def check_custom_validator
|
37
|
+
if @validator.kind_of? @custom_validator
|
38
|
+
@positive_result_message << " with custom validator of type #{@custom_validator.name}"
|
39
|
+
else
|
40
|
+
@negative_result_message << " with custom validator not of type #{@custom_validator.name}"
|
41
|
+
@result = false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def check_expected_message
|
46
|
+
actual_message = @validator.options[:message]
|
47
|
+
if actual_message.nil?
|
48
|
+
@negative_result_message << " with no custom message"
|
49
|
+
@result = false
|
50
|
+
elsif actual_message == @expected_message
|
51
|
+
@positive_result_message << " with custom message '#{@expected_message}'"
|
52
|
+
else
|
53
|
+
@negative_result_message << " got message '#{actual_message}'"
|
54
|
+
@result = false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def custom_validate(field)
|
60
|
+
ValidateWithCustomValidatorMatcher.new(field)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -43,7 +43,7 @@ module Mongoid
|
|
43
43
|
options_desc << " scoped to #{@scope.inspect}" if @scope
|
44
44
|
options_desc << " allowing blank values" if @allow_blank
|
45
45
|
options_desc << " allowing case insensitive values" if @case_insensitive
|
46
|
-
options_desc << " with message '#{@expected_message}'" if @
|
46
|
+
options_desc << " with message '#{@expected_message}'" if @expected_message
|
47
47
|
super << options_desc.to_sentence
|
48
48
|
end
|
49
49
|
|
data/lib/mongoid-rspec.rb
CHANGED
@@ -2,10 +2,12 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
2
2
|
|
3
3
|
require 'mongoid'
|
4
4
|
require 'rspec'
|
5
|
+
require "active_model"
|
5
6
|
require 'matchers/document'
|
6
7
|
require 'matchers/associations'
|
7
8
|
require 'matchers/collections'
|
8
9
|
require 'matchers/indexes'
|
10
|
+
require 'matchers/allow_mass_assignment'
|
9
11
|
require 'matchers/validations'
|
10
12
|
require 'matchers/validations/associated'
|
11
13
|
require 'matchers/validations/confirmation_of'
|
@@ -17,6 +19,7 @@ require 'matchers/validations/numericality_of'
|
|
17
19
|
require 'matchers/validations/presence_of'
|
18
20
|
require 'matchers/validations/uniqueness_of'
|
19
21
|
require 'matchers/validations/acceptance_of'
|
22
|
+
require 'matchers/validations/custom_validation_of'
|
20
23
|
|
21
24
|
module Mongoid
|
22
25
|
module Matchers
|
data/mongoid-rspec.gemspec
CHANGED
data/spec/models/article.rb
CHANGED
data/spec/models/log.rb
CHANGED
data/spec/models/profile.rb
CHANGED
@@ -10,10 +10,5 @@ class Profile
|
|
10
10
|
validates_numericality_of :age, :greater_than => 0
|
11
11
|
validates_acceptance_of :terms_of_service
|
12
12
|
|
13
|
-
index(
|
14
|
-
[
|
15
|
-
[ :first_name, Mongo::ASCENDING ],
|
16
|
-
[ :last_name, Mongo::ASCENDING ]
|
17
|
-
]
|
18
|
-
)
|
13
|
+
index({first_name: 1, last_name: 1 })
|
19
14
|
end
|
data/spec/models/user.rb
CHANGED
@@ -22,6 +22,9 @@ class User
|
|
22
22
|
validates :age, :presence => true, :numericality => true, :inclusion => { :in => 23..42 }, :on => [:create, :update]
|
23
23
|
validates :password, :presence => true, :on => :create
|
24
24
|
|
25
|
+
attr_accessible :login, :email, :age, :password
|
26
|
+
attr_accessible :role, :as => :admin
|
27
|
+
|
25
28
|
def admin?
|
26
29
|
false
|
27
30
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,20 +2,20 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "lib"))
|
3
3
|
MODELS = File.join(File.dirname(__FILE__), "models")
|
4
4
|
$LOAD_PATH.unshift(MODELS)
|
5
|
+
VALIDATORS = File.join(File.dirname(__FILE__), "validators")
|
6
|
+
$LOAD_PATH.unshift(VALIDATORS)
|
5
7
|
|
6
8
|
require "rubygems"
|
7
9
|
require "bundler"
|
8
10
|
Bundler.setup
|
9
11
|
|
12
|
+
require 'mongoid'
|
10
13
|
require 'rspec'
|
11
14
|
require 'rspec/core'
|
12
15
|
require 'rspec/expectations'
|
13
|
-
require 'mongoid'
|
14
16
|
|
15
17
|
Mongoid.configure do |config|
|
16
|
-
|
17
|
-
host = "localhost"
|
18
|
-
config.master = Mongo::Connection.new.db(name)
|
18
|
+
config.connect_to("mongoid-rspec-test")
|
19
19
|
end
|
20
20
|
|
21
21
|
Dir[ File.join(MODELS, "*.rb") ].sort.each { |file| require File.basename(file) }
|
@@ -27,6 +27,6 @@ RSpec.configure do |config|
|
|
27
27
|
config.include Mongoid::Matchers
|
28
28
|
config.mock_with :rspec
|
29
29
|
config.after :all do
|
30
|
-
Mongoid.
|
30
|
+
Mongoid::Config.purge!
|
31
31
|
end
|
32
32
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "AllowMassAssignment" do
|
4
|
+
describe User do
|
5
|
+
it { should allow_mass_assignment_of(:login) }
|
6
|
+
it { should allow_mass_assignment_of(:email) }
|
7
|
+
it { should allow_mass_assignment_of(:age) }
|
8
|
+
it { should allow_mass_assignment_of(:password) }
|
9
|
+
it { should allow_mass_assignment_of(:password) }
|
10
|
+
it { should allow_mass_assignment_of(:role).as(:admin) }
|
11
|
+
|
12
|
+
it { should_not allow_mass_assignment_of(:role) }
|
13
|
+
end
|
14
|
+
end
|
data/spec/unit/indexes_spec.rb
CHANGED
@@ -2,11 +2,11 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe "Indexes" do
|
4
4
|
describe Article do
|
5
|
-
it { should have_index_for(:
|
6
|
-
it { should have_index_for(:
|
5
|
+
it { should have_index_for(published: 1) }
|
6
|
+
it { should have_index_for(title: 1).with_options(unique: true, background: true) }
|
7
7
|
end
|
8
8
|
|
9
9
|
describe Profile do
|
10
|
-
it { should have_index_for(
|
10
|
+
it { should have_index_for(first_name: 1, last_name: 1) }
|
11
11
|
end
|
12
12
|
end
|
@@ -35,4 +35,9 @@ describe "Validations" do
|
|
35
35
|
it { should validate_numericality_of(:rating).to_allow(:greater_than => 0).less_than_or_equal_to(5) }
|
36
36
|
it { should validate_numericality_of(:classification).to_allow(:even => true, :only_integer => true, :nil => false) }
|
37
37
|
end
|
38
|
+
|
39
|
+
describe Person do
|
40
|
+
it { should custom_validate(:ssn).with_validator(SsnValidator) }
|
41
|
+
it { should_not custom_validate(:name) }
|
42
|
+
end
|
38
43
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class SsnValidator < ActiveModel::EachValidator
|
2
|
+
|
3
|
+
def validate_each(record, attribute, value)
|
4
|
+
record.errors[attribute] << "#{value} is not a valid Social Security Number" unless valid_ssn?(record, attribute, value)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.kind() :custom end
|
8
|
+
|
9
|
+
def valid_ssn?(record, attribute, value)
|
10
|
+
# irrelevant here how validation is done
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid-rspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-06-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &70121800719080 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,21 +21,21 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70121800719080
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: mongoid
|
27
|
-
requirement: &
|
27
|
+
requirement: &70121800717200 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 3.0.0.rc
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70121800717200
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70121800716000 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '2.9'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70121800716000
|
47
47
|
description: RSpec matches for Mongoid models, including association and validation
|
48
48
|
matchers
|
49
49
|
email: evansagge@gmail.com
|
@@ -60,6 +60,7 @@ files:
|
|
60
60
|
- LICENSE
|
61
61
|
- README.md
|
62
62
|
- Rakefile
|
63
|
+
- lib/matchers/allow_mass_assignment.rb
|
63
64
|
- lib/matchers/associations.rb
|
64
65
|
- lib/matchers/collections.rb
|
65
66
|
- lib/matchers/document.rb
|
@@ -68,6 +69,7 @@ files:
|
|
68
69
|
- lib/matchers/validations/acceptance_of.rb
|
69
70
|
- lib/matchers/validations/associated.rb
|
70
71
|
- lib/matchers/validations/confirmation_of.rb
|
72
|
+
- lib/matchers/validations/custom_validation_of.rb
|
71
73
|
- lib/matchers/validations/exclusion_of.rb
|
72
74
|
- lib/matchers/validations/format_of.rb
|
73
75
|
- lib/matchers/validations/inclusion_of.rb
|
@@ -83,16 +85,19 @@ files:
|
|
83
85
|
- spec/models/log.rb
|
84
86
|
- spec/models/movie_article.rb
|
85
87
|
- spec/models/permalink.rb
|
88
|
+
- spec/models/person.rb
|
86
89
|
- spec/models/profile.rb
|
87
90
|
- spec/models/record.rb
|
88
91
|
- spec/models/site.rb
|
89
92
|
- spec/models/user.rb
|
90
93
|
- spec/spec_helper.rb
|
94
|
+
- spec/unit/allow_mass_assignment_spec.rb
|
91
95
|
- spec/unit/associations_spec.rb
|
92
96
|
- spec/unit/collections_spec.rb
|
93
97
|
- spec/unit/document_spec.rb
|
94
98
|
- spec/unit/indexes_spec.rb
|
95
99
|
- spec/unit/validations_spec.rb
|
100
|
+
- spec/validators/ssn_validator.rb
|
96
101
|
homepage: http://github.com/evansagge/mongoid-rspec
|
97
102
|
licenses: []
|
98
103
|
post_install_message:
|
@@ -123,13 +128,16 @@ test_files:
|
|
123
128
|
- spec/models/log.rb
|
124
129
|
- spec/models/movie_article.rb
|
125
130
|
- spec/models/permalink.rb
|
131
|
+
- spec/models/person.rb
|
126
132
|
- spec/models/profile.rb
|
127
133
|
- spec/models/record.rb
|
128
134
|
- spec/models/site.rb
|
129
135
|
- spec/models/user.rb
|
130
136
|
- spec/spec_helper.rb
|
137
|
+
- spec/unit/allow_mass_assignment_spec.rb
|
131
138
|
- spec/unit/associations_spec.rb
|
132
139
|
- spec/unit/collections_spec.rb
|
133
140
|
- spec/unit/document_spec.rb
|
134
141
|
- spec/unit/indexes_spec.rb
|
135
142
|
- spec/unit/validations_spec.rb
|
143
|
+
- spec/validators/ssn_validator.rb
|