stannum 0.1.0 → 0.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/CHANGELOG.md +32 -0
- data/README.md +85 -21
- data/config/locales/en.rb +17 -3
- data/lib/stannum/constraints/base.rb +11 -4
- data/lib/stannum/constraints/hashes/extra_keys.rb +10 -2
- data/lib/stannum/constraints/hashes/indifferent_extra_keys.rb +47 -0
- data/lib/stannum/constraints/hashes.rb +6 -2
- data/lib/stannum/constraints/parameters/extra_arguments.rb +23 -0
- data/lib/stannum/constraints/parameters/extra_keywords.rb +29 -0
- data/lib/stannum/constraints/parameters.rb +11 -0
- data/lib/stannum/constraints/properties/base.rb +124 -0
- data/lib/stannum/constraints/properties/do_not_match_property.rb +117 -0
- data/lib/stannum/constraints/properties/match_property.rb +117 -0
- data/lib/stannum/constraints/properties/matching.rb +112 -0
- data/lib/stannum/constraints/properties.rb +17 -0
- data/lib/stannum/constraints/tuples/extra_items.rb +1 -1
- data/lib/stannum/constraints/type.rb +1 -1
- data/lib/stannum/constraints/types/hash_type.rb +6 -2
- data/lib/stannum/constraints.rb +2 -0
- data/lib/stannum/contracts/builder.rb +13 -2
- data/lib/stannum/contracts/hash_contract.rb +14 -0
- data/lib/stannum/contracts/indifferent_hash_contract.rb +13 -0
- data/lib/stannum/contracts/parameters/arguments_contract.rb +2 -7
- data/lib/stannum/contracts/parameters/keywords_contract.rb +2 -7
- data/lib/stannum/contracts/tuple_contract.rb +1 -1
- data/lib/stannum/entities/attributes.rb +218 -0
- data/lib/stannum/entities/constraints.rb +177 -0
- data/lib/stannum/entities/properties.rb +186 -0
- data/lib/stannum/entities.rb +13 -0
- data/lib/stannum/entity.rb +83 -0
- data/lib/stannum/errors.rb +3 -3
- data/lib/stannum/messages/default_loader.rb +95 -0
- data/lib/stannum/messages/default_strategy.rb +31 -50
- data/lib/stannum/messages.rb +1 -0
- data/lib/stannum/rspec/match_errors_matcher.rb +6 -6
- data/lib/stannum/rspec/validate_parameter_matcher.rb +10 -9
- data/lib/stannum/schema.rb +78 -37
- data/lib/stannum/struct.rb +12 -346
- data/lib/stannum/support/coercion.rb +19 -0
- data/lib/stannum/version.rb +1 -1
- data/lib/stannum.rb +3 -0
- metadata +29 -19
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'stannum/constraints/properties'
|
4
|
+
require 'stannum/constraints/properties/matching'
|
5
|
+
|
6
|
+
module Stannum::Constraints::Properties
|
7
|
+
# Compares the properties of the given object with the specified property.
|
8
|
+
#
|
9
|
+
# If none of the property values equal the expected value, the constraint will
|
10
|
+
# match the object; otherwise, if there are any matching values, the
|
11
|
+
# constraint will not match.
|
12
|
+
#
|
13
|
+
# @example Using an Properties::Match constraint
|
14
|
+
# UpdatePassword = Struct.new(:old_password, :new_password)
|
15
|
+
# constraint = Stannum::Constraints::Properties::DoNotMatchProperty.new(
|
16
|
+
# :old_password,
|
17
|
+
# :new_password
|
18
|
+
# )
|
19
|
+
#
|
20
|
+
# params = UpdatePassword.new('tronlives', 'ifightfortheusers')
|
21
|
+
# constraint.matches?(params)
|
22
|
+
# #=> true
|
23
|
+
#
|
24
|
+
# params = UpdatePassword.new('tronlives', 'tronlives')
|
25
|
+
# constraint.matches?(params)
|
26
|
+
# #=> false
|
27
|
+
# constraint.errors_for(params)
|
28
|
+
# #=> [
|
29
|
+
# {
|
30
|
+
# path: [:confirmation],
|
31
|
+
# type: 'stannum.constraints.is_equal_to',
|
32
|
+
# data: { expected: '[FILTERED]', actual: '[FILTERED]' }
|
33
|
+
# }
|
34
|
+
# ]
|
35
|
+
class DoNotMatchProperty < Stannum::Constraints::Properties::Matching
|
36
|
+
# The :type of the error generated for a matching object.
|
37
|
+
NEGATED_TYPE = Stannum::Constraints::Equality::TYPE
|
38
|
+
|
39
|
+
# The :type of the error generated for a non-matching object.
|
40
|
+
TYPE = Stannum::Constraints::Equality::NEGATED_TYPE
|
41
|
+
|
42
|
+
# @return [true, false] true if the property values match the reference
|
43
|
+
# property value; otherwise false.
|
44
|
+
def does_not_match?(actual)
|
45
|
+
return false unless can_match_properties?(actual)
|
46
|
+
|
47
|
+
expected = expected_value(actual)
|
48
|
+
|
49
|
+
return false if skip_property?(expected)
|
50
|
+
|
51
|
+
each_non_matching_property(
|
52
|
+
actual: actual,
|
53
|
+
expected: expected,
|
54
|
+
include_all: true
|
55
|
+
)
|
56
|
+
.none?
|
57
|
+
end
|
58
|
+
|
59
|
+
# (see Stannum::Constraints::Base#errors_for)
|
60
|
+
def errors_for(actual, errors: nil)
|
61
|
+
errors ||= Stannum::Errors.new
|
62
|
+
|
63
|
+
return invalid_object_errors(errors) unless can_match_properties?(actual)
|
64
|
+
|
65
|
+
expected = expected_value(actual)
|
66
|
+
matching = each_matching_property(actual: actual, expected: expected)
|
67
|
+
|
68
|
+
return generic_errors(errors) if matching.count.zero?
|
69
|
+
|
70
|
+
matching.each do |property_name, _|
|
71
|
+
errors[property_name].add(type, message: message)
|
72
|
+
end
|
73
|
+
|
74
|
+
errors
|
75
|
+
end
|
76
|
+
|
77
|
+
# @return [true, false] false if any of the property values match the
|
78
|
+
# reference property value; otherwise true.
|
79
|
+
def matches?(actual)
|
80
|
+
return false unless can_match_properties?(actual)
|
81
|
+
|
82
|
+
expected = expected_value(actual)
|
83
|
+
|
84
|
+
return true if skip_property?(expected)
|
85
|
+
|
86
|
+
each_matching_property(actual: actual, expected: expected).none?
|
87
|
+
end
|
88
|
+
alias match? matches?
|
89
|
+
|
90
|
+
# (see Stannum::Constraints::Base#negated_errors_for)
|
91
|
+
def negated_errors_for(actual, errors: nil) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
92
|
+
errors ||= Stannum::Errors.new
|
93
|
+
|
94
|
+
return invalid_object_errors(errors) unless can_match_properties?(actual)
|
95
|
+
|
96
|
+
expected = expected_value(actual)
|
97
|
+
matching = each_non_matching_property(
|
98
|
+
actual: actual,
|
99
|
+
expected: expected,
|
100
|
+
include_all: true
|
101
|
+
)
|
102
|
+
|
103
|
+
return generic_errors(errors) if matching.count.zero?
|
104
|
+
|
105
|
+
matching.each do |property_name, value|
|
106
|
+
errors[property_name].add(
|
107
|
+
negated_type,
|
108
|
+
message: negated_message,
|
109
|
+
expected: filter_parameters? ? '[FILTERED]' : expected_value(actual),
|
110
|
+
actual: filter_parameters? ? '[FILTERED]' : value
|
111
|
+
)
|
112
|
+
end
|
113
|
+
|
114
|
+
errors
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'stannum/constraints/properties'
|
4
|
+
require 'stannum/constraints/properties/matching'
|
5
|
+
|
6
|
+
module Stannum::Constraints::Properties
|
7
|
+
# Compares the properties of the given object with the specified property.
|
8
|
+
#
|
9
|
+
# If all of the property values equal the expected value, the constraint will
|
10
|
+
# match the object; otherwise, if there are any non-matching values, the
|
11
|
+
# constraint will not match.
|
12
|
+
#
|
13
|
+
# @example Using an Properties::Match constraint
|
14
|
+
# ConfirmPassword = Struct.new(:password, :confirmation)
|
15
|
+
# constraint = Stannum::Constraints::Properties::MatchProperty.new(
|
16
|
+
# :password,
|
17
|
+
# :confirmation
|
18
|
+
# )
|
19
|
+
#
|
20
|
+
# params = ConfirmPassword.new('tronlives', 'ifightfortheusers')
|
21
|
+
# constraint.matches?(params)
|
22
|
+
# #=> false
|
23
|
+
# constraint.errors_for(params)
|
24
|
+
# #=> [
|
25
|
+
# {
|
26
|
+
# path: [:confirmation],
|
27
|
+
# type: 'stannum.constraints.is_not_equal_to',
|
28
|
+
# data: { expected: '[FILTERED]', actual: '[FILTERED]' }
|
29
|
+
# }
|
30
|
+
# ]
|
31
|
+
#
|
32
|
+
# params = ConfirmPassword.new('tronlives', 'tronlives')
|
33
|
+
# constraint.matches?(params)
|
34
|
+
# #=> true
|
35
|
+
class MatchProperty < Stannum::Constraints::Properties::Matching
|
36
|
+
# The :type of the error generated for a matching object.
|
37
|
+
NEGATED_TYPE = Stannum::Constraints::Equality::NEGATED_TYPE
|
38
|
+
|
39
|
+
# The :type of the error generated for a non-matching object.
|
40
|
+
TYPE = Stannum::Constraints::Equality::TYPE
|
41
|
+
|
42
|
+
# @return [true, false] false if any of the property values match the
|
43
|
+
# reference property value; otherwise true.
|
44
|
+
def does_not_match?(actual)
|
45
|
+
return false unless can_match_properties?(actual)
|
46
|
+
|
47
|
+
expected = expected_value(actual)
|
48
|
+
|
49
|
+
return false if skip_property?(expected)
|
50
|
+
|
51
|
+
each_matching_property(
|
52
|
+
actual: actual,
|
53
|
+
expected: expected,
|
54
|
+
include_all: true
|
55
|
+
)
|
56
|
+
.none?
|
57
|
+
end
|
58
|
+
|
59
|
+
# (see Stannum::Constraints::Base#errors_for)
|
60
|
+
def errors_for(actual, errors: nil) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
61
|
+
errors ||= Stannum::Errors.new
|
62
|
+
|
63
|
+
return invalid_object_errors(errors) unless can_match_properties?(actual)
|
64
|
+
|
65
|
+
expected = expected_value(actual)
|
66
|
+
matching = each_non_matching_property(actual: actual, expected: expected)
|
67
|
+
|
68
|
+
return generic_errors(errors) if matching.count.zero?
|
69
|
+
|
70
|
+
matching.each do |property_name, value|
|
71
|
+
errors[property_name].add(
|
72
|
+
type,
|
73
|
+
message: message,
|
74
|
+
expected: filter_parameters? ? '[FILTERED]' : expected_value(actual),
|
75
|
+
actual: filter_parameters? ? '[FILTERED]' : value
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
errors
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [true, false] true if the property values match the reference
|
83
|
+
# property value; otherwise false.
|
84
|
+
def matches?(actual)
|
85
|
+
return false unless can_match_properties?(actual)
|
86
|
+
|
87
|
+
expected = expected_value(actual)
|
88
|
+
|
89
|
+
return true if skip_property?(expected)
|
90
|
+
|
91
|
+
each_non_matching_property(actual: actual, expected: expected).none?
|
92
|
+
end
|
93
|
+
alias match? matches?
|
94
|
+
|
95
|
+
# (see Stannum::Constraints::Base#negated_errors_for)
|
96
|
+
def negated_errors_for(actual, errors: nil) # rubocop:disable Metrics/MethodLength
|
97
|
+
errors ||= Stannum::Errors.new
|
98
|
+
|
99
|
+
return invalid_object_errors(errors) unless can_match_properties?(actual)
|
100
|
+
|
101
|
+
expected = expected_value(actual)
|
102
|
+
matching = each_matching_property(
|
103
|
+
actual: actual,
|
104
|
+
expected: expected,
|
105
|
+
include_all: true
|
106
|
+
)
|
107
|
+
|
108
|
+
return generic_errors(errors) if matching.count.zero?
|
109
|
+
|
110
|
+
matching.each do |property_name, _|
|
111
|
+
errors[property_name].add(negated_type, message: negated_message)
|
112
|
+
end
|
113
|
+
|
114
|
+
errors
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'stannum/constraints/properties'
|
4
|
+
require 'stannum/constraints/properties/base'
|
5
|
+
|
6
|
+
module Stannum::Constraints::Properties
|
7
|
+
# Abstract base class for property matching constraints.
|
8
|
+
class Matching < Stannum::Constraints::Properties::Base
|
9
|
+
# @param reference_name [String, Symbol] the name of the reference property
|
10
|
+
# to compare to.
|
11
|
+
# @param property_names [Array<String, Symbol>] the name or names of the
|
12
|
+
# properties to compare.
|
13
|
+
# @param options [Hash<Symbol, Object>] configuration options for the
|
14
|
+
# constraint. Defaults to an empty Hash.
|
15
|
+
#
|
16
|
+
# @option options allow_empty [true, false] if true, will match against an
|
17
|
+
# object with empty property values, such as an empty string.
|
18
|
+
# @option options allow_nil [true, false] if true, will match against an
|
19
|
+
# object with nil property values.
|
20
|
+
def initialize(reference_name, *property_names, **options)
|
21
|
+
@reference_name = reference_name
|
22
|
+
|
23
|
+
validate_reference_name
|
24
|
+
|
25
|
+
super(*property_names, reference_name: reference_name, **options)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [String, Symbol] the name of the reference property to compare to.
|
29
|
+
attr_reader :reference_name
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def each_matching_property( # rubocop:disable Metrics/MethodLength
|
34
|
+
actual:,
|
35
|
+
expected:,
|
36
|
+
include_all: false,
|
37
|
+
&block
|
38
|
+
)
|
39
|
+
unless block_given?
|
40
|
+
return to_enum(
|
41
|
+
__method__,
|
42
|
+
actual: actual,
|
43
|
+
expected: expected,
|
44
|
+
include_all: include_all
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
enumerator = each_property(actual)
|
49
|
+
|
50
|
+
unless include_all
|
51
|
+
enumerator = enumerator.reject { |_, value| skip_property?(value) }
|
52
|
+
end
|
53
|
+
|
54
|
+
enumerator = enumerator.select { |_, value| valid?(expected, value) }
|
55
|
+
|
56
|
+
block_given? ? enumerator.each(&block) : enumerator
|
57
|
+
end
|
58
|
+
|
59
|
+
def each_non_matching_property( # rubocop:disable Metrics/MethodLength
|
60
|
+
actual:,
|
61
|
+
expected:,
|
62
|
+
include_all: false,
|
63
|
+
&block
|
64
|
+
)
|
65
|
+
unless block_given?
|
66
|
+
return to_enum(
|
67
|
+
__method__,
|
68
|
+
actual: actual,
|
69
|
+
expected: expected,
|
70
|
+
include_all: include_all
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
enumerator = each_property(actual)
|
75
|
+
|
76
|
+
unless include_all
|
77
|
+
enumerator = enumerator.reject { |_, value| skip_property?(value) }
|
78
|
+
end
|
79
|
+
|
80
|
+
enumerator = enumerator.reject { |_, value| valid?(expected, value) }
|
81
|
+
|
82
|
+
block_given? ? enumerator.each(&block) : enumerator
|
83
|
+
end
|
84
|
+
|
85
|
+
def expected_value(actual)
|
86
|
+
actual[reference_name]
|
87
|
+
end
|
88
|
+
|
89
|
+
def filter_parameters?
|
90
|
+
return @filter_parameters unless @filter_parameters.nil?
|
91
|
+
|
92
|
+
filters = filtered_parameters.map { |param| Regexp.new(param.to_s) }
|
93
|
+
|
94
|
+
@filter_parameters =
|
95
|
+
[reference_name, *property_names].any? do |property_name|
|
96
|
+
filters.any? { |filter| filter.match?(property_name.to_s) }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def generic_errors(errors)
|
101
|
+
errors.add(Stannum::Constraints::Base::NEGATED_TYPE)
|
102
|
+
end
|
103
|
+
|
104
|
+
def valid?(expected, value)
|
105
|
+
value == expected
|
106
|
+
end
|
107
|
+
|
108
|
+
def validate_reference_name
|
109
|
+
tools.assertions.validate_name(reference_name, as: 'reference name')
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'stannum/constraints'
|
4
|
+
|
5
|
+
module Stannum::Constraints
|
6
|
+
# Namespace for Object property-specific constraints.
|
7
|
+
module Properties
|
8
|
+
autoload :Base,
|
9
|
+
'stannum/constraints/properties/base'
|
10
|
+
autoload :DoNotMatchProperty,
|
11
|
+
'stannum/constraints/properties/do_not_match_property'
|
12
|
+
autoload :MatchProperty,
|
13
|
+
'stannum/constraints/properties/match_property'
|
14
|
+
autoload :Matching,
|
15
|
+
'stannum/constraints/properties/matching'
|
16
|
+
end
|
17
|
+
end
|
@@ -78,7 +78,7 @@ module Stannum::Constraints::Tuples
|
|
78
78
|
def each_extra_item(actual, &block)
|
79
79
|
return if matches?(actual)
|
80
80
|
|
81
|
-
actual[expected_count
|
81
|
+
actual[expected_count..].each.with_index(expected_count, &block)
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
@@ -184,13 +184,17 @@ module Stannum::Constraints::Types
|
|
184
184
|
|
185
185
|
def update_key_errors_for(actual:, errors:)
|
186
186
|
non_matching_keys(actual).each do |key|
|
187
|
-
|
187
|
+
mapped_key = Stannum::Support::Coercion.error_key(key)
|
188
|
+
|
189
|
+
key_type.errors_for(key, errors: errors[:keys][mapped_key])
|
188
190
|
end
|
189
191
|
end
|
190
192
|
|
191
193
|
def update_value_errors_for(actual:, errors:)
|
192
194
|
non_matching_values(actual).each do |key, value|
|
193
|
-
|
195
|
+
mapped_key = Stannum::Support::Coercion.error_key(key)
|
196
|
+
|
197
|
+
value_type.errors_for(value, errors: errors[mapped_key])
|
194
198
|
end
|
195
199
|
end
|
196
200
|
|
data/lib/stannum/constraints.rb
CHANGED
@@ -15,7 +15,9 @@ module Stannum
|
|
15
15
|
autoload :Hashes, 'stannum/constraints/hashes'
|
16
16
|
autoload :Identity, 'stannum/constraints/identity'
|
17
17
|
autoload :Nothing, 'stannum/constraints/nothing'
|
18
|
+
autoload :Parameters, 'stannum/constraints/parameters'
|
18
19
|
autoload :Presence, 'stannum/constraints/presence'
|
20
|
+
autoload :Properties, 'stannum/constraints/properties'
|
19
21
|
autoload :Signature, 'stannum/constraints/signature'
|
20
22
|
autoload :Signatures, 'stannum/constraints/signatures'
|
21
23
|
autoload :Tuples, 'stannum/constraints/tuples'
|
@@ -18,6 +18,17 @@ module Stannum::Contracts
|
|
18
18
|
# @return [Stannum::Contract] The contract to which constraints are added.
|
19
19
|
attr_reader :contract
|
20
20
|
|
21
|
+
# Concatenate the constraints from the given other contract.
|
22
|
+
#
|
23
|
+
# @param other [Stannum::Contract] the other contract.
|
24
|
+
#
|
25
|
+
# @return [self] the contract builder.
|
26
|
+
#
|
27
|
+
# @see Stannum::Contracts::Base#concat.
|
28
|
+
def concat(other)
|
29
|
+
contract.concat(other)
|
30
|
+
end
|
31
|
+
|
21
32
|
# Adds a constraint to the contract.
|
22
33
|
#
|
23
34
|
# @overload constraint(constraint, **options)
|
@@ -47,8 +58,8 @@ module Stannum::Contracts
|
|
47
58
|
private
|
48
59
|
|
49
60
|
def ambiguous_values_error(constraint)
|
50
|
-
'expected either a block or a constraint instance, but received both a' \
|
51
|
-
"
|
61
|
+
'expected either a block or a constraint instance, but received both a ' \
|
62
|
+
"block and #{constraint.inspect}"
|
52
63
|
end
|
53
64
|
|
54
65
|
def resolve_constraint(constraint = nil, **options, &block)
|
@@ -121,6 +121,20 @@ module Stannum::Contracts
|
|
121
121
|
options[:value_type]
|
122
122
|
end
|
123
123
|
|
124
|
+
protected
|
125
|
+
|
126
|
+
def map_errors(errors, **options)
|
127
|
+
return super unless options[:property_type] == :key
|
128
|
+
|
129
|
+
property_name = options.fetch(:property_name, options[:property])
|
130
|
+
property_name = property_name.nil? ? [nil] : Array(property_name)
|
131
|
+
property_name = property_name.map do |key|
|
132
|
+
Stannum::Support::Coercion.error_key(key)
|
133
|
+
end
|
134
|
+
|
135
|
+
errors.dig(*property_name)
|
136
|
+
end
|
137
|
+
|
124
138
|
private
|
125
139
|
|
126
140
|
def add_type_constraint
|
@@ -74,5 +74,18 @@ module Stannum::Contracts
|
|
74
74
|
actual.fetch(property) { actual[property.to_s] }
|
75
75
|
end
|
76
76
|
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def add_extra_keys_constraint
|
81
|
+
return if options[:allow_extra_keys]
|
82
|
+
|
83
|
+
keys = -> { expected_keys }
|
84
|
+
|
85
|
+
add_constraint(
|
86
|
+
Stannum::Constraints::Hashes::IndifferentExtraKeys.new(keys),
|
87
|
+
concatenatable: false
|
88
|
+
)
|
89
|
+
end
|
77
90
|
end
|
78
91
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'stannum/constraints/parameters/extra_arguments'
|
3
4
|
require 'stannum/contracts/parameters'
|
4
5
|
require 'stannum/support/coercion'
|
5
6
|
|
@@ -8,9 +9,6 @@ module Stannum::Contracts::Parameters
|
|
8
9
|
#
|
9
10
|
# An ArgumentsContract constrains the arguments given for a method.
|
10
11
|
class ArgumentsContract < Stannum::Contracts::TupleContract
|
11
|
-
# The :type of the error generated for extra arguments.
|
12
|
-
EXTRA_ARGUMENTS_TYPE = 'stannum.constraints.parameters.extra_arguments'
|
13
|
-
|
14
12
|
# Value used when arguments array does not have a value for the given index.
|
15
13
|
UNDEFINED = Object.new.freeze
|
16
14
|
|
@@ -154,10 +152,7 @@ module Stannum::Contracts::Parameters
|
|
154
152
|
count = -> { expected_count }
|
155
153
|
|
156
154
|
@variadic_constraint = Stannum::Constraints::Delegator.new(
|
157
|
-
Stannum::Constraints::
|
158
|
-
count,
|
159
|
-
type: EXTRA_ARGUMENTS_TYPE
|
160
|
-
)
|
155
|
+
Stannum::Constraints::Parameters::ExtraArguments.new(count)
|
161
156
|
)
|
162
157
|
|
163
158
|
add_constraint @variadic_constraint
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'stannum/constraints/parameters/extra_keywords'
|
3
4
|
require 'stannum/contracts/indifferent_hash_contract'
|
4
5
|
require 'stannum/contracts/parameters'
|
5
6
|
|
@@ -8,9 +9,6 @@ module Stannum::Contracts::Parameters
|
|
8
9
|
#
|
9
10
|
# A KeywordsContract constrains the keywords given for a method.
|
10
11
|
class KeywordsContract < Stannum::Contracts::IndifferentHashContract
|
11
|
-
# The :type of the error generated for extra keywords.
|
12
|
-
EXTRA_KEYWORDS_TYPE = 'stannum.constraints.parameters.extra_keywords'
|
13
|
-
|
14
12
|
# Value used when keywords hash does not have a value for the given key.
|
15
13
|
UNDEFINED = Object.new.freeze
|
16
14
|
|
@@ -156,10 +154,7 @@ module Stannum::Contracts::Parameters
|
|
156
154
|
keys = -> { expected_keys }
|
157
155
|
|
158
156
|
@variadic_constraint = Stannum::Constraints::Delegator.new(
|
159
|
-
Stannum::Constraints::
|
160
|
-
keys,
|
161
|
-
type: EXTRA_KEYWORDS_TYPE
|
162
|
-
)
|
157
|
+
Stannum::Constraints::Parameters::ExtraKeywords.new(keys)
|
163
158
|
)
|
164
159
|
|
165
160
|
add_constraint @variadic_constraint
|