cuprum 1.2.0.rc.0 → 1.3.0.rc.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 +28 -0
- data/README.md +4 -2
- data/lib/cuprum/command.rb +40 -3
- data/lib/cuprum/command_factory.rb +5 -5
- data/lib/cuprum/currying/curried_command.rb +2 -0
- data/lib/cuprum/currying.rb +3 -3
- data/lib/cuprum/error.rb +1 -1
- data/lib/cuprum/errors/command_not_implemented.rb +1 -1
- data/lib/cuprum/errors/invalid_parameters.rb +44 -0
- data/lib/cuprum/errors/multiple_errors.rb +1 -1
- data/lib/cuprum/errors/operation_not_called.rb +1 -1
- data/lib/cuprum/errors/uncaught_exception.rb +1 -1
- data/lib/cuprum/errors.rb +1 -0
- data/lib/cuprum/exception_handling.rb +11 -2
- data/lib/cuprum/map_command.rb +4 -0
- data/lib/cuprum/matcher.rb +2 -2
- data/lib/cuprum/matcher_list.rb +4 -4
- data/lib/cuprum/matching.rb +7 -7
- data/lib/cuprum/operation.rb +2 -2
- data/lib/cuprum/parameter_validation/validation_rule.rb +51 -0
- data/lib/cuprum/parameter_validation/validator.rb +109 -0
- data/lib/cuprum/parameter_validation.rb +220 -0
- data/lib/cuprum/processing.rb +5 -5
- data/lib/cuprum/result.rb +3 -3
- data/lib/cuprum/result_helpers.rb +3 -3
- data/lib/cuprum/result_list.rb +2 -2
- data/lib/cuprum/rspec/be_a_result_matcher.rb +1 -1
- data/lib/cuprum/rspec/deferred/parameter_validation_examples.rb +81 -0
- data/lib/cuprum/rspec/deferred.rb +8 -0
- data/lib/cuprum/utils/instance_spy.rb +6 -6
- data/lib/cuprum/utils/parameters_mapping.rb +143 -0
- data/lib/cuprum/version.rb +1 -1
- data/lib/cuprum.rb +16 -10
- metadata +15 -11
@@ -0,0 +1,220 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tools'
|
4
|
+
|
5
|
+
require 'cuprum'
|
6
|
+
require 'cuprum/utils/parameters_mapping'
|
7
|
+
|
8
|
+
module Cuprum
|
9
|
+
# Mixin for declaring validations for command parameters.
|
10
|
+
module ParameterValidation
|
11
|
+
extend SleepingKingStudios::Tools::Toolbox::Mixin
|
12
|
+
|
13
|
+
autoload :ValidationRule, 'cuprum/parameter_validation/validation_rule'
|
14
|
+
autoload :Validator, 'cuprum/parameter_validation/validator'
|
15
|
+
|
16
|
+
# Class methods for parameter validation.
|
17
|
+
module ClassMethods
|
18
|
+
# @private
|
19
|
+
def each_validation(&)
|
20
|
+
return enum_for(:each_validation) unless block_given?
|
21
|
+
|
22
|
+
ancestors.reverse_each do |ancestor|
|
23
|
+
next unless ancestor.respond_to?(:validation_rules, true)
|
24
|
+
|
25
|
+
ancestor.validation_rules.each(&)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# @overload validate(name, **options)
|
30
|
+
# Defines a validation for the specified parameter.
|
31
|
+
#
|
32
|
+
# This validation will call the #validate_$name method on the command
|
33
|
+
# with the value of the named parameter. If the method returns a failure
|
34
|
+
# message, that message is added to the failed validations.
|
35
|
+
#
|
36
|
+
# @param name [String, Symbol] the parameter to validate.
|
37
|
+
# @param options [Hash] additional options to pass to the validation
|
38
|
+
# method.
|
39
|
+
#
|
40
|
+
# @option options as [String, Symbol] the name of the parameter as
|
41
|
+
# displayed in the failure message, if any. Defaults to the value of
|
42
|
+
# the name parameter.
|
43
|
+
#
|
44
|
+
# @return void
|
45
|
+
#
|
46
|
+
# @overload validate(name, using:, **options)
|
47
|
+
# Defines a validation for the specified parameter.
|
48
|
+
#
|
49
|
+
# This validation will call the named method on the command with the
|
50
|
+
# value of the named parameter. If the method returns a failure message,
|
51
|
+
# that message is added to the failed validations.
|
52
|
+
#
|
53
|
+
# @param name [String, Symbol] the parameter to validate.
|
54
|
+
# @param using [String, Symbol] the name of the method used to validate
|
55
|
+
# the parameter.
|
56
|
+
# @param options [Hash] additional options to pass to the validation
|
57
|
+
# method.
|
58
|
+
#
|
59
|
+
# @option options as [String, Symbol] the name of the parameter as
|
60
|
+
# displayed in the failure message, if any. Defaults to the value of
|
61
|
+
# the name parameter.
|
62
|
+
#
|
63
|
+
# @return void
|
64
|
+
#
|
65
|
+
# @overload validate(name, **options, &block)
|
66
|
+
# Defines a validation for the specified parameter.
|
67
|
+
#
|
68
|
+
# This validation will call the given block with the value of the named
|
69
|
+
# parameter. If the block returns nil or false, a failure message is
|
70
|
+
# added to the failed validations
|
71
|
+
#
|
72
|
+
# @param name [String, Symbol] the parameter to validate.
|
73
|
+
# @param options [Hash] additional options for the validation.
|
74
|
+
#
|
75
|
+
# @option options as [String, Symbol] the name of the parameter as
|
76
|
+
# displayed in the failure message, if any. Defaults to the value of
|
77
|
+
# the name parameter.
|
78
|
+
# @option options message [String] the failure message to display.
|
79
|
+
# Defaults to "$name is invalid".
|
80
|
+
#
|
81
|
+
# @yield the block to validate the parameter.
|
82
|
+
# @yieldparam value [Object] the value of the named parameter.
|
83
|
+
# @yieldreturn [true, false] true if the given value is valid for the
|
84
|
+
# parameter; otherwise false.
|
85
|
+
#
|
86
|
+
# @return void
|
87
|
+
#
|
88
|
+
# @overload validate(name, type, **options)
|
89
|
+
# Defines a validation for the specified parameter.
|
90
|
+
#
|
91
|
+
# This validation will call the #validate_$type method on the command
|
92
|
+
# with the value of the named parameter. If the method returns a failure
|
93
|
+
# message, that message is added to the failed validations.
|
94
|
+
#
|
95
|
+
# If the command does not define the method, it will call the
|
96
|
+
# SleepingKingStudios::Tools::Assertions instance method with the same
|
97
|
+
# name. If the validation fails, the failure message is added to the
|
98
|
+
# failed validations.
|
99
|
+
#
|
100
|
+
# @param name [String, Symbol] the parameter to validate.
|
101
|
+
# @param type [String, Symbol] the validation method to run.
|
102
|
+
# @param options [Hash] additional options to pass to the validation
|
103
|
+
# method.
|
104
|
+
#
|
105
|
+
# @option options as [String, Symbol] the name of the parameter as
|
106
|
+
# displayed in the failure message, if any. Defaults to the value of
|
107
|
+
# the name parameter.
|
108
|
+
# @option options message [String] the message to display on a failed
|
109
|
+
# validation.
|
110
|
+
#
|
111
|
+
# @raise [Cuprum::ParameterValidation::Validator::UnknownValidationError]
|
112
|
+
# if neither the command nor the standard tools defines the method.
|
113
|
+
def validate(name, type = nil, using: nil, **options, &)
|
114
|
+
tools.assertions.validate_name(name, as: 'name')
|
115
|
+
|
116
|
+
if type && !type.is_a?(Module)
|
117
|
+
tools.assertions.validate_name(type, as: 'type')
|
118
|
+
end
|
119
|
+
|
120
|
+
tools.assertions.validate_name(using, as: 'using') if using
|
121
|
+
|
122
|
+
validation_rules <<
|
123
|
+
build_validation_rule(name:, options:, type:, using:, &)
|
124
|
+
end
|
125
|
+
|
126
|
+
# @private
|
127
|
+
def validate_parameters(command, ...)
|
128
|
+
parameters = parameters_mapping.call(...)
|
129
|
+
rules = each_validation
|
130
|
+
|
131
|
+
Validator.new.call(command:, parameters:, rules:)
|
132
|
+
rescue NameError => exception
|
133
|
+
raise unless exception.name == :process
|
134
|
+
|
135
|
+
error = Cuprum::Errors::CommandNotImplemented.new(command:)
|
136
|
+
|
137
|
+
Cuprum::Result.new(error:)
|
138
|
+
end
|
139
|
+
|
140
|
+
protected
|
141
|
+
|
142
|
+
def validation_rules
|
143
|
+
@validation_rules ||= []
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
def build_block_validation(name, **options, &)
|
149
|
+
type = ValidationRule::BLOCK_VALIDATION_TYPE
|
150
|
+
|
151
|
+
ValidationRule.new(name:, type:, as: name.to_s, **options, &)
|
152
|
+
end
|
153
|
+
|
154
|
+
def build_method_validation(name, method_name, **options)
|
155
|
+
type = ValidationRule::NAMED_VALIDATION_TYPE
|
156
|
+
|
157
|
+
ValidationRule.new(name:, type:, as: name.to_s, method_name:, **options)
|
158
|
+
end
|
159
|
+
|
160
|
+
def build_named_validation(name, **options)
|
161
|
+
type = ValidationRule::NAMED_VALIDATION_TYPE
|
162
|
+
|
163
|
+
ValidationRule.new(name:, type:, as: name.to_s, **options)
|
164
|
+
end
|
165
|
+
|
166
|
+
def build_type_validation(name, type, **options)
|
167
|
+
unless type.is_a?(Module)
|
168
|
+
return ValidationRule.new(name:, type:, as: name.to_s, **options)
|
169
|
+
end
|
170
|
+
|
171
|
+
ValidationRule.new(
|
172
|
+
name:,
|
173
|
+
type: :instance_of,
|
174
|
+
as: name.to_s,
|
175
|
+
expected: type,
|
176
|
+
**options
|
177
|
+
)
|
178
|
+
end
|
179
|
+
|
180
|
+
def build_validation_rule(name:, options:, type:, using:, &)
|
181
|
+
return build_type_validation(name, type, **options) if type
|
182
|
+
|
183
|
+
return build_method_validation(name, using, **options) if using
|
184
|
+
|
185
|
+
return build_block_validation(name, **options, &) if block_given?
|
186
|
+
|
187
|
+
build_named_validation(name, **options)
|
188
|
+
end
|
189
|
+
|
190
|
+
def parameters_mapping
|
191
|
+
@parameters_mapping ||=
|
192
|
+
Cuprum::Utils::ParametersMapping.build(instance_method(:process))
|
193
|
+
end
|
194
|
+
|
195
|
+
def tools
|
196
|
+
SleepingKingStudios::Tools::Toolbelt.instance
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# @overload call(*arguments, **keywords, &block)
|
201
|
+
# Validates the parameters and passes them to super.
|
202
|
+
#
|
203
|
+
# @param arguments [Array] the arguments to validate.
|
204
|
+
# @param keywords [Hash] the keywords to validate.
|
205
|
+
# @param block [Proc] the block to validate, if any,
|
206
|
+
#
|
207
|
+
# @return [Cuprum::Result] a failing result with a
|
208
|
+
# Cuprum::Errors::InvalidParameters error if the validation fails;
|
209
|
+
# otherwise the normal result of calling the command.
|
210
|
+
#
|
211
|
+
# @see Cuprum::Processing#call.
|
212
|
+
def call(...)
|
213
|
+
result = self.class.validate_parameters(self, ...)
|
214
|
+
|
215
|
+
return result if result.failure?
|
216
|
+
|
217
|
+
super
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
data/lib/cuprum/processing.rb
CHANGED
@@ -95,17 +95,17 @@ module Cuprum
|
|
95
95
|
#
|
96
96
|
# @yield If a block argument is given, it will be passed to the
|
97
97
|
# implementation.
|
98
|
-
def call(*args, **kwargs, &
|
98
|
+
def call(*args, **kwargs, &)
|
99
99
|
value =
|
100
100
|
if kwargs.empty?
|
101
|
-
process(*args, &
|
101
|
+
process(*args, &)
|
102
102
|
else
|
103
|
-
process(*args, **kwargs, &
|
103
|
+
process(*args, **kwargs, &)
|
104
104
|
end
|
105
105
|
|
106
106
|
return value.to_cuprum_result if value_is_result?(value)
|
107
107
|
|
108
|
-
build_result(value:
|
108
|
+
build_result(value:)
|
109
109
|
end
|
110
110
|
|
111
111
|
private
|
@@ -136,7 +136,7 @@ module Cuprum
|
|
136
136
|
def process(*_args)
|
137
137
|
error = Cuprum::Errors::CommandNotImplemented.new(command: self)
|
138
138
|
|
139
|
-
build_result(error:
|
139
|
+
build_result(error:)
|
140
140
|
end
|
141
141
|
|
142
142
|
def value_is_result?(value)
|
data/lib/cuprum/result.rb
CHANGED
@@ -8,15 +8,15 @@ module Cuprum
|
|
8
8
|
private
|
9
9
|
|
10
10
|
def build_result(error: nil, status: nil, value: nil)
|
11
|
-
Cuprum::Result.new(error
|
11
|
+
Cuprum::Result.new(error:, status:, value:)
|
12
12
|
end
|
13
13
|
|
14
14
|
def failure(error)
|
15
|
-
build_result(error:
|
15
|
+
build_result(error:)
|
16
16
|
end
|
17
17
|
|
18
18
|
def success(value)
|
19
|
-
build_result(value:
|
19
|
+
build_result(value:)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
data/lib/cuprum/result_list.rb
CHANGED
@@ -143,7 +143,7 @@ module Cuprum
|
|
143
143
|
# @see #status
|
144
144
|
# @see #value
|
145
145
|
def to_cuprum_result
|
146
|
-
Cuprum::Result.new(error
|
146
|
+
Cuprum::Result.new(error:, status:, value:)
|
147
147
|
end
|
148
148
|
|
149
149
|
# @return [Array<Object, nil>] the value, if any, for each result.
|
@@ -156,7 +156,7 @@ module Cuprum
|
|
156
156
|
def build_error
|
157
157
|
return if errors.compact.empty?
|
158
158
|
|
159
|
-
Cuprum::Errors::MultipleErrors.new(errors:
|
159
|
+
Cuprum::Errors::MultipleErrors.new(errors:)
|
160
160
|
end
|
161
161
|
|
162
162
|
def build_status
|
@@ -104,7 +104,7 @@ module Cuprum::RSpec
|
|
104
104
|
# @param actual [Object] the actual object to match.
|
105
105
|
#
|
106
106
|
# @return [Boolean] false if the actual object is a result; otherwise true.
|
107
|
-
def does_not_match?(actual)
|
107
|
+
def does_not_match?(actual) # rubocop:disable Naming/PredicateName
|
108
108
|
@actual = actual
|
109
109
|
|
110
110
|
raise ArgumentError, negated_matcher_warning if expected_properties?
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec/sleeping_king_studios/deferred'
|
4
|
+
|
5
|
+
require 'cuprum/errors/invalid_parameters'
|
6
|
+
require 'cuprum/rspec/be_a_result'
|
7
|
+
require 'cuprum/rspec/deferred'
|
8
|
+
|
9
|
+
module Cuprum::RSpec::Deferred
|
10
|
+
# Deferred examples for testing parameter validation.
|
11
|
+
#
|
12
|
+
# @example With A Validation Type
|
13
|
+
# RSpec.describe LaunchRocket do
|
14
|
+
# include Cuprum::RSpec::Deferred::ParameterValidationExamples
|
15
|
+
#
|
16
|
+
# describe '#call' do
|
17
|
+
# let(:launch_site) { 'KSC' }
|
18
|
+
#
|
19
|
+
# def call_command
|
20
|
+
# subject.call(launch_site:)
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# describe 'with invalid parameters' do
|
24
|
+
# let(:launch_site) { nil }
|
25
|
+
#
|
26
|
+
# include_deferred 'should validate the parameter',
|
27
|
+
# :launch_site,
|
28
|
+
# 'sleeping_king_studios.tools.assertions.presence',
|
29
|
+
# as: 'launch site'
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# @example With A Message
|
35
|
+
# RSpec.describe LaunchRocket do
|
36
|
+
# include Cuprum::RSpec::Deferred::ParameterValidationExamples
|
37
|
+
#
|
38
|
+
# describe '#call' do
|
39
|
+
# let(:launch_site) { 'KSC' }
|
40
|
+
#
|
41
|
+
# def call_command
|
42
|
+
# subject.call(launch_site:)
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# describe 'with invalid parameters' do
|
46
|
+
# let(:launch_site) { nil }
|
47
|
+
#
|
48
|
+
# include_deferred 'should validate the parameter',
|
49
|
+
# :launch_site,
|
50
|
+
# message: "launch site can't be blank"
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
module ParameterValidationExamples
|
55
|
+
include Cuprum::RSpec::Matchers
|
56
|
+
include RSpec::SleepingKingStudios::Deferred::Provider
|
57
|
+
|
58
|
+
deferred_examples 'should validate the parameter' \
|
59
|
+
do |name, type = nil, message: nil, **options|
|
60
|
+
it 'should return a failing result with InvalidParameters error' do
|
61
|
+
expected_failure =
|
62
|
+
message ||
|
63
|
+
tools.assertions.error_message_for(type, as: name, **options)
|
64
|
+
expected_error = Cuprum::Errors::InvalidParameters.new(
|
65
|
+
command_class: subject.class,
|
66
|
+
failures: [expected_failure]
|
67
|
+
)
|
68
|
+
|
69
|
+
expect(call_command)
|
70
|
+
.to be_a_failing_result
|
71
|
+
.with_error(expected_error)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def tools
|
78
|
+
SleepingKingStudios::Tools::Toolbelt.instance
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -30,7 +30,7 @@ module Cuprum::Utils
|
|
30
30
|
# Minimal class double implementing the #call method.
|
31
31
|
class Spy
|
32
32
|
# Empty method that accepts any parameters and an optional block.
|
33
|
-
def call(*_args, **_kwargs, &
|
33
|
+
def call(*_args, **_kwargs, &); end
|
34
34
|
end
|
35
35
|
|
36
36
|
class << self
|
@@ -96,8 +96,8 @@ module Cuprum::Utils
|
|
96
96
|
Cuprum::Utils::InstanceSpy::Spy.new
|
97
97
|
end
|
98
98
|
|
99
|
-
def call_spies_for(command,
|
100
|
-
spies_for(command).each { |spy| spy.call(
|
99
|
+
def call_spies_for(command, ...)
|
100
|
+
spies_for(command).each { |spy| spy.call(...) }
|
101
101
|
end
|
102
102
|
|
103
103
|
def guard_spy_class!(command_class)
|
@@ -127,13 +127,13 @@ module Cuprum::Utils
|
|
127
127
|
end
|
128
128
|
|
129
129
|
# (see Cuprum::Processing#call)
|
130
|
-
def call(*args, **kwargs, &
|
130
|
+
def call(*args, **kwargs, &)
|
131
131
|
if kwargs.empty?
|
132
|
-
Cuprum::Utils::InstanceSpy.send(:call_spies_for, self, *args, &
|
132
|
+
Cuprum::Utils::InstanceSpy.send(:call_spies_for, self, *args, &)
|
133
133
|
else
|
134
134
|
# :nocov:
|
135
135
|
Cuprum::Utils::InstanceSpy
|
136
|
-
.send(:call_spies_for, self, *args, **kwargs, &
|
136
|
+
.send(:call_spies_for, self, *args, **kwargs, &)
|
137
137
|
# :nocov:
|
138
138
|
end
|
139
139
|
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
require 'cuprum/utils'
|
6
|
+
|
7
|
+
module Cuprum::Utils
|
8
|
+
# Utility class mapping a method's parameters by parameter name.
|
9
|
+
class ParametersMapping
|
10
|
+
# Generates a parameters mapping for the given method or Proc.
|
11
|
+
#
|
12
|
+
# @param callable [#parameters] the method or Proc for which to map
|
13
|
+
# parameters.
|
14
|
+
#
|
15
|
+
# @return [ParametersMapping] the mapping for the callable object.
|
16
|
+
def self.build(callable) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
17
|
+
arguments = []
|
18
|
+
block = nil
|
19
|
+
keywords = []
|
20
|
+
variadic_arguments = nil
|
21
|
+
variadic_keywords = nil
|
22
|
+
|
23
|
+
callable.parameters.each do |(type, name)|
|
24
|
+
next if name.nil?
|
25
|
+
|
26
|
+
case type
|
27
|
+
when :opt, :req
|
28
|
+
arguments << name
|
29
|
+
when :key, :keyreq
|
30
|
+
keywords << name
|
31
|
+
when :rest
|
32
|
+
variadic_arguments = name
|
33
|
+
when :keyrest
|
34
|
+
variadic_keywords = name
|
35
|
+
when :block
|
36
|
+
block = name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
new(
|
41
|
+
arguments:,
|
42
|
+
block:,
|
43
|
+
keywords:,
|
44
|
+
variadic_arguments:,
|
45
|
+
variadic_keywords:
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
# @param arguments [Array<Symbol>] the named arguments to the method, both
|
50
|
+
# required and optional, but excluding variadic args).
|
51
|
+
# @param block [Symbol, nil] the name of the block parameter, if any.
|
52
|
+
# @param keywords [Array<Symbol>] the keywords for the method, both
|
53
|
+
# required and optional, but excluding variadic keywords.
|
54
|
+
# @param variadic_arguments [Symbol] the name of the variadic arguments
|
55
|
+
# parameter, if any.
|
56
|
+
# @param variadic_keywords [Symbol] the name of the variadic keywords
|
57
|
+
# parameter, if any.
|
58
|
+
def initialize(
|
59
|
+
arguments: [],
|
60
|
+
keywords: [],
|
61
|
+
block: nil,
|
62
|
+
variadic_arguments: nil,
|
63
|
+
variadic_keywords: nil
|
64
|
+
)
|
65
|
+
@arguments = arguments.map(&:to_sym).freeze
|
66
|
+
@block = block&.to_sym
|
67
|
+
@keywords = Set.new(keywords.map(&:to_sym)).freeze
|
68
|
+
@variadic_arguments = variadic_arguments&.to_sym
|
69
|
+
@variadic_keywords = variadic_keywords&.to_sym
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Hash{Symbol=>Integer}] the named arguments to the method, both
|
73
|
+
# required and optional, but excluding variadic args).
|
74
|
+
attr_reader :arguments
|
75
|
+
|
76
|
+
# @return [Symbol, nil] the name of the block parameter, if any.
|
77
|
+
attr_reader :block
|
78
|
+
|
79
|
+
# @return [Set<Symbol>] the keywords for the method, both required and
|
80
|
+
# optional, but excluding variadic keywords.
|
81
|
+
attr_reader :keywords
|
82
|
+
|
83
|
+
# @return [Symbol] the name of the variadic arguments parameter, if any.
|
84
|
+
attr_reader :variadic_arguments
|
85
|
+
|
86
|
+
# @return [Symbol] the name of the variadic keywords parameter, if any.
|
87
|
+
attr_reader :variadic_keywords
|
88
|
+
|
89
|
+
# @return [Integer] the number of named arguments.
|
90
|
+
def arguments_count
|
91
|
+
@arguments_count ||= arguments.size
|
92
|
+
end
|
93
|
+
|
94
|
+
# @return [true, false] true if the method has a block parameter; otherwise
|
95
|
+
# false.
|
96
|
+
def block?
|
97
|
+
!@block.nil?
|
98
|
+
end
|
99
|
+
|
100
|
+
# @overload call(*arguments, **keywords, &block)
|
101
|
+
# Maps the given parameters to a Hash of parameter names and values.
|
102
|
+
#
|
103
|
+
# @param arguments [Array] the positional parameters to map.
|
104
|
+
# @param keywords [Hash] the keyword parameters to map.
|
105
|
+
# @param block [Proc] the block parameter to map, if any.
|
106
|
+
#
|
107
|
+
# @return [Hash{Symbol=>Object}] the mapped parameters.
|
108
|
+
def call(*args, **kwargs, &block_arg) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
109
|
+
params = {}
|
110
|
+
extras = {}
|
111
|
+
|
112
|
+
arguments.each.with_index { |name, index| params[name] = args[index] }
|
113
|
+
|
114
|
+
if variadic_arguments?
|
115
|
+
params[variadic_arguments] = args[arguments_count..] || []
|
116
|
+
end
|
117
|
+
|
118
|
+
keywords.each { |name| params[name] = nil }
|
119
|
+
|
120
|
+
kwargs.each do |(name, value)|
|
121
|
+
(keywords.include?(name) ? params : extras)[name] = value
|
122
|
+
end
|
123
|
+
|
124
|
+
params[variadic_keywords] = extras if variadic_keywords?
|
125
|
+
|
126
|
+
params[block] = block_arg if block?
|
127
|
+
|
128
|
+
params
|
129
|
+
end
|
130
|
+
|
131
|
+
# @return [true, false] true if the method has a variadic arguments
|
132
|
+
# parameter; otherwise false.
|
133
|
+
def variadic_arguments?
|
134
|
+
!@variadic_arguments.nil?
|
135
|
+
end
|
136
|
+
|
137
|
+
# @return [true, false] true if the method has a variadic keywords
|
138
|
+
# parameter; otherwise false.
|
139
|
+
def variadic_keywords?
|
140
|
+
!@variadic_keywords.nil?
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
data/lib/cuprum/version.rb
CHANGED
data/lib/cuprum.rb
CHANGED
@@ -2,20 +2,26 @@
|
|
2
2
|
|
3
3
|
# Toolkit for implementing business logic as function objects.
|
4
4
|
module Cuprum
|
5
|
-
autoload :Command,
|
6
|
-
autoload :
|
7
|
-
autoload :
|
8
|
-
autoload :
|
9
|
-
autoload :
|
10
|
-
autoload :
|
11
|
-
autoload :
|
12
|
-
autoload :
|
13
|
-
autoload :
|
5
|
+
autoload :Command, 'cuprum/command'
|
6
|
+
autoload :CommandFactory, 'cuprum/command_factory'
|
7
|
+
autoload :Currying, 'cuprum/currying'
|
8
|
+
autoload :Error, 'cuprum/error'
|
9
|
+
autoload :ExceptionHandling, 'cuprum/exception_handling'
|
10
|
+
autoload :MapCommand, 'cuprum/map_command'
|
11
|
+
autoload :Matcher, 'cuprum/matcher'
|
12
|
+
autoload :Middleware, 'cuprum/middleware'
|
13
|
+
autoload :Operation, 'cuprum/operation'
|
14
|
+
autoload :ParameterValidation, 'cuprum/parameter_validation'
|
15
|
+
autoload :Result, 'cuprum/result'
|
16
|
+
autoload :ResultList, 'cuprum/result_list'
|
17
|
+
autoload :Steps, 'cuprum/steps'
|
14
18
|
|
15
19
|
class << self
|
16
|
-
# @return [String]
|
20
|
+
# @return [String] the current version of the gem.
|
17
21
|
def version
|
18
22
|
VERSION
|
19
23
|
end
|
20
24
|
end
|
21
25
|
end
|
26
|
+
|
27
|
+
require 'cuprum/version'
|