servactory 1.1.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 +7 -0
- data/README.md +116 -0
- data/Rakefile +12 -0
- data/lib/servactory/base.rb +11 -0
- data/lib/servactory/configuration.rb +18 -0
- data/lib/servactory/context/configuration.rb +23 -0
- data/lib/servactory/context/dsl.rb +58 -0
- data/lib/servactory/context/store.rb +51 -0
- data/lib/servactory/errors/base.rb +7 -0
- data/lib/servactory/errors/failure.rb +7 -0
- data/lib/servactory/errors/input_argument_error.rb +7 -0
- data/lib/servactory/errors/internal_argument_error.rb +7 -0
- data/lib/servactory/errors/output_argument_error.rb +7 -0
- data/lib/servactory/input_arguments/checks/base.rb +23 -0
- data/lib/servactory/input_arguments/checks/inclusion.rb +45 -0
- data/lib/servactory/input_arguments/checks/must.rb +75 -0
- data/lib/servactory/input_arguments/checks/required.rb +54 -0
- data/lib/servactory/input_arguments/checks/type.rb +84 -0
- data/lib/servactory/input_arguments/collection.rb +19 -0
- data/lib/servactory/input_arguments/dsl.rb +27 -0
- data/lib/servactory/input_arguments/input_argument.rb +79 -0
- data/lib/servactory/input_arguments/tools/check.rb +74 -0
- data/lib/servactory/input_arguments/tools/find_unnecessary.rb +32 -0
- data/lib/servactory/input_arguments/tools/prepare.rb +89 -0
- data/lib/servactory/input_arguments/tools/rules.rb +38 -0
- data/lib/servactory/input_arguments/workbench.rb +40 -0
- data/lib/servactory/inputs.rb +7 -0
- data/lib/servactory/internal_arguments/checks/base.rb +17 -0
- data/lib/servactory/internal_arguments/checks/type.rb +55 -0
- data/lib/servactory/internal_arguments/collection.rb +19 -0
- data/lib/servactory/internal_arguments/dsl.rb +27 -0
- data/lib/servactory/internal_arguments/internal_argument.rb +33 -0
- data/lib/servactory/internal_arguments/tools/prepare.rb +58 -0
- data/lib/servactory/internal_arguments/workbench.rb +27 -0
- data/lib/servactory/output_arguments/checks/base.rb +17 -0
- data/lib/servactory/output_arguments/checks/type.rb +55 -0
- data/lib/servactory/output_arguments/collection.rb +19 -0
- data/lib/servactory/output_arguments/dsl.rb +27 -0
- data/lib/servactory/output_arguments/output_argument.rb +40 -0
- data/lib/servactory/output_arguments/tools/conflicts.rb +34 -0
- data/lib/servactory/output_arguments/tools/prepare.rb +58 -0
- data/lib/servactory/output_arguments/workbench.rb +31 -0
- data/lib/servactory/result.rb +21 -0
- data/lib/servactory/stage/dsl.rb +29 -0
- data/lib/servactory/stage/factory.rb +15 -0
- data/lib/servactory/stage/handyman.rb +35 -0
- data/lib/servactory/stage/method.rb +21 -0
- data/lib/servactory/stage/methods.rb +15 -0
- data/lib/servactory/utils.rb +11 -0
- data/lib/servactory/version.rb +11 -0
- data/lib/servactory.rb +34 -0
- metadata +237 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InputArguments
|
5
|
+
class InputArgument
|
6
|
+
attr_reader :name,
|
7
|
+
:types,
|
8
|
+
:inclusion,
|
9
|
+
:must,
|
10
|
+
:array,
|
11
|
+
:required,
|
12
|
+
:internal,
|
13
|
+
:default
|
14
|
+
|
15
|
+
def initialize(name, type:, **options)
|
16
|
+
@name = name
|
17
|
+
@types = Array(type)
|
18
|
+
|
19
|
+
@inclusion = options.fetch(:inclusion, nil)
|
20
|
+
@must = options.fetch(:must, nil)
|
21
|
+
@array = options.fetch(:array, false)
|
22
|
+
@required = options.fetch(:required, true)
|
23
|
+
@internal = options.fetch(:internal, false)
|
24
|
+
@default = options.fetch(:default, nil)
|
25
|
+
end
|
26
|
+
|
27
|
+
def options_for_checks
|
28
|
+
{
|
29
|
+
types:,
|
30
|
+
inclusion:,
|
31
|
+
must:,
|
32
|
+
required:,
|
33
|
+
# internal:,
|
34
|
+
default:
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def conflict_code
|
39
|
+
return :required_vs_default if required? && default_value_present?
|
40
|
+
return :array_vs_array if array? && types.include?(Array)
|
41
|
+
return :array_vs_inclusion if array? && inclusion_present?
|
42
|
+
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def inclusion_present?
|
47
|
+
inclusion.is_a?(Array) && inclusion.present?
|
48
|
+
end
|
49
|
+
|
50
|
+
def must_present?
|
51
|
+
must.present?
|
52
|
+
end
|
53
|
+
|
54
|
+
def array?
|
55
|
+
Servactory::Utils.boolean?(array)
|
56
|
+
end
|
57
|
+
|
58
|
+
def required?
|
59
|
+
Servactory::Utils.boolean?(required)
|
60
|
+
end
|
61
|
+
|
62
|
+
def optional?
|
63
|
+
!required?
|
64
|
+
end
|
65
|
+
|
66
|
+
def internal?
|
67
|
+
Servactory::Utils.boolean?(internal)
|
68
|
+
end
|
69
|
+
|
70
|
+
def default_value_present?
|
71
|
+
!default.nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
def with_conflicts?
|
75
|
+
conflict_code.present?
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InputArguments
|
5
|
+
module Tools
|
6
|
+
class Check
|
7
|
+
def self.check!(...)
|
8
|
+
new(...).check!
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(context, incoming_arguments, collection_of_input_arguments)
|
12
|
+
@context = context
|
13
|
+
@incoming_arguments = incoming_arguments
|
14
|
+
@collection_of_input_arguments = collection_of_input_arguments
|
15
|
+
|
16
|
+
@errors = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def check!
|
20
|
+
@collection_of_input_arguments.each do |input|
|
21
|
+
process_input(input)
|
22
|
+
end
|
23
|
+
|
24
|
+
raise_errors
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def process_input(input)
|
30
|
+
input.options_for_checks.each do |check_key, check_options|
|
31
|
+
process_option(check_key, check_options, input:)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def process_option(check_key, check_options, input:)
|
36
|
+
check_classes.each do |check_class|
|
37
|
+
errors_from_checks = process_check_class(check_class, input:, check_key:, check_options:)
|
38
|
+
|
39
|
+
@errors.push(*errors_from_checks)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def process_check_class(check_class, input:, check_key:, check_options:)
|
44
|
+
check_class.check(
|
45
|
+
context: @context,
|
46
|
+
input:,
|
47
|
+
value: @incoming_arguments.fetch(input.name, nil),
|
48
|
+
check_key:,
|
49
|
+
check_options:
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
########################################################################
|
54
|
+
|
55
|
+
def check_classes
|
56
|
+
[
|
57
|
+
Servactory::InputArguments::Checks::Required,
|
58
|
+
Servactory::InputArguments::Checks::Type,
|
59
|
+
Servactory::InputArguments::Checks::Inclusion,
|
60
|
+
Servactory::InputArguments::Checks::Must
|
61
|
+
]
|
62
|
+
end
|
63
|
+
|
64
|
+
########################################################################
|
65
|
+
|
66
|
+
def raise_errors
|
67
|
+
return if @errors.empty?
|
68
|
+
|
69
|
+
raise Servactory.configuration.input_argument_error_class, @errors.first
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InputArguments
|
5
|
+
module Tools
|
6
|
+
class FindUnnecessary
|
7
|
+
def self.check!(...)
|
8
|
+
new(...).check!
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(context, incoming_arguments, collection_of_input_arguments)
|
12
|
+
@context = context
|
13
|
+
@incoming_arguments = incoming_arguments
|
14
|
+
@collection_of_input_arguments = collection_of_input_arguments
|
15
|
+
end
|
16
|
+
|
17
|
+
def check!
|
18
|
+
return if unnecessary_attributes.empty?
|
19
|
+
|
20
|
+
raise Servactory.configuration.input_argument_error_class,
|
21
|
+
"[#{@context.class.name}] Unexpected attributes: `#{unnecessary_attributes.join(', ')}`"
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def unnecessary_attributes
|
27
|
+
@unnecessary_attributes ||= @incoming_arguments.keys - @collection_of_input_arguments.names
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InputArguments
|
5
|
+
module Tools
|
6
|
+
class Prepare
|
7
|
+
def self.prepare(...)
|
8
|
+
new(...).prepare
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(context, incoming_arguments, collection_of_input_arguments)
|
12
|
+
@context = context
|
13
|
+
@incoming_arguments = incoming_arguments
|
14
|
+
@collection_of_input_arguments = collection_of_input_arguments
|
15
|
+
end
|
16
|
+
|
17
|
+
def prepare
|
18
|
+
@inputs_variables = {}
|
19
|
+
@internal_variables = {}
|
20
|
+
|
21
|
+
@collection_of_input_arguments.each do |input|
|
22
|
+
process_input(input)
|
23
|
+
end
|
24
|
+
|
25
|
+
create_instance_variables
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def process_input(input)
|
31
|
+
input_value = @incoming_arguments.fetch(input.name, nil)
|
32
|
+
input_value = input.default if input.optional? && input_value.blank?
|
33
|
+
|
34
|
+
@inputs_variables[input.name] = input_value
|
35
|
+
|
36
|
+
return unless input.internal?
|
37
|
+
|
38
|
+
@internal_variables[input.name] = input_value
|
39
|
+
end
|
40
|
+
|
41
|
+
def create_instance_variables
|
42
|
+
Servactory::Inputs.class_eval(class_inputs_template)
|
43
|
+
|
44
|
+
@context.assign_inputs(Servactory::Inputs.new(**@inputs_variables))
|
45
|
+
|
46
|
+
@context.class.class_eval(context_internal_variables_template)
|
47
|
+
|
48
|
+
@internal_variables.each do |input_name, input_value|
|
49
|
+
@context.instance_variable_set(:"@#{input_name}", input_value)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
########################################################################
|
54
|
+
|
55
|
+
# EXAMPLE:
|
56
|
+
#
|
57
|
+
# attr_reader(*[:attr_1]); def initialize(attr_1); @attr_1 = attr_1; end
|
58
|
+
#
|
59
|
+
# OR
|
60
|
+
#
|
61
|
+
# attr_reader(*[:attr_1, :attr_2, :attr_3])
|
62
|
+
#
|
63
|
+
# def initialize(attr_1:, attr_2:, attr_3:)
|
64
|
+
# @attr_1 = attr_1; @attr_2 = attr_2; @attr_3 = attr_3;
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
def class_inputs_template
|
68
|
+
<<-RUBY.squish
|
69
|
+
attr_reader(*#{@inputs_variables.keys});
|
70
|
+
|
71
|
+
def initialize(#{@inputs_variables.keys.join(':, ')}:);
|
72
|
+
#{@inputs_variables.keys.map { |key| "@#{key} = #{key}" }.join('; ')};
|
73
|
+
end
|
74
|
+
RUBY
|
75
|
+
end
|
76
|
+
|
77
|
+
# EXAMPLE:
|
78
|
+
#
|
79
|
+
# private attr_reader(*[:attr_1]);
|
80
|
+
#
|
81
|
+
def context_internal_variables_template
|
82
|
+
<<-RUBY.squish
|
83
|
+
private attr_reader(*#{@internal_variables.keys});
|
84
|
+
RUBY
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InputArguments
|
5
|
+
module Tools
|
6
|
+
class Rules
|
7
|
+
def self.check!(...)
|
8
|
+
new(...).check!
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(context, collection_of_input_arguments)
|
12
|
+
@context = context
|
13
|
+
@collection_of_input_arguments = collection_of_input_arguments
|
14
|
+
end
|
15
|
+
|
16
|
+
def check!
|
17
|
+
@collection_of_input_arguments.each do |input_argument|
|
18
|
+
check_for!(input_argument)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def check_for!(input_argument)
|
25
|
+
return unless input_argument.with_conflicts?
|
26
|
+
|
27
|
+
raise_error_for(input_argument)
|
28
|
+
end
|
29
|
+
|
30
|
+
def raise_error_for(input_argument)
|
31
|
+
raise Servactory.configuration.input_argument_error_class,
|
32
|
+
"[#{@context.class.name}] Conflict in `#{input_argument.name}` input " \
|
33
|
+
"options: `#{input_argument.conflict_code}`"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InputArguments
|
5
|
+
class Workbench
|
6
|
+
def self.work_with(...)
|
7
|
+
new(...)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(collection_of_input_arguments)
|
11
|
+
@collection_of_input_arguments = collection_of_input_arguments
|
12
|
+
end
|
13
|
+
|
14
|
+
def assign(context:, arguments:)
|
15
|
+
@context = context
|
16
|
+
@incoming_arguments = arguments
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_unnecessary!
|
20
|
+
Tools::FindUnnecessary.check!(context, @incoming_arguments, collection_of_input_arguments)
|
21
|
+
end
|
22
|
+
|
23
|
+
def check_rules!
|
24
|
+
Tools::Rules.check!(context, collection_of_input_arguments)
|
25
|
+
end
|
26
|
+
|
27
|
+
def prepare
|
28
|
+
Tools::Prepare.prepare(context, @incoming_arguments, collection_of_input_arguments)
|
29
|
+
end
|
30
|
+
|
31
|
+
def check!
|
32
|
+
Tools::Check.check!(context, @incoming_arguments, collection_of_input_arguments)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :context, :collection_of_input_arguments
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InternalArguments
|
5
|
+
module Checks
|
6
|
+
class Base
|
7
|
+
protected
|
8
|
+
|
9
|
+
def raise_error_with(message, **arguments)
|
10
|
+
message = message.call(**arguments) if message.is_a?(Proc)
|
11
|
+
|
12
|
+
raise Servactory.configuration.internal_argument_error_class, message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InternalArguments
|
5
|
+
module Checks
|
6
|
+
class Type < Base
|
7
|
+
DEFAULT_MESSAGE = lambda do |service_class_name:, internal_argument:, expected_type:, given_type:|
|
8
|
+
"The \"#{internal_argument.name}\" internal argument on \"#{service_class_name}\" must be of type " \
|
9
|
+
"\"#{expected_type}\" but was \"#{given_type}\""
|
10
|
+
end
|
11
|
+
|
12
|
+
private_constant :DEFAULT_MESSAGE
|
13
|
+
|
14
|
+
def self.check!(...)
|
15
|
+
new(...).check!
|
16
|
+
end
|
17
|
+
|
18
|
+
##########################################################################
|
19
|
+
|
20
|
+
def initialize(context:, internal_argument:, value:)
|
21
|
+
super()
|
22
|
+
|
23
|
+
@context = context
|
24
|
+
@internal_argument = internal_argument
|
25
|
+
@value = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def check!
|
29
|
+
return if prepared_types.any? { |type| @value.is_a?(type) }
|
30
|
+
|
31
|
+
raise_error_with(
|
32
|
+
DEFAULT_MESSAGE,
|
33
|
+
service_class_name: @context.class.name,
|
34
|
+
internal_argument: @internal_argument,
|
35
|
+
expected_type: prepared_types.join(", "),
|
36
|
+
given_type: @value.class.name
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def prepared_types
|
43
|
+
@prepared_types ||=
|
44
|
+
Array(@internal_argument.types).map do |type|
|
45
|
+
if type.is_a?(String)
|
46
|
+
Object.const_get(type)
|
47
|
+
else
|
48
|
+
type
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InternalArguments
|
5
|
+
class Collection
|
6
|
+
# NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :@collection, :<<, :each, :map
|
9
|
+
|
10
|
+
def initialize(*)
|
11
|
+
@collection = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def names
|
15
|
+
map(&:name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InternalArguments
|
5
|
+
module DSL
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
private
|
12
|
+
|
13
|
+
def internal(name, **options)
|
14
|
+
collection_of_internal_arguments << InternalArgument.new(name, **options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def collection_of_internal_arguments
|
18
|
+
@collection_of_internal_arguments ||= Collection.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def internal_arguments_workbench
|
22
|
+
@internal_arguments_workbench ||= Workbench.work_with(collection_of_internal_arguments)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InternalArguments
|
5
|
+
class InternalArgument
|
6
|
+
attr_reader :name,
|
7
|
+
:types,
|
8
|
+
:required
|
9
|
+
|
10
|
+
def initialize(name, type:, **options)
|
11
|
+
@name = name
|
12
|
+
@types = Array(type)
|
13
|
+
|
14
|
+
@required = options.fetch(:required, true)
|
15
|
+
end
|
16
|
+
|
17
|
+
def options_for_checks
|
18
|
+
{
|
19
|
+
types:,
|
20
|
+
required:
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def required?
|
25
|
+
required
|
26
|
+
end
|
27
|
+
|
28
|
+
def optional?
|
29
|
+
!required
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InternalArguments
|
5
|
+
module Tools
|
6
|
+
class Prepare
|
7
|
+
def self.prepare(...)
|
8
|
+
new(...).prepare
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(context, collection_of_internal_arguments)
|
12
|
+
@context = context
|
13
|
+
@collection_of_internal_arguments = collection_of_internal_arguments
|
14
|
+
end
|
15
|
+
|
16
|
+
def prepare
|
17
|
+
@collection_of_internal_arguments.each do |internal_argument|
|
18
|
+
create_instance_variable_for(internal_argument)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def create_instance_variable_for(internal_argument)
|
25
|
+
@context.instance_variable_set(:"@#{internal_argument.name}", nil)
|
26
|
+
|
27
|
+
@context.class.class_eval(context_internal_argument_template_for(internal_argument))
|
28
|
+
end
|
29
|
+
|
30
|
+
# EXAMPLE:
|
31
|
+
#
|
32
|
+
# define_method(:user=) do |value|;
|
33
|
+
# Servactory::InternalArguments::Checks::Type.check!( context: self, internal_argument:, value: );
|
34
|
+
#
|
35
|
+
# instance_variable_set(:@user, value);
|
36
|
+
# end;
|
37
|
+
#
|
38
|
+
# private attr_reader :user;
|
39
|
+
#
|
40
|
+
def context_internal_argument_template_for(internal_argument)
|
41
|
+
<<-RUBY.squish
|
42
|
+
define_method(:#{internal_argument.name}=) do |value|;
|
43
|
+
Servactory::InternalArguments::Checks::Type.check!(
|
44
|
+
context: self,
|
45
|
+
internal_argument:,
|
46
|
+
value:
|
47
|
+
);
|
48
|
+
|
49
|
+
instance_variable_set(:@#{internal_argument.name}, value);
|
50
|
+
end;
|
51
|
+
|
52
|
+
private attr_reader :#{internal_argument.name};
|
53
|
+
RUBY
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module InternalArguments
|
5
|
+
class Workbench
|
6
|
+
def self.work_with(...)
|
7
|
+
new(...)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(collection_of_internal_arguments)
|
11
|
+
@collection_of_internal_arguments = collection_of_internal_arguments
|
12
|
+
end
|
13
|
+
|
14
|
+
def assign(context:)
|
15
|
+
@context = context
|
16
|
+
end
|
17
|
+
|
18
|
+
def prepare
|
19
|
+
Tools::Prepare.prepare(context, collection_of_internal_arguments)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :context, :collection_of_internal_arguments
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module OutputArguments
|
5
|
+
module Checks
|
6
|
+
class Base
|
7
|
+
protected
|
8
|
+
|
9
|
+
def raise_error_with(message, **arguments)
|
10
|
+
message = message.call(**arguments) if message.is_a?(Proc)
|
11
|
+
|
12
|
+
raise Servactory.configuration.output_argument_error_class, message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module OutputArguments
|
5
|
+
module Checks
|
6
|
+
class Type < Base
|
7
|
+
DEFAULT_MESSAGE = lambda do |service_class_name:, output_argument:, expected_type:, given_type:|
|
8
|
+
"The \"#{output_argument.name}\" output argument on \"#{service_class_name}\" must be of type " \
|
9
|
+
"\"#{expected_type}\" but was \"#{given_type}\""
|
10
|
+
end
|
11
|
+
|
12
|
+
private_constant :DEFAULT_MESSAGE
|
13
|
+
|
14
|
+
def self.check!(...)
|
15
|
+
new(...).check!
|
16
|
+
end
|
17
|
+
|
18
|
+
##########################################################################
|
19
|
+
|
20
|
+
def initialize(context:, output_argument:, value:)
|
21
|
+
super()
|
22
|
+
|
23
|
+
@context = context
|
24
|
+
@output_argument = output_argument
|
25
|
+
@value = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def check!
|
29
|
+
return if prepared_types.any? { |type| @value.is_a?(type) }
|
30
|
+
|
31
|
+
raise_error_with(
|
32
|
+
DEFAULT_MESSAGE,
|
33
|
+
service_class_name: @context.class.name,
|
34
|
+
output_argument: @output_argument,
|
35
|
+
expected_type: prepared_types.join(", "),
|
36
|
+
given_type: @value.class.name
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def prepared_types
|
43
|
+
@prepared_types ||=
|
44
|
+
Array(@output_argument.types).map do |type|
|
45
|
+
if type.is_a?(String)
|
46
|
+
Object.const_get(type)
|
47
|
+
else
|
48
|
+
type
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module OutputArguments
|
5
|
+
class Collection
|
6
|
+
# NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :@collection, :<<, :each, :map
|
9
|
+
|
10
|
+
def initialize(*)
|
11
|
+
@collection = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def names
|
15
|
+
map(&:name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|