shoulda-matchers 4.5.1 → 5.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +15 -13
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +0 -87
- data/lib/shoulda/matchers/action_controller/flash_store.rb +2 -4
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +3 -6
- data/lib/shoulda/matchers/active_model/helpers.rb +1 -1
- 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/qualifiers/allow_blank.rb +26 -0
- data/lib/shoulda/matchers/active_model/qualifiers.rb +1 -0
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +14 -2
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +6 -4
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +47 -1
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +31 -6
- data/lib/shoulda/matchers/active_model/validator.rb +1 -6
- data/lib/shoulda/matchers/active_model.rb +2 -1
- data/lib/shoulda/matchers/active_record/association_matcher.rb +20 -22
- data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +125 -22
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +21 -3
- data/lib/shoulda/matchers/rails_shim.rb +14 -39
- data/lib/shoulda/matchers/util/word_wrap.rb +2 -2
- data/lib/shoulda/matchers/version.rb +1 -1
- data/shoulda-matchers.gemspec +3 -3
- metadata +10 -8
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +0 -161
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
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# Shoulda Matchers [![Gem Version][version-badge]][rubygems] [![Build Status][
|
1
|
+
# Shoulda Matchers [![Gem Version][version-badge]][rubygems] [![Build Status][github-actions-badge]][github-actions] [![Total Downloads][downloads-total]][rubygems] [![Downloads][downloads-badge]][rubygems]
|
2
2
|
|
3
3
|
[version-badge]: https://img.shields.io/gem/v/shoulda-matchers.svg
|
4
4
|
[rubygems]: https://rubygems.org/gems/shoulda-matchers
|
5
|
-
[
|
6
|
-
[
|
5
|
+
[github-actions-badge]: https://img.shields.io/github/workflow/status/thoughtbot/shoulda-matchers/Test
|
6
|
+
[github-actions]: https://github.com/thoughtbot/shoulda-matchers/actions
|
7
7
|
[downloads-total]: https://img.shields.io/gem/dt/shoulda-matchers.svg
|
8
8
|
[downloads-badge]: https://img.shields.io/gem/dtv/shoulda-matchers.svg
|
9
9
|
[downloads-badge]: https://img.shields.io/gem/dtv/shoulda-matchers.svg
|
@@ -19,7 +19,7 @@ complex, and error-prone.
|
|
19
19
|
|
20
20
|
## Quick links
|
21
21
|
|
22
|
-
📖 **[Read the documentation for the latest version][rubydocs].**
|
22
|
+
📖 **[Read the documentation for the latest version][rubydocs].**
|
23
23
|
📢 **[See what's changed in recent versions][changelog].**
|
24
24
|
|
25
25
|
[rubydocs]: https://matchers.shoulda.io/docs
|
@@ -55,7 +55,7 @@ Start by including `shoulda-matchers` in your Gemfile:
|
|
55
55
|
|
56
56
|
```ruby
|
57
57
|
group :test do
|
58
|
-
gem 'shoulda-matchers', '~>
|
58
|
+
gem 'shoulda-matchers', '~> 5.0'
|
59
59
|
end
|
60
60
|
```
|
61
61
|
|
@@ -117,7 +117,7 @@ Otherwise, add `shoulda-matchers` to your Gemfile:
|
|
117
117
|
|
118
118
|
```ruby
|
119
119
|
group :test do
|
120
|
-
gem 'shoulda-matchers', '~>
|
120
|
+
gem 'shoulda-matchers', '~> 5.0'
|
121
121
|
end
|
122
122
|
```
|
123
123
|
|
@@ -430,11 +430,11 @@ about any of them, make sure to [consult the documentation][rubydocs]!
|
|
430
430
|
makes assertions on the `session` hash.
|
431
431
|
* **[set_flash](lib/shoulda/matchers/action_controller/set_flash_matcher.rb)**
|
432
432
|
makes assertions on the `flash` hash.
|
433
|
-
* **[use_after_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#
|
433
|
+
* **[use_after_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L29)**
|
434
434
|
tests that an `after_action` callback is defined in your controller.
|
435
|
-
* **[use_around_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#
|
435
|
+
* **[use_around_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L75)**
|
436
436
|
tests that an `around_action` callback is defined in your controller.
|
437
|
-
* **[use_before_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#
|
437
|
+
* **[use_before_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L4)**
|
438
438
|
tests that a `before_action` callback is defined in your controller.
|
439
439
|
|
440
440
|
### Routing matchers
|
@@ -468,12 +468,14 @@ machine, understanding the codebase, and creating a good pull request.
|
|
468
468
|
|
469
469
|
## Compatibility
|
470
470
|
|
471
|
-
Shoulda Matchers is
|
472
|
-
|
471
|
+
Shoulda Matchers is tested and supported against Ruby 2.6+, Rails
|
472
|
+
5.2+, RSpec 3.x, and Minitest 5.x.
|
473
473
|
|
474
|
-
For Ruby < 2.4 and Rails < 4.1 compatibility, please use [v3.1.3][v3.1.3].
|
474
|
+
- For Ruby < 2.4 and Rails < 4.1 compatibility, please use [v3.1.3][v3.1.3].
|
475
|
+
- For Ruby < 3.0 and Rails < 6.1 compatibility, please use [v4.5.1][v4.5.1].
|
475
476
|
|
476
477
|
[v3.1.3]: https://github.com/thoughtbot/shoulda-matchers/tree/v3.1.3
|
478
|
+
[v4.5.1]: https://github.com/thoughtbot/shoulda-matchers/tree/v4.5.1
|
477
479
|
|
478
480
|
## Versioning
|
479
481
|
|
@@ -490,7 +492,7 @@ Albuk][guialbuk].
|
|
490
492
|
|
491
493
|
## Copyright/License
|
492
494
|
|
493
|
-
Shoulda Matchers is copyright © 2006-
|
495
|
+
Shoulda Matchers is copyright © 2006-2022 Tammer Saleh and [thoughtbot,
|
494
496
|
inc][thoughtbot-website]. It is free and opensource software and may be
|
495
497
|
redistributed under the terms specified in the [LICENSE](LICENSE) file.
|
496
498
|
|
@@ -1,64 +1,6 @@
|
|
1
1
|
module Shoulda
|
2
2
|
module Matchers
|
3
3
|
module ActionController
|
4
|
-
# The `use_before_filter` matcher is used to test that a before_filter
|
5
|
-
# callback is defined within your controller.
|
6
|
-
#
|
7
|
-
# class UsersController < ApplicationController
|
8
|
-
# before_filter :authenticate_user!
|
9
|
-
# end
|
10
|
-
#
|
11
|
-
# # RSpec
|
12
|
-
# RSpec.describe UsersController, type: :controller do
|
13
|
-
# it { should use_before_filter(:authenticate_user!) }
|
14
|
-
# it { should_not use_before_filter(:prevent_ssl) }
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# # Minitest (Shoulda)
|
18
|
-
# class UsersControllerTest < ActionController::TestCase
|
19
|
-
# should use_before_filter(:authenticate_user!)
|
20
|
-
# should_not use_before_filter(:prevent_ssl)
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# @note This method is only available when using shoulda-matchers under
|
24
|
-
# Rails 4.x.
|
25
|
-
# @return [CallbackMatcher]
|
26
|
-
#
|
27
|
-
if RailsShim.action_pack_lt_5?
|
28
|
-
def use_before_filter(callback)
|
29
|
-
CallbackMatcher.new(callback, :before, :filter)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# The `use_after_filter` matcher is used to test that an after_filter
|
34
|
-
# callback is defined within your controller.
|
35
|
-
#
|
36
|
-
# class IssuesController < ApplicationController
|
37
|
-
# after_filter :log_activity
|
38
|
-
# end
|
39
|
-
#
|
40
|
-
# # RSpec
|
41
|
-
# RSpec.describe IssuesController, type: :controller do
|
42
|
-
# it { should use_after_filter(:log_activity) }
|
43
|
-
# it { should_not use_after_filter(:destroy_user) }
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
# # Minitest (Shoulda)
|
47
|
-
# class IssuesControllerTest < ActionController::TestCase
|
48
|
-
# should use_after_filter(:log_activity)
|
49
|
-
# should_not use_after_filter(:destroy_user)
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
# @note This method is only available when using shoulda-matchers under
|
53
|
-
# Rails 4.x.
|
54
|
-
# @return [CallbackMatcher]
|
55
|
-
#
|
56
|
-
if RailsShim.action_pack_lt_5?
|
57
|
-
def use_after_filter(callback)
|
58
|
-
CallbackMatcher.new(callback, :after, :filter)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
4
|
# The `use_before_action` matcher is used to test that a before_action
|
63
5
|
# callback is defined within your controller.
|
64
6
|
#
|
@@ -109,35 +51,6 @@ module Shoulda
|
|
109
51
|
CallbackMatcher.new(callback, :after, :action)
|
110
52
|
end
|
111
53
|
|
112
|
-
# The `use_around_filter` matcher is used to test that an around_filter
|
113
|
-
# callback is defined within your controller.
|
114
|
-
#
|
115
|
-
# class ChangesController < ApplicationController
|
116
|
-
# around_filter :wrap_in_transaction
|
117
|
-
# end
|
118
|
-
#
|
119
|
-
# # RSpec
|
120
|
-
# RSpec.describe ChangesController, type: :controller do
|
121
|
-
# it { should use_around_filter(:wrap_in_transaction) }
|
122
|
-
# it { should_not use_around_filter(:save_view_context) }
|
123
|
-
# end
|
124
|
-
#
|
125
|
-
# # Minitest (Shoulda)
|
126
|
-
# class ChangesControllerTest < ActionController::TestCase
|
127
|
-
# should use_around_filter(:wrap_in_transaction)
|
128
|
-
# should_not use_around_filter(:save_view_context)
|
129
|
-
# end
|
130
|
-
#
|
131
|
-
# @note This method is only available when using shoulda-matchers under
|
132
|
-
# Rails 4.x.
|
133
|
-
# @return [CallbackMatcher]
|
134
|
-
#
|
135
|
-
if RailsShim.action_pack_lt_5?
|
136
|
-
def use_around_filter(callback)
|
137
|
-
CallbackMatcher.new(callback, :around, :filter)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
54
|
# The `use_around_action` matcher is used to test that an around_action
|
142
55
|
# callback is defined within your controller.
|
143
56
|
#
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
1
2
|
module Shoulda
|
2
3
|
module Matchers
|
3
4
|
module ActionController
|
@@ -34,10 +35,7 @@ module Shoulda
|
|
34
35
|
expected_value === actual_value
|
35
36
|
end
|
36
37
|
end
|
37
|
-
|
38
|
-
def empty?
|
39
|
-
flash.empty?
|
40
|
-
end
|
38
|
+
delegate :empty?, to: :flash
|
41
39
|
|
42
40
|
def use_now!
|
43
41
|
@use_now = true
|
@@ -251,12 +251,9 @@ module Shoulda
|
|
251
251
|
parameters_double_registry.register
|
252
252
|
|
253
253
|
Doublespeak.with_doubles_activated do
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
action,
|
258
|
-
request_params,
|
259
|
-
)
|
254
|
+
params = { params: request_params }
|
255
|
+
|
256
|
+
context.__send__(verb, action, **params)
|
260
257
|
end
|
261
258
|
|
262
259
|
unpermitted_parameter_names.empty?
|
@@ -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
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActiveModel
|
4
|
+
module Qualifiers
|
5
|
+
# @private
|
6
|
+
module AllowBlank
|
7
|
+
def initialize(*args)
|
8
|
+
super
|
9
|
+
@expects_to_allow_blank = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def allow_blank
|
13
|
+
@expects_to_allow_blank = true
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def expects_to_allow_blank?
|
20
|
+
@expects_to_allow_blank
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -108,14 +108,17 @@ module Shoulda
|
|
108
108
|
obj
|
109
109
|
end
|
110
110
|
elsif array_column?
|
111
|
-
['an
|
111
|
+
['an arbitrary value']
|
112
|
+
elsif enum_column?
|
113
|
+
enum_values.first
|
112
114
|
else
|
113
115
|
case column_type
|
114
116
|
when :integer, :float then 1
|
115
117
|
when :decimal then BigDecimal(1, 0)
|
116
|
-
when :datetime, :time, :timestamp then Time.
|
118
|
+
when :datetime, :time, :timestamp then Time.current
|
117
119
|
when :date then Date.new
|
118
120
|
when :binary then '0'
|
121
|
+
when :uuid then SecureRandom.uuid
|
119
122
|
else 'an arbitrary value'
|
120
123
|
end
|
121
124
|
end
|
@@ -145,6 +148,15 @@ module Shoulda
|
|
145
148
|
@subject.class.columns_hash[@attribute.to_s].respond_to?(:array) &&
|
146
149
|
@subject.class.columns_hash[@attribute.to_s].array
|
147
150
|
end
|
151
|
+
|
152
|
+
def enum_column?
|
153
|
+
@subject.class.respond_to?(:defined_enums) &&
|
154
|
+
@subject.class.defined_enums.key?(@attribute.to_s)
|
155
|
+
end
|
156
|
+
|
157
|
+
def enum_values
|
158
|
+
@subject.class.defined_enums[@attribute.to_s].values
|
159
|
+
end
|
148
160
|
end
|
149
161
|
end
|
150
162
|
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)
|
@@ -355,7 +357,7 @@ EOT
|
|
355
357
|
description = "validate that :#{@attribute}"
|
356
358
|
|
357
359
|
description <<
|
358
|
-
if @array.
|
360
|
+
if @array.count > 1
|
359
361
|
" is either #{inspected_array}"
|
360
362
|
else
|
361
363
|
" is #{inspected_array}"
|
@@ -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
|
@@ -643,7 +681,7 @@ module Shoulda
|
|
643
681
|
if number_of_submatchers_for_failure_message > 1
|
644
682
|
"In checking that #{model.name} #{submatcher_description}, " +
|
645
683
|
failure_message[0].downcase +
|
646
|
-
failure_message[1
|
684
|
+
failure_message[1..]
|
647
685
|
else
|
648
686
|
failure_message
|
649
687
|
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
|