convenient_service 0.5.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +49 -0
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/ROADMAP.md +26 -4
- data/Taskfile.yml +30 -0
- data/convenient_service.gemspec +5 -2
- data/lib/convenient_service/aliases.rb +2 -0
- data/lib/convenient_service/common/plugins/assigns_attributes_in_constructor/using_active_model_attribute_assignment/concern.rb +0 -2
- data/lib/convenient_service/common/plugins/assigns_attributes_in_constructor/using_dry_initializer/concern.rb +0 -2
- data/lib/convenient_service/common/plugins/has_around_callbacks/middleware.rb +24 -4
- data/lib/convenient_service/common/plugins/has_callbacks/container.rb +17 -0
- data/lib/convenient_service/common/plugins/has_callbacks/entities/callback.rb +98 -5
- data/lib/convenient_service/common/plugins/has_callbacks/middleware.rb +25 -4
- data/lib/convenient_service/common/plugins/has_callbacks.rb +1 -0
- data/lib/convenient_service/common/plugins.rb +1 -1
- data/lib/convenient_service/configs/standard.rb +25 -12
- data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/container/commands/resolve_methods_middlewares_callers.rb +1 -24
- data/lib/convenient_service/dependencies.rb +19 -0
- data/lib/convenient_service/examples/dry/gemfile/dry_service/config.rb +4 -2
- data/lib/convenient_service/examples/rails/gemfile/rails_service/config.rb +4 -2
- data/lib/convenient_service/examples/rails/gemfile/services/format.rb +35 -6
- data/lib/convenient_service/examples/rails/gemfile/services/format_header.rb +1 -2
- data/lib/convenient_service/examples/rails/gemfile/services/merge_sections.rb +25 -0
- data/lib/convenient_service/examples/rails/gemfile/services/replace_file_content.rb +37 -0
- data/lib/convenient_service/examples/rails/gemfile/services.rb +8 -4
- data/lib/convenient_service/examples/standard/gemfile/services/format.rb +45 -6
- data/lib/convenient_service/examples/standard/gemfile/services/merge_sections.rb +52 -0
- data/lib/convenient_service/examples/standard/gemfile/services/replace_file_content.rb +48 -0
- data/lib/convenient_service/examples/standard/gemfile/services.rb +8 -4
- data/lib/convenient_service/examples/standard/request_params/constants.rb +15 -0
- data/lib/convenient_service/examples/standard/request_params/entities/description.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/entities/format.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/entities/id.rb +47 -0
- data/lib/convenient_service/examples/standard/request_params/entities/logger.rb +21 -0
- data/lib/convenient_service/examples/standard/request_params/entities/request.rb +23 -0
- data/lib/convenient_service/examples/standard/request_params/entities/source.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/entities/tag.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/entities/title.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/entities.rb +11 -0
- data/lib/convenient_service/examples/standard/request_params/services/apply_default_param_values.rb +26 -0
- data/lib/convenient_service/examples/standard/request_params/services/cast_params.rb +38 -0
- data/lib/convenient_service/examples/standard/request_params/services/extract_params_from_body.rb +70 -0
- data/lib/convenient_service/examples/standard/request_params/services/extract_params_from_path.rb +62 -0
- data/lib/convenient_service/examples/standard/request_params/services/filter_out_unpermitted_params.rb +26 -0
- data/lib/convenient_service/examples/standard/request_params/services/log_request_params.rb +54 -0
- data/lib/convenient_service/examples/standard/request_params/services/merge_params.rb +26 -0
- data/lib/convenient_service/examples/standard/request_params/services/prepare.rb +65 -0
- data/lib/convenient_service/examples/standard/request_params/services/validate_casted_params.rb +94 -0
- data/lib/convenient_service/examples/standard/request_params/services/validate_uncasted_params.rb +72 -0
- data/lib/convenient_service/examples/standard/request_params/services.rb +13 -0
- data/lib/convenient_service/examples/standard/request_params/utils/array/wrap.rb +46 -0
- data/lib/convenient_service/examples/standard/request_params/utils/array.rb +21 -0
- data/lib/convenient_service/examples/standard/request_params/utils/http/request/parse_body.rb +42 -0
- data/lib/convenient_service/examples/standard/request_params/utils/http/request/parse_path.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/utils/http/request.rb +28 -0
- data/lib/convenient_service/examples/standard/request_params/utils/http.rb +3 -0
- data/lib/convenient_service/examples/standard/request_params/utils/integer/safe_parse.rb +31 -0
- data/lib/convenient_service/examples/standard/request_params/utils/integer.rb +25 -0
- data/lib/convenient_service/examples/standard/request_params/utils/json/safe_parse.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/utils/json.rb +21 -0
- data/lib/convenient_service/examples/standard/request_params/utils/object/blank.rb +34 -0
- data/lib/convenient_service/examples/standard/request_params/utils/object/present.rb +31 -0
- data/lib/convenient_service/examples/standard/request_params/utils/object.rb +26 -0
- data/lib/convenient_service/examples/standard/request_params/utils.rb +7 -0
- data/lib/convenient_service/examples/standard/request_params.rb +48 -0
- data/lib/convenient_service/factories/arguments.rb +43 -0
- data/lib/convenient_service/factories/results.rb +214 -0
- data/lib/convenient_service/factories/services.rb +189 -0
- data/lib/convenient_service/factories/step/instance.rb +32 -0
- data/lib/convenient_service/factories/step.rb +3 -0
- data/lib/convenient_service/factories/steps.rb +126 -0
- data/lib/convenient_service/factories.rb +22 -0
- data/lib/convenient_service/factory.rb +21 -0
- data/lib/convenient_service/rspec/matchers/custom/be_descendant_of.rb +2 -2
- data/lib/convenient_service/rspec/matchers/custom/be_direct_descendant_of.rb +2 -2
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/commands/generate_printable_method.rb +50 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/commands.rb +3 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments/commands/apply_stub_to_track_delegations.rb +78 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments/commands/generate_printable_arguments.rb +100 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments/commands.rb +4 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments.rb +95 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/base.rb +87 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/return_its_value.rb +129 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/with_any_arguments.rb +37 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/with_concrete_arguments.rb +37 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/without_arguments.rb +37 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/values/base.rb +41 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/values/with_calling_original.rb +30 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/values/without_calling_original.rb +30 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings.rb +12 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings_collection/errors.rb +57 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings_collection.rb +171 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/delegation.rb +79 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities.rb +5 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher.rb +276 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities.rb +3 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to.rb +66 -233
- data/lib/convenient_service/rspec/matchers/custom/results/base/commands/find_result_method_step.rb +74 -0
- data/lib/convenient_service/rspec/matchers/custom/results/base/commands/find_result_result_method_step.rb +66 -0
- data/lib/convenient_service/rspec/matchers/custom/results/base/commands/find_result_service_step.rb +48 -0
- data/lib/convenient_service/rspec/matchers/custom/results/base/commands/generate_expected_step_part.rb +42 -0
- data/lib/convenient_service/rspec/matchers/custom/results/base/commands/generate_got_step_part.rb +42 -0
- data/lib/convenient_service/rspec/matchers/custom/results/base/commands/match_result_step.rb +89 -0
- data/lib/convenient_service/rspec/matchers/custom/results/base/commands.rb +10 -0
- data/lib/convenient_service/rspec/matchers/custom/results/base/errors.rb +35 -0
- data/lib/convenient_service/rspec/matchers/custom/results/base.rb +73 -12
- data/lib/convenient_service/rspec/matchers/custom/singleton_prepend_module.rb +79 -0
- data/lib/convenient_service/rspec/matchers/custom.rb +1 -0
- data/lib/convenient_service/rspec/matchers/singleton_prepend_module.rb +13 -0
- data/lib/convenient_service/rspec/matchers.rb +2 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/concern.rb +85 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/initialize/middleware.rb +27 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/initialize.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/to_kwargs/middleware.rb +25 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/to_kwargs.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result.rb +5 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/concern/instance_methods.rb +7 -1
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/data.rb +4 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/concern.rb +27 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/initialize/middleware.rb +27 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/initialize.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/to_kwargs/middleware.rb +25 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/to_kwargs.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step.rb +5 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins.rb +2 -0
- data/lib/convenient_service/service/plugins/has_result_method_steps.rb +0 -2
- data/lib/convenient_service/service/plugins/has_result_steps/concern.rb +40 -4
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_caller.rb +8 -1
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_direction.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_key.rb +8 -1
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_name.rb +9 -5
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/define_method_in_container.rb +2 -2
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/concern/instance_methods.rb +4 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/base.rb +4 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment/commands/define_method_in_container.rb +74 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment/commands.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment.rb +50 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers.rb +1 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values/reassignment.rb +43 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities.rb +1 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/errors.rb +22 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/step/concern/instance_methods.rb +39 -3
- data/lib/convenient_service/service/plugins/has_result_steps/entities/step/plugins/can_have_parent_result/middleware.rb +23 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/step/plugins/can_have_parent_result.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/step/plugins.rb +1 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/step_collection.rb +13 -0
- data/lib/convenient_service/service/plugins/has_result_steps/middleware.rb +18 -4
- data/lib/convenient_service/services/run_method_in_organizer.rb +28 -0
- data/lib/convenient_service/services/run_own_method_in_organizer.rb +64 -0
- data/lib/convenient_service/{service/plugins/has_result_method_steps/services.rb → services.rb} +0 -1
- data/lib/convenient_service/support/arguments/null_arguments.rb +28 -0
- data/lib/convenient_service/support/arguments.rb +87 -0
- data/lib/convenient_service/support/copyable.rb +6 -2
- data/lib/convenient_service/support/dependency_container/commands/assert_valid_scope.rb +32 -0
- data/lib/convenient_service/support/dependency_container/commands/import_method.rb +13 -23
- data/lib/convenient_service/support/dependency_container/commands.rb +1 -0
- data/lib/convenient_service/support/dependency_container/constants.rb +4 -2
- data/lib/convenient_service/support/dependency_container/entities/method.rb +2 -9
- data/lib/convenient_service/support/dependency_container/entities/namespace_collection.rb +0 -9
- data/lib/convenient_service/support/dependency_container/errors.rb +26 -1
- data/lib/convenient_service/support/dependency_container/export.rb +8 -0
- data/lib/convenient_service/support/dependency_container/import.rb +3 -1
- data/lib/convenient_service/support/not_passed.rb +3 -1
- data/lib/convenient_service/support/version/null_version.rb +7 -0
- data/lib/convenient_service/support/version.rb +11 -1
- data/lib/convenient_service/support.rb +1 -0
- data/lib/convenient_service/utils/object/instance_variable_delete.rb +41 -0
- data/lib/convenient_service/utils/object/instance_variable_fetch.rb +4 -0
- data/lib/convenient_service/utils/object.rb +9 -0
- data/lib/convenient_service/utils/proc/display.rb +43 -0
- data/lib/convenient_service/utils/proc.rb +5 -0
- data/lib/convenient_service/version.rb +1 -1
- data/lib/convenient_service.rb +6 -0
- data/logo.png +0 -0
- metadata +154 -10
- data/lib/convenient_service/service/plugins/has_result_method_steps/errors.rb +0 -23
- data/lib/convenient_service/service/plugins/has_result_method_steps/services/method_step_config.rb +0 -55
- data/lib/convenient_service/service/plugins/has_result_method_steps/services/run_method_in_organizer.rb +0 -30
- data/lib/convenient_service/service/plugins/has_result_method_steps/services/run_own_method_in_organizer.rb +0 -52
@@ -5,6 +5,9 @@ module ConvenientService
|
|
5
5
|
module Plugins
|
6
6
|
module HasResultSteps
|
7
7
|
class Middleware < Core::MethodChainMiddleware
|
8
|
+
##
|
9
|
+
# @return [ConvenientService::Service::Plugins::HasResultSteps::Entities::Step]
|
10
|
+
#
|
8
11
|
def next(...)
|
9
12
|
return chain.next(...) if entity.steps.none?
|
10
13
|
|
@@ -13,11 +16,22 @@ module ConvenientService
|
|
13
16
|
|
14
17
|
private
|
15
18
|
|
19
|
+
##
|
20
|
+
# @return [ConvenientService::Service::Plugins::HasResultSteps::Entities::Step]
|
21
|
+
#
|
16
22
|
def last_step
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
23
|
+
@last_step ||= entity.steps.find.with_index { |step, index| not_success?(step, index) } || entity.steps.last
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# @return [ConvenientService::Service::Plugins::HasResultSteps::Entities::Step]
|
28
|
+
#
|
29
|
+
# @internal
|
30
|
+
# NOTE: `entity.step(index)` is used as a hook (callbacks trigger).
|
31
|
+
# IMPORTANT: `step` status MUST be checked before triggering callbacks.
|
32
|
+
#
|
33
|
+
def not_success?(step, index)
|
34
|
+
step.not_success?.tap { entity.step(index) }
|
21
35
|
end
|
22
36
|
end
|
23
37
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Services
|
5
|
+
class RunMethodInOrganizer
|
6
|
+
##
|
7
|
+
# @internal
|
8
|
+
# TODO: Reuse parent config?
|
9
|
+
#
|
10
|
+
include Configs::Standard
|
11
|
+
|
12
|
+
attr_reader :method_name, :organizer, :kwargs
|
13
|
+
|
14
|
+
def initialize(method_name:, organizer:, **kwargs)
|
15
|
+
@method_name = method_name
|
16
|
+
@organizer = organizer
|
17
|
+
@kwargs = kwargs
|
18
|
+
end
|
19
|
+
|
20
|
+
def result
|
21
|
+
##
|
22
|
+
# NOTE: `kwargs` are intentionally NOT passed, since all the corresponding methods are available inside `organizer.__send__(method_name)` body.
|
23
|
+
#
|
24
|
+
organizer.__send__(method_name)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Services
|
5
|
+
class RunOwnMethodInOrganizer
|
6
|
+
module Errors
|
7
|
+
class MethodForStepIsNotDefined < ConvenientService::Error
|
8
|
+
def initialize(service_class:, method_name:)
|
9
|
+
message = <<~TEXT
|
10
|
+
Service #{service_class} tries to use `#{method_name}` method in a step, but it NOT defined.
|
11
|
+
|
12
|
+
Did you forget to define it?
|
13
|
+
TEXT
|
14
|
+
|
15
|
+
super(message)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# @internal
|
22
|
+
# TODO: Reuse parent config?
|
23
|
+
#
|
24
|
+
include Configs::Standard
|
25
|
+
|
26
|
+
attr_reader :method_name, :organizer, :kwargs
|
27
|
+
|
28
|
+
def initialize(method_name:, organizer:, **kwargs)
|
29
|
+
@method_name = method_name
|
30
|
+
@organizer = organizer
|
31
|
+
@kwargs = kwargs
|
32
|
+
end
|
33
|
+
|
34
|
+
def result
|
35
|
+
raise Errors::MethodForStepIsNotDefined.new(service_class: organizer.class, method_name: method_name) unless own_method
|
36
|
+
|
37
|
+
##
|
38
|
+
# NOTE: `kwargs` are intentionally NOT passed, since all the corresponding methods are available inside `own_method` body.
|
39
|
+
#
|
40
|
+
own_method.call
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
##
|
46
|
+
# @return [Method, nil]
|
47
|
+
#
|
48
|
+
# @internal
|
49
|
+
# TODO: A possible bottleneck. Should be removed if receives negative feedback.
|
50
|
+
#
|
51
|
+
# NOTE: `own_method.bind(organizer).call` is logically the same as `own_method.bind_call(organizer)`.
|
52
|
+
# - https://ruby-doc.org/core-2.7.1/UnboundMethod.html#method-i-bind_call
|
53
|
+
# - https://blog.saeloun.com/2019/10/17/ruby-2-7-adds-unboundmethod-bind_call-method.html
|
54
|
+
#
|
55
|
+
def own_method
|
56
|
+
method = Utils::Module.get_own_instance_method(organizer.class, method_name, private: true)
|
57
|
+
|
58
|
+
return unless method
|
59
|
+
|
60
|
+
method.bind(organizer)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
class Arguments
|
6
|
+
##
|
7
|
+
# @api private
|
8
|
+
#
|
9
|
+
class NullArguments < Support::Arguments
|
10
|
+
##
|
11
|
+
# @return [void]
|
12
|
+
#
|
13
|
+
def initialize
|
14
|
+
@args = []
|
15
|
+
@kwargs = {}
|
16
|
+
@block = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# @return [Boolean]
|
21
|
+
#
|
22
|
+
def null_arguments?
|
23
|
+
true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "arguments/null_arguments"
|
4
|
+
|
5
|
+
module ConvenientService
|
6
|
+
module Support
|
7
|
+
class Arguments
|
8
|
+
##
|
9
|
+
# @!attribute [r] args
|
10
|
+
# @return [Array]
|
11
|
+
#
|
12
|
+
attr_reader :args
|
13
|
+
|
14
|
+
##
|
15
|
+
# @!attribute [r] kwargs
|
16
|
+
# @return [Hash]
|
17
|
+
#
|
18
|
+
attr_reader :kwargs
|
19
|
+
|
20
|
+
##
|
21
|
+
# @!attribute [r] block
|
22
|
+
# @return [Proc]
|
23
|
+
#
|
24
|
+
attr_reader :block
|
25
|
+
|
26
|
+
##
|
27
|
+
# @param args [Array]
|
28
|
+
# @param kwargs [Hash]
|
29
|
+
# @param block [Proc]
|
30
|
+
# @return [void]
|
31
|
+
#
|
32
|
+
def initialize(*args, **kwargs, &block)
|
33
|
+
@args = args
|
34
|
+
@kwargs = kwargs
|
35
|
+
@block = block
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
##
|
40
|
+
# @return [ConvenientService::Support::Arguments::NullArguments]
|
41
|
+
#
|
42
|
+
def null_arguments
|
43
|
+
@null_arguments ||= Support::Arguments::NullArguments.new
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# @return [Boolean]
|
49
|
+
#
|
50
|
+
def null_arguments?
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# @return [Booleam]
|
56
|
+
#
|
57
|
+
def any?
|
58
|
+
return true if args.any?
|
59
|
+
return true if kwargs.any?
|
60
|
+
return true if block
|
61
|
+
|
62
|
+
false
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# @return [Booleam]
|
67
|
+
#
|
68
|
+
def none?
|
69
|
+
!any?
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# @param other [Object]
|
74
|
+
# @return [Boolean]
|
75
|
+
#
|
76
|
+
def ==(other)
|
77
|
+
return unless other.instance_of?(self.class)
|
78
|
+
|
79
|
+
return false if args != other.args
|
80
|
+
return false if kwargs != other.kwargs
|
81
|
+
return false if block != other.block
|
82
|
+
|
83
|
+
true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -20,8 +20,12 @@ module ConvenientService
|
|
20
20
|
# NOTE: This method is NOT likely to be ever changed, that is why inline logic is preferred over command classes in this particular case.
|
21
21
|
#
|
22
22
|
def copy(overrides: {})
|
23
|
-
|
24
|
-
|
23
|
+
defaults = {args: {}, kwargs: {}}
|
24
|
+
|
25
|
+
##
|
26
|
+
# IMPORTANT: Do not mutate `overrides`.
|
27
|
+
#
|
28
|
+
overrides = defaults.merge(overrides)
|
25
29
|
|
26
30
|
##
|
27
31
|
# TODO: Refactor runtime `respond_to?`. Investigate before refactoring.
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Commands
|
7
|
+
class AssertValidScope < Support::Command
|
8
|
+
##
|
9
|
+
# @!attribute [r] scope
|
10
|
+
# @return [Object]
|
11
|
+
#
|
12
|
+
attr_reader :scope
|
13
|
+
|
14
|
+
##
|
15
|
+
# @param scope [Object]
|
16
|
+
# @return [void]
|
17
|
+
#
|
18
|
+
def initialize(scope:)
|
19
|
+
@scope = scope
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# @return [Module]
|
24
|
+
#
|
25
|
+
def call
|
26
|
+
raise Errors::InvalidScope.new(scope: scope) unless Constants::SCOPES.include?(scope)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -5,6 +5,8 @@ module ConvenientService
|
|
5
5
|
module DependencyContainer
|
6
6
|
module Commands
|
7
7
|
class ImportMethod < Support::Command
|
8
|
+
include Support::Delegate
|
9
|
+
|
8
10
|
##
|
9
11
|
# @!attribute [r] importing_module
|
10
12
|
# @return [Module]
|
@@ -12,41 +14,31 @@ module ConvenientService
|
|
12
14
|
attr_reader :importing_module
|
13
15
|
|
14
16
|
##
|
15
|
-
# @!attribute [r]
|
16
|
-
# @return [
|
17
|
+
# @!attribute [r] exported_method
|
18
|
+
# @return [ConvenientService::Support::DependencyContainer::Method]
|
17
19
|
#
|
18
|
-
attr_reader :
|
20
|
+
attr_reader :exported_method
|
19
21
|
|
20
22
|
##
|
21
|
-
# @!attribute [r]
|
22
|
-
# @return [
|
23
|
+
# @!attribute [r] prepend
|
24
|
+
# @return [Boolean]
|
23
25
|
#
|
24
|
-
attr_reader :
|
26
|
+
attr_reader :prepend
|
25
27
|
|
26
28
|
##
|
27
29
|
# @!attribute [r] scope
|
28
30
|
# @return [Symbol]
|
29
31
|
#
|
30
|
-
|
31
|
-
|
32
|
-
##
|
33
|
-
# @!attribute [r] prepend
|
34
|
-
# @return [Boolean]
|
35
|
-
#
|
36
|
-
attr_reader :prepend
|
32
|
+
delegate :scope, to: :exported_method
|
37
33
|
|
38
34
|
##
|
39
35
|
# @param importing_module [Module]
|
40
|
-
# @param
|
41
|
-
# @param method [ConvenientService::Support::DependencyContainer::Method]
|
42
|
-
# @param scope [:instance, :class]
|
36
|
+
# @param exported_method [ConvenientService::Support::DependencyContainer::Method]
|
43
37
|
# @param prepend [Boolean]
|
44
38
|
#
|
45
|
-
def initialize(importing_module:,
|
39
|
+
def initialize(importing_module:, exported_method:, prepend:)
|
46
40
|
@importing_module = importing_module
|
47
|
-
@
|
48
|
-
@method = method
|
49
|
-
@scope = scope
|
41
|
+
@exported_method = exported_method
|
50
42
|
@prepend = prepend
|
51
43
|
end
|
52
44
|
|
@@ -56,9 +48,7 @@ module ConvenientService
|
|
56
48
|
def call
|
57
49
|
import imported_scoped_methods
|
58
50
|
|
59
|
-
|
60
|
-
|
61
|
-
method
|
51
|
+
exported_method.define_in_module!(imported_scoped_methods)
|
62
52
|
end
|
63
53
|
|
64
54
|
private
|
@@ -4,8 +4,10 @@ module ConvenientService
|
|
4
4
|
module Support
|
5
5
|
module DependencyContainer
|
6
6
|
module Constants
|
7
|
-
|
8
|
-
|
7
|
+
SCOPES = [
|
8
|
+
INSTANCE_SCOPE = :instance,
|
9
|
+
CLASS_SCOPE = :class
|
10
|
+
]
|
9
11
|
|
10
12
|
DEFAULT_SCOPE = Constants::INSTANCE_SCOPE
|
11
13
|
DEFAULT_PREPEND = false
|
@@ -80,9 +80,9 @@ module ConvenientService
|
|
80
80
|
# - Same methods are redefined.
|
81
81
|
# - In contrast, same namespaces are always reused.
|
82
82
|
#
|
83
|
-
innermost_namespace.define_method(
|
83
|
+
innermost_namespace.define_method(name, &body)
|
84
84
|
|
85
|
-
|
85
|
+
self
|
86
86
|
end
|
87
87
|
|
88
88
|
##
|
@@ -101,13 +101,6 @@ module ConvenientService
|
|
101
101
|
|
102
102
|
private
|
103
103
|
|
104
|
-
##
|
105
|
-
# @return [ConvenientService::Support::DependencyContainer::Entities::Method]
|
106
|
-
#
|
107
|
-
def method
|
108
|
-
self
|
109
|
-
end
|
110
|
-
|
111
104
|
##
|
112
105
|
# @return [Array<String>]
|
113
106
|
#
|
@@ -13,15 +13,6 @@ module ConvenientService
|
|
13
13
|
@namespaces = namespaces
|
14
14
|
end
|
15
15
|
|
16
|
-
##
|
17
|
-
#
|
18
|
-
#
|
19
|
-
def define_namespace(namespace)
|
20
|
-
namespaces << namespace
|
21
|
-
|
22
|
-
define_singleton_method(namespace.name) { namespace.body.call }
|
23
|
-
end
|
24
|
-
|
25
16
|
##
|
26
17
|
# @param name [String, Symbol]
|
27
18
|
# @return [ConvenientService::Support::DependencyContainer::Entities::Namespace, nil]
|
@@ -4,6 +4,31 @@ module ConvenientService
|
|
4
4
|
module Support
|
5
5
|
module DependencyContainer
|
6
6
|
module Errors
|
7
|
+
class InvalidScope < ConvenientService::Error
|
8
|
+
##
|
9
|
+
# @param scope [Object]
|
10
|
+
# @return [void]
|
11
|
+
#
|
12
|
+
def initialize(scope:)
|
13
|
+
message = <<~TEXT
|
14
|
+
Scope `#{scope.inspect}` is NOT valid.
|
15
|
+
|
16
|
+
Valid options are #{printable_valid_scopes}.
|
17
|
+
TEXT
|
18
|
+
|
19
|
+
super(message)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
##
|
25
|
+
# @return [String]
|
26
|
+
#
|
27
|
+
def printable_valid_scopes
|
28
|
+
Constants::SCOPES.map { |scope| "`:#{scope}`" }.join(", ")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
7
32
|
class NotExportableModule < ConvenientService::Error
|
8
33
|
##
|
9
34
|
# @param mod [Module]
|
@@ -31,7 +56,7 @@ module ConvenientService
|
|
31
56
|
message = <<~TEXT
|
32
57
|
Module `#{mod}` does NOT export method `#{method_name}` with `#{method_scope}` scope.
|
33
58
|
|
34
|
-
Did you forget to export
|
59
|
+
Did you forget to export it from `#{mod}`? For example:
|
35
60
|
|
36
61
|
module #{mod}
|
37
62
|
export #{method_name}, scope: :#{method_scope} do |*args, **kwargs, &block|
|
@@ -13,7 +13,15 @@ module ConvenientService
|
|
13
13
|
# @param body [Proc]
|
14
14
|
# @return [ConvenientService::Support::DependencyContainer::Entities::Method]
|
15
15
|
#
|
16
|
+
# @internal
|
17
|
+
# NOTE: `export` does NOT accept `prepend` kwarg intentionally.
|
18
|
+
# It is done to follow "the Ruby way".
|
19
|
+
# You won't ever see a module in Ruby that contains methods for `include` and `prepend` at the same time.
|
20
|
+
# So why `export` should allow to do it?
|
21
|
+
#
|
16
22
|
def export(full_name, scope: Constants::DEFAULT_SCOPE, &body)
|
23
|
+
Commands::AssertValidScope.call(scope: scope)
|
24
|
+
|
17
25
|
Entities::Method.new(full_name: full_name, scope: scope, body: body).tap { |method| exported_methods << method }
|
18
26
|
end
|
19
27
|
|
@@ -15,13 +15,15 @@ module ConvenientService
|
|
15
15
|
# @return [ConvenientService::Support::DependencyContainer::Entities::Method]
|
16
16
|
#
|
17
17
|
def import(full_name, from:, scope: Constants::DEFAULT_SCOPE, prepend: Constants::DEFAULT_PREPEND)
|
18
|
+
Commands::AssertValidScope.call(scope: scope)
|
19
|
+
|
18
20
|
raise Errors::NotExportableModule.new(mod: from) unless Utils::Module.include_module?(from, DependencyContainer::Export)
|
19
21
|
|
20
22
|
method = from.exported_methods.find_by(full_name: full_name, scope: scope)
|
21
23
|
|
22
24
|
raise Errors::NotExportedMethod.new(method_name: full_name, method_scope: scope, mod: from) unless method
|
23
25
|
|
24
|
-
Commands::ImportMethod.call(importing_module: self,
|
26
|
+
Commands::ImportMethod.call(importing_module: self, exported_method: method, prepend: prepend)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
@@ -24,10 +24,17 @@ module ConvenientService
|
|
24
24
|
# @return [ConvenientService::Support::Version::NullVersion]
|
25
25
|
#
|
26
26
|
def null_version
|
27
|
-
@null_version ||= NullVersion.new
|
27
|
+
@null_version ||= Support::Version::NullVersion.new
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
##
|
32
|
+
# @return [Boolean]
|
33
|
+
#
|
34
|
+
def null_version?
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
31
38
|
##
|
32
39
|
# @return [Gem::Version, nil]
|
33
40
|
#
|
@@ -52,6 +59,9 @@ module ConvenientService
|
|
52
59
|
|
53
60
|
private
|
54
61
|
|
62
|
+
##
|
63
|
+
# @return [String]
|
64
|
+
#
|
55
65
|
attr_reader :value
|
56
66
|
|
57
67
|
##
|
@@ -4,6 +4,7 @@ require_relative "support/not_passed"
|
|
4
4
|
require_relative "support/concern"
|
5
5
|
|
6
6
|
require_relative "support/abstract_method"
|
7
|
+
require_relative "support/arguments"
|
7
8
|
require_relative "support/cache"
|
8
9
|
require_relative "support/castable"
|
9
10
|
require_relative "support/command"
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
##
|
4
|
+
#
|
5
|
+
#
|
6
|
+
module ConvenientService
|
7
|
+
module Utils
|
8
|
+
module Object
|
9
|
+
class InstanceVariableDelete < Support::Command
|
10
|
+
##
|
11
|
+
# @!attribute [r] object
|
12
|
+
# @return [Object]
|
13
|
+
#
|
14
|
+
attr_reader :object
|
15
|
+
|
16
|
+
##
|
17
|
+
# @!attribute [r] ivar_name
|
18
|
+
# @return [Symbol, String]
|
19
|
+
#
|
20
|
+
attr_reader :ivar_name
|
21
|
+
|
22
|
+
##
|
23
|
+
# @param object [Object]
|
24
|
+
# @param ivar_name [Symbol]
|
25
|
+
# @return [void]
|
26
|
+
#
|
27
|
+
def initialize(object, ivar_name)
|
28
|
+
@object = object
|
29
|
+
@ivar_name = ivar_name
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# @return [Object] Value of ivar. Can be any type.
|
34
|
+
#
|
35
|
+
def call
|
36
|
+
return object.remove_instance_variable(ivar_name) if object.instance_variable_defined?(ivar_name)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -6,6 +6,10 @@
|
|
6
6
|
module ConvenientService
|
7
7
|
module Utils
|
8
8
|
module Object
|
9
|
+
##
|
10
|
+
# Can be used instead of `return @ivar if defined? @ivar`.
|
11
|
+
# @see https://www.justinweiss.com/articles/4-simple-memoization-patterns-in-ruby-and-one-gem/
|
12
|
+
#
|
9
13
|
class InstanceVariableFetch < Support::Command
|
10
14
|
##
|
11
15
|
# @!attribute [r] object
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "object/instance_variable_delete"
|
3
4
|
require_relative "object/instance_variable_fetch"
|
4
5
|
require_relative "object/resolve_type"
|
5
6
|
|
@@ -7,6 +8,14 @@ module ConvenientService
|
|
7
8
|
module Utils
|
8
9
|
module Object
|
9
10
|
class << self
|
11
|
+
##
|
12
|
+
# @example
|
13
|
+
# ConvenientService::Utils::Object.instance_variable_delete("abc", :@foo)
|
14
|
+
#
|
15
|
+
def instance_variable_delete(...)
|
16
|
+
InstanceVariableDelete.call(...)
|
17
|
+
end
|
18
|
+
|
10
19
|
##
|
11
20
|
# @example
|
12
21
|
# ConvenientService::Utils::Object.instance_variable_fetch("abc", :@foo) { :bar }
|