convenient_service 0.5.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +49 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +1 -1
  5. data/ROADMAP.md +26 -4
  6. data/Taskfile.yml +30 -0
  7. data/convenient_service.gemspec +5 -2
  8. data/lib/convenient_service/aliases.rb +2 -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/common/plugins/has_around_callbacks/middleware.rb +24 -4
  12. data/lib/convenient_service/common/plugins/has_callbacks/container.rb +17 -0
  13. data/lib/convenient_service/common/plugins/has_callbacks/entities/callback.rb +98 -5
  14. data/lib/convenient_service/common/plugins/has_callbacks/middleware.rb +25 -4
  15. data/lib/convenient_service/common/plugins/has_callbacks.rb +1 -0
  16. data/lib/convenient_service/common/plugins.rb +1 -1
  17. data/lib/convenient_service/configs/standard.rb +25 -12
  18. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/container/commands/resolve_methods_middlewares_callers.rb +1 -24
  19. data/lib/convenient_service/dependencies.rb +19 -0
  20. data/lib/convenient_service/examples/dry/gemfile/dry_service/config.rb +4 -2
  21. data/lib/convenient_service/examples/rails/gemfile/rails_service/config.rb +4 -2
  22. data/lib/convenient_service/examples/rails/gemfile/services/format.rb +35 -6
  23. data/lib/convenient_service/examples/rails/gemfile/services/format_header.rb +1 -2
  24. data/lib/convenient_service/examples/rails/gemfile/services/merge_sections.rb +25 -0
  25. data/lib/convenient_service/examples/rails/gemfile/services/replace_file_content.rb +37 -0
  26. data/lib/convenient_service/examples/rails/gemfile/services.rb +8 -4
  27. data/lib/convenient_service/examples/standard/gemfile/services/format.rb +45 -6
  28. data/lib/convenient_service/examples/standard/gemfile/services/merge_sections.rb +52 -0
  29. data/lib/convenient_service/examples/standard/gemfile/services/replace_file_content.rb +48 -0
  30. data/lib/convenient_service/examples/standard/gemfile/services.rb +8 -4
  31. data/lib/convenient_service/examples/standard/request_params/constants.rb +15 -0
  32. data/lib/convenient_service/examples/standard/request_params/entities/description.rb +40 -0
  33. data/lib/convenient_service/examples/standard/request_params/entities/format.rb +40 -0
  34. data/lib/convenient_service/examples/standard/request_params/entities/id.rb +47 -0
  35. data/lib/convenient_service/examples/standard/request_params/entities/logger.rb +21 -0
  36. data/lib/convenient_service/examples/standard/request_params/entities/request.rb +23 -0
  37. data/lib/convenient_service/examples/standard/request_params/entities/source.rb +40 -0
  38. data/lib/convenient_service/examples/standard/request_params/entities/tag.rb +40 -0
  39. data/lib/convenient_service/examples/standard/request_params/entities/title.rb +40 -0
  40. data/lib/convenient_service/examples/standard/request_params/entities.rb +11 -0
  41. data/lib/convenient_service/examples/standard/request_params/services/apply_default_param_values.rb +26 -0
  42. data/lib/convenient_service/examples/standard/request_params/services/cast_params.rb +38 -0
  43. data/lib/convenient_service/examples/standard/request_params/services/extract_params_from_body.rb +70 -0
  44. data/lib/convenient_service/examples/standard/request_params/services/extract_params_from_path.rb +62 -0
  45. data/lib/convenient_service/examples/standard/request_params/services/filter_out_unpermitted_params.rb +26 -0
  46. data/lib/convenient_service/examples/standard/request_params/services/log_request_params.rb +54 -0
  47. data/lib/convenient_service/examples/standard/request_params/services/merge_params.rb +26 -0
  48. data/lib/convenient_service/examples/standard/request_params/services/prepare.rb +65 -0
  49. data/lib/convenient_service/examples/standard/request_params/services/validate_casted_params.rb +94 -0
  50. data/lib/convenient_service/examples/standard/request_params/services/validate_uncasted_params.rb +72 -0
  51. data/lib/convenient_service/examples/standard/request_params/services.rb +13 -0
  52. data/lib/convenient_service/examples/standard/request_params/utils/array/wrap.rb +46 -0
  53. data/lib/convenient_service/examples/standard/request_params/utils/array.rb +21 -0
  54. data/lib/convenient_service/examples/standard/request_params/utils/http/request/parse_body.rb +42 -0
  55. data/lib/convenient_service/examples/standard/request_params/utils/http/request/parse_path.rb +40 -0
  56. data/lib/convenient_service/examples/standard/request_params/utils/http/request.rb +28 -0
  57. data/lib/convenient_service/examples/standard/request_params/utils/http.rb +3 -0
  58. data/lib/convenient_service/examples/standard/request_params/utils/integer/safe_parse.rb +31 -0
  59. data/lib/convenient_service/examples/standard/request_params/utils/integer.rb +25 -0
  60. data/lib/convenient_service/examples/standard/request_params/utils/json/safe_parse.rb +40 -0
  61. data/lib/convenient_service/examples/standard/request_params/utils/json.rb +21 -0
  62. data/lib/convenient_service/examples/standard/request_params/utils/object/blank.rb +34 -0
  63. data/lib/convenient_service/examples/standard/request_params/utils/object/present.rb +31 -0
  64. data/lib/convenient_service/examples/standard/request_params/utils/object.rb +26 -0
  65. data/lib/convenient_service/examples/standard/request_params/utils.rb +7 -0
  66. data/lib/convenient_service/examples/standard/request_params.rb +48 -0
  67. data/lib/convenient_service/factories/arguments.rb +43 -0
  68. data/lib/convenient_service/factories/results.rb +214 -0
  69. data/lib/convenient_service/factories/services.rb +189 -0
  70. data/lib/convenient_service/factories/step/instance.rb +32 -0
  71. data/lib/convenient_service/factories/step.rb +3 -0
  72. data/lib/convenient_service/factories/steps.rb +126 -0
  73. data/lib/convenient_service/factories.rb +22 -0
  74. data/lib/convenient_service/factory.rb +21 -0
  75. data/lib/convenient_service/rspec/matchers/custom/be_descendant_of.rb +2 -2
  76. data/lib/convenient_service/rspec/matchers/custom/be_direct_descendant_of.rb +2 -2
  77. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/commands/generate_printable_method.rb +50 -0
  78. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/commands.rb +3 -0
  79. 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
  80. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments/commands/generate_printable_arguments.rb +100 -0
  81. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments/commands.rb +4 -0
  82. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments.rb +95 -0
  83. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/base.rb +87 -0
  84. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/return_its_value.rb +129 -0
  85. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/with_any_arguments.rb +37 -0
  86. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/with_concrete_arguments.rb +37 -0
  87. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/without_arguments.rb +37 -0
  88. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/values/base.rb +41 -0
  89. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/values/with_calling_original.rb +30 -0
  90. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/values/without_calling_original.rb +30 -0
  91. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings.rb +12 -0
  92. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings_collection/errors.rb +57 -0
  93. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings_collection.rb +171 -0
  94. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/delegation.rb +79 -0
  95. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities.rb +5 -0
  96. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher.rb +276 -0
  97. data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities.rb +3 -0
  98. data/lib/convenient_service/rspec/matchers/custom/delegate_to.rb +66 -233
  99. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/find_result_method_step.rb +74 -0
  100. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/find_result_result_method_step.rb +66 -0
  101. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/find_result_service_step.rb +48 -0
  102. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/generate_expected_step_part.rb +42 -0
  103. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/generate_got_step_part.rb +42 -0
  104. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/match_result_step.rb +89 -0
  105. data/lib/convenient_service/rspec/matchers/custom/results/base/commands.rb +10 -0
  106. data/lib/convenient_service/rspec/matchers/custom/results/base/errors.rb +35 -0
  107. data/lib/convenient_service/rspec/matchers/custom/results/base.rb +73 -12
  108. data/lib/convenient_service/rspec/matchers/custom/singleton_prepend_module.rb +79 -0
  109. data/lib/convenient_service/rspec/matchers/custom.rb +1 -0
  110. data/lib/convenient_service/rspec/matchers/singleton_prepend_module.rb +13 -0
  111. data/lib/convenient_service/rspec/matchers.rb +2 -0
  112. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/concern.rb +85 -0
  113. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/initialize/middleware.rb +27 -0
  114. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/initialize.rb +3 -0
  115. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/to_kwargs/middleware.rb +25 -0
  116. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/to_kwargs.rb +3 -0
  117. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result.rb +5 -0
  118. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/concern/instance_methods.rb +7 -1
  119. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/data.rb +4 -0
  120. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/concern.rb +27 -0
  121. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/initialize/middleware.rb +27 -0
  122. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/initialize.rb +3 -0
  123. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/to_kwargs/middleware.rb +25 -0
  124. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/to_kwargs.rb +3 -0
  125. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step.rb +5 -0
  126. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins.rb +2 -0
  127. data/lib/convenient_service/service/plugins/has_result_method_steps.rb +0 -2
  128. data/lib/convenient_service/service/plugins/has_result_steps/concern.rb +40 -4
  129. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method.rb +3 -0
  130. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_caller.rb +8 -1
  131. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_direction.rb +3 -0
  132. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_key.rb +8 -1
  133. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_name.rb +9 -5
  134. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/define_method_in_container.rb +2 -2
  135. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/concern/instance_methods.rb +4 -0
  136. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/base.rb +4 -0
  137. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment/commands/define_method_in_container.rb +74 -0
  138. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment/commands.rb +3 -0
  139. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment.rb +50 -0
  140. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers.rb +1 -0
  141. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values/reassignment.rb +43 -0
  142. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values.rb +3 -0
  143. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities.rb +1 -0
  144. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/errors.rb +22 -0
  145. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/concern/instance_methods.rb +39 -3
  146. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/plugins/can_have_parent_result/middleware.rb +23 -0
  147. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/plugins/can_have_parent_result.rb +3 -0
  148. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/plugins.rb +1 -0
  149. data/lib/convenient_service/service/plugins/has_result_steps/entities/step_collection.rb +13 -0
  150. data/lib/convenient_service/service/plugins/has_result_steps/middleware.rb +18 -4
  151. data/lib/convenient_service/services/run_method_in_organizer.rb +28 -0
  152. data/lib/convenient_service/services/run_own_method_in_organizer.rb +64 -0
  153. data/lib/convenient_service/{service/plugins/has_result_method_steps/services.rb → services.rb} +0 -1
  154. data/lib/convenient_service/support/arguments/null_arguments.rb +28 -0
  155. data/lib/convenient_service/support/arguments.rb +87 -0
  156. data/lib/convenient_service/support/copyable.rb +6 -2
  157. data/lib/convenient_service/support/dependency_container/commands/assert_valid_scope.rb +32 -0
  158. data/lib/convenient_service/support/dependency_container/commands/import_method.rb +13 -23
  159. data/lib/convenient_service/support/dependency_container/commands.rb +1 -0
  160. data/lib/convenient_service/support/dependency_container/constants.rb +4 -2
  161. data/lib/convenient_service/support/dependency_container/entities/method.rb +2 -9
  162. data/lib/convenient_service/support/dependency_container/entities/namespace_collection.rb +0 -9
  163. data/lib/convenient_service/support/dependency_container/errors.rb +26 -1
  164. data/lib/convenient_service/support/dependency_container/export.rb +8 -0
  165. data/lib/convenient_service/support/dependency_container/import.rb +3 -1
  166. data/lib/convenient_service/support/not_passed.rb +3 -1
  167. data/lib/convenient_service/support/version/null_version.rb +7 -0
  168. data/lib/convenient_service/support/version.rb +11 -1
  169. data/lib/convenient_service/support.rb +1 -0
  170. data/lib/convenient_service/utils/object/instance_variable_delete.rb +41 -0
  171. data/lib/convenient_service/utils/object/instance_variable_fetch.rb +4 -0
  172. data/lib/convenient_service/utils/object.rb +9 -0
  173. data/lib/convenient_service/utils/proc/display.rb +43 -0
  174. data/lib/convenient_service/utils/proc.rb +5 -0
  175. data/lib/convenient_service/version.rb +1 -1
  176. data/lib/convenient_service.rb +6 -0
  177. data/logo.png +0 -0
  178. metadata +154 -10
  179. data/lib/convenient_service/service/plugins/has_result_method_steps/errors.rb +0 -23
  180. data/lib/convenient_service/service/plugins/has_result_method_steps/services/method_step_config.rb +0 -55
  181. data/lib/convenient_service/service/plugins/has_result_method_steps/services/run_method_in_organizer.rb +0 -30
  182. data/lib/convenient_service/service/plugins/has_result_method_steps/services/run_own_method_in_organizer.rb +0 -52
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module RSpec
5
+ module Matchers
6
+ module Custom
7
+ module Results
8
+ class Base
9
+ module Commands
10
+ class MatchResultStep < Support::Command
11
+ ##
12
+ # @!attribute result [r]
13
+ # @return [ConvenientService::Service::Plugins::HasResult::Entities::Result]
14
+ #
15
+ attr_reader :result
16
+
17
+ ##
18
+ # @!attribute step [r]
19
+ # @return [Class, Symbol]
20
+ #
21
+ attr_reader :step
22
+
23
+ ##
24
+ # @param result [ConvenientService::Service::Plugins::HasResult::Entities::Result]
25
+ # @param step [Class, Symbol]
26
+ # @return [void]
27
+ #
28
+ def initialize(result:, step:)
29
+ @result = result
30
+ @step = step
31
+ end
32
+
33
+ ##
34
+ # @return [Boolean]
35
+ # @raise [ConvenientService::RSpec::Matchers::Custom::Results::Base::Errors::InvalidStep]
36
+ #
37
+ def call
38
+ case step
39
+ when ::Class then match_service_step?
40
+ when :result then match_result_method_step?
41
+ when ::Symbol then match_method_step?
42
+ when nil then match_without_step?
43
+ else raise Errors::InvalidStep.new(step: step)
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ ##
50
+ # @return [Boolean]
51
+ #
52
+ def match_service_step?
53
+ service_step = Commands::FindResultServiceStep.call(result: result, service_class: step)
54
+
55
+ Utils::Bool.to_bool(service_step)
56
+ end
57
+
58
+ ##
59
+ # @return [Boolean]
60
+ #
61
+ def match_result_method_step?
62
+ result_method_step = Commands::FindResultResultMethodStep.call(result: result)
63
+
64
+ Utils::Bool.to_bool(result_method_step)
65
+ end
66
+
67
+ ##
68
+ # @return [Boolean]
69
+ #
70
+ def match_method_step?
71
+ method_step = Commands::FindResultMethodStep.call(result: result, method_name: step)
72
+
73
+ Utils::Bool.to_bool(method_step)
74
+ end
75
+
76
+ ##
77
+ # @return [Boolean]
78
+ #
79
+ def match_without_step?
80
+ result.step.nil?
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "commands/find_result_method_step"
4
+ require_relative "commands/find_result_result_method_step"
5
+ require_relative "commands/find_result_service_step"
6
+
7
+ require_relative "commands/generate_expected_step_part"
8
+ require_relative "commands/generate_got_step_part"
9
+
10
+ require_relative "commands/match_result_step"
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module RSpec
5
+ module Matchers
6
+ module Custom
7
+ module Results
8
+ class Base
9
+ module Errors
10
+ class InvalidStep < ConvenientService::Error
11
+ def initialize(step:)
12
+ message = <<~TEXT
13
+ Step `#{step}` is NOT valid.
14
+
15
+ `of_step` only accepts a Class or a Symbol. For example:
16
+
17
+ be_success.of_step(ReadFileContent)
18
+ be_success.of_step(:validate_path)
19
+ be_success.of_step(:result)
20
+
21
+ If you need to confirm that `result` has NO step - use `without_step` instead.
22
+
23
+ be_success.without_step
24
+ TEXT
25
+
26
+ super(message)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "base/commands"
4
+ require_relative "base/errors"
5
+
3
6
  module ConvenientService
4
7
  module RSpec
5
8
  module Matchers
@@ -24,7 +27,8 @@ module ConvenientService
24
27
 
25
28
  rules << ->(result) { result.class.include?(Service::Plugins::HasResult::Entities::Result::Concern) }
26
29
  rules << ->(result) { result.status.in?(statuses) }
27
- rules << ->(result) { result.service.instance_of?(service_class) } if used_of?
30
+ rules << ->(result) { result.service.instance_of?(service_class) } if used_of_service?
31
+ rules << ->(result) { Commands::MatchResultStep.call(result: result, step: step) } if used_of_step?
28
32
  rules << ->(result) { result.unsafe_data == data } if used_data?
29
33
  rules << ->(result) { result.unsafe_message == message } if used_message?
30
34
  rules << ->(result) { result.unsafe_code == code } if used_code?
@@ -38,14 +42,14 @@ module ConvenientService
38
42
  # @return [String]
39
43
  #
40
44
  def description
41
- default_text
45
+ expected_parts
42
46
  end
43
47
 
44
48
  ##
45
49
  # @return [String]
46
50
  #
47
51
  def failure_message
48
- "expected that `#{result}` would #{default_text}"
52
+ "expected that `#{result.service.class}` result would #{default_text}"
49
53
  end
50
54
 
51
55
  ##
@@ -55,7 +59,7 @@ module ConvenientService
55
59
  # https://relishapp.com/rspec/rspec-expectations/v/3-11/docs/custom-matchers/define-a-custom-matcher#overriding-the-failure-message-when-negated
56
60
  #
57
61
  def failure_message_when_negated
58
- "expected that #{result} would NOT #{default_text}"
62
+ "expected that `#{result.service.class}` result would NOT #{default_text}"
59
63
  end
60
64
 
61
65
  ##
@@ -131,12 +135,31 @@ module ConvenientService
131
135
  # @param service_class [Class]
132
136
  # @return [ConvenientService::RSpec::Matchers::Custom::Results::Base]
133
137
  #
134
- def of(service_class)
138
+ def of_service(service_class)
135
139
  chain[:service_class] = service_class
136
140
 
137
141
  self
138
142
  end
139
143
 
144
+ ##
145
+ # @param step [Class, Symbol]
146
+ # @return [ConvenientService::RSpec::Matchers::Custom::Results::Base]
147
+ #
148
+ def of_step(step)
149
+ chain[:step] = step
150
+
151
+ self
152
+ end
153
+
154
+ ##
155
+ # @return [ConvenientService::RSpec::Matchers::Custom::Results::Base]
156
+ #
157
+ def without_step
158
+ chain[:step] = nil
159
+
160
+ self
161
+ end
162
+
140
163
  private
141
164
 
142
165
  ##
@@ -149,21 +172,45 @@ module ConvenientService
149
172
  # @return [String]
150
173
  #
151
174
  def default_text
175
+ expected_parts << "\n\n" << got_parts
176
+ end
177
+
178
+ ##
179
+ # @return [String]
180
+ #
181
+ # @internal
182
+ # TODO: Align for easier visual comparison.
183
+ # TODO: New line for each attribute.
184
+ #
185
+ def expected_parts
152
186
  parts = []
153
187
 
154
188
  parts << "be #{printable_statuses}"
155
- parts << "of `#{service_class}`" if used_of?
189
+ parts << "of service `#{service_class}`" if used_of_service?
190
+ parts << Commands::GenerateExpectedStepPart.call(step: step) if used_of_step?
156
191
  parts << "with data `#{data}`" if used_data?
157
192
  parts << "with message `#{message}`" if used_message?
158
193
  parts << "with code `#{code}`" if used_code?
159
194
 
160
- parts << "\n\n"
195
+ parts.join(" ")
196
+ end
197
+
198
+ ##
199
+ # @return [String]
200
+ #
201
+ # @internal
202
+ # TODO: Align for easier visual comparison.
203
+ # TODO: New line for each attribute.
204
+ #
205
+ def got_parts
206
+ parts = []
161
207
 
162
208
  parts << "got `#{result.status}`"
163
- parts << "of `#{result.service.class}`" if used_of?
164
- parts << "with data `#{result.data}`" if used_data?
165
- parts << "with message `#{result.message}`" if used_message?
166
- parts << "with code `#{result.code}`" if used_code?
209
+ parts << "of service `#{result.service.class}`" if used_of_service?
210
+ parts << Commands::GenerateGotStepPart.call(result: result) if used_of_step?
211
+ parts << "with data `#{result.unsafe_data}`" if used_data?
212
+ parts << "with message `#{result.unsafe_message}`" if used_message?
213
+ parts << "with code `#{result.unsafe_code}`" if used_code?
167
214
 
168
215
  parts.join(" ")
169
216
  end
@@ -192,10 +239,17 @@ module ConvenientService
192
239
  ##
193
240
  # @return [Boolean]
194
241
  #
195
- def used_of?
242
+ def used_of_service?
196
243
  chain.key?(:service_class)
197
244
  end
198
245
 
246
+ ##
247
+ # @return [Boolean]
248
+ #
249
+ def used_of_step?
250
+ chain.key?(:step)
251
+ end
252
+
199
253
  ##
200
254
  # @return [Hash]
201
255
  #
@@ -224,6 +278,13 @@ module ConvenientService
224
278
  Utils::Object.instance_variable_fetch(self, :@service_class) { chain[:service_class] }
225
279
  end
226
280
 
281
+ ##
282
+ # @return [Class]
283
+ #
284
+ def step
285
+ Utils::Object.instance_variable_fetch(self, :@step) { chain[:step] }
286
+ end
287
+
227
288
  ##
228
289
  # @return [Hash]
229
290
  #
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module RSpec
5
+ module Matchers
6
+ module Custom
7
+ ##
8
+ # @internal
9
+ # class User
10
+ # include InstanceMethods
11
+ #
12
+ # singleton_class.include ClassMethods # or more common `extend ClassMethods`.
13
+ #
14
+ # prepend InstanceMethods
15
+ #
16
+ # singleton_class.prepend ClassMethods # no short form like `extend`.
17
+ # end
18
+ #
19
+ class SingletonPrependModule
20
+ ##
21
+ # @param mod [Module]
22
+ # @return [void]
23
+ #
24
+ # @internal
25
+ # NOTE: `mod` since `module` is a keyword.
26
+ #
27
+ def initialize(mod)
28
+ @mod = mod
29
+ end
30
+
31
+ ##
32
+ # @param klass [Class, Module]
33
+ # @return [Boolean]
34
+ #
35
+ def matches?(klass)
36
+ @klass = klass
37
+
38
+ klass.singleton_class.ancestors.take_while { |ancestor| ancestor != klass }.include?(mod)
39
+ end
40
+
41
+ ##
42
+ # @return [String]
43
+ #
44
+ def description
45
+ "`singleton_class.prepend` module `#{mod}`"
46
+ end
47
+
48
+ ##
49
+ # @return [String]
50
+ #
51
+ def failure_message
52
+ "expected `#{klass}` to `singleton_class.prepend` module `#{mod}`"
53
+ end
54
+
55
+ ##
56
+ # @return [String]
57
+ #
58
+ def failure_message_when_negated
59
+ "expected `#{klass}` NOT to `singleton_class.prepend` module `#{mod}`"
60
+ end
61
+
62
+ private
63
+
64
+ ##
65
+ # @!attribute [r] klass
66
+ # @return [Class, Module]
67
+ #
68
+ attr_reader :klass
69
+
70
+ ##
71
+ # @!attribute [r] mod
72
+ # @return [Module]
73
+ #
74
+ attr_reader :mod
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -14,3 +14,4 @@ require_relative "custom/have_attr_writer"
14
14
  require_relative "custom/include_module"
15
15
  require_relative "custom/prepend_module"
16
16
  require_relative "custom/results"
17
+ require_relative "custom/singleton_prepend_module"
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module RSpec
5
+ module Matchers
6
+ module SingletonPrependModule
7
+ def singleton_prepend_module(...)
8
+ Custom::SingletonPrependModule.new(...)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -16,6 +16,7 @@ require_relative "matchers/have_attr_writer"
16
16
  require_relative "matchers/include_module"
17
17
  require_relative "matchers/prepend_module"
18
18
  require_relative "matchers/results"
19
+ require_relative "matchers/singleton_prepend_module"
19
20
 
20
21
  module ConvenientService
21
22
  module RSpec
@@ -37,6 +38,7 @@ module ConvenientService
37
38
  include Matchers::IncludeModule
38
39
  include Matchers::PrependModule
39
40
  include Matchers::Results
41
+ include Matchers::SingletonPrependModule
40
42
  end
41
43
  end
42
44
  end
@@ -0,0 +1,85 @@
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 CanHaveParentResult
11
+ module Concern
12
+ include Support::Concern
13
+
14
+ instance_methods do
15
+ ##
16
+ # @return [ConvenientService::Service::Plugins::HasResult::Entities::Result, nil]
17
+ #
18
+ def parent
19
+ @parent ||= internals.cache[:parent]
20
+ end
21
+
22
+ ##
23
+ # @param include_self [Boolean]
24
+ # @return [Array<ConvenientService::Service::Plugins::HasResult::Entities::Result>]
25
+ #
26
+ # @internal
27
+ # Without enumerator `parents` method is roughly equivalent to the following code:
28
+ #
29
+ # def parents(include_self: false)
30
+ # parents = []
31
+ #
32
+ # parents << self if include_self
33
+ #
34
+ # ##
35
+ # # NOTE: Empty parentheses are used to force a method call
36
+ # # https://docs.ruby-lang.org/en/2.7.0/syntax/assignment_rdoc.html#label-Local+Variables+and+Methods
37
+ # #
38
+ # parent = parent()
39
+ #
40
+ # while parent
41
+ # parents << parent
42
+ #
43
+ # parent = parent.parent
44
+ # end
45
+ #
46
+ # parents
47
+ # end
48
+ #
49
+ def parents(include_self: false)
50
+ parents_enum(include_self: include_self).to_a
51
+ end
52
+
53
+ ##
54
+ # @param include_self [Boolean]
55
+ # @return [Enumerator<ConvenientService::Service::Plugins::HasResult::Entities::Result>]
56
+ #
57
+ # @see https://ruby-doc.org/core-2.7.0/Enumerator.html
58
+ #
59
+ def parents_enum(include_self: false)
60
+ ::Enumerator.new do |yielder|
61
+ yielder.yield(self) if include_self
62
+
63
+ ##
64
+ # NOTE: Empty parentheses are used to force a method call
65
+ # https://docs.ruby-lang.org/en/2.7.0/syntax/assignment_rdoc.html#label-Local+Variables+and+Methods
66
+ #
67
+ parent = parent()
68
+
69
+ while parent
70
+ yielder.yield(parent)
71
+
72
+ parent = parent.parent
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,27 @@
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 CanHaveParentResult
11
+ module Initialize
12
+ class Middleware < Core::MethodChainMiddleware
13
+ def next(*args, **kwargs, &block)
14
+ entity.internals.cache[:parent] = kwargs[:parent]
15
+
16
+ chain.next(*args, **kwargs, &block)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "initialize/middleware"
@@ -0,0 +1,25 @@
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 CanHaveParentResult
11
+ module ToKwargs
12
+ class Middleware < Core::MethodChainMiddleware
13
+ def next(...)
14
+ chain.next(...).merge(parent: entity.parent)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "to_kwargs/middleware"
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "can_have_parent_result/concern"
4
+ require_relative "can_have_parent_result/initialize"
5
+ require_relative "can_have_parent_result/to_kwargs"
@@ -113,7 +113,13 @@ module ConvenientService
113
113
  # @return [Hash]
114
114
  #
115
115
  def to_kwargs
116
- {service: service, status: status, data: data, message: message, code: code}
116
+ {
117
+ service: service,
118
+ status: status,
119
+ data: unsafe_data,
120
+ message: unsafe_message,
121
+ code: unsafe_code
122
+ }
117
123
  end
118
124
  end
119
125
  end
@@ -45,6 +45,10 @@ module ConvenientService
45
45
  def to_h
46
46
  @to_h ||= value.to_h
47
47
  end
48
+
49
+ def to_s
50
+ @to_s ||= to_h.to_s
51
+ end
48
52
  end
49
53
  end
50
54
  end
@@ -0,0 +1,27 @@
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 HasStep
11
+ module Concern
12
+ include Support::Concern
13
+
14
+ instance_methods do
15
+ def step
16
+ @step ||= internals.cache[:step]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
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 HasStep
11
+ module Initialize
12
+ class Middleware < Core::MethodChainMiddleware
13
+ def next(*args, **kwargs, &block)
14
+ entity.internals.cache[:step] = kwargs[:step]
15
+
16
+ chain.next(*args, **kwargs, &block)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "initialize/middleware"
@@ -0,0 +1,25 @@
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 HasStep
11
+ module ToKwargs
12
+ class Middleware < Core::MethodChainMiddleware
13
+ def next(...)
14
+ chain.next(...).merge(step: entity.step)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end