convenient_service 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -0
  3. data/ROADMAP.md +12 -1
  4. data/convenient_service.gemspec +2 -1
  5. data/lib/convenient_service/aliases.rb +1 -0
  6. data/lib/convenient_service/common/plugins/has_around_callbacks/middleware.rb +24 -4
  7. data/lib/convenient_service/common/plugins/has_callbacks/container.rb +17 -0
  8. data/lib/convenient_service/common/plugins/has_callbacks/entities/callback.rb +98 -5
  9. data/lib/convenient_service/common/plugins/has_callbacks/middleware.rb +25 -4
  10. data/lib/convenient_service/common/plugins/has_callbacks.rb +1 -0
  11. data/lib/convenient_service/common/plugins.rb +1 -1
  12. data/lib/convenient_service/configs/standard.rb +25 -12
  13. data/lib/convenient_service/dependencies.rb +12 -0
  14. data/lib/convenient_service/examples/dry/gemfile/dry_service/config.rb +1 -1
  15. data/lib/convenient_service/examples/rails/gemfile/rails_service/config.rb +1 -1
  16. data/lib/convenient_service/examples/rails/gemfile/services/format.rb +35 -6
  17. data/lib/convenient_service/examples/rails/gemfile/services/format_header.rb +1 -2
  18. data/lib/convenient_service/examples/rails/gemfile/services/merge_sections.rb +25 -0
  19. data/lib/convenient_service/examples/rails/gemfile/services/replace_file_content.rb +37 -0
  20. data/lib/convenient_service/examples/rails/gemfile/services.rb +8 -4
  21. data/lib/convenient_service/examples/standard/gemfile/services/format.rb +45 -6
  22. data/lib/convenient_service/examples/standard/gemfile/services/merge_sections.rb +52 -0
  23. data/lib/convenient_service/examples/standard/gemfile/services/replace_file_content.rb +48 -0
  24. data/lib/convenient_service/examples/standard/gemfile/services.rb +8 -4
  25. data/lib/convenient_service/factories/arguments.rb +43 -0
  26. data/lib/convenient_service/factories/results.rb +214 -0
  27. data/lib/convenient_service/factories/services.rb +189 -0
  28. data/lib/convenient_service/factories/step/instance.rb +32 -0
  29. data/lib/convenient_service/factories/step.rb +3 -0
  30. data/lib/convenient_service/factories/steps.rb +126 -0
  31. data/lib/convenient_service/factories.rb +22 -0
  32. data/lib/convenient_service/factory.rb +21 -0
  33. data/lib/convenient_service/rspec/matchers/custom/be_descendant_of.rb +2 -2
  34. data/lib/convenient_service/rspec/matchers/custom/be_direct_descendant_of.rb +2 -2
  35. data/lib/convenient_service/rspec/matchers/custom/delegate_to.rb +9 -0
  36. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/find_result_method_step.rb +74 -0
  37. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/find_result_result_method_step.rb +66 -0
  38. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/find_result_service_step.rb +48 -0
  39. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/generate_expected_step_part.rb +42 -0
  40. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/generate_got_step_part.rb +42 -0
  41. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/match_result_step.rb +89 -0
  42. data/lib/convenient_service/rspec/matchers/custom/results/base/commands.rb +10 -0
  43. data/lib/convenient_service/rspec/matchers/custom/results/base/errors.rb +35 -0
  44. data/lib/convenient_service/rspec/matchers/custom/results/base.rb +73 -12
  45. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/concern.rb +85 -0
  46. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/initialize/middleware.rb +27 -0
  47. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/initialize.rb +3 -0
  48. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/to_kwargs/middleware.rb +25 -0
  49. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/to_kwargs.rb +3 -0
  50. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result.rb +5 -0
  51. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/concern/instance_methods.rb +7 -1
  52. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/data.rb +4 -0
  53. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/concern.rb +27 -0
  54. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/initialize/middleware.rb +27 -0
  55. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/initialize.rb +3 -0
  56. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/to_kwargs/middleware.rb +25 -0
  57. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/to_kwargs.rb +3 -0
  58. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step.rb +5 -0
  59. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins.rb +2 -0
  60. data/lib/convenient_service/service/plugins/has_result_method_steps.rb +0 -2
  61. data/lib/convenient_service/service/plugins/has_result_steps/concern.rb +18 -7
  62. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/define_method_in_container.rb +2 -2
  63. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment/commands/define_method_in_container.rb +1 -1
  64. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/concern/instance_methods.rb +26 -1
  65. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/plugins/can_have_parent_result/middleware.rb +23 -0
  66. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/plugins/can_have_parent_result.rb +3 -0
  67. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/plugins.rb +1 -0
  68. data/lib/convenient_service/service/plugins/has_result_steps/entities/step_collection.rb +13 -0
  69. data/lib/convenient_service/service/plugins/has_result_steps/middleware.rb +18 -4
  70. data/lib/convenient_service/services/run_method_in_organizer.rb +28 -0
  71. data/lib/convenient_service/services/run_own_method_in_organizer.rb +64 -0
  72. data/lib/convenient_service/{service/plugins/has_result_method_steps/services.rb → services.rb} +0 -1
  73. data/lib/convenient_service/support/copyable.rb +6 -2
  74. data/lib/convenient_service/support/dependency_container/errors.rb +1 -1
  75. data/lib/convenient_service/support/not_passed.rb +3 -1
  76. data/lib/convenient_service/version.rb +1 -1
  77. data/lib/convenient_service.rb +6 -0
  78. data/logo.png +0 -0
  79. metadata +58 -11
  80. data/lib/convenient_service/service/plugins/has_result_method_steps/errors.rb +0 -23
  81. data/lib/convenient_service/service/plugins/has_result_method_steps/services/method_step_config.rb +0 -55
  82. data/lib/convenient_service/service/plugins/has_result_method_steps/services/run_method_in_organizer.rb +0 -30
  83. data/lib/convenient_service/service/plugins/has_result_method_steps/services/run_own_method_in_organizer.rb +0 -52
@@ -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,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
@@ -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 "has_step/concern"
4
+ require_relative "has_step/initialize"
5
+ require_relative "has_step/to_kwargs"
@@ -3,6 +3,8 @@
3
3
  require_relative "plugins/can_recalculate_result"
4
4
  require_relative "plugins/has_jsend_status_and_attributes"
5
5
  require_relative "plugins/has_inspect"
6
+ require_relative "plugins/has_step"
7
+ require_relative "plugins/can_have_parent_result"
6
8
  require_relative "plugins/has_result_short_syntax"
7
9
  require_relative "plugins/marks_result_status_as_checked"
8
10
  require_relative "plugins/raises_on_not_checked_result_status"
@@ -1,5 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "has_result_method_steps/errors"
4
3
  require_relative "has_result_method_steps/middleware"
5
- require_relative "has_result_method_steps/services"
@@ -9,7 +9,7 @@ module ConvenientService
9
9
 
10
10
  instance_methods do
11
11
  ##
12
- # @return [Array]
12
+ # @return [Array<ConvenientService::Service::Plugins::HasResultSteps::Entities::Step>]
13
13
  #
14
14
  def steps
15
15
  internals.cache.fetch(:steps) do
@@ -21,18 +21,26 @@ module ConvenientService
21
21
  end
22
22
 
23
23
  ##
24
- # TODO: Create for callbacks.
24
+ # Returns step by index.
25
+ # Returns `nil` when index is out of range.
25
26
  #
26
- # def step(step_result)
27
- # step_result
28
- # end
27
+ # @param index [Integer]
28
+ # @return [ConvenientService::Service::Plugins::HasResultSteps::Entities::Step]
29
+ #
30
+ # @note This method was initially designed as a hook (callback trigger).
31
+ # @see ConvenientService::Service::Plugins::HasResultSteps::Middleware#next
29
32
  #
33
+ def step(index)
34
+ steps[index]
35
+ end
30
36
  end
31
37
 
32
38
  class_methods do
33
39
  ##
34
- # @params args [Array]
35
- # @params kwargs [Hash]
40
+ # Registers a step (step definition).
41
+ #
42
+ # @param args [Array]
43
+ # @param kwargs [Hash]
36
44
  # @return [ConvenientService::Service::Plugins::HasResultSteps::Entities::Step]
37
45
  #
38
46
  def step(*args, **kwargs)
@@ -41,6 +49,9 @@ module ConvenientService
41
49
  end
42
50
 
43
51
  ##
52
+ # @param value [Object] Can be any type.
53
+ # @return [ConvenientService::Support::RawValue]
54
+ #
44
55
  # Allows to pass a value to `in` method without its intermediate processing.
45
56
  # @see https://marian13.github.io/convenient_service_docs/basics/step_to_result_translation_table
46
57
  #
@@ -30,9 +30,9 @@ module ConvenientService
30
30
 
31
31
  raise #{not_completed_step_error}.new(step: step, method_name: method_name) unless step.completed?
32
32
 
33
- raise #{not_existing_step_result_data_attribute_error}.new(step: step, key: key) unless step.result.data.has_attribute?(key)
33
+ raise #{not_existing_step_result_data_attribute_error}.new(step: step, key: key) unless step.result.unsafe_data.has_attribute?(key)
34
34
 
35
- step.result.data[key]
35
+ step.result.unsafe_data[key]
36
36
  end
37
37
  RUBY
38
38
 
@@ -46,7 +46,7 @@ module ConvenientService
46
46
 
47
47
  key = step.reassignment(__method__).key.to_sym
48
48
 
49
- step.result.data[key]
49
+ step.result.unsafe_data[key]
50
50
  end
51
51
  RUBY
52
52
 
@@ -18,6 +18,12 @@ module ConvenientService
18
18
  :not_success?,
19
19
  :not_failure?,
20
20
  :not_error?,
21
+ :data,
22
+ :message,
23
+ :code,
24
+ :unsafe_data,
25
+ :unsafe_message,
26
+ :unsafe_code,
21
27
  to: :result
22
28
 
23
29
  delegate \
@@ -74,6 +80,10 @@ module ConvenientService
74
80
  @input_values ||= calculate_input_values
75
81
  end
76
82
 
83
+ def original_result
84
+ @original_result ||= calculate_original_result
85
+ end
86
+
77
87
  def result
78
88
  @result ||= calculate_result
79
89
  end
@@ -88,6 +98,13 @@ module ConvenientService
88
98
  service.klass.to_s
89
99
  end
90
100
 
101
+ ##
102
+ # @return [Class]
103
+ #
104
+ def service_class
105
+ service.klass
106
+ end
107
+
91
108
  def validate!
92
109
  inputs.each { |input| input.validate_as_input_for_container!(container) }
93
110
 
@@ -114,6 +131,10 @@ module ConvenientService
114
131
 
115
132
  attr_reader :args, :kwargs
116
133
 
134
+ ##
135
+ # @internal
136
+ # TODO: Commands instead of private methods.
137
+ #
117
138
  def calculate_input_values
118
139
  assert_has_organizer!
119
140
 
@@ -124,7 +145,7 @@ module ConvenientService
124
145
  # @internal
125
146
  # IMPORTANT: `service.result(**input_values)` is the reason, why services should have only kwargs as arguments.
126
147
  #
127
- def calculate_result
148
+ def calculate_original_result
128
149
  assert_has_organizer!
129
150
 
130
151
  result = service.result(**input_values)
@@ -134,6 +155,10 @@ module ConvenientService
134
155
  result
135
156
  end
136
157
 
158
+ def calculate_result
159
+ original_result.copy(overrides: {kwargs: {step: self, service: organizer}})
160
+ end
161
+
137
162
  def resolve_params
138
163
  original_params = Commands::ExtractParams.call(args: args, kwargs: kwargs)
139
164
 
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Service
5
+ module Plugins
6
+ module HasResultSteps
7
+ module Entities
8
+ class Step
9
+ module Plugins
10
+ module CanHaveParentResult
11
+ class Middleware < Core::MethodChainMiddleware
12
+ def next(...)
13
+ chain.next(...).copy(overrides: {kwargs: {parent: entity.original_result}})
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "can_have_parent_result/middleware"
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "plugins/can_have_parent_result"
3
4
  require_relative "plugins/has_inspect"
@@ -36,6 +36,19 @@ module ConvenientService
36
36
  steps.each(&block)
37
37
  end
38
38
 
39
+ ##
40
+ # Returns step by index.
41
+ #
42
+ # @param index [Integer]
43
+ # @return [ConvenientService::Service::Plugins::HasResultSteps::Entities::Step]
44
+ #
45
+ # @note Works in a similar way as `Array#[]`.
46
+ # @see https://ruby-doc.org/core-2.7.0/Array.html#method-i-5B-5D
47
+ #
48
+ def [](index)
49
+ steps[index]
50
+ end
51
+
39
52
  def <<(step)
40
53
  steps << step.copy(overrides: {kwargs: {index: next_available_index}})
41
54
  end