convenient_service 0.9.0 → 0.10.1
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 +23 -0
- data/lib/convenient_service/common/plugins/can_have_user_provided_entity/commands/find_or_create_entity.rb +117 -0
- data/lib/convenient_service/common/plugins/can_have_user_provided_entity/commands.rb +3 -0
- data/lib/convenient_service/common/plugins/can_have_user_provided_entity/container.rb +17 -0
- data/lib/convenient_service/common/plugins/can_have_user_provided_entity/errors.rb +42 -0
- data/lib/convenient_service/common/plugins/can_have_user_provided_entity.rb +5 -0
- data/lib/convenient_service/common/plugins/has_internals/commands/create_internals_class.rb +21 -36
- data/lib/convenient_service/common/plugins/has_internals/concern.rb +1 -4
- data/lib/convenient_service/common/plugins.rb +1 -0
- data/lib/convenient_service/rspec/matchers/custom/results/base.rb +5 -0
- data/lib/convenient_service/service/plugins/can_have_stubbed_result/concern.rb +18 -1
- data/lib/convenient_service/service/plugins/has_result/commands/create_result_class.rb +13 -38
- data/lib/convenient_service/service/plugins/has_result/concern/class_methods.rb +4 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/concern/class_methods.rb +22 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/concern.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/code/concern/class_methods.rb +40 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/code/concern/instance_methods.rb +65 -0
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/code/{class_methods.rb → concern.rb} +12 -10
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/code.rb +2 -26
- data/lib/convenient_service/service/plugins/has_result_steps/commands/create_step_class.rb +19 -38
- data/lib/convenient_service/service/plugins/has_result_steps/entities/step_collection.rb +4 -1
- data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_cause.rb +16 -2
- data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_class.rb +40 -0
- data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_exception.rb +31 -6
- data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_message.rb +48 -0
- data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands.rb +2 -0
- data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/constants.rb +8 -0
- data/lib/convenient_service/utils/string/camelize.rb +6 -2
- data/lib/convenient_service/utils/string/demodulize.rb +50 -0
- data/lib/convenient_service/utils/string/split.rb +4 -4
- data/lib/convenient_service/utils/string.rb +5 -0
- data/lib/convenient_service/version.rb +1 -1
- metadata +14 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bea27107b54aa89400ea5c24d48db2087287b5c4d4aea9bdf3f860dc626bf864
|
|
4
|
+
data.tar.gz: 58a10038fa38887094a47b7dc00745244ac9ce0ef8daa5d1afa1fc8fd6ef893f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: faade4af5c03737c1954bfba9cbd9eaa5e31b13856e527cfcfb6e05db3f645729b81b65be8ed22e5f678845b1c3024224b9fe42eccb0bc3b27ed24ae5d8a2dec
|
|
7
|
+
data.tar.gz: 55fef97517812e04cf89eed571570728fd9a9f1ba2504422e3399600d5d71e27cc2723ced664b1eed147f0289b1cf0d0963805c8ffed45c0dfc173f0b4646505
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.1](https://github.com/marian13/convenient_service/compare/v0.10.0...v0.10.1) (2023-03-02)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **can_have_stubbed_result:** add thread-safety ([1962dcc](https://github.com/marian13/convenient_service/commit/1962dccdea29fb36c1b581e312329f41bb23c179))
|
|
9
|
+
|
|
10
|
+
## [0.10.0](https://github.com/marian13/convenient_service/compare/v0.9.0...v0.10.0) (2023-03-01)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* **utils:** introduce Utils::String.demodulize ([87a145a](https://github.com/marian13/convenient_service/commit/87a145a7742e1fce04fa40917dae6ee61e811c71))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **be_result:** commit config manually ([658e314](https://github.com/marian13/convenient_service/commit/658e3147cad50cb7226c8530227e704bb4c30945))
|
|
21
|
+
* **can_have_user_provided_entity:** use demodulized proto entity name ([f25e63c](https://github.com/marian13/convenient_service/commit/f25e63c23a9407ec8cc513311de506781e3cb5ca))
|
|
22
|
+
* **has_result_steps:** no validate ([6c14a57](https://github.com/marian13/convenient_service/commit/6c14a572b8fa2dfcb3afef26e64859bb67ac9729))
|
|
23
|
+
* **rescues_result_unhandled_exceptions:** add indentation for all message lines ([6458103](https://github.com/marian13/convenient_service/commit/6458103c362c66da42587b1a0bec4935b42606ac))
|
|
24
|
+
* **rescues_result_unhandled_exceptions:** use formatted message and class for cause ([c75c389](https://github.com/marian13/convenient_service/commit/c75c3891158ea58d28d8de3718a6296565a1cd84))
|
|
25
|
+
|
|
3
26
|
## [0.9.0](https://github.com/marian13/convenient_service/compare/v0.8.0...v0.9.0) (2023-02-22)
|
|
4
27
|
|
|
5
28
|
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ConvenientService
|
|
4
|
+
module Common
|
|
5
|
+
module Plugins
|
|
6
|
+
module CanHaveUserProvidedEntity
|
|
7
|
+
module Commands
|
|
8
|
+
class FindOrCreateEntity < Support::Command
|
|
9
|
+
##
|
|
10
|
+
# @!attribute [r] namespace
|
|
11
|
+
# @return [Class]
|
|
12
|
+
#
|
|
13
|
+
attr_reader :namespace
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# @!attribute [r] proto_entity
|
|
17
|
+
# @return [Class]
|
|
18
|
+
#
|
|
19
|
+
attr_reader :proto_entity
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# @param namespace [Class]
|
|
23
|
+
# @param proto_entity [Class]
|
|
24
|
+
# @return [void]
|
|
25
|
+
#
|
|
26
|
+
def initialize(namespace:, proto_entity:)
|
|
27
|
+
@namespace = namespace
|
|
28
|
+
@proto_entity = proto_entity
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# @return [void]
|
|
33
|
+
#
|
|
34
|
+
def call
|
|
35
|
+
raise Errors::ProtoEntityHasNoName.new(proto_entity: proto_entity) unless proto_entity_name
|
|
36
|
+
raise Errors::ProtoEntityHasNoConcern.new(proto_entity: proto_entity) unless proto_entity_concern
|
|
37
|
+
|
|
38
|
+
entity.include proto_entity_concern
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# @example Result for service.
|
|
42
|
+
#
|
|
43
|
+
# klass = ConvenientService::Common::Plugins::CanHaveUserProvidedEntity::Commands::FindOrCreateEntity.call(
|
|
44
|
+
# namespace: SomeService,
|
|
45
|
+
# proto_entity: ConvenientService::Service::Plugins::HasResult::Entities::Result
|
|
46
|
+
# )
|
|
47
|
+
#
|
|
48
|
+
# ##
|
|
49
|
+
# # `klass` is something like:
|
|
50
|
+
# #
|
|
51
|
+
# # class Result < ConvenientService::Service::Plugins::HasResult::Entities::Result # or just `class Result` if service (namespace) class defines its own.
|
|
52
|
+
# # include ConvenientService::Service::Plugins::HasResult::Entities::Result::Concern # (concern)
|
|
53
|
+
# #
|
|
54
|
+
# # class << self
|
|
55
|
+
# # def proto_entity
|
|
56
|
+
# # ##
|
|
57
|
+
# # # NOTE: Returns `proto_entity` passed to `FindOrCreateEntity`.
|
|
58
|
+
# # #
|
|
59
|
+
# # proto_entity
|
|
60
|
+
# # end
|
|
61
|
+
# #
|
|
62
|
+
# # def ==(other)
|
|
63
|
+
# # return unless other.respond_to?(:proto_entity)
|
|
64
|
+
# #
|
|
65
|
+
# # self.proto_entity == other.proto_entity
|
|
66
|
+
# # end
|
|
67
|
+
# # end
|
|
68
|
+
# # end
|
|
69
|
+
#
|
|
70
|
+
entity.class_exec(proto_entity) do |proto_entity|
|
|
71
|
+
define_singleton_method(:proto_entity) { proto_entity }
|
|
72
|
+
define_singleton_method(:==) { |other| self.proto_entity == other.proto_entity if other.respond_to?(:proto_entity) }
|
|
73
|
+
|
|
74
|
+
##
|
|
75
|
+
# TODO: `inspect`.
|
|
76
|
+
#
|
|
77
|
+
# define_singleton_method(:inspect) { "#{entity}(Prototyped by #{proto_entity})" }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
entity
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
##
|
|
86
|
+
# @return [Class]
|
|
87
|
+
#
|
|
88
|
+
def entity
|
|
89
|
+
@entity ||= Utils::Module.get_own_const(namespace, proto_entity_demodulized_name) || ::Class.new(proto_entity)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
##
|
|
93
|
+
# @return [String, nil]
|
|
94
|
+
#
|
|
95
|
+
def proto_entity_name
|
|
96
|
+
Utils::Object.memoize_including_falsy_values(self, :@proto_entity_name) { proto_entity.name }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
##
|
|
100
|
+
# @return [String]
|
|
101
|
+
#
|
|
102
|
+
def proto_entity_demodulized_name
|
|
103
|
+
@proto_entity_demodulized_name ||= Utils::String.demodulize(proto_entity_name)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
##
|
|
107
|
+
# @return [Module]
|
|
108
|
+
#
|
|
109
|
+
def proto_entity_concern
|
|
110
|
+
Utils::Object.memoize_including_falsy_values(self, :@proto_entity_concern) { Utils::Module.get_own_const(proto_entity, :Concern) }
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ConvenientService
|
|
4
|
+
module Common
|
|
5
|
+
module Plugins
|
|
6
|
+
module CanHaveUserProvidedEntity
|
|
7
|
+
module Container
|
|
8
|
+
include Support::DependencyContainer::Export
|
|
9
|
+
|
|
10
|
+
export :"commands.FindOrCreateEntity" do
|
|
11
|
+
Commands::FindOrCreateEntity
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ConvenientService
|
|
4
|
+
module Common
|
|
5
|
+
module Plugins
|
|
6
|
+
module CanHaveUserProvidedEntity
|
|
7
|
+
module Errors
|
|
8
|
+
class ProtoEntityHasNoName < ConvenientService::Error
|
|
9
|
+
def initialize(proto_entity:)
|
|
10
|
+
message = <<~TEXT
|
|
11
|
+
Proto entity `#{proto_entity}` has no name.
|
|
12
|
+
|
|
13
|
+
In other words:
|
|
14
|
+
|
|
15
|
+
proto_entity.name
|
|
16
|
+
# => nil
|
|
17
|
+
|
|
18
|
+
NOTE: Anonymous classes do NOT have names. Are you passing an anonymous class?
|
|
19
|
+
TEXT
|
|
20
|
+
|
|
21
|
+
super(message)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class ProtoEntityHasNoConcern < ConvenientService::Error
|
|
26
|
+
def initialize(proto_entity:)
|
|
27
|
+
message = <<~TEXT
|
|
28
|
+
Proto entity `#{proto_entity}` has no concern.
|
|
29
|
+
|
|
30
|
+
Have a look at `ConvenientService::Service::Plugins::HasResult::Entities::Result`.
|
|
31
|
+
|
|
32
|
+
It is an example of a valid proto entity.
|
|
33
|
+
TEXT
|
|
34
|
+
|
|
35
|
+
super(message)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -6,47 +6,32 @@ module ConvenientService
|
|
|
6
6
|
module HasInternals
|
|
7
7
|
module Commands
|
|
8
8
|
class CreateInternalsClass < Support::Command
|
|
9
|
-
|
|
9
|
+
include Support::DependencyContainer::Import
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
internals_class.include Entities::Internals::Concern
|
|
11
|
+
##
|
|
12
|
+
# @!attribute [r] entity_class
|
|
13
|
+
# @return Class
|
|
14
|
+
#
|
|
15
|
+
attr_reader :entity_class
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
# class << self
|
|
23
|
-
# def service_class
|
|
24
|
-
# ##
|
|
25
|
-
# # NOTE: Returns `service_class` passed to `CreateInternalsClass`.
|
|
26
|
-
# #
|
|
27
|
-
# service_class
|
|
28
|
-
# end
|
|
29
|
-
#
|
|
30
|
-
# def ==(other)
|
|
31
|
-
# return unless other.instance_of?(self.class)
|
|
32
|
-
#
|
|
33
|
-
# self.service_class == other.service_class
|
|
34
|
-
# end
|
|
35
|
-
# end
|
|
36
|
-
# end
|
|
37
|
-
#
|
|
38
|
-
internals_class.class_exec(service_class) do |service_class|
|
|
39
|
-
define_singleton_method(:service_class) { service_class }
|
|
40
|
-
define_singleton_method(:==) { |other| self.service_class == other.service_class if other.instance_of?(self.class) }
|
|
41
|
-
end
|
|
17
|
+
##
|
|
18
|
+
# @return Class
|
|
19
|
+
#
|
|
20
|
+
import :"commands.FindOrCreateEntity", from: Common::Plugins::CanHaveUserProvidedEntity::Container
|
|
42
21
|
|
|
43
|
-
|
|
22
|
+
##
|
|
23
|
+
# @param entity_class [Class]
|
|
24
|
+
# @return [void]
|
|
25
|
+
#
|
|
26
|
+
def initialize(entity_class:)
|
|
27
|
+
@entity_class = entity_class
|
|
44
28
|
end
|
|
45
29
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
30
|
+
##
|
|
31
|
+
# @return [Class]
|
|
32
|
+
#
|
|
33
|
+
def call
|
|
34
|
+
commands.FindOrCreateEntity.call(namespace: entity_class, proto_entity: Entities::Internals)
|
|
50
35
|
end
|
|
51
36
|
end
|
|
52
37
|
end
|
|
@@ -15,10 +15,7 @@ module ConvenientService
|
|
|
15
15
|
|
|
16
16
|
class_methods do
|
|
17
17
|
def internals_class
|
|
18
|
-
|
|
19
|
-
# TODO: Generic `CreateInternalsClass`.
|
|
20
|
-
#
|
|
21
|
-
@internals_class ||= Commands::CreateInternalsClass.call(service_class: self)
|
|
18
|
+
@internals_class ||= Commands::CreateInternalsClass.call(entity_class: self)
|
|
22
19
|
end
|
|
23
20
|
end
|
|
24
21
|
end
|
|
@@ -8,6 +8,7 @@ require_relative "plugins/normalizes_env"
|
|
|
8
8
|
require_relative "plugins/caches_constructor_params"
|
|
9
9
|
require_relative "plugins/caches_return_value"
|
|
10
10
|
require_relative "plugins/can_be_copied"
|
|
11
|
+
require_relative "plugins/can_have_user_provided_entity"
|
|
11
12
|
require_relative "plugins/has_callbacks"
|
|
12
13
|
require_relative "plugins/has_around_callbacks"
|
|
13
14
|
require_relative "plugins/has_constructor"
|
|
@@ -25,6 +25,11 @@ module ConvenientService
|
|
|
25
25
|
|
|
26
26
|
rules = []
|
|
27
27
|
|
|
28
|
+
##
|
|
29
|
+
# IMPORTANT: Makes `result.class.include?` from the following line idempotent.
|
|
30
|
+
#
|
|
31
|
+
result.commit_config! if result.respond_to?(:commit_config!)
|
|
32
|
+
|
|
28
33
|
rules << ->(result) { result.class.include?(Service::Plugins::HasResult::Entities::Result::Concern) }
|
|
29
34
|
|
|
30
35
|
##
|
|
@@ -22,7 +22,24 @@ module ConvenientService
|
|
|
22
22
|
def stubbed_results
|
|
23
23
|
return Support::Cache.new unless Support::Gems::RSpec.current_example
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
##
|
|
26
|
+
# IMPORTANT: ivar name with class and current thread enforces thread safety since there is no resource to share.
|
|
27
|
+
#
|
|
28
|
+
# TODO: Thread safety specs.
|
|
29
|
+
#
|
|
30
|
+
# NOTE: `self` is a service class in the current context. For example:
|
|
31
|
+
#
|
|
32
|
+
# before do
|
|
33
|
+
# stub_service(ConvenientService::Examples::Standard::Gemfile::Services::RunShell)
|
|
34
|
+
# .with_arguments(command: node_available_command)
|
|
35
|
+
# .to return_result(node_available_status)
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# # Then `self` is `ConvenientService::Examples::Standard::Gemfile::Services::RunShell`.
|
|
39
|
+
#
|
|
40
|
+
ivar_name = "@__convenient_service_stubbed_results__#{object_id}__#{Thread.current.object_id}__"
|
|
41
|
+
|
|
42
|
+
cache = Utils::Object.instance_variable_fetch(::RSpec.current_example, ivar_name) { Support::Cache.new }
|
|
26
43
|
|
|
27
44
|
cache.scope(self)
|
|
28
45
|
end
|
|
@@ -6,57 +6,32 @@ module ConvenientService
|
|
|
6
6
|
module HasResult
|
|
7
7
|
module Commands
|
|
8
8
|
class CreateResultClass < Support::Command
|
|
9
|
+
include Support::DependencyContainer::Import
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# @!attribute [r] service_class
|
|
13
|
+
# @return Class
|
|
14
|
+
#
|
|
9
15
|
attr_reader :service_class
|
|
10
16
|
|
|
11
17
|
##
|
|
12
|
-
# @
|
|
13
|
-
# @return [void]
|
|
18
|
+
# @return Class
|
|
14
19
|
#
|
|
15
|
-
|
|
16
|
-
@service_class = service_class
|
|
17
|
-
end
|
|
20
|
+
import :"commands.FindOrCreateEntity", from: Common::Plugins::CanHaveUserProvidedEntity::Container
|
|
18
21
|
|
|
19
22
|
##
|
|
23
|
+
# @param service_class [Class]
|
|
20
24
|
# @return [void]
|
|
21
25
|
#
|
|
22
|
-
def
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
##
|
|
26
|
-
# class Result < ConvenientService::Service::Plugins::HasResult::Entities::Result # or just `class Result` if service class defines its own.
|
|
27
|
-
# include ConvenientService::Service::Plugins::HasResult::Entities::Result::Concern
|
|
28
|
-
#
|
|
29
|
-
# class << self
|
|
30
|
-
# def service_class
|
|
31
|
-
# ##
|
|
32
|
-
# # NOTE: Returns `service_class` passed to `CreateResultClass`.
|
|
33
|
-
# #
|
|
34
|
-
# service_class
|
|
35
|
-
# end
|
|
36
|
-
#
|
|
37
|
-
# def ==(other)
|
|
38
|
-
# return unless other.instance_of?(self.class)
|
|
39
|
-
#
|
|
40
|
-
# self.service_class == other.service_class
|
|
41
|
-
# end
|
|
42
|
-
# end
|
|
43
|
-
# end
|
|
44
|
-
#
|
|
45
|
-
result_class.class_exec(service_class) do |service_class|
|
|
46
|
-
define_singleton_method(:service_class) { service_class }
|
|
47
|
-
define_singleton_method(:==) { |other| self.service_class == other.service_class if other.instance_of?(self.class) }
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
result_class
|
|
26
|
+
def initialize(service_class:)
|
|
27
|
+
@service_class = service_class
|
|
51
28
|
end
|
|
52
29
|
|
|
53
|
-
private
|
|
54
|
-
|
|
55
30
|
##
|
|
56
31
|
# @return [Class]
|
|
57
32
|
#
|
|
58
|
-
def
|
|
59
|
-
|
|
33
|
+
def call
|
|
34
|
+
commands.FindOrCreateEntity.call(namespace: service_class, proto_entity: Entities::Result)
|
|
60
35
|
end
|
|
61
36
|
end
|
|
62
37
|
end
|
|
@@ -80,6 +80,10 @@ module ConvenientService
|
|
|
80
80
|
# @api private
|
|
81
81
|
# @return [Class]
|
|
82
82
|
#
|
|
83
|
+
# @internal
|
|
84
|
+
# NOTE: A command instead of `import` is used in order to NOT pollute the public interface.
|
|
85
|
+
# TODO: Specs that prevent public interface accidental pollution.
|
|
86
|
+
#
|
|
83
87
|
def result_class
|
|
84
88
|
@result_class ||= Commands::CreateResultClass.call(service_class: self)
|
|
85
89
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ConvenientService
|
|
4
|
+
module Service
|
|
5
|
+
module Plugins
|
|
6
|
+
module HasResult
|
|
7
|
+
module Entities
|
|
8
|
+
class Result
|
|
9
|
+
module Plugins
|
|
10
|
+
module HasJsendStatusAndAttributes
|
|
11
|
+
module Concern
|
|
12
|
+
module ClassMethods
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "concern/class_methods"
|
|
3
4
|
require_relative "concern/instance_methods"
|
|
4
5
|
|
|
5
6
|
module ConvenientService
|
|
@@ -15,6 +16,8 @@ module ConvenientService
|
|
|
15
16
|
|
|
16
17
|
included do |result_class|
|
|
17
18
|
result_class.include InstanceMethods
|
|
19
|
+
|
|
20
|
+
result_class.extend ClassMethods
|
|
18
21
|
end
|
|
19
22
|
end
|
|
20
23
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ConvenientService
|
|
4
|
+
module Service
|
|
5
|
+
module Plugins
|
|
6
|
+
module HasResult
|
|
7
|
+
module Entities
|
|
8
|
+
class Result
|
|
9
|
+
module Plugins
|
|
10
|
+
module HasJsendStatusAndAttributes
|
|
11
|
+
module Entities
|
|
12
|
+
class Code
|
|
13
|
+
module Concern
|
|
14
|
+
module ClassMethods
|
|
15
|
+
##
|
|
16
|
+
# @param other [Object] Can be any type.
|
|
17
|
+
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJsendStatusAndAttributes::Entities::Code, nil]
|
|
18
|
+
#
|
|
19
|
+
def cast(other)
|
|
20
|
+
case other
|
|
21
|
+
when ::String
|
|
22
|
+
new(value: other.to_sym)
|
|
23
|
+
when ::Symbol
|
|
24
|
+
new(value: other)
|
|
25
|
+
when Code
|
|
26
|
+
new(value: other.value)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ConvenientService
|
|
4
|
+
module Service
|
|
5
|
+
module Plugins
|
|
6
|
+
module HasResult
|
|
7
|
+
module Entities
|
|
8
|
+
class Result
|
|
9
|
+
module Plugins
|
|
10
|
+
module HasJsendStatusAndAttributes
|
|
11
|
+
module Entities
|
|
12
|
+
class Code
|
|
13
|
+
module Concern
|
|
14
|
+
module InstanceMethods
|
|
15
|
+
##
|
|
16
|
+
# @!attribute value [r]
|
|
17
|
+
# @return [Symbol]
|
|
18
|
+
#
|
|
19
|
+
attr_reader :value
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# @param value [Symbol]
|
|
23
|
+
# @return [void]
|
|
24
|
+
#
|
|
25
|
+
def initialize(value:)
|
|
26
|
+
@value = value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# @param other [Object] Can be any type.
|
|
31
|
+
# @return [Boolean]
|
|
32
|
+
#
|
|
33
|
+
def ==(other)
|
|
34
|
+
casted = cast(other)
|
|
35
|
+
|
|
36
|
+
return unless casted
|
|
37
|
+
|
|
38
|
+
value == casted.value
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
##
|
|
42
|
+
# @return [String]
|
|
43
|
+
#
|
|
44
|
+
def to_s
|
|
45
|
+
@to_s ||= value.to_s
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
##
|
|
49
|
+
# @return [Symbol]
|
|
50
|
+
#
|
|
51
|
+
def to_sym
|
|
52
|
+
@to_sym ||= value.to_sym
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "concern/class_methods"
|
|
4
|
+
require_relative "concern/instance_methods"
|
|
5
|
+
|
|
3
6
|
module ConvenientService
|
|
4
7
|
module Service
|
|
5
8
|
module Plugins
|
|
@@ -10,16 +13,15 @@ module ConvenientService
|
|
|
10
13
|
module HasJsendStatusAndAttributes
|
|
11
14
|
module Entities
|
|
12
15
|
class Code
|
|
13
|
-
module
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
end
|
|
16
|
+
module Concern
|
|
17
|
+
include Support::Concern
|
|
18
|
+
|
|
19
|
+
included do |code_class|
|
|
20
|
+
code_class.include Support::Castable
|
|
21
|
+
|
|
22
|
+
code_class.include InstanceMethods
|
|
23
|
+
|
|
24
|
+
code_class.extend ClassMethods
|
|
23
25
|
end
|
|
24
26
|
end
|
|
25
27
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "code/
|
|
3
|
+
require_relative "code/concern"
|
|
4
4
|
|
|
5
5
|
module ConvenientService
|
|
6
6
|
module Service
|
|
@@ -12,31 +12,7 @@ module ConvenientService
|
|
|
12
12
|
module HasJsendStatusAndAttributes
|
|
13
13
|
module Entities
|
|
14
14
|
class Code
|
|
15
|
-
include
|
|
16
|
-
|
|
17
|
-
extend ClassMethods
|
|
18
|
-
|
|
19
|
-
attr_reader :value
|
|
20
|
-
|
|
21
|
-
def initialize(value:)
|
|
22
|
-
@value = value
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def ==(other)
|
|
26
|
-
casted = cast(other)
|
|
27
|
-
|
|
28
|
-
return unless casted
|
|
29
|
-
|
|
30
|
-
value == casted.value
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def to_s
|
|
34
|
-
@to_s ||= value.to_s
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def to_sym
|
|
38
|
-
@to_sym ||= value.to_sym
|
|
39
|
-
end
|
|
15
|
+
include Concern
|
|
40
16
|
end
|
|
41
17
|
end
|
|
42
18
|
end
|
|
@@ -6,51 +6,32 @@ module ConvenientService
|
|
|
6
6
|
module HasResultSteps
|
|
7
7
|
module Commands
|
|
8
8
|
class CreateStepClass < Support::Command
|
|
9
|
+
include Support::DependencyContainer::Import
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# @!attribute [r] service_class
|
|
13
|
+
# @return Class
|
|
14
|
+
#
|
|
9
15
|
attr_reader :service_class
|
|
10
16
|
|
|
17
|
+
##
|
|
18
|
+
# @return Class
|
|
19
|
+
#
|
|
20
|
+
import :"commands.FindOrCreateEntity", from: Common::Plugins::CanHaveUserProvidedEntity::Container
|
|
21
|
+
|
|
22
|
+
##
|
|
23
|
+
# @param service_class [Class]
|
|
24
|
+
# @return [void]
|
|
25
|
+
#
|
|
11
26
|
def initialize(service_class:)
|
|
12
27
|
@service_class = service_class
|
|
13
28
|
end
|
|
14
29
|
|
|
30
|
+
##
|
|
31
|
+
# @return [Class]
|
|
32
|
+
#
|
|
15
33
|
def call
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
##
|
|
19
|
-
# class Step < ConvenientService::Service::Plugins::HasResultSteps::Entities::Step # or just `class Step` if service class defines its own.
|
|
20
|
-
# include ConvenientService::Service::Plugins::HasResultSteps::Entities::Step::Concern
|
|
21
|
-
#
|
|
22
|
-
# class << self
|
|
23
|
-
# def service_class
|
|
24
|
-
# ##
|
|
25
|
-
# # NOTE: Returns `service_class` passed to `CreateResultClass`.
|
|
26
|
-
# #
|
|
27
|
-
# service_class
|
|
28
|
-
# end
|
|
29
|
-
#
|
|
30
|
-
# def ==(other)
|
|
31
|
-
# return unless other.instance_of?(self.class)
|
|
32
|
-
#
|
|
33
|
-
# self.service_class == other.service_class
|
|
34
|
-
# end
|
|
35
|
-
# end
|
|
36
|
-
# end
|
|
37
|
-
#
|
|
38
|
-
step_class.class_exec(service_class) do |service_class|
|
|
39
|
-
define_singleton_method(:service_class) { service_class }
|
|
40
|
-
|
|
41
|
-
##
|
|
42
|
-
# TODO: Fix a bug with `ap`.
|
|
43
|
-
#
|
|
44
|
-
define_singleton_method(:==) { |other| self.service_class == other.service_class if other.instance_of?(self.class) }
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
step_class
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
private
|
|
51
|
-
|
|
52
|
-
def step_class
|
|
53
|
-
@step_class ||= Utils::Module.get_own_const(service_class, :Step) || ::Class.new(Entities::Step)
|
|
34
|
+
commands.FindOrCreateEntity.call(namespace: service_class, proto_entity: Entities::Step)
|
|
54
35
|
end
|
|
55
36
|
end
|
|
56
37
|
end
|
|
@@ -20,7 +20,10 @@ module ConvenientService
|
|
|
20
20
|
def commit!
|
|
21
21
|
return false if committed?
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
##
|
|
24
|
+
# IMPORTANT: Temporarily removed `step.validate!` since it is neither thread-safe nor idempotent.
|
|
25
|
+
#
|
|
26
|
+
steps.each { |step| step.define! }.freeze
|
|
24
27
|
|
|
25
28
|
true
|
|
26
29
|
end
|
|
@@ -39,14 +39,28 @@ module ConvenientService
|
|
|
39
39
|
<<~MESSAGE.chomp
|
|
40
40
|
------------------
|
|
41
41
|
--- Caused by: ---
|
|
42
|
-
#{
|
|
43
|
-
|
|
42
|
+
#{formatted_cause_class}
|
|
43
|
+
#{formatted_cause_message}
|
|
44
44
|
#{formatted_cause_first_line}
|
|
45
45
|
MESSAGE
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
private
|
|
49
49
|
|
|
50
|
+
##
|
|
51
|
+
# @return [String]
|
|
52
|
+
#
|
|
53
|
+
def formatted_cause_class
|
|
54
|
+
Commands::FormatClass.call(klass: cause.class)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
##
|
|
58
|
+
# @return [String]
|
|
59
|
+
#
|
|
60
|
+
def formatted_cause_message
|
|
61
|
+
Commands::FormatMessage.call(message: cause.message)
|
|
62
|
+
end
|
|
63
|
+
|
|
50
64
|
##
|
|
51
65
|
# @return [String, nil]
|
|
52
66
|
#
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ConvenientService
|
|
4
|
+
module Service
|
|
5
|
+
module Plugins
|
|
6
|
+
module RescuesResultUnhandledExceptions
|
|
7
|
+
module Commands
|
|
8
|
+
class FormatClass < Support::Command
|
|
9
|
+
##
|
|
10
|
+
# @!attribute [r] klass
|
|
11
|
+
# @return [Class]
|
|
12
|
+
#
|
|
13
|
+
attr_reader :klass
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# @param klass [Class]
|
|
17
|
+
# @return [void]
|
|
18
|
+
#
|
|
19
|
+
def initialize(klass:)
|
|
20
|
+
@klass = klass
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# @return [String]
|
|
25
|
+
#
|
|
26
|
+
# @note Exceptions formatting is inspired by RSpec. It has almost the same output (at least for RSpec 3).
|
|
27
|
+
#
|
|
28
|
+
# @example Line.
|
|
29
|
+
#
|
|
30
|
+
# StandardError:
|
|
31
|
+
#
|
|
32
|
+
def call
|
|
33
|
+
"#{klass}:"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -64,6 +64,23 @@ module ConvenientService
|
|
|
64
64
|
# # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middleware.rb:73:in `call'
|
|
65
65
|
# # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/chain.rb:35:in `next'
|
|
66
66
|
#
|
|
67
|
+
# @example Exception with multiline message.
|
|
68
|
+
#
|
|
69
|
+
# StandardError:
|
|
70
|
+
# exception message first line
|
|
71
|
+
# exception message second line
|
|
72
|
+
# exception message third line
|
|
73
|
+
# # /gem/lib/convenient_service/factories/services.rb:120:in `result'
|
|
74
|
+
# # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/caller/commands/define_method_middlewares_caller.rb:116:in `call'
|
|
75
|
+
# # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/caller/commands/define_method_middlewares_caller.rb:116:in `block in result'
|
|
76
|
+
# # /gem/lib/convenient_service/dependencies/extractions/ruby_middleware/middleware/runner.rb:67:in `block (2 levels) in build_call_chain'
|
|
77
|
+
# # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/chain.rb:35:in `next'
|
|
78
|
+
# # /gem/lib/convenient_service/common/plugins/caches_return_value/middleware.rb:17:in `block in next'
|
|
79
|
+
# # /gem/lib/convenient_service/support/cache.rb:110:in `fetch'
|
|
80
|
+
# # /gem/lib/convenient_service/common/plugins/caches_return_value/middleware.rb:17:in `next'
|
|
81
|
+
# # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middleware.rb:73:in `call'
|
|
82
|
+
# # /gem/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/chain.rb:35:in `next'
|
|
83
|
+
#
|
|
67
84
|
# @example Exception with backtrace with more than 10 lines.
|
|
68
85
|
#
|
|
69
86
|
# StandardError:
|
|
@@ -107,7 +124,8 @@ module ConvenientService
|
|
|
107
124
|
#
|
|
108
125
|
def call
|
|
109
126
|
<<~MESSAGE.rstrip
|
|
110
|
-
#{
|
|
127
|
+
#{formatted_exception_class}
|
|
128
|
+
#{formatted_exception_message}
|
|
111
129
|
#{formatted_exception_backtrace}
|
|
112
130
|
#{formatted_exception_cause}
|
|
113
131
|
MESSAGE
|
|
@@ -118,11 +136,15 @@ module ConvenientService
|
|
|
118
136
|
##
|
|
119
137
|
# @return [String]
|
|
120
138
|
#
|
|
121
|
-
def
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
139
|
+
def formatted_exception_class
|
|
140
|
+
Commands::FormatClass.call(klass: exception.class)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
##
|
|
144
|
+
# @return [String]
|
|
145
|
+
#
|
|
146
|
+
def formatted_exception_message
|
|
147
|
+
Commands::FormatMessage.call(message: exception.message)
|
|
126
148
|
end
|
|
127
149
|
|
|
128
150
|
##
|
|
@@ -151,6 +173,9 @@ module ConvenientService
|
|
|
151
173
|
##
|
|
152
174
|
# @return [String]
|
|
153
175
|
#
|
|
176
|
+
# @note `exception.cause` may be `$!`.
|
|
177
|
+
# @see https://ruby-doc.org/core-2.7.0/Exception.html#method-i-cause
|
|
178
|
+
#
|
|
154
179
|
def formatted_exception_cause
|
|
155
180
|
Commands::FormatCause.call(cause: exception.cause)
|
|
156
181
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ConvenientService
|
|
4
|
+
module Service
|
|
5
|
+
module Plugins
|
|
6
|
+
module RescuesResultUnhandledExceptions
|
|
7
|
+
module Commands
|
|
8
|
+
class FormatMessage < Support::Command
|
|
9
|
+
##
|
|
10
|
+
# @!attribute [r] message
|
|
11
|
+
# @return [String, nil]
|
|
12
|
+
#
|
|
13
|
+
attr_reader :message
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# @param message [String, nil]
|
|
17
|
+
# @return [void]
|
|
18
|
+
#
|
|
19
|
+
def initialize(message:)
|
|
20
|
+
@message = message
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# @return [String]
|
|
25
|
+
#
|
|
26
|
+
# @note Message formatting is inspired by RSpec. It has almost the same output (at least for RSpec 3).
|
|
27
|
+
#
|
|
28
|
+
# @note Underscores are used to highlight spaces in docs, they are NOT included in the resulting message, check `FormatException` for a full example.
|
|
29
|
+
#
|
|
30
|
+
# @example Message.
|
|
31
|
+
# __exception message
|
|
32
|
+
#
|
|
33
|
+
# @example Multiline message.
|
|
34
|
+
# __exception message first line
|
|
35
|
+
# __exception message second line
|
|
36
|
+
# __exception message third line
|
|
37
|
+
#
|
|
38
|
+
# @see ConvenientService::Service::Plugins::RescuesResultUnhandledExceptions::Commands::FormatException
|
|
39
|
+
#
|
|
40
|
+
def call
|
|
41
|
+
message.to_s.chomp.split("\n").map { |line| line.prepend(Constants::MESSAGE_LINE_PREFIX) }.join("\n")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "commands/format_backtrace"
|
|
4
4
|
require_relative "commands/format_cause"
|
|
5
|
+
require_relative "commands/format_class"
|
|
5
6
|
require_relative "commands/format_line"
|
|
7
|
+
require_relative "commands/format_message"
|
|
6
8
|
|
|
7
9
|
require_relative "commands/format_exception"
|
data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/constants.rb
CHANGED
|
@@ -5,7 +5,15 @@ module ConvenientService
|
|
|
5
5
|
module Plugins
|
|
6
6
|
module RescuesResultUnhandledExceptions
|
|
7
7
|
module Constants
|
|
8
|
+
##
|
|
9
|
+
# @return [Integer]
|
|
10
|
+
#
|
|
8
11
|
DEFAULT_MAX_BACKTRACE_SIZE = 10
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# @return [String]
|
|
15
|
+
#
|
|
16
|
+
MESSAGE_LINE_PREFIX = " " * 2
|
|
9
17
|
end
|
|
10
18
|
end
|
|
11
19
|
end
|
|
@@ -13,7 +13,7 @@ module ConvenientService
|
|
|
13
13
|
class Camelize < Support::Command
|
|
14
14
|
##
|
|
15
15
|
# @!attribute [r] string
|
|
16
|
-
# @return [
|
|
16
|
+
# @return [String]
|
|
17
17
|
#
|
|
18
18
|
attr_reader :string
|
|
19
19
|
|
|
@@ -24,7 +24,7 @@ module ConvenientService
|
|
|
24
24
|
attr_reader :capitalize_first_letter
|
|
25
25
|
|
|
26
26
|
##
|
|
27
|
-
# @param string [
|
|
27
|
+
# @param string [#to_s]
|
|
28
28
|
# @return [void]
|
|
29
29
|
#
|
|
30
30
|
def initialize(string, capitalize_first_letter: true)
|
|
@@ -45,6 +45,10 @@ module ConvenientService
|
|
|
45
45
|
|
|
46
46
|
private
|
|
47
47
|
|
|
48
|
+
##
|
|
49
|
+
# @param part [String]
|
|
50
|
+
# @return [String]
|
|
51
|
+
#
|
|
48
52
|
def upcase_first_char(part)
|
|
49
53
|
return part if part.empty?
|
|
50
54
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ConvenientService
|
|
4
|
+
module Utils
|
|
5
|
+
module String
|
|
6
|
+
##
|
|
7
|
+
# @example
|
|
8
|
+
# demodulize('ActiveSupport::Inflector::Inflections') # => "Inflections"
|
|
9
|
+
# demodulize('Inflections') # => "Inflections"
|
|
10
|
+
# demodulize('::Inflections') # => "Inflections"
|
|
11
|
+
# demodulize('') # => ""
|
|
12
|
+
#
|
|
13
|
+
# @see https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-demodulize
|
|
14
|
+
#
|
|
15
|
+
class Demodulize < Support::Command
|
|
16
|
+
##
|
|
17
|
+
# @!attribute [r] string
|
|
18
|
+
# @return [String]
|
|
19
|
+
#
|
|
20
|
+
attr_reader :string
|
|
21
|
+
|
|
22
|
+
##
|
|
23
|
+
# @param string [#to_s]
|
|
24
|
+
# @return [void]
|
|
25
|
+
#
|
|
26
|
+
def initialize(string)
|
|
27
|
+
@string = string.to_s
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
# @return [String]
|
|
32
|
+
#
|
|
33
|
+
# @internal
|
|
34
|
+
# NOTE: Copied with cosmetic modifications from:
|
|
35
|
+
# - https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-demodulize
|
|
36
|
+
#
|
|
37
|
+
# NOTE: Modifications.
|
|
38
|
+
# - `string` is `path.to_s` is the original implementation.
|
|
39
|
+
# - Fixed Rubocop complaint about `Style/SlicingWithRange`.
|
|
40
|
+
# - Fixed Rubocop complaint about `Lint/AssignmentInCondition`.
|
|
41
|
+
#
|
|
42
|
+
def call
|
|
43
|
+
i = string.rindex("::")
|
|
44
|
+
|
|
45
|
+
i ? string[(i + 2)..] : string
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -6,7 +6,7 @@ module ConvenientService
|
|
|
6
6
|
class Split < Support::Command
|
|
7
7
|
##
|
|
8
8
|
# @!attribute [r] string
|
|
9
|
-
# @return [
|
|
9
|
+
# @return [String]
|
|
10
10
|
#
|
|
11
11
|
attr_reader :string
|
|
12
12
|
|
|
@@ -17,12 +17,12 @@ module ConvenientService
|
|
|
17
17
|
attr_reader :delimiters
|
|
18
18
|
|
|
19
19
|
##
|
|
20
|
-
# @param string [
|
|
20
|
+
# @param string [#to_s]
|
|
21
21
|
# @param delimiters [Array<String>]
|
|
22
22
|
# @return [void]
|
|
23
23
|
#
|
|
24
24
|
def initialize(string, *delimiters)
|
|
25
|
-
@string = string
|
|
25
|
+
@string = string.to_s
|
|
26
26
|
@delimiters = delimiters
|
|
27
27
|
end
|
|
28
28
|
|
|
@@ -33,7 +33,7 @@ module ConvenientService
|
|
|
33
33
|
# https://stackoverflow.com/a/51380514/12201472
|
|
34
34
|
#
|
|
35
35
|
def call
|
|
36
|
-
string.
|
|
36
|
+
string.split(::Regexp.union(delimiters))
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "string/camelize"
|
|
4
|
+
require_relative "string/demodulize"
|
|
4
5
|
require_relative "string/split"
|
|
5
6
|
|
|
6
7
|
module ConvenientService
|
|
@@ -11,6 +12,10 @@ module ConvenientService
|
|
|
11
12
|
Camelize.call(...)
|
|
12
13
|
end
|
|
13
14
|
|
|
15
|
+
def demodulize(...)
|
|
16
|
+
Demodulize.call(...)
|
|
17
|
+
end
|
|
18
|
+
|
|
14
19
|
def split(...)
|
|
15
20
|
Split.call(...)
|
|
16
21
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: convenient_service
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marian Kostyk
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-02
|
|
11
|
+
date: 2023-03-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: appraisal
|
|
@@ -391,6 +391,11 @@ files:
|
|
|
391
391
|
- lib/convenient_service/common/plugins/caches_return_value/middleware.rb
|
|
392
392
|
- lib/convenient_service/common/plugins/can_be_copied.rb
|
|
393
393
|
- lib/convenient_service/common/plugins/can_be_copied/concern.rb
|
|
394
|
+
- lib/convenient_service/common/plugins/can_have_user_provided_entity.rb
|
|
395
|
+
- lib/convenient_service/common/plugins/can_have_user_provided_entity/commands.rb
|
|
396
|
+
- lib/convenient_service/common/plugins/can_have_user_provided_entity/commands/find_or_create_entity.rb
|
|
397
|
+
- lib/convenient_service/common/plugins/can_have_user_provided_entity/container.rb
|
|
398
|
+
- lib/convenient_service/common/plugins/can_have_user_provided_entity/errors.rb
|
|
394
399
|
- lib/convenient_service/common/plugins/has_around_callbacks.rb
|
|
395
400
|
- lib/convenient_service/common/plugins/has_around_callbacks/concern.rb
|
|
396
401
|
- lib/convenient_service/common/plugins/has_around_callbacks/errors.rb
|
|
@@ -712,10 +717,13 @@ files:
|
|
|
712
717
|
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/commands.rb
|
|
713
718
|
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/commands/cast_jsend_attributes.rb
|
|
714
719
|
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/concern.rb
|
|
720
|
+
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/concern/class_methods.rb
|
|
715
721
|
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/concern/instance_methods.rb
|
|
716
722
|
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities.rb
|
|
717
723
|
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/code.rb
|
|
718
|
-
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/code/
|
|
724
|
+
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/code/concern.rb
|
|
725
|
+
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/code/concern/class_methods.rb
|
|
726
|
+
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/code/concern/instance_methods.rb
|
|
719
727
|
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/data.rb
|
|
720
728
|
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/data/class_methods.rb
|
|
721
729
|
- lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/message.rb
|
|
@@ -829,8 +837,10 @@ files:
|
|
|
829
837
|
- lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands.rb
|
|
830
838
|
- lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_backtrace.rb
|
|
831
839
|
- lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_cause.rb
|
|
840
|
+
- lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_class.rb
|
|
832
841
|
- lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_exception.rb
|
|
833
842
|
- lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_line.rb
|
|
843
|
+
- lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_message.rb
|
|
834
844
|
- lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/constants.rb
|
|
835
845
|
- lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/middleware.rb
|
|
836
846
|
- lib/convenient_service/service/plugins/wraps_result_in_db_transaction.rb
|
|
@@ -914,6 +924,7 @@ files:
|
|
|
914
924
|
- lib/convenient_service/utils/proc/exec_config.rb
|
|
915
925
|
- lib/convenient_service/utils/string.rb
|
|
916
926
|
- lib/convenient_service/utils/string/camelize.rb
|
|
927
|
+
- lib/convenient_service/utils/string/demodulize.rb
|
|
917
928
|
- lib/convenient_service/utils/string/split.rb
|
|
918
929
|
- lib/convenient_service/version.rb
|
|
919
930
|
- logo.png
|