shoulda-matchers 2.6.1.rc1 → 2.6.1.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile.lock +1 -1
- data/NEWS.md +16 -2
- data/gemfiles/3.0.gemfile.lock +1 -1
- data/gemfiles/3.1.gemfile.lock +1 -1
- data/gemfiles/3.2.gemfile.lock +1 -1
- data/gemfiles/4.0.0.gemfile.lock +1 -1
- data/gemfiles/4.0.1.gemfile.lock +1 -1
- data/gemfiles/4.1.gemfile.lock +1 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +13 -2
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +13 -6
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +2 -1
- data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +6 -1
- data/lib/shoulda/matchers/version.rb +1 -1
- data/spec/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +1 -1
- data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +18 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +0 -6
- data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +42 -0
- data/spec/support/activemodel_helpers.rb +6 -2
- data/spec/support/rails_versions.rb +1 -1
- metadata +17 -39
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8f8f865b9ee2e09b27b831e0e107beea74dc14e8
|
4
|
+
data.tar.gz: c58cab17d485bfa69d7601e8475d26520c19995d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 03120f384bc8795a623bd9af2db57acd7722bc4322809a2ae791b0d0bc7928091e6d1ed40c50c8766aaad4b585936ef25d5ab931cfae0fcf4da31b0b962eb626
|
7
|
+
data.tar.gz: 12bf17877fa26dff8f5df3a274a5416c541f2c59105edb693aa98fef7969cf84b2859948ef815ca894875a471e1a10243791fe5c4a22ba063d98608e03adfd2c
|
data/Gemfile.lock
CHANGED
data/NEWS.md
CHANGED
@@ -1,7 +1,19 @@
|
|
1
1
|
# HEAD
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
## Features
|
4
|
+
|
5
|
+
* Teach `with_message` qualifier on `allow_value` to accept a hash of i18n
|
6
|
+
interpolation values:
|
7
|
+
`allow_value('foo').for(:attr).with_message(:greater_than, values: { count: 20 })`.
|
8
|
+
|
9
|
+
## Bug fixes
|
10
|
+
|
11
|
+
* Revert changes to `validate_numericality_of` made in the last release, which
|
12
|
+
made it so that comparison qualifiers specified on the validation are tested
|
13
|
+
using a very small decimal number offset rather than a whole number by
|
14
|
+
default, except if the matcher was qualified with `only_integer`. This means
|
15
|
+
that prior to 2.6.0, if your validation specified `only_integer` and you did
|
16
|
+
not, then after 2.6.0 that test now fails.
|
5
17
|
|
6
18
|
* Fix so that ActiveRecord matchers aren't included when ActiveRecord
|
7
19
|
isn't defined (i.e. if you are using ActiveModel only).
|
@@ -32,6 +44,8 @@
|
|
32
44
|
* Fix `delegate_method` so that it does not stub the target method forever,
|
33
45
|
returning it to its original implementation after the match ends.
|
34
46
|
|
47
|
+
* Fix `validate_uniqueness_of` to work with Rails 4.1 enum columns.
|
48
|
+
|
35
49
|
# 2.6.0
|
36
50
|
|
37
51
|
* The boolean argument to `have_db_index`'s `unique` option is now optional, for
|
data/gemfiles/3.0.gemfile.lock
CHANGED
data/gemfiles/3.1.gemfile.lock
CHANGED
data/gemfiles/3.2.gemfile.lock
CHANGED
data/gemfiles/4.0.0.gemfile.lock
CHANGED
data/gemfiles/4.0.1.gemfile.lock
CHANGED
data/gemfiles/4.1.gemfile.lock
CHANGED
@@ -53,9 +53,12 @@ module Shoulda # :nodoc:
|
|
53
53
|
|
54
54
|
def with_message(message, options={})
|
55
55
|
self.options[:expected_message] = message
|
56
|
+
self.options[:expected_message_values] = options.fetch(:values, {})
|
57
|
+
|
56
58
|
if options.key?(:against)
|
57
59
|
self.attribute_to_check_message_against = options[:against]
|
58
60
|
end
|
61
|
+
|
59
62
|
self
|
60
63
|
end
|
61
64
|
|
@@ -173,10 +176,18 @@ module Shoulda # :nodoc:
|
|
173
176
|
def default_attribute_message
|
174
177
|
default_error_message(
|
175
178
|
options[:expected_message],
|
179
|
+
default_attribute_message_values
|
180
|
+
)
|
181
|
+
end
|
182
|
+
|
183
|
+
def default_attribute_message_values
|
184
|
+
defaults = {
|
176
185
|
model_name: model_name,
|
177
186
|
instance: instance,
|
178
|
-
attribute: attribute_to_set
|
179
|
-
|
187
|
+
attribute: attribute_to_set,
|
188
|
+
}
|
189
|
+
|
190
|
+
defaults.merge(options[:expected_message_values])
|
180
191
|
end
|
181
192
|
|
182
193
|
def model_name
|
@@ -7,8 +7,13 @@ module Shoulda # :nodoc:
|
|
7
7
|
# is_greater_than(6).
|
8
8
|
# less_than(20)...(and so on) }
|
9
9
|
class ComparisonMatcher < ValidationMatcher
|
10
|
-
|
11
|
-
|
10
|
+
ERROR_MESSAGES = {
|
11
|
+
:> => :greater_than,
|
12
|
+
:>= => :greater_than_or_equal_to,
|
13
|
+
:< => :less_than,
|
14
|
+
:<= => :less_than_or_equal_to,
|
15
|
+
:== => :equal_to
|
16
|
+
}
|
12
17
|
|
13
18
|
def initialize(numericality_matcher, value, operator)
|
14
19
|
unless numericality_matcher.respond_to? :diff_to_compare
|
@@ -17,8 +22,8 @@ module Shoulda # :nodoc:
|
|
17
22
|
@numericality_matcher = numericality_matcher
|
18
23
|
@value = value
|
19
24
|
@operator = operator
|
20
|
-
@message =
|
21
|
-
@
|
25
|
+
@message = ERROR_MESSAGES[operator]
|
26
|
+
@comparison_combos = comparison_combos
|
22
27
|
end
|
23
28
|
|
24
29
|
def for(attribute)
|
@@ -71,8 +76,10 @@ module Shoulda # :nodoc:
|
|
71
76
|
end
|
72
77
|
|
73
78
|
def all_bounds_correct?
|
74
|
-
comparison_combos.all? do |diff, checker_type|
|
75
|
-
__send__(checker_type, @value + diff
|
79
|
+
@comparison_combos.all? do |diff, checker_type|
|
80
|
+
__send__(checker_type, @value + diff) do |matcher|
|
81
|
+
matcher.with_message(@message, values: { count: @value })
|
82
|
+
end
|
76
83
|
end
|
77
84
|
end
|
78
85
|
end
|
@@ -26,7 +26,8 @@ module Shoulda # :nodoc:
|
|
26
26
|
class ValidateNumericalityOfMatcher
|
27
27
|
NUMERIC_NAME = 'numbers'
|
28
28
|
NON_NUMERIC_VALUE = 'abcd'
|
29
|
-
DEFAULT_DIFF_TO_COMPARE =
|
29
|
+
DEFAULT_DIFF_TO_COMPARE = 1
|
30
|
+
|
30
31
|
attr_reader :diff_to_compare
|
31
32
|
|
32
33
|
def initialize(attribute)
|
@@ -173,7 +173,12 @@ module Shoulda # :nodoc:
|
|
173
173
|
previous_value ||= correct_type_for_column(@subject.class.columns_hash[scope.to_s])
|
174
174
|
|
175
175
|
next_value =
|
176
|
-
if
|
176
|
+
if @subject.class.respond_to?(:defined_enums) && @subject.defined_enums[scope.to_s]
|
177
|
+
available_values = @subject.defined_enums[scope.to_s].reject do |key, _|
|
178
|
+
key == previous_value
|
179
|
+
end
|
180
|
+
available_values.keys.last
|
181
|
+
elsif previous_value.respond_to?(:next)
|
177
182
|
previous_value.next
|
178
183
|
elsif previous_value.respond_to?(:to_datetime)
|
179
184
|
previous_value.to_datetime.next
|
@@ -261,7 +261,7 @@ describe Shoulda::Matchers::ActionController::StrongParametersMatcher do
|
|
261
261
|
end
|
262
262
|
|
263
263
|
context 'when given :update' do
|
264
|
-
if
|
264
|
+
if rails_gte_4_1?
|
265
265
|
it 'PATCHes to the controller' do
|
266
266
|
controller = ActionController::Base.new
|
267
267
|
context = mock()
|
@@ -68,6 +68,24 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher do
|
|
68
68
|
expect(validating_format(with: /abc/, message: 'bad value')).
|
69
69
|
not_to allow_value('xyz').for(:attr).with_message(/bad/)
|
70
70
|
end
|
71
|
+
|
72
|
+
it 'allows interpolation values for the message to be provided' do
|
73
|
+
options = {
|
74
|
+
attribute_name: :attr,
|
75
|
+
attribute_type: :string
|
76
|
+
}
|
77
|
+
|
78
|
+
record = record_with_custom_validation(options) do
|
79
|
+
if self.attr == 'xyz'
|
80
|
+
self.errors.add :attr, :greater_than, count: 2
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
expect(record).
|
85
|
+
not_to allow_value('xyz').
|
86
|
+
for(:attr).
|
87
|
+
with_message(:greater_than, values: { count: 2 })
|
88
|
+
end
|
71
89
|
end
|
72
90
|
|
73
91
|
context 'an attribute where the message occurs on another attribute' do
|
@@ -5,12 +5,6 @@ describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::ComparisonMatcher
|
|
5
5
|
|
6
6
|
it_behaves_like 'a numerical submatcher'
|
7
7
|
|
8
|
-
describe '#diff_to_compare' do
|
9
|
-
it { expect(subject.diff_to_compare).to eq 0.000_001 }
|
10
|
-
it { expect(described_class.new(matcher, 2**34, :>).diff_to_compare).to eq 1 }
|
11
|
-
it { expect(described_class.new(matcher, -2**34, :>).diff_to_compare).to eq 1 }
|
12
|
-
end
|
13
|
-
|
14
8
|
context 'when initialized without correct numerical matcher' do
|
15
9
|
it 'raises an argument error' do
|
16
10
|
fake_matcher = matcher
|
@@ -122,6 +122,40 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
122
122
|
not_to matcher.scoped_to(:fake)
|
123
123
|
end
|
124
124
|
|
125
|
+
if rails_gte_4_1?
|
126
|
+
context 'when the scoped attribute is an enum' do
|
127
|
+
it 'accepts' do
|
128
|
+
expect(validating_scoped_uniqueness_with_enum([:scope1], scope1: 0)).
|
129
|
+
to matcher.scoped_to(:scope1)
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'with a nil value' do
|
133
|
+
it 'accepts' do
|
134
|
+
expect(validating_scoped_uniqueness_with_enum([:scope1], scope1: nil)).
|
135
|
+
to matcher.scoped_to(:scope1)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'when too narrow of a scope is specified' do
|
140
|
+
it 'rejects' do
|
141
|
+
expect(validating_scoped_uniqueness_with_enum_with_two_scopes).
|
142
|
+
not_to matcher.scoped_to(:scope1, :scope2, :other)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'when too broad of a scope is specified' do
|
147
|
+
it 'rejects' do
|
148
|
+
expect(validating_scoped_uniqueness_with_enum_with_two_scopes).
|
149
|
+
not_to matcher.scoped_to(:scope1)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def validating_scoped_uniqueness_with_enum_with_two_scopes
|
154
|
+
validating_scoped_uniqueness_with_enum([:scope1, :scope2], scope1: 0, scope2: 0)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
125
159
|
context 'when the scoped attribute is a date' do
|
126
160
|
it "accepts" do
|
127
161
|
expect(validating_scoped_uniqueness([:scope1], :date, scope1: Date.today)).
|
@@ -250,6 +284,14 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
250
284
|
model
|
251
285
|
end
|
252
286
|
|
287
|
+
def validating_scoped_uniqueness_with_enum(*args)
|
288
|
+
attributes = args.extract_options!
|
289
|
+
model = define_scoped_model(*args)
|
290
|
+
model.enum scope1: [:foo, :bar]
|
291
|
+
create_existing_record(attributes)
|
292
|
+
model.new
|
293
|
+
end
|
294
|
+
|
253
295
|
def validating_scoped_uniqueness_with_conflicting_next(*args)
|
254
296
|
attributes = args.extract_options!
|
255
297
|
model = define_scoped_model(*args).new
|
@@ -1,11 +1,15 @@
|
|
1
1
|
module ActiveModelHelpers
|
2
|
-
def custom_validation(&block)
|
3
|
-
|
2
|
+
def custom_validation(options = {}, &block)
|
3
|
+
attribute_name = options.fetch(:attribute_name, :attr)
|
4
|
+
attribute_type = options.fetch(:attribute_type, :integer)
|
5
|
+
|
6
|
+
define_model(:example, attribute_name => attribute_type) do
|
4
7
|
validate :custom_validation
|
5
8
|
|
6
9
|
define_method(:custom_validation, &block)
|
7
10
|
end.new
|
8
11
|
end
|
12
|
+
alias record_with_custom_validation custom_validation
|
9
13
|
|
10
14
|
def validating_format(options)
|
11
15
|
define_model :example, attr: :string do
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shoulda-matchers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.6.1.
|
5
|
-
prerelease: 6
|
4
|
+
version: 2.6.1.rc2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Tammer Saleh
|
@@ -14,28 +13,25 @@ authors:
|
|
14
13
|
autorequire:
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
|
-
date: 2014-04-
|
16
|
+
date: 2014-04-28 00:00:00.000000000 Z
|
18
17
|
dependencies:
|
19
18
|
- !ruby/object:Gem::Dependency
|
20
19
|
name: activesupport
|
21
20
|
requirement: !ruby/object:Gem::Requirement
|
22
|
-
none: false
|
23
21
|
requirements:
|
24
|
-
- -
|
22
|
+
- - '>='
|
25
23
|
- !ruby/object:Gem::Version
|
26
24
|
version: 3.0.0
|
27
25
|
type: :runtime
|
28
26
|
prerelease: false
|
29
27
|
version_requirements: !ruby/object:Gem::Requirement
|
30
|
-
none: false
|
31
28
|
requirements:
|
32
|
-
- -
|
29
|
+
- - '>='
|
33
30
|
- !ruby/object:Gem::Version
|
34
31
|
version: 3.0.0
|
35
32
|
- !ruby/object:Gem::Dependency
|
36
33
|
name: appraisal
|
37
34
|
requirement: !ruby/object:Gem::Requirement
|
38
|
-
none: false
|
39
35
|
requirements:
|
40
36
|
- - ~>
|
41
37
|
- !ruby/object:Gem::Version
|
@@ -43,7 +39,6 @@ dependencies:
|
|
43
39
|
type: :development
|
44
40
|
prerelease: false
|
45
41
|
version_requirements: !ruby/object:Gem::Requirement
|
46
|
-
none: false
|
47
42
|
requirements:
|
48
43
|
- - ~>
|
49
44
|
- !ruby/object:Gem::Version
|
@@ -51,39 +46,34 @@ dependencies:
|
|
51
46
|
- !ruby/object:Gem::Dependency
|
52
47
|
name: aruba
|
53
48
|
requirement: !ruby/object:Gem::Requirement
|
54
|
-
none: false
|
55
49
|
requirements:
|
56
|
-
- -
|
50
|
+
- - '>='
|
57
51
|
- !ruby/object:Gem::Version
|
58
52
|
version: '0'
|
59
53
|
type: :development
|
60
54
|
prerelease: false
|
61
55
|
version_requirements: !ruby/object:Gem::Requirement
|
62
|
-
none: false
|
63
56
|
requirements:
|
64
|
-
- -
|
57
|
+
- - '>='
|
65
58
|
- !ruby/object:Gem::Version
|
66
59
|
version: '0'
|
67
60
|
- !ruby/object:Gem::Dependency
|
68
61
|
name: pry
|
69
62
|
requirement: !ruby/object:Gem::Requirement
|
70
|
-
none: false
|
71
63
|
requirements:
|
72
|
-
- -
|
64
|
+
- - '>='
|
73
65
|
- !ruby/object:Gem::Version
|
74
66
|
version: '0'
|
75
67
|
type: :development
|
76
68
|
prerelease: false
|
77
69
|
version_requirements: !ruby/object:Gem::Requirement
|
78
|
-
none: false
|
79
70
|
requirements:
|
80
|
-
- -
|
71
|
+
- - '>='
|
81
72
|
- !ruby/object:Gem::Version
|
82
73
|
version: '0'
|
83
74
|
- !ruby/object:Gem::Dependency
|
84
75
|
name: bourne
|
85
76
|
requirement: !ruby/object:Gem::Requirement
|
86
|
-
none: false
|
87
77
|
requirements:
|
88
78
|
- - ~>
|
89
79
|
- !ruby/object:Gem::Version
|
@@ -91,7 +81,6 @@ dependencies:
|
|
91
81
|
type: :development
|
92
82
|
prerelease: false
|
93
83
|
version_requirements: !ruby/object:Gem::Requirement
|
94
|
-
none: false
|
95
84
|
requirements:
|
96
85
|
- - ~>
|
97
86
|
- !ruby/object:Gem::Version
|
@@ -99,7 +88,6 @@ dependencies:
|
|
99
88
|
- !ruby/object:Gem::Dependency
|
100
89
|
name: bundler
|
101
90
|
requirement: !ruby/object:Gem::Requirement
|
102
|
-
none: false
|
103
91
|
requirements:
|
104
92
|
- - ~>
|
105
93
|
- !ruby/object:Gem::Version
|
@@ -107,7 +95,6 @@ dependencies:
|
|
107
95
|
type: :development
|
108
96
|
prerelease: false
|
109
97
|
version_requirements: !ruby/object:Gem::Requirement
|
110
|
-
none: false
|
111
98
|
requirements:
|
112
99
|
- - ~>
|
113
100
|
- !ruby/object:Gem::Version
|
@@ -115,7 +102,6 @@ dependencies:
|
|
115
102
|
- !ruby/object:Gem::Dependency
|
116
103
|
name: cucumber
|
117
104
|
requirement: !ruby/object:Gem::Requirement
|
118
|
-
none: false
|
119
105
|
requirements:
|
120
106
|
- - ~>
|
121
107
|
- !ruby/object:Gem::Version
|
@@ -123,7 +109,6 @@ dependencies:
|
|
123
109
|
type: :development
|
124
110
|
prerelease: false
|
125
111
|
version_requirements: !ruby/object:Gem::Requirement
|
126
|
-
none: false
|
127
112
|
requirements:
|
128
113
|
- - ~>
|
129
114
|
- !ruby/object:Gem::Version
|
@@ -131,7 +116,6 @@ dependencies:
|
|
131
116
|
- !ruby/object:Gem::Dependency
|
132
117
|
name: rails
|
133
118
|
requirement: !ruby/object:Gem::Requirement
|
134
|
-
none: false
|
135
119
|
requirements:
|
136
120
|
- - ~>
|
137
121
|
- !ruby/object:Gem::Version
|
@@ -139,7 +123,6 @@ dependencies:
|
|
139
123
|
type: :development
|
140
124
|
prerelease: false
|
141
125
|
version_requirements: !ruby/object:Gem::Requirement
|
142
|
-
none: false
|
143
126
|
requirements:
|
144
127
|
- - ~>
|
145
128
|
- !ruby/object:Gem::Version
|
@@ -147,25 +130,22 @@ dependencies:
|
|
147
130
|
- !ruby/object:Gem::Dependency
|
148
131
|
name: rake
|
149
132
|
requirement: !ruby/object:Gem::Requirement
|
150
|
-
none: false
|
151
133
|
requirements:
|
152
|
-
- -
|
134
|
+
- - '>='
|
153
135
|
- !ruby/object:Gem::Version
|
154
136
|
version: 0.9.2
|
155
137
|
type: :development
|
156
138
|
prerelease: false
|
157
139
|
version_requirements: !ruby/object:Gem::Requirement
|
158
|
-
none: false
|
159
140
|
requirements:
|
160
|
-
- -
|
141
|
+
- - '>='
|
161
142
|
- !ruby/object:Gem::Version
|
162
143
|
version: 0.9.2
|
163
144
|
- !ruby/object:Gem::Dependency
|
164
145
|
name: rspec-rails
|
165
146
|
requirement: !ruby/object:Gem::Requirement
|
166
|
-
none: false
|
167
147
|
requirements:
|
168
|
-
- -
|
148
|
+
- - '>='
|
169
149
|
- !ruby/object:Gem::Version
|
170
150
|
version: 2.13.1
|
171
151
|
- - <
|
@@ -174,9 +154,8 @@ dependencies:
|
|
174
154
|
type: :development
|
175
155
|
prerelease: false
|
176
156
|
version_requirements: !ruby/object:Gem::Requirement
|
177
|
-
none: false
|
178
157
|
requirements:
|
179
|
-
- -
|
158
|
+
- - '>='
|
180
159
|
- !ruby/object:Gem::Version
|
181
160
|
version: 2.13.1
|
182
161
|
- - <
|
@@ -359,27 +338,26 @@ files:
|
|
359
338
|
homepage: http://thoughtbot.com/community/
|
360
339
|
licenses:
|
361
340
|
- MIT
|
341
|
+
metadata: {}
|
362
342
|
post_install_message:
|
363
343
|
rdoc_options: []
|
364
344
|
require_paths:
|
365
345
|
- lib
|
366
346
|
required_ruby_version: !ruby/object:Gem::Requirement
|
367
|
-
none: false
|
368
347
|
requirements:
|
369
|
-
- -
|
348
|
+
- - '>='
|
370
349
|
- !ruby/object:Gem::Version
|
371
350
|
version: 1.9.2
|
372
351
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
373
|
-
none: false
|
374
352
|
requirements:
|
375
|
-
- -
|
353
|
+
- - '>'
|
376
354
|
- !ruby/object:Gem::Version
|
377
355
|
version: 1.3.1
|
378
356
|
requirements: []
|
379
357
|
rubyforge_project:
|
380
|
-
rubygems_version:
|
358
|
+
rubygems_version: 2.0.3
|
381
359
|
signing_key:
|
382
|
-
specification_version:
|
360
|
+
specification_version: 4
|
383
361
|
summary: Making tests easy on the fingers and eyes
|
384
362
|
test_files:
|
385
363
|
- features/activemodel_integration.feature
|