convenient_service 0.20.0 → 0.21.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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -4
  3. data/lib/convenient_service/aliases.rb +113 -1
  4. data/lib/convenient_service/common/plugins/aliases.rb +69 -0
  5. data/lib/convenient_service/common/plugins/can_have_callbacks/entities/type_collection.rb +2 -2
  6. data/lib/convenient_service/common/plugins/has_instance_proxy/entities/instance_proxy.rb +8 -8
  7. data/lib/convenient_service/common.rb +14 -0
  8. data/lib/convenient_service/config.rb +8 -0
  9. data/lib/convenient_service/core/aliases.rb +84 -0
  10. data/lib/convenient_service/dependencies/built_in.rb +15 -1
  11. data/lib/convenient_service/dependencies/only_queries.rb +0 -6
  12. data/lib/convenient_service/dependencies/queries/gems/minitest.rb +55 -0
  13. data/lib/convenient_service/dependencies/queries/gems/rspec.rb +1 -1
  14. data/lib/convenient_service/dependencies/queries/gems.rb +2 -0
  15. data/lib/convenient_service/dependencies/queries/ruby.rb +2 -2
  16. data/lib/convenient_service/dependencies/queries.rb +67 -16
  17. data/lib/convenient_service/dependencies.rb +6 -6
  18. data/lib/convenient_service/extras/alias.rb +4 -1
  19. data/lib/convenient_service/feature/configs/standard.rb +34 -13
  20. data/lib/convenient_service/feature/core.rb +41 -0
  21. data/lib/convenient_service/feature/plugins/aliases.rb +29 -0
  22. data/lib/convenient_service/feature/plugins/can_have_rspec_stubbed_entries/concern.rb +34 -0
  23. data/lib/convenient_service/{rspec/helpers/classes/stub_entry/entities.rb → feature/plugins/can_have_rspec_stubbed_entries.rb} +1 -2
  24. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/commands/delete_feature_stubbed_entry.rb +71 -0
  25. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/commands/fetch_all_features_stubbed_entries_cache.rb +16 -2
  26. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/commands/fetch_feature_stubbed_entries_cache.rb +1 -1
  27. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/commands.rb +2 -0
  28. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/concern.rb +23 -0
  29. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/entities/feature_stub.rb +123 -0
  30. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/entities/feature_unstub.rb +122 -0
  31. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/entities/value_mock.rb +118 -0
  32. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/entities/value_unmock.rb +88 -0
  33. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/entities.rb +12 -0
  34. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries.rb +1 -14
  35. data/lib/convenient_service/feature/plugins/has_amazing_print_inspect/concern.rb +34 -0
  36. data/lib/convenient_service/feature/{configs/standard/commands.rb → plugins/has_amazing_print_inspect.rb} +1 -2
  37. data/lib/convenient_service/feature/plugins/has_awesome_print_inspect/concern.rb +34 -0
  38. data/lib/convenient_service/{rspec/helpers/classes/stub_service/entities.rb → feature/plugins/has_awesome_print_inspect.rb} +1 -2
  39. data/lib/convenient_service/feature/plugins/has_inspect/concern.rb +27 -0
  40. data/lib/convenient_service/{service/configs/standard/commands.rb → feature/plugins/has_inspect.rb} +1 -2
  41. data/lib/convenient_service/feature/plugins.rb +1 -0
  42. data/lib/convenient_service/feature.rb +16 -0
  43. data/lib/convenient_service/logger.rb +11 -12
  44. data/lib/convenient_service/rspec/helpers/classes.rb +0 -2
  45. data/lib/convenient_service/rspec/helpers/stub_entry.rb +23 -5
  46. data/lib/convenient_service/rspec/helpers/stub_service.rb +79 -11
  47. data/lib/convenient_service/rspec/matchers/classes/cache_its_value.rb +2 -1
  48. data/lib/convenient_service/rspec/matchers/classes/delegate_to.rb +3 -5
  49. data/lib/convenient_service/rspec/matchers/classes/include_config.rb +4 -0
  50. data/lib/convenient_service/service/configs/aliases.rb +42 -0
  51. data/lib/convenient_service/service/configs/standard/aliases.rb +24 -0
  52. data/lib/convenient_service/service/configs/standard/v1.rb +17 -0
  53. data/lib/convenient_service/service/configs/standard.rb +50 -25
  54. data/lib/convenient_service/service/core.rb +39 -0
  55. data/lib/convenient_service/service/plugins/aliases.rb +48 -0
  56. data/lib/convenient_service/service/plugins/can_have_rollbacks/middleware.rb +33 -2
  57. data/lib/convenient_service/service/plugins/can_have_rspec_stubbed_results/concern.rb +34 -0
  58. data/lib/convenient_service/service/plugins/can_have_rspec_stubbed_results.rb +8 -0
  59. data/lib/convenient_service/service/plugins/can_have_stubbed_results/commands/delete_service_stubbed_result.rb +63 -0
  60. data/lib/convenient_service/service/plugins/can_have_stubbed_results/commands/fetch_all_services_stubbed_results_cache.rb +15 -10
  61. data/lib/convenient_service/service/plugins/can_have_stubbed_results/commands/fetch_service_stubbed_results_cache.rb +3 -3
  62. data/lib/convenient_service/service/plugins/can_have_stubbed_results/commands.rb +2 -0
  63. data/lib/convenient_service/service/plugins/can_have_stubbed_results/concern.rb +25 -0
  64. data/lib/convenient_service/service/plugins/can_have_stubbed_results/entities/result_mock.rb +254 -0
  65. data/lib/convenient_service/service/plugins/can_have_stubbed_results/entities/result_unmock.rb +82 -0
  66. data/lib/convenient_service/service/plugins/can_have_stubbed_results/entities/service_stub.rb +135 -0
  67. data/lib/convenient_service/service/plugins/can_have_stubbed_results/entities/service_unstub.rb +113 -0
  68. data/lib/convenient_service/service/plugins/can_have_stubbed_results/entities.rb +12 -0
  69. data/lib/convenient_service/service/plugins/can_have_stubbed_results.rb +1 -14
  70. data/lib/convenient_service/service/plugins/forbids_convenient_service_entities_as_constructor_arguments/exceptions.rb +84 -0
  71. data/lib/convenient_service/service/plugins/forbids_convenient_service_entities_as_constructor_arguments/middleware.rb +84 -32
  72. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/concern.rb +42 -2
  73. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/can_be_called/exceptions.rb +3 -2
  74. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/status/concern/instance_methods.rb +5 -0
  75. data/lib/convenient_service/service.rb +16 -0
  76. data/lib/convenient_service/specification.rb +42 -12
  77. data/lib/convenient_service/support/backtrace_cleaner.rb +6 -7
  78. data/lib/convenient_service/support/middleware/stack_builder/entities/builders/custom.rb +4 -0
  79. data/lib/convenient_service/support/middleware/stack_builder/entities/builders/ruby_middleware.rb +4 -0
  80. data/lib/convenient_service/support/unique_value.rb +4 -1
  81. data/lib/convenient_service/support.rb +13 -0
  82. data/lib/convenient_service/utils/array/find_last.rb +18 -9
  83. data/lib/convenient_service/utils/class/display_name.rb +9 -9
  84. data/lib/convenient_service/utils/enumerable/find_last.rb +48 -0
  85. data/lib/convenient_service/utils/enumerable.rb +20 -0
  86. data/lib/convenient_service/utils/hash/assert_valid_keys.rb +4 -4
  87. data/lib/convenient_service/utils/hash/except.rb +5 -4
  88. data/lib/convenient_service/utils/hash/triple_equality_compare.rb +8 -8
  89. data/lib/convenient_service/utils/kernel/silence_warnings.rb +4 -4
  90. data/lib/convenient_service/utils/module/fetch_own_const.rb +36 -31
  91. data/lib/convenient_service/utils/module/get_namespace.rb +26 -21
  92. data/lib/convenient_service/utils/module/get_own_const.rb +21 -16
  93. data/lib/convenient_service/utils/object/clamp_class.rb +50 -47
  94. data/lib/convenient_service/utils/object/duck_class.rb +84 -81
  95. data/lib/convenient_service/utils/object/get_own_method.rb +1 -1
  96. data/lib/convenient_service/utils/object/instance_variable_delete.rb +0 -3
  97. data/lib/convenient_service/utils/object/instance_variable_fetch.rb +0 -3
  98. data/lib/convenient_service/utils/object/memoize_including_falsy_values.rb +0 -3
  99. data/lib/convenient_service/utils/object/resolve_type.rb +13 -11
  100. data/lib/convenient_service/utils/object/safe_send.rb +2 -0
  101. data/lib/convenient_service/utils/string/enclose.rb +11 -11
  102. data/lib/convenient_service/utils/string/tab.rb +60 -0
  103. data/lib/convenient_service/utils/string.rb +5 -0
  104. data/lib/convenient_service/utils.rb +9 -0
  105. data/lib/convenient_service/version.rb +8 -1
  106. data/lib/convenient_service.rb +232 -14
  107. metadata +37 -754
  108. data/lib/convenient_service/feature/configs/standard/commands/is_feature.rb +0 -39
  109. data/lib/convenient_service/feature/configs/standard/commands/is_feature_class.rb +0 -41
  110. data/lib/convenient_service/rspec/helpers/classes/stub_entry/constants.rb +0 -25
  111. data/lib/convenient_service/rspec/helpers/classes/stub_entry/entities/stubbed_feature.rb +0 -128
  112. data/lib/convenient_service/rspec/helpers/classes/stub_entry/entities/value_spec.rb +0 -79
  113. data/lib/convenient_service/rspec/helpers/classes/stub_entry.rb +0 -48
  114. data/lib/convenient_service/rspec/helpers/classes/stub_service/constants.rb +0 -25
  115. data/lib/convenient_service/rspec/helpers/classes/stub_service/entities/result_spec.rb +0 -211
  116. data/lib/convenient_service/rspec/helpers/classes/stub_service/entities/stubbed_service.rb +0 -119
  117. data/lib/convenient_service/rspec/helpers/classes/stub_service.rb +0 -43
  118. data/lib/convenient_service/service/configs/standard/commands/is_service.rb +0 -39
  119. data/lib/convenient_service/service/configs/standard/commands/is_service_class.rb +0 -41
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # @author Marian Kostyk <mariankostyk13895@gmail.com>
5
+ # @license LGPLv3 <https://www.gnu.org/licenses/lgpl-3.0.html>
6
+ ##
7
+
8
+ module ConvenientService
9
+ module Service
10
+ module Plugins
11
+ module CanHaveStubbedResults
12
+ module Entities
13
+ class ServiceUnstub
14
+ ##
15
+ # @param service_class [Class<ConvenientService::Service>]
16
+ # @return [void]
17
+ #
18
+ # @internal
19
+ # NOTE: `@arguments = nil` means "match any arguments".
20
+ #
21
+ def initialize(service_class:)
22
+ @service_class = service_class
23
+ @arguments = nil
24
+ end
25
+
26
+ ##
27
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ServiceUnstub]
28
+ #
29
+ # @internal
30
+ # NOTE: `@arguments = nil` means "match any arguments".
31
+ #
32
+ def with_any_arguments(...)
33
+ @arguments = nil
34
+
35
+ self
36
+ end
37
+
38
+ ##
39
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ServiceUnstub]
40
+ #
41
+ def with_arguments(...)
42
+ @arguments = Support::Arguments.new(...)
43
+
44
+ self
45
+ end
46
+
47
+ ##
48
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ServiceUnstub]
49
+ #
50
+ def without_arguments
51
+ @arguments = Support::Arguments.null_arguments
52
+
53
+ self
54
+ end
55
+
56
+ ##
57
+ # @param result_unmock [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultUnmock]
58
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ServiceStub]
59
+ #
60
+ def to(result_unmock)
61
+ @result_unmock = result_unmock.for(service_class, arguments)
62
+
63
+ @result_unmock.register
64
+
65
+ self
66
+ end
67
+
68
+ ##
69
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultUnmock]
70
+ #
71
+ def to_return_result_mock
72
+ @result_unmock = Entities::ResultUnmock.new(service_class: service_class, arguments: arguments)
73
+ end
74
+
75
+ ##
76
+ # @param other [Object] Can be any type.
77
+ # @return [Boolean, nil]
78
+ #
79
+ def ==(other)
80
+ return unless other.instance_of?(self.class)
81
+
82
+ return false if service_class != other.service_class
83
+ return false if arguments != other.arguments
84
+ return false if result_unmock != other.result_unmock
85
+
86
+ true
87
+ end
88
+
89
+ protected
90
+
91
+ ##
92
+ # @!attribute [r] service_class
93
+ # @return [Class<ConvenientService::Service>]
94
+ #
95
+ attr_reader :service_class
96
+
97
+ ##
98
+ # @!attribute [r] arguments
99
+ # @return [ConvenientService::Support::Arguments]
100
+ #
101
+ attr_reader :arguments
102
+
103
+ ##
104
+ # @!attribute [r] result_unmock
105
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultUnmock]
106
+ #
107
+ attr_reader :result_unmock
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # @author Marian Kostyk <mariankostyk13895@gmail.com>
5
+ # @license LGPLv3 <https://www.gnu.org/licenses/lgpl-3.0.html>
6
+ ##
7
+
8
+ require_relative "entities/service_stub"
9
+ require_relative "entities/service_unstub"
10
+
11
+ require_relative "entities/result_mock"
12
+ require_relative "entities/result_unmock"
@@ -7,18 +7,5 @@
7
7
 
8
8
  require_relative "can_have_stubbed_results/commands"
9
9
  require_relative "can_have_stubbed_results/concern"
10
+ require_relative "can_have_stubbed_results/entities"
10
11
  require_relative "can_have_stubbed_results/middleware"
11
-
12
- module ConvenientService
13
- module Service
14
- module Plugins
15
- module CanHaveStubbedResults
16
- class << self
17
- def set_service_stubbed_result(service, arguments, result)
18
- Commands::SetServiceStubbedResult[service: service, arguments: arguments, result: result]
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -38,6 +38,90 @@ module ConvenientService
38
38
  end
39
39
  end
40
40
 
41
+ class StatusPassedAsConstructorArgument < ::ConvenientService::Exception
42
+ def initialize_with_kwargs(selector:, service:, status:)
43
+ message = <<~TEXT
44
+ Status of `#{Utils::Class.display_name(status.result.service.class)}` result is passed as constructor argument `#{selector}` to `#{Utils::Class.display_name(service.class)}`.
45
+
46
+ It is an antipattern. It neglects the idea of steps.
47
+
48
+ Please, convert it to symbol or try to reorganize `#{Utils::Class.display_name(service.class)}` service.
49
+ TEXT
50
+
51
+ initialize(message)
52
+ end
53
+ end
54
+
55
+ class DataPassedAsConstructorArgument < ::ConvenientService::Exception
56
+ def initialize_with_kwargs(selector:, service:, data:)
57
+ message = <<~TEXT
58
+ Data of `#{Utils::Class.display_name(data.result.service.class)}` result is passed as constructor argument `#{selector}` to `#{Utils::Class.display_name(service.class)}`.
59
+
60
+ It is an antipattern. It neglects the idea of steps.
61
+
62
+ Please, convert it to hash or try to reorganize `#{Utils::Class.display_name(service.class)}` service.
63
+ TEXT
64
+
65
+ initialize(message)
66
+ end
67
+ end
68
+
69
+ class MessagePassedAsConstructorArgument < ::ConvenientService::Exception
70
+ def initialize_with_kwargs(selector:, service:, message:)
71
+ exception_message = <<~TEXT
72
+ Message of `#{Utils::Class.display_name(message.result.service.class)}` result is passed as constructor argument `#{selector}` to `#{Utils::Class.display_name(service.class)}`.
73
+
74
+ It is an antipattern. It neglects the idea of steps.
75
+
76
+ Please, convert it to string or try to reorganize `#{Utils::Class.display_name(service.class)}` service.
77
+ TEXT
78
+
79
+ initialize(exception_message)
80
+ end
81
+ end
82
+
83
+ class CodePassedAsConstructorArgument < ::ConvenientService::Exception
84
+ def initialize_with_kwargs(selector:, service:, code:)
85
+ message = <<~TEXT
86
+ Code of `#{Utils::Class.display_name(code.result.service.class)}` result is passed as constructor argument `#{selector}` to `#{Utils::Class.display_name(service.class)}`.
87
+
88
+ It is an antipattern. It neglects the idea of steps.
89
+
90
+ Please, convert it to symbol or try to reorganize `#{Utils::Class.display_name(service.class)}` service.
91
+ TEXT
92
+
93
+ initialize(message)
94
+ end
95
+ end
96
+
97
+ class FeaturePassedAsConstructorArgument < ::ConvenientService::Exception
98
+ def initialize_with_kwargs(selector:, service:, feature:)
99
+ message = <<~TEXT
100
+ Feature `#{Utils::Class.display_name(feature.class)}` is passed as constructor argument `#{selector}` to `#{Utils::Class.display_name(service.class)}`.
101
+
102
+ It is an antipattern. It neglects the idea of steps.
103
+
104
+ Please, try to reorganize `#{Utils::Class.display_name(service.class)}` service.
105
+ TEXT
106
+
107
+ initialize(message)
108
+ end
109
+ end
110
+
111
+ class EntityPassedAsConstructorArgument < ::ConvenientService::Exception
112
+ def initialize_with_kwargs(selector:, service:, entity:)
113
+ message = <<~TEXT
114
+ Convenient Service entity `#{Utils::Class.display_name(entity.class)}` is passed as constructor argument `#{selector}` to `#{Utils::Class.display_name(service.class)}`.
115
+
116
+ It is an antipattern. It neglects the idea of steps.
117
+
118
+ Please, try to reorganize `#{Utils::Class.display_name(service.class)}` service.
119
+ TEXT
120
+
121
+ initialize(message)
122
+ end
123
+ end
124
+
41
125
  class StepPassedAsConstructorArgument < ::ConvenientService::Exception
42
126
  def initialize_with_kwargs(selector:, service:, step:)
43
127
  message = <<~TEXT
@@ -25,9 +25,9 @@ module ConvenientService
25
25
  # @return [void]
26
26
  #
27
27
  def next(*args, **kwargs, &block)
28
- args.each_with_index { |value, index| validate!(:args, index, value) }
28
+ args.each_with_index { |value, index| validate!(index, value) }
29
29
 
30
- kwargs.each_pair { |key, value| validate!(:kwargs, key, value) }
30
+ kwargs.each_pair { |key, value| validate!(key, value) }
31
31
 
32
32
  chain.next(*args, **kwargs, &block)
33
33
  end
@@ -35,76 +35,128 @@ module ConvenientService
35
35
  private
36
36
 
37
37
  ##
38
- # @param collection_type [Symbol]
39
38
  # @param key [Integer, Symbol]
40
39
  # @param value [Object] Can be any type.
41
- # @raise [ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::ServicePassedAsConstructorArgument, ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::ResultPassedAsConstructorArgument, ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::StepPassedAsConstructorArgument]
40
+ # @raise [ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::ServicePassedAsConstructorArgument, ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::ResultPassedAsConstructorArgument, ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::StatusPassedAsConstructorArgument, ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::DataPassedAsConstructorArgument, ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::MessagePassedAsConstructorArgument, ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::CodePassedAsConstructorArgument, ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::StepPassedAsConstructorArgument, ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::FeaturePassedAsConstructorArgument]
42
41
  # @return [void]
43
42
  #
44
- def validate!(collection_type, key, value)
45
- refute_service!(collection_type, key, value)
46
- refute_result!(collection_type, key, value)
47
- refute_step!(collection_type, key, value)
43
+ def validate!(key, value)
44
+ return unless ::ConvenientService::Core.entity?(value)
45
+
46
+ refute_service!(key, value)
47
+ refute_result!(key, value)
48
+ refute_data!(key, value)
49
+ refute_message!(key, value)
50
+ refute_code!(key, value)
51
+ refute_status!(key, value)
52
+ refute_step!(key, value)
53
+ refute_feature!(key, value)
54
+
55
+ ::ConvenientService.raise Exceptions::EntityPassedAsConstructorArgument.new(selector: selector_from(key), service: service, entity: value)
48
56
  end
49
57
 
50
58
  ##
51
- # @param collection_type [Symbol]
52
59
  # @param key [Integer, Symbol]
53
60
  # @param value [Object] Can be any type.
54
61
  # @raise [ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::ServicePassedAsConstructorArgument]
55
62
  # @return [void]
56
63
  #
57
- # @internal
58
- # NOTE: `refute` is `!assert`.
59
- # - https://docs.seattlerb.org/minitest
60
- #
61
- def refute_service!(collection_type, key, value)
64
+ def refute_service!(key, value)
62
65
  return unless ::ConvenientService::Standard::Config.service?(value)
63
66
 
64
- ::ConvenientService.raise Exceptions::ServicePassedAsConstructorArgument.new(selector: selector_from(collection_type, key), service: service, other_service: value)
67
+ ::ConvenientService.raise Exceptions::ServicePassedAsConstructorArgument.new(selector: selector_from(key), service: service, other_service: value)
65
68
  end
66
69
 
67
70
  ##
68
- # @param collection_type [Symbol]
69
71
  # @param key [Integer, Symbol]
70
72
  # @param value [Object] Can be any type.
71
73
  # @raise [ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::ResultPassedAsConstructorArgument]
72
74
  # @return [void]
73
75
  #
74
- # @internal
75
- # NOTE: `refute` is `!assert`.
76
- # - https://docs.seattlerb.org/minitest
77
- #
78
- def refute_result!(collection_type, key, value)
76
+ def refute_result!(key, value)
79
77
  return unless ::ConvenientService::Plugins::Service::HasJSendResult.result?(value)
80
78
 
81
- ::ConvenientService.raise Exceptions::ResultPassedAsConstructorArgument.new(selector: selector_from(collection_type, key), service: service, result: value)
79
+ ::ConvenientService.raise Exceptions::ResultPassedAsConstructorArgument.new(selector: selector_from(key), service: service, result: value)
82
80
  end
83
81
 
84
82
  ##
85
- # @param collection_type [Symbol]
86
83
  # @param key [Integer, Symbol]
87
84
  # @param value [Object] Can be any type.
88
- # @raise [ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::StepPassedAsConstructorArgument]
85
+ # @raise [ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::DataPassedAsConstructorArgument]
86
+ # @return [void]
87
+ #
88
+ def refute_data!(key, value)
89
+ return unless ::ConvenientService::Service::Plugins::HasJSendResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Data.data?(value)
90
+
91
+ ::ConvenientService.raise Exceptions::DataPassedAsConstructorArgument.new(selector: selector_from(key), service: service, data: value)
92
+ end
93
+
94
+ ##
95
+ # @param key [Integer, Symbol]
96
+ # @param value [Object] Can be any type.
97
+ # @raise [ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::MessagePassedAsConstructorArgument]
98
+ # @return [void]
99
+ #
100
+ def refute_message!(key, value)
101
+ return unless ::ConvenientService::Service::Plugins::HasJSendResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Message.message?(value)
102
+
103
+ ::ConvenientService.raise Exceptions::MessagePassedAsConstructorArgument.new(selector: selector_from(key), service: service, message: value)
104
+ end
105
+
106
+ ##
107
+ # @param key [Integer, Symbol]
108
+ # @param value [Object] Can be any type.
109
+ # @raise [ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::CodePassedAsConstructorArgument]
110
+ # @return [void]
111
+ #
112
+ def refute_code!(key, value)
113
+ return unless ::ConvenientService::Service::Plugins::HasJSendResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Code.code?(value)
114
+
115
+ ::ConvenientService.raise Exceptions::CodePassedAsConstructorArgument.new(selector: selector_from(key), service: service, code: value)
116
+ end
117
+
118
+ ##
119
+ # @param key [Integer, Symbol]
120
+ # @param value [Object] Can be any type.
121
+ # @raise [ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::StatusPassedAsConstructorArgument]
89
122
  # @return [void]
90
123
  #
91
- # @internal
92
- # NOTE: `refute` is `!assert`.
93
- # - https://docs.seattlerb.org/minitest
124
+ def refute_status!(key, value)
125
+ return unless ::ConvenientService::Service::Plugins::HasJSendResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Status.status?(value)
126
+
127
+ ::ConvenientService.raise Exceptions::StatusPassedAsConstructorArgument.new(selector: selector_from(key), service: service, status: value)
128
+ end
129
+
130
+ ##
131
+ # @param key [Integer, Symbol]
132
+ # @param value [Object] Can be any type.
133
+ # @raise [ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::StepPassedAsConstructorArgument]
134
+ # @return [void]
94
135
  #
95
- def refute_step!(collection_type, key, value)
136
+ def refute_step!(key, value)
96
137
  return unless ::ConvenientService::Plugins::Service::CanHaveSteps.step?(value)
97
138
 
98
- ::ConvenientService.raise Exceptions::StepPassedAsConstructorArgument.new(selector: selector_from(collection_type, key), service: service, step: value)
139
+ ::ConvenientService.raise Exceptions::StepPassedAsConstructorArgument.new(selector: selector_from(key), service: service, step: value)
140
+ end
141
+
142
+ ##
143
+ # @param key [Integer, Symbol]
144
+ # @param value [Object] Can be any type.
145
+ # @raise [ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Exceptions::FeaturePassedAsConstructorArgument]
146
+ # @return [void]
147
+ #
148
+ def refute_feature!(key, value)
149
+ return unless ::ConvenientService::Feature::Standard::Config.feature?(value)
150
+
151
+ ::ConvenientService.raise Exceptions::FeaturePassedAsConstructorArgument.new(selector: selector_from(key), service: service, feature: value)
99
152
  end
100
153
 
101
154
  ##
102
- # @param collection_type [Symbol]
103
155
  # @param key [Integer, Symbol]
104
156
  # @return [String]
105
157
  #
106
- def selector_from(collection_type, key)
107
- "#{collection_type}[#{key.inspect}]"
158
+ def selector_from(key)
159
+ key.instance_of?(::Integer) ? "args[#{key}]" : "kwargs[:#{key}]"
108
160
  end
109
161
  end
110
162
  end
@@ -12,10 +12,50 @@ module ConvenientService
12
12
  module Entities
13
13
  class Result
14
14
  ##
15
- # @internal
16
- # This concern is needed for `CastResultClass` and `be_success`, `be_error`, `be_failure` matchers.
15
+ # @api private
16
+ # @since 1.0.0
17
17
  #
18
18
  module Concern
19
+ include Support::Concern
20
+
21
+ instance_methods do
22
+ ##
23
+ # Returns string representation of result.
24
+ #
25
+ # @api public
26
+ # @since 1.0.0
27
+ #
28
+ # @param format [Symbol]
29
+ # @return [String]
30
+ #
31
+ # @note Intended to be used for debugging purposes.
32
+ #
33
+ # @example Common usage.
34
+ # class Service
35
+ # include ConvenientService::Standard::Config
36
+ #
37
+ # def result
38
+ # success
39
+ # end
40
+ # end
41
+ #
42
+ # puts Service.result
43
+ # # <Service::Result status: :success>
44
+ # # => nil
45
+ #
46
+ # Service.result.to_s
47
+ # # => "<Service::Result status: :success>"
48
+ #
49
+ # Service.result.to_s(format: :inspect)
50
+ # # => "<Service::Result status: :success>"
51
+ #
52
+ # Service.result.to_s(format: :original)
53
+ # # => "#<Service::Result:0x00005639cd363000>"
54
+ #
55
+ def to_s(format: :inspect)
56
+ (format == :inspect) ? inspect : super()
57
+ end
58
+ end
19
59
  end
20
60
  end
21
61
  end
@@ -21,7 +21,7 @@ module ConvenientService
21
21
  #
22
22
  def initialize_with_kwargs(result:)
23
23
  message = <<~TEXT
24
- An `error` result of service `#{ConvenientService::Utils::Class.display_name(result.service.class)}` is called.
24
+ An `error` result of service `#{Utils::Class.display_name(result.service.class)}` is called.
25
25
 
26
26
  Only the `success` and `failure` results are expected to be called.
27
27
 
@@ -31,7 +31,8 @@ module ConvenientService
31
31
 
32
32
  If this `error` result is NOT expected, update the service logic.
33
33
 
34
- #{result.unsafe_message}
34
+ Original `error` result message:
35
+ #{Utils::String.tab(result.unsafe_message)}
35
36
  TEXT
36
37
 
37
38
  initialize(message)
@@ -142,9 +142,14 @@ module ConvenientService
142
142
  # @param statuses [Array<ConvenientService::Service::Plugins::HasJSendResult::Entities::Result::Plugins::HasJSendStatusAndAttributes::Entities::Status>]
143
143
  # @return [Boolean]
144
144
  #
145
+ # @internal
146
+ # NOTE: `any?(arg)` compares with `===`. For this method `==` is mandatory.
147
+ #
148
+ # rubocop:disable Performance/RedundantEqualityComparisonBlock
145
149
  def in?(statuses)
146
150
  statuses.any? { |status| self == status }
147
151
  end
152
+ # rubocop:enable Performance/RedundantEqualityComparisonBlock
148
153
 
149
154
  ##
150
155
  # @return [Hash{Symbol => Object}]
@@ -8,3 +8,19 @@
8
8
  require_relative "service/core"
9
9
  require_relative "service/plugins"
10
10
  require_relative "service/configs"
11
+
12
+ module ConvenientService
13
+ ##
14
+ # Intermediate module/namespace to access core, plugins and configs that can be applied only to services.
15
+ #
16
+ # @api private
17
+ # @since 1.0.0
18
+ # @return [Module]
19
+ #
20
+ # @note Service core expected to be used via {ConvenientService::Service::Core}.
21
+ # @note Service configs expected to be used via {ConvenientService::Standard::Config} alias.
22
+ # @note Service plugins expected to be used via {ConvenientService::Plugins::Service} alias.
23
+ #
24
+ module Service
25
+ end
26
+ end
@@ -5,50 +5,80 @@
5
5
  # @license LGPLv3 <https://www.gnu.org/licenses/lgpl-3.0.html>
6
6
  ##
7
7
 
8
- ##
9
- # Convenient Service gem specification.
10
- # @see https://guides.rubygems.org/specification-reference
11
- #
12
- # @internal
13
- # IMPORTNANT:
14
- # This module must NOT be loaded by the `lib` folder.
15
- # It is only intended for `gemspec`.
16
- # `bundle` loads it inside specs.
17
- #
18
8
  module ConvenientService
9
+ ##
10
+ # Convenient Service gem specification. Used mainly by `convenient_service.gemspec`.
11
+ #
12
+ # @since 1.0.0
13
+ # @see https://guides.rubygems.org/specification-reference
14
+ # @see https://github.com/marian13/convenient_service/blob/main/convenient_service.gemspec
15
+ #
16
+ # @internal
17
+ # IMPORTNANT: This module must NOT be loaded by the `lib` folder. It is only intended for `gemspec`. `bundle` loads it inside specs.
18
+ # NOTE: `Specification` module was created to be able to test `gemspec` content.
19
+ #
19
20
  module Specification
20
21
  ##
22
+ # Convenient Service gem name.
23
+ # It is used by the `gem install convenient_service` command or `gem "convenient_service"` Gemfile directive.
24
+ #
21
25
  # @return [String]
26
+ # @since 1.0.0
22
27
  #
23
28
  NAME = "convenient_service"
24
29
 
25
30
  ##
31
+ # Convenient Service gem author names.
32
+ #
26
33
  # @return [Array<String>]
34
+ # @since 1.0.0
27
35
  #
28
36
  AUTHORS = ["Marian Kostyk"].freeze
29
37
 
30
38
  ##
39
+ # Convenient Service gem author emails.
40
+ #
31
41
  # @return [Array<String>]
42
+ # @since 1.0.0
32
43
  #
33
44
  EMAIL = ["mariankostyk13895@gmail.com"].freeze
34
45
 
35
46
  ##
47
+ # Convenient Service gem homepage URL (GitHub repo URL). It contains references to the user docs, api docs, etc.
48
+ #
36
49
  # @return [String]
50
+ # @since 1.0.0
37
51
  #
38
52
  HOMEPAGE = "https://github.com/marian13/convenient_service"
39
53
 
40
54
  ##
55
+ # Convenient Service gem short summary.
56
+ #
41
57
  # @return [String]
58
+ # @since 1.0.0
59
+ #
60
+ # @internal
61
+ # NOTE: Keep summary in sync with the GitHub repo "About" section.
42
62
  #
43
63
  SUMMARY = <<~TEXT
44
- Ruby Service Objects with Steps.
64
+ Ruby Service Objects with Steps and more.
45
65
  TEXT
46
66
 
47
67
  ##
68
+ # Convenient Service gem general description.
69
+ #
48
70
  # @return [String]
71
+ # @since 1.0.0
72
+ #
73
+ # @internal
74
+ # NOTE: Keep description in sync with Convenient Service User Docs homepage.
49
75
  #
50
76
  DESCRIPTION = <<~TEXT
51
- Yet another approach to revisit the service object pattern in Ruby, but this time focusing on the unique, opinionated, moderately obtrusive, but not mandatory features.
77
+ Manage complex business logic in Ruby applications using Service Objects with Results and Steps.
78
+
79
+ Hide technical details with Configs, Concerns and Middlewares.
80
+
81
+ Group related code with Features and Entries.
52
82
  TEXT
53
83
  end
54
84
  end
@@ -5,16 +5,10 @@
5
5
  # @license LGPLv3 <https://www.gnu.org/licenses/lgpl-3.0.html>
6
6
  ##
7
7
 
8
- ##
9
- # @note Other gems are also trying to integrate with Rails Backtrace Cleaner.
10
- # @see https://github.com/sidekiq/sidekiq/pull/5796
11
- # @see https://github.com/sidekiq/sidekiq/issues/5589
12
- # @see https://github.com/appsignal/appsignal-ruby/issues/380
13
- #
14
8
  module ConvenientService
15
9
  module Support
16
10
  ##
17
- # Rails v7.1.2 Backtrace Cleaner descendant.
11
+ # Rails v8.0.2 Backtrace Cleaner descendant.
18
12
  # Has Convenient Service specific silencer - `add_convenient_service_silencer`.
19
13
  # By default, it uses only `add_stdlib_silencer` and `add_convenient_service_silencer`.
20
14
  #
@@ -23,6 +17,11 @@ module ConvenientService
23
17
  # @see https://twitter.com/websebdev/status/1375831554518360065?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1375831554518360065%7Ctwgr%5E459595174e71c0f1aa3826c89f2ffca0c3da6ea3%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Fwww.redditmedia.com%2Fmediaembed%2Fmegii9%2F%3Fresponsive%3Dtrueis_nightmode%3Dtrue
24
18
  # @see https://stackoverflow.com/questions/22727219/using-backtracecleaner-in-rails-console
25
19
  #
20
+ # @note Other gems are also trying to integrate with Rails Backtrace Cleaner.
21
+ # @see https://github.com/sidekiq/sidekiq/pull/5796
22
+ # @see https://github.com/sidekiq/sidekiq/issues/5589
23
+ # @see https://github.com/appsignal/appsignal-ruby/issues/380
24
+ #
26
25
  class BacktraceCleaner < Dependencies::Extractions::ActiveSupportBacktraceCleaner::BacktraceCleaner
27
26
  ##
28
27
  # @return [void]
@@ -60,9 +60,13 @@ module ConvenientService
60
60
  # @param some_middleware [#call<Hash>]
61
61
  # @return [Boolean]
62
62
  #
63
+ # NOTE: `any?(arg)` compares with `===`. For this method `==` is mandatory.
64
+ #
65
+ # rubocop:disable Performance/RedundantEqualityComparisonBlock
63
66
  def has?(some_middleware)
64
67
  stack.any? { |middleware| middleware == some_middleware }
65
68
  end
69
+ # rubocop:enable Performance/RedundantEqualityComparisonBlock
66
70
 
67
71
  ##
68
72
  # @return [Boolean]
@@ -49,9 +49,13 @@ module ConvenientService
49
49
  # @param some_middleware [#call<Hash>]
50
50
  # @return [Boolean]
51
51
  #
52
+ # NOTE: `any?(arg)` compares with `===`. For this method `==` is mandatory.
53
+ #
54
+ # rubocop:disable Performance/RedundantEqualityComparisonBlock
52
55
  def has?(some_middleware)
53
56
  stack.any? { |middleware| middleware == [some_middleware, [], nil] }
54
57
  end
58
+ # rubocop:enable Performance/RedundantEqualityComparisonBlock
55
59
 
56
60
  ##
57
61
  # @return [Boolean]