convenient_service 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +1 -1
  5. data/ROADMAP.md +14 -3
  6. data/Taskfile.yml +30 -0
  7. data/convenient_service.gemspec +3 -1
  8. data/lib/convenient_service/aliases.rb +1 -0
  9. data/lib/convenient_service/common/plugins/assigns_attributes_in_constructor/using_active_model_attribute_assignment/concern.rb +0 -2
  10. data/lib/convenient_service/common/plugins/assigns_attributes_in_constructor/using_dry_initializer/concern.rb +0 -2
  11. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/container/commands/resolve_methods_middlewares_callers.rb +1 -24
  12. data/lib/convenient_service/dependencies.rb +7 -0
  13. data/lib/convenient_service/examples/dry/gemfile/dry_service/config.rb +3 -1
  14. data/lib/convenient_service/examples/rails/gemfile/rails_service/config.rb +3 -1
  15. data/lib/convenient_service/examples/standard/request_params/constants.rb +15 -0
  16. data/lib/convenient_service/examples/standard/request_params/entities/description.rb +40 -0
  17. data/lib/convenient_service/examples/standard/request_params/entities/format.rb +40 -0
  18. data/lib/convenient_service/examples/standard/request_params/entities/id.rb +47 -0
  19. data/lib/convenient_service/examples/standard/request_params/entities/logger.rb +21 -0
  20. data/lib/convenient_service/examples/standard/request_params/entities/request.rb +23 -0
  21. data/lib/convenient_service/examples/standard/request_params/entities/source.rb +40 -0
  22. data/lib/convenient_service/examples/standard/request_params/entities/tag.rb +40 -0
  23. data/lib/convenient_service/examples/standard/request_params/entities/title.rb +40 -0
  24. data/lib/convenient_service/examples/standard/request_params/entities.rb +11 -0
  25. data/lib/convenient_service/examples/standard/request_params/services/apply_default_param_values.rb +26 -0
  26. data/lib/convenient_service/examples/standard/request_params/services/cast_params.rb +38 -0
  27. data/lib/convenient_service/examples/standard/request_params/services/extract_params_from_body.rb +70 -0
  28. data/lib/convenient_service/examples/standard/request_params/services/extract_params_from_path.rb +62 -0
  29. data/lib/convenient_service/examples/standard/request_params/services/filter_out_unpermitted_params.rb +26 -0
  30. data/lib/convenient_service/examples/standard/request_params/services/log_request_params.rb +54 -0
  31. data/lib/convenient_service/examples/standard/request_params/services/merge_params.rb +26 -0
  32. data/lib/convenient_service/examples/standard/request_params/services/prepare.rb +65 -0
  33. data/lib/convenient_service/examples/standard/request_params/services/validate_casted_params.rb +94 -0
  34. data/lib/convenient_service/examples/standard/request_params/services/validate_uncasted_params.rb +72 -0
  35. data/lib/convenient_service/examples/standard/request_params/services.rb +13 -0
  36. data/lib/convenient_service/examples/standard/request_params/utils/array/wrap.rb +46 -0
  37. data/lib/convenient_service/examples/standard/request_params/utils/array.rb +21 -0
  38. data/lib/convenient_service/examples/standard/request_params/utils/http/request/parse_body.rb +42 -0
  39. data/lib/convenient_service/examples/standard/request_params/utils/http/request/parse_path.rb +40 -0
  40. data/lib/convenient_service/examples/standard/request_params/utils/http/request.rb +28 -0
  41. data/lib/convenient_service/examples/standard/request_params/utils/http.rb +3 -0
  42. data/lib/convenient_service/examples/standard/request_params/utils/integer/safe_parse.rb +31 -0
  43. data/lib/convenient_service/examples/standard/request_params/utils/integer.rb +25 -0
  44. data/lib/convenient_service/examples/standard/request_params/utils/json/safe_parse.rb +40 -0
  45. data/lib/convenient_service/examples/standard/request_params/utils/json.rb +21 -0
  46. data/lib/convenient_service/examples/standard/request_params/utils/object/blank.rb +34 -0
  47. data/lib/convenient_service/examples/standard/request_params/utils/object/present.rb +31 -0
  48. data/lib/convenient_service/examples/standard/request_params/utils/object.rb +26 -0
  49. data/lib/convenient_service/examples/standard/request_params/utils.rb +7 -0
  50. data/lib/convenient_service/examples/standard/request_params.rb +48 -0
  51. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/commands/generate_printable_method.rb +50 -0
  52. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/commands.rb +3 -0
  53. 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
  54. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments/commands/generate_printable_arguments.rb +100 -0
  55. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments/commands.rb +4 -0
  56. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments.rb +95 -0
  57. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/base.rb +87 -0
  58. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/return_its_value.rb +129 -0
  59. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/with_any_arguments.rb +37 -0
  60. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/with_concrete_arguments.rb +37 -0
  61. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/without_arguments.rb +37 -0
  62. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/values/base.rb +41 -0
  63. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/values/with_calling_original.rb +30 -0
  64. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/values/without_calling_original.rb +30 -0
  65. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings.rb +12 -0
  66. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings_collection/errors.rb +57 -0
  67. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings_collection.rb +171 -0
  68. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/delegation.rb +79 -0
  69. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities.rb +5 -0
  70. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher.rb +276 -0
  71. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities.rb +3 -0
  72. data/lib/convenient_service/rspec/matchers/custom/delegate_to.rb +58 -234
  73. data/lib/convenient_service/rspec/matchers/custom/singleton_prepend_module.rb +79 -0
  74. data/lib/convenient_service/rspec/matchers/custom.rb +1 -0
  75. data/lib/convenient_service/rspec/matchers/singleton_prepend_module.rb +13 -0
  76. data/lib/convenient_service/rspec/matchers.rb +2 -0
  77. data/lib/convenient_service/service/plugins/has_result_steps/concern.rb +25 -0
  78. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method.rb +3 -0
  79. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_caller.rb +8 -1
  80. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_direction.rb +3 -0
  81. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_key.rb +8 -1
  82. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_name.rb +9 -5
  83. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/concern/instance_methods.rb +4 -0
  84. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/base.rb +4 -0
  85. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment/commands/define_method_in_container.rb +74 -0
  86. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment/commands.rb +3 -0
  87. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment.rb +50 -0
  88. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers.rb +1 -0
  89. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values/reassignment.rb +43 -0
  90. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values.rb +3 -0
  91. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities.rb +1 -0
  92. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/errors.rb +22 -0
  93. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/concern/instance_methods.rb +13 -2
  94. data/lib/convenient_service/support/arguments/null_arguments.rb +28 -0
  95. data/lib/convenient_service/support/arguments.rb +87 -0
  96. data/lib/convenient_service/support/dependency_container/commands/assert_valid_scope.rb +32 -0
  97. data/lib/convenient_service/support/dependency_container/commands/import_method.rb +13 -23
  98. data/lib/convenient_service/support/dependency_container/commands.rb +1 -0
  99. data/lib/convenient_service/support/dependency_container/constants.rb +4 -2
  100. data/lib/convenient_service/support/dependency_container/entities/method.rb +2 -9
  101. data/lib/convenient_service/support/dependency_container/entities/namespace_collection.rb +0 -9
  102. data/lib/convenient_service/support/dependency_container/errors.rb +25 -0
  103. data/lib/convenient_service/support/dependency_container/export.rb +8 -0
  104. data/lib/convenient_service/support/dependency_container/import.rb +3 -1
  105. data/lib/convenient_service/support/version/null_version.rb +7 -0
  106. data/lib/convenient_service/support/version.rb +11 -1
  107. data/lib/convenient_service/support.rb +1 -0
  108. data/lib/convenient_service/utils/object/instance_variable_delete.rb +41 -0
  109. data/lib/convenient_service/utils/object/instance_variable_fetch.rb +4 -0
  110. data/lib/convenient_service/utils/object.rb +9 -0
  111. data/lib/convenient_service/utils/proc/display.rb +43 -0
  112. data/lib/convenient_service/utils/proc.rb +5 -0
  113. data/lib/convenient_service/version.rb +1 -1
  114. metadata +101 -4
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module RSpec
5
+ module Matchers
6
+ module Custom
7
+ class DelegateTo
8
+ module Entities
9
+ class Matcher
10
+ module Entities
11
+ class Delegation
12
+ ##
13
+ # @!attribute [r] object
14
+ # @return [Object] Can be any type.
15
+ #
16
+ attr_reader :object
17
+
18
+ ##
19
+ # @!attribute [r] method
20
+ # @return [Symbol]
21
+ #
22
+ attr_reader :method
23
+
24
+ ##
25
+ # @!attribute [r] arguments
26
+ # @return [ConvenientService::RSpec::Matchers::Custom::DelegateTo::Entities::Matcher::Entities::Delegation]
27
+ #
28
+ attr_reader :arguments
29
+
30
+ ##
31
+ # @param object [Object] Can be any type.
32
+ # @param method [Symbol]
33
+ # @param args [Array]
34
+ # @param kwargs [Hash]
35
+ # @param block [Proc]
36
+ # @return [void]
37
+ #
38
+ def initialize(object:, method:, args:, kwargs:, block:)
39
+ @object = object
40
+ @method = method
41
+ @arguments = Support::Arguments.new(*args, **kwargs, &block)
42
+ end
43
+
44
+ ##
45
+ # @return [Booleam]
46
+ #
47
+ def with_arguments?
48
+ arguments.any?
49
+ end
50
+
51
+ ##
52
+ # @return [Boolean]
53
+ #
54
+ def without_arguments?
55
+ !with_arguments?
56
+ end
57
+
58
+ ##
59
+ # @param other [Object]
60
+ # @return [Boolean]
61
+ #
62
+ def ==(other)
63
+ return unless other.instance_of?(self.class)
64
+
65
+ return false if object != other.object
66
+ return false if method != other.method
67
+ return false if arguments != other.arguments
68
+
69
+ true
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "entities/chainings"
4
+ require_relative "entities/chainings_collection"
5
+ require_relative "entities/delegation"
@@ -0,0 +1,276 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "matcher/commands"
4
+ require_relative "matcher/entities"
5
+
6
+ ##
7
+ # @internal
8
+ # IMPORTANT: This matcher has a dedicated end-user doc. Do NOT forget to update it when needed.
9
+ # https://github.com/marian13/convenient_service_docs/blob/main/docs/api/tests/rspec/matchers/delegate_to.mdx
10
+ #
11
+ module ConvenientService
12
+ module RSpec
13
+ module Matchers
14
+ module Custom
15
+ ##
16
+ # @internal
17
+ # specify {
18
+ # expect { method_class.cast(other, **options) }
19
+ # .to delegate_to(ConvenientService::Service::Plugins::HasResultSteps::Entities::Method::Commands::CastMethod, :call)
20
+ # .with_arguments(other: other, options: options)
21
+ # .and_return_its_value
22
+ # }
23
+ #
24
+ # { method_class.cast(other, **options) }
25
+ # # => block_expectation
26
+ #
27
+ # ConvenientService::Service::Plugins::HasResultSteps::Entities::Method::Commands::CastMethod
28
+ # # => object
29
+ #
30
+ # :call
31
+ # #=> method
32
+ #
33
+ # (other: other, options: options)
34
+ # # => expected_arguments
35
+ #
36
+ # and_return_its_value
37
+ # # => return_its_value_chaining
38
+ #
39
+ # NOTE: A similar (with different behaviour) matcher exists in `saharspec`.
40
+ # https://github.com/zverok/saharspec#send_messageobject-method-matcher
41
+ #
42
+ class DelegateTo
43
+ module Entities
44
+ class Matcher
45
+ include Support::Delegate
46
+
47
+ ##
48
+ # @!attribute [r] object
49
+ # @return [Object] Can be any type.
50
+ #
51
+ attr_reader :object
52
+
53
+ ##
54
+ # @!attribute [r] method
55
+ # @return [String, Symbol]
56
+ #
57
+ attr_reader :method
58
+
59
+ ##
60
+ # @!attribute [r] block_expectation
61
+ # @return [Proc]
62
+ #
63
+ attr_reader :block_expectation
64
+
65
+ ##
66
+ # @return [Boolean]
67
+ #
68
+ delegate :should_call_original?, to: :chainings
69
+
70
+ ##
71
+ # @param object [Object]
72
+ # @param method [String, Symbol]
73
+ # @param block_expectation [Proc]
74
+ # @return [void]
75
+ #
76
+ def initialize(object, method, block_expectation = nil)
77
+ ##
78
+ # TODO: `raise unless object.respond_to?(method)`.
79
+ # TODO: `any_block`.
80
+ # TODO: `with_warmup`.
81
+ #
82
+ @object = object
83
+ @method = method
84
+ @block_expectation = block_expectation
85
+ end
86
+
87
+ ##
88
+ # @param block_expectation [Proc]
89
+ # @return [Boolean]
90
+ #
91
+ def matches?(block_expectation)
92
+ @block_expectation = block_expectation
93
+
94
+ chainings.arguments = Entities::Chainings::SubMatchers::WithAnyArguments.new(matcher: self) unless chainings.has_arguments?
95
+ chainings.call_original = Entities::Chainings::Values::WithCallingOriginal.new(matcher: self) unless chainings.has_call_original?
96
+
97
+ chainings.sub_matchers_match?(block_expectation)
98
+ end
99
+
100
+ ##
101
+ # @internal
102
+ # NOTE: Required by RSpec.
103
+ # https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/custom-matchers/define-a-matcher-supporting-block-expectations
104
+ #
105
+ def supports_block_expectations?
106
+ true
107
+ end
108
+
109
+ ##
110
+ # @return [String]
111
+ #
112
+ def description
113
+ "delegate to `#{printable_method}`"
114
+ end
115
+
116
+ ##
117
+ # @return [String]
118
+ #
119
+ def failure_message
120
+ chainings.failure_message
121
+ end
122
+
123
+ ##
124
+ # @return [String]
125
+ #
126
+ def failure_message_when_negated
127
+ chainings.failure_message_when_negated
128
+ end
129
+
130
+ ##
131
+ # @return [ConvenientService::RSpec::Matchers::Custom::DelegateTo]
132
+ # @raise [ConvenientService::RSpec::Matchers::Custom::DelegateTo::Errors::ArgumentsChainingIsAlreadySet]
133
+ #
134
+ def with_arguments(...)
135
+ self.expected_arguments = Support::Arguments.new(...)
136
+
137
+ chainings.arguments = Entities::Chainings::SubMatchers::WithConcreteArguments.new(matcher: self)
138
+
139
+ self
140
+ end
141
+
142
+ ##
143
+ # @return [ConvenientService::RSpec::Matchers::Custom::DelegateTo]
144
+ # @raise [ConvenientService::RSpec::Matchers::Custom::DelegateTo::Errors::ArgumentsChainingIsAlreadySet]
145
+ #
146
+ def with_any_arguments
147
+ chainings.arguments = Entities::Chainings::SubMatchers::WithAnyArguments.new(matcher: self)
148
+
149
+ self
150
+ end
151
+
152
+ ##
153
+ # @return [ConvenientService::RSpec::Matchers::Custom::DelegateTo]
154
+ # @raise [ConvenientService::RSpec::Matchers::Custom::DelegateTo::Errors::ArgumentsChainingIsAlreadySet]
155
+ #
156
+ def without_arguments
157
+ chainings.arguments = Entities::Chainings::SubMatchers::WithoutArguments.new(matcher: self)
158
+
159
+ self
160
+ end
161
+
162
+ ##
163
+ # @return [ConvenientService::RSpec::Matchers::Custom::DelegateTo]
164
+ # @raise [ConvenientService::RSpec::Matchers::Custom::DelegateTo::Errors::ReturnItsValueChainingIsAlreadySet]
165
+ #
166
+ def and_return_its_value
167
+ chainings.return_its_value = Entities::Chainings::SubMatchers::ReturnItsValue.new(matcher: self)
168
+
169
+ self
170
+ end
171
+
172
+ ##
173
+ # @return [ConvenientService::RSpec::Matchers::Custom::DelegateTo]
174
+ #
175
+ def with_calling_original
176
+ chainings.call_original = Entities::Chainings::Values::WithCallingOriginal.new(matcher: self)
177
+
178
+ self
179
+ end
180
+
181
+ ##
182
+ # @return [ConvenientService::RSpec::Matchers::Custom::DelegateTo]
183
+ #
184
+ def without_calling_original
185
+ chainings.call_original = Entities::Chainings::Values::WithoutCallingOriginal.new(matcher: self)
186
+
187
+ self
188
+ end
189
+
190
+ ##
191
+ # @return [ConvenientService::Support::Arguments]
192
+ #
193
+ def expected_arguments
194
+ @expected_arguments ||= Support::Arguments.null_arguments
195
+ end
196
+
197
+ ##
198
+ # @param arguments [ConvenientService::Support::Arguments]
199
+ # @return [ConvenientService::Support::Arguments]
200
+ #
201
+ def expected_arguments=(arguments)
202
+ Utils::Object.instance_variable_delete(self, :@delegation_value)
203
+
204
+ @expected_arguments = arguments
205
+ end
206
+
207
+ ##
208
+ # @return [Object] Can be any type.
209
+ #
210
+ # @internal
211
+ # IMPORTANT: Must be refreshed when `expected_arguments` are reset.
212
+ #
213
+ def delegation_value
214
+ Utils::Object.instance_variable_fetch(self, :@delegation_value) do
215
+ object.__send__(
216
+ method,
217
+ *expected_arguments.args,
218
+ **expected_arguments.kwargs,
219
+ &expected_arguments.block
220
+ )
221
+ end
222
+ end
223
+
224
+ ##
225
+ # @return [ConvenientService::RSpec::Matchers::Custom::DelegateTo::Entities::Matcher::Entities::Chainings]
226
+ # @api private
227
+ #
228
+ def chainings
229
+ @chainings ||= Entities::ChainingsCollection.new(matcher: self)
230
+ end
231
+
232
+ ##
233
+ # @return [Array]
234
+ # @api private
235
+ #
236
+ def delegations
237
+ @delegations ||= []
238
+ end
239
+
240
+ ##
241
+ # @return [String]
242
+ #
243
+ def printable_method
244
+ @printable_method ||= Commands::GeneratePrintableMethod.call(object: object, method: method)
245
+ end
246
+
247
+ ##
248
+ # @return [String]
249
+ #
250
+ def printable_block_expectation
251
+ @printable_block_expectation ||= Utils::Proc.display(block_expectation)
252
+ end
253
+
254
+ ##
255
+ # @param other [Object] Can be any type.
256
+ # @return [Boolean, nil]
257
+ #
258
+ # @internal
259
+ # TODO: Unify ==(other) YARD tags.
260
+ #
261
+ def ==(other)
262
+ return unless other.instance_of?(self.class)
263
+
264
+ return false if object != other.object
265
+ return false if method != other.method
266
+ return false if block_expectation != other.block_expectation
267
+
268
+ true
269
+ end
270
+ end
271
+ end
272
+ end
273
+ end
274
+ end
275
+ end
276
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "entities/matcher"