shoulda-matchers 5.2.0 → 5.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/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +13 -34
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +3 -5
- data/lib/shoulda/matchers/active_model/numericality_matchers/range_matcher.rb +71 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/submatchers.rb +43 -0
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +2 -1
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +5 -3
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +46 -0
- data/lib/shoulda/matchers/active_model.rb +2 -0
- data/lib/shoulda/matchers/rails_shim.rb +2 -2
- data/lib/shoulda/matchers/util/word_wrap.rb +1 -1
- data/lib/shoulda/matchers/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d083d22f49f99bf60d6c6bdfed7ea08ea1f838a90b4aed439d84108ebc814af9
|
4
|
+
data.tar.gz: 90cc8440d8c63da1c338306b3d9f129cc9af8dc1a80277d9e7f5b233f2bbe115
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09b1dcf7e19179b50992d34cf73a86e72727cf27a1db911f2adb98fe291dc4d3d711da962d3efdbec60d2b1f280dcecd441e725a7e6a701a152ff60fdd8e340c'
|
7
|
+
data.tar.gz: 8ba54626246e133cfd86b84aba3d3b05487166d6359b2ba97256af242a057b5ff6cd40d5eae35bd35f619c9a9b0f39cc2c8b6508e299b44e2605e3cdf4f64078
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
2
|
+
|
1
3
|
module Shoulda
|
2
4
|
module Matchers
|
3
5
|
module ActiveModel
|
@@ -31,6 +33,8 @@ module Shoulda
|
|
31
33
|
},
|
32
34
|
}.freeze
|
33
35
|
|
36
|
+
delegate :failure_message, :failure_message_when_negated, to: :submatchers
|
37
|
+
|
34
38
|
def initialize(numericality_matcher, value, operator)
|
35
39
|
super(nil)
|
36
40
|
unless numericality_matcher.respond_to? :diff_to_compare
|
@@ -72,49 +76,24 @@ module Shoulda
|
|
72
76
|
|
73
77
|
def matches?(subject)
|
74
78
|
@subject = subject
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
|
-
def failure_message
|
79
|
-
last_failing_submatcher.failure_message
|
80
|
-
end
|
81
|
-
|
82
|
-
def failure_message_when_negated
|
83
|
-
last_failing_submatcher.failure_message_when_negated
|
79
|
+
submatchers.matches?(subject)
|
84
80
|
end
|
85
81
|
|
86
82
|
def comparison_description
|
87
83
|
"#{comparison_expectation} #{@value}"
|
88
84
|
end
|
89
85
|
|
90
|
-
private
|
91
|
-
|
92
|
-
def all_bounds_correct?
|
93
|
-
failing_submatchers.empty?
|
94
|
-
end
|
95
|
-
|
96
|
-
def failing_submatchers
|
97
|
-
submatchers_and_results.
|
98
|
-
select { |x| !x[:matched] }.
|
99
|
-
map { |x| x[:matcher] }
|
100
|
-
end
|
101
|
-
|
102
|
-
def last_failing_submatcher
|
103
|
-
failing_submatchers.last
|
104
|
-
end
|
105
|
-
|
106
86
|
def submatchers
|
107
|
-
@_submatchers ||=
|
108
|
-
comparison_combos.map do |diff, submatcher_method_name|
|
109
|
-
matcher = __send__(submatcher_method_name, diff, nil)
|
110
|
-
matcher.with_message(@message, values: { count: @value })
|
111
|
-
matcher
|
112
|
-
end
|
87
|
+
@_submatchers ||= NumericalityMatchers::Submatchers.new(build_submatchers)
|
113
88
|
end
|
114
89
|
|
115
|
-
|
116
|
-
|
117
|
-
|
90
|
+
private
|
91
|
+
|
92
|
+
def build_submatchers
|
93
|
+
comparison_combos.map do |diff, submatcher_method_name|
|
94
|
+
matcher = __send__(submatcher_method_name, diff, nil)
|
95
|
+
matcher.with_message(@message, values: { count: @value })
|
96
|
+
matcher
|
118
97
|
end
|
119
98
|
end
|
120
99
|
|
@@ -55,11 +55,9 @@ module Shoulda
|
|
55
55
|
private
|
56
56
|
|
57
57
|
def disallow_value_matcher
|
58
|
-
@_disallow_value_matcher ||=
|
59
|
-
|
60
|
-
|
61
|
-
wrap_disallow_value_matcher(matcher)
|
62
|
-
end
|
58
|
+
@_disallow_value_matcher ||= DisallowValueMatcher.new(disallowed_value).tap do |matcher|
|
59
|
+
matcher.for(attribute)
|
60
|
+
wrap_disallow_value_matcher(matcher)
|
63
61
|
end
|
64
62
|
end
|
65
63
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
2
|
+
|
3
|
+
module Shoulda
|
4
|
+
module Matchers
|
5
|
+
module ActiveModel
|
6
|
+
module NumericalityMatchers
|
7
|
+
# @private
|
8
|
+
class RangeMatcher < ValidationMatcher
|
9
|
+
OPERATORS = [:>=, :<=].freeze
|
10
|
+
|
11
|
+
delegate :failure_message, to: :submatchers
|
12
|
+
|
13
|
+
def initialize(numericality_matcher, attribute, range)
|
14
|
+
super(attribute)
|
15
|
+
unless numericality_matcher.respond_to? :diff_to_compare
|
16
|
+
raise ArgumentError, 'numericality_matcher is invalid'
|
17
|
+
end
|
18
|
+
|
19
|
+
@numericality_matcher = numericality_matcher
|
20
|
+
@range = range
|
21
|
+
@attribute = attribute
|
22
|
+
end
|
23
|
+
|
24
|
+
def matches?(subject)
|
25
|
+
@subject = subject
|
26
|
+
submatchers.matches?(subject)
|
27
|
+
end
|
28
|
+
|
29
|
+
def simple_description
|
30
|
+
description = ''
|
31
|
+
|
32
|
+
if expects_strict?
|
33
|
+
description << ' strictly'
|
34
|
+
end
|
35
|
+
|
36
|
+
description +
|
37
|
+
"disallow :#{attribute} from being a number that is not " +
|
38
|
+
range_description
|
39
|
+
end
|
40
|
+
|
41
|
+
def range_description
|
42
|
+
"from #{Shoulda::Matchers::Util.inspect_range(@range)}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def submatchers
|
46
|
+
@_submatchers ||= NumericalityMatchers::Submatchers.new(build_submatchers)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def build_submatchers
|
52
|
+
submatcher_combos.map do |value, operator|
|
53
|
+
build_comparison_submatcher(value, operator)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def submatcher_combos
|
58
|
+
@range.minmax.zip(OPERATORS)
|
59
|
+
end
|
60
|
+
|
61
|
+
def build_comparison_submatcher(value, operator)
|
62
|
+
NumericalityMatchers::ComparisonMatcher.new(@numericality_matcher, value, operator).
|
63
|
+
for(@attribute).
|
64
|
+
with_message(@message).
|
65
|
+
on(@context)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActiveModel
|
4
|
+
module NumericalityMatchers
|
5
|
+
# @private
|
6
|
+
class Submatchers
|
7
|
+
def initialize(submatchers)
|
8
|
+
@submatchers = submatchers
|
9
|
+
end
|
10
|
+
|
11
|
+
def matches?(subject)
|
12
|
+
@subject = subject
|
13
|
+
failing_submatchers.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
def failure_message
|
17
|
+
last_failing_submatcher.failure_message
|
18
|
+
end
|
19
|
+
|
20
|
+
def failure_message_when_negated
|
21
|
+
last_failing_submatcher.failure_message_when_negated
|
22
|
+
end
|
23
|
+
|
24
|
+
def add(submatcher)
|
25
|
+
@submatchers << submatcher
|
26
|
+
end
|
27
|
+
|
28
|
+
def last_failing_submatcher
|
29
|
+
failing_submatchers.last
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def failing_submatchers
|
35
|
+
@_failing_submatchers ||= @submatchers.reject do |submatcher|
|
36
|
+
submatcher.matches?(@subject)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -108,7 +108,7 @@ module Shoulda
|
|
108
108
|
obj
|
109
109
|
end
|
110
110
|
elsif array_column?
|
111
|
-
['an
|
111
|
+
['an arbitrary value']
|
112
112
|
elsif enum_column?
|
113
113
|
enum_values.first
|
114
114
|
else
|
@@ -118,6 +118,7 @@ module Shoulda
|
|
118
118
|
when :datetime, :time, :timestamp then Time.current
|
119
119
|
when :date then Date.new
|
120
120
|
when :binary then '0'
|
121
|
+
when :uuid then SecureRandom.uuid
|
121
122
|
else 'an arbitrary value'
|
122
123
|
end
|
123
124
|
end
|
@@ -33,9 +33,9 @@ module Shoulda
|
|
33
33
|
#
|
34
34
|
# class Game
|
35
35
|
# include ActiveModel::Model
|
36
|
-
# attr_accessor :
|
36
|
+
# attr_accessor :floors_with_enemies
|
37
37
|
#
|
38
|
-
# validates_exclusion_of :
|
38
|
+
# validates_exclusion_of :floors_with_enemies, in: 5..8
|
39
39
|
# end
|
40
40
|
#
|
41
41
|
# # RSpec
|
@@ -3,6 +3,8 @@ require 'date'
|
|
3
3
|
|
4
4
|
module Shoulda
|
5
5
|
module Matchers
|
6
|
+
class ExampleClass; end
|
7
|
+
|
6
8
|
module ActiveModel
|
7
9
|
# The `validate_inclusion_of` matcher tests usage of the
|
8
10
|
# `validates_inclusion_of` validation, asserting that an attribute can
|
@@ -43,12 +45,12 @@ module Shoulda
|
|
43
45
|
#
|
44
46
|
# # RSpec
|
45
47
|
# RSpec.describe Issue, type: :model do
|
46
|
-
# it { should validate_inclusion_of(:
|
48
|
+
# it { should validate_inclusion_of(:priority).in_range(1..5) }
|
47
49
|
# end
|
48
50
|
#
|
49
51
|
# # Minitest (Shoulda)
|
50
52
|
# class IssueTest < ActiveSupport::TestCase
|
51
|
-
# should validate_inclusion_of(:
|
53
|
+
# should validate_inclusion_of(:priority).in_range(1..5)
|
52
54
|
# end
|
53
55
|
#
|
54
56
|
# #### Caveats
|
@@ -269,7 +271,7 @@ module Shoulda
|
|
269
271
|
# @private
|
270
272
|
class ValidateInclusionOfMatcher < ValidationMatcher
|
271
273
|
BLANK_VALUES = ['', ' ', "\n", "\r", "\t", "\f"].freeze
|
272
|
-
ARBITRARY_OUTSIDE_STRING =
|
274
|
+
ARBITRARY_OUTSIDE_STRING = Shoulda::Matchers::ExampleClass.name
|
273
275
|
ARBITRARY_OUTSIDE_INTEGER = 123456789
|
274
276
|
ARBITRARY_OUTSIDE_DECIMAL = BigDecimal('0.123456789')
|
275
277
|
ARBITRARY_OUTSIDE_DATE = Date.jd(9999999)
|
@@ -276,6 +276,33 @@ module Shoulda
|
|
276
276
|
# should validate_numericality_of(:birth_day).odd
|
277
277
|
# end
|
278
278
|
#
|
279
|
+
# ##### is_in
|
280
|
+
#
|
281
|
+
# Use `is_in` to test usage of the `:in` option.
|
282
|
+
# This asserts that the attribute can take a number which is contained
|
283
|
+
# in the given range.
|
284
|
+
#
|
285
|
+
# class Person
|
286
|
+
# include ActiveModel::Model
|
287
|
+
# attr_accessor :legal_age
|
288
|
+
#
|
289
|
+
# validates_numericality_of :birth_month, in: 1..12
|
290
|
+
# end
|
291
|
+
#
|
292
|
+
# # RSpec
|
293
|
+
# RSpec.describe Person, type: :model do
|
294
|
+
# it do
|
295
|
+
# should validate_numericality_of(:birth_month).
|
296
|
+
# is_in(1..12)
|
297
|
+
# end
|
298
|
+
# end
|
299
|
+
#
|
300
|
+
# # Minitest (Shoulda)
|
301
|
+
# class PersonTest < ActiveSupport::TestCase
|
302
|
+
# should validate_numericality_of(:birth_month).
|
303
|
+
# is_in(1..12)
|
304
|
+
# end
|
305
|
+
#
|
279
306
|
# ##### with_message
|
280
307
|
#
|
281
308
|
# Use `with_message` if you are using a custom validation message.
|
@@ -426,6 +453,13 @@ module Shoulda
|
|
426
453
|
self
|
427
454
|
end
|
428
455
|
|
456
|
+
def is_in(range)
|
457
|
+
prepare_submatcher(
|
458
|
+
NumericalityMatchers::RangeMatcher.new(self, @attribute, range),
|
459
|
+
)
|
460
|
+
self
|
461
|
+
end
|
462
|
+
|
429
463
|
def with_message(message)
|
430
464
|
@expects_custom_validation_message = true
|
431
465
|
@expected_message = message
|
@@ -457,6 +491,10 @@ module Shoulda
|
|
457
491
|
description << "validate that :#{@attribute} looks like "
|
458
492
|
description << Shoulda::Matchers::Util.a_or_an(full_allowed_type)
|
459
493
|
|
494
|
+
if range_description.present?
|
495
|
+
description << " #{range_description}"
|
496
|
+
end
|
497
|
+
|
460
498
|
if comparison_descriptions.present?
|
461
499
|
description << " #{comparison_descriptions}"
|
462
500
|
end
|
@@ -673,6 +711,14 @@ module Shoulda
|
|
673
711
|
end
|
674
712
|
end
|
675
713
|
|
714
|
+
def range_description
|
715
|
+
range_submatcher = @submatchers.detect do |submatcher|
|
716
|
+
submatcher.respond_to? :range_description
|
717
|
+
end
|
718
|
+
|
719
|
+
range_submatcher&.range_description
|
720
|
+
end
|
721
|
+
|
676
722
|
def model
|
677
723
|
@subject.class
|
678
724
|
end
|
@@ -26,6 +26,8 @@ require 'shoulda/matchers/active_model/numericality_matchers/comparison_matcher'
|
|
26
26
|
require 'shoulda/matchers/active_model/numericality_matchers/odd_number_matcher'
|
27
27
|
require 'shoulda/matchers/active_model/numericality_matchers/even_number_matcher'
|
28
28
|
require 'shoulda/matchers/active_model/numericality_matchers/only_integer_matcher'
|
29
|
+
require 'shoulda/matchers/active_model/numericality_matchers/range_matcher'
|
30
|
+
require 'shoulda/matchers/active_model/numericality_matchers/submatchers'
|
29
31
|
require 'shoulda/matchers/active_model/errors'
|
30
32
|
require 'shoulda/matchers/active_model/have_secure_password_matcher'
|
31
33
|
|
@@ -25,8 +25,8 @@ module Shoulda
|
|
25
25
|
Gem::Version.new('0')
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
29
|
-
Gem::Requirement.new('
|
28
|
+
def active_model_st_6_1?
|
29
|
+
Gem::Requirement.new('< 6.1').satisfied_by?(active_model_version)
|
30
30
|
end
|
31
31
|
|
32
32
|
def active_model_lt_7?
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shoulda-matchers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tammer Saleh
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2022-
|
17
|
+
date: 2022-12-16 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: activesupport
|
@@ -79,6 +79,8 @@ files:
|
|
79
79
|
- lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb
|
80
80
|
- lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb
|
81
81
|
- lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb
|
82
|
+
- lib/shoulda/matchers/active_model/numericality_matchers/range_matcher.rb
|
83
|
+
- lib/shoulda/matchers/active_model/numericality_matchers/submatchers.rb
|
82
84
|
- lib/shoulda/matchers/active_model/qualifiers.rb
|
83
85
|
- lib/shoulda/matchers/active_model/qualifiers/allow_blank.rb
|
84
86
|
- lib/shoulda/matchers/active_model/qualifiers/allow_nil.rb
|
@@ -193,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
193
195
|
- !ruby/object:Gem::Version
|
194
196
|
version: '0'
|
195
197
|
requirements: []
|
196
|
-
rubygems_version: 3.
|
198
|
+
rubygems_version: 3.3.7
|
197
199
|
signing_key:
|
198
200
|
specification_version: 4
|
199
201
|
summary: Simple one-liner tests for common Rails functionality
|