convenient_service 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +58 -0
  3. data/ROADMAP.md +14 -1
  4. data/convenient_service.gemspec +2 -1
  5. data/lib/convenient_service/aliases.rb +10 -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/has_constructor_without_initialize/concern.rb +19 -0
  12. data/lib/convenient_service/common/plugins.rb +1 -1
  13. data/lib/convenient_service/configs/minimal.rb +176 -0
  14. data/lib/convenient_service/configs/standard.rb +30 -105
  15. data/lib/convenient_service/configs.rb +1 -0
  16. data/lib/convenient_service/dependencies.rb +20 -0
  17. data/lib/convenient_service/examples/dry/gemfile/dry_service/config.rb +5 -5
  18. data/lib/convenient_service/examples/rails/gemfile/rails_service/config.rb +7 -7
  19. data/lib/convenient_service/examples/rails/gemfile/services/format.rb +35 -6
  20. data/lib/convenient_service/examples/rails/gemfile/services/format_header.rb +1 -2
  21. data/lib/convenient_service/examples/rails/gemfile/services/merge_sections.rb +25 -0
  22. data/lib/convenient_service/examples/rails/gemfile/services/replace_file_content.rb +37 -0
  23. data/lib/convenient_service/examples/rails/gemfile/services.rb +8 -4
  24. data/lib/convenient_service/examples/standard/gemfile/services/format.rb +45 -6
  25. data/lib/convenient_service/examples/standard/gemfile/services/merge_sections.rb +52 -0
  26. data/lib/convenient_service/examples/standard/gemfile/services/replace_file_content.rb +48 -0
  27. data/lib/convenient_service/examples/standard/gemfile/services.rb +8 -4
  28. data/lib/convenient_service/factories/arguments.rb +43 -0
  29. data/lib/convenient_service/factories/results.rb +214 -0
  30. data/lib/convenient_service/factories/services.rb +189 -0
  31. data/lib/convenient_service/factories/step/instance.rb +32 -0
  32. data/lib/convenient_service/factories/step.rb +3 -0
  33. data/lib/convenient_service/factories/steps.rb +126 -0
  34. data/lib/convenient_service/factories.rb +22 -0
  35. data/lib/convenient_service/factory.rb +21 -0
  36. data/lib/convenient_service/rspec/helpers/custom/ignoring_error.rb +3 -0
  37. data/lib/convenient_service/rspec/helpers/custom/wrap_method/entities/wrapped_method.rb +29 -3
  38. data/lib/convenient_service/rspec/matchers/custom/be_descendant_of.rb +2 -2
  39. data/lib/convenient_service/rspec/matchers/custom/be_direct_descendant_of.rb +2 -2
  40. data/lib/convenient_service/rspec/matchers/custom/delegate_to.rb +9 -0
  41. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/find_result_method_step.rb +74 -0
  42. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/find_result_result_method_step.rb +66 -0
  43. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/find_result_service_step.rb +48 -0
  44. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/generate_expected_step_part.rb +42 -0
  45. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/generate_got_step_part.rb +42 -0
  46. data/lib/convenient_service/rspec/matchers/custom/results/base/commands/match_result_step.rb +89 -0
  47. data/lib/convenient_service/rspec/matchers/custom/results/base/commands.rb +10 -0
  48. data/lib/convenient_service/rspec/matchers/custom/results/base/errors.rb +35 -0
  49. data/lib/convenient_service/rspec/matchers/custom/results/base.rb +78 -12
  50. data/lib/convenient_service/service/plugins/has_result/concern/class_methods.rb +3 -3
  51. data/lib/convenient_service/service/plugins/has_result/constants.rb +0 -3
  52. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/concern.rb +85 -0
  53. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/initialize/middleware.rb +27 -0
  54. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/initialize.rb +3 -0
  55. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/to_kwargs/middleware.rb +25 -0
  56. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result/to_kwargs.rb +3 -0
  57. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/can_have_parent_result.rb +5 -0
  58. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/concern/instance_methods.rb +7 -1
  59. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/entities/data.rb +17 -0
  60. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/concern.rb +27 -0
  61. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/initialize/middleware.rb +27 -0
  62. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/initialize.rb +3 -0
  63. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/to_kwargs/middleware.rb +25 -0
  64. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step/to_kwargs.rb +3 -0
  65. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_step.rb +5 -0
  66. data/lib/convenient_service/service/plugins/has_result/entities/result/plugins.rb +2 -0
  67. data/lib/convenient_service/service/plugins/has_result_method_steps.rb +0 -2
  68. data/lib/convenient_service/service/plugins/has_result_steps/concern.rb +18 -7
  69. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/define_method_in_container.rb +2 -2
  70. data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment/commands/define_method_in_container.rb +1 -1
  71. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/concern/instance_methods.rb +26 -1
  72. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/plugins/can_have_parent_result/middleware.rb +23 -0
  73. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/plugins/can_have_parent_result.rb +3 -0
  74. data/lib/convenient_service/service/plugins/has_result_steps/entities/step/plugins.rb +1 -0
  75. data/lib/convenient_service/service/plugins/has_result_steps/entities/step_collection.rb +13 -0
  76. data/lib/convenient_service/service/plugins/has_result_steps/middleware.rb +18 -4
  77. data/lib/convenient_service/service/plugins/raises_on_double_result/middleware.rb +37 -2
  78. data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_backtrace.rb +80 -0
  79. data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_cause.rb +78 -0
  80. data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_exception.rb +169 -0
  81. data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands/format_line.rb +40 -0
  82. data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/commands.rb +7 -0
  83. data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/constants.rb +13 -0
  84. data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/middleware.rb +58 -0
  85. data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions.rb +5 -0
  86. data/lib/convenient_service/services/run_method_in_organizer.rb +28 -0
  87. data/lib/convenient_service/services/run_own_method_in_organizer.rb +64 -0
  88. data/lib/convenient_service/{service/plugins/has_result_method_steps/services.rb → services.rb} +0 -1
  89. data/lib/convenient_service/support/copyable.rb +6 -2
  90. data/lib/convenient_service/support/dependency_container/errors.rb +1 -1
  91. data/lib/convenient_service/support/not_passed.rb +3 -1
  92. data/lib/convenient_service/support/undefined.rb +9 -0
  93. data/lib/convenient_service/support.rb +2 -0
  94. data/lib/convenient_service/version.rb +1 -1
  95. data/lib/convenient_service.rb +6 -0
  96. data/logo.png +0 -0
  97. metadata +68 -11
  98. data/lib/convenient_service/service/plugins/has_result_method_steps/errors.rb +0 -23
  99. data/lib/convenient_service/service/plugins/has_result_method_steps/services/method_step_config.rb +0 -55
  100. data/lib/convenient_service/service/plugins/has_result_method_steps/services/run_method_in_organizer.rb +0 -30
  101. data/lib/convenient_service/service/plugins/has_result_method_steps/services/run_own_method_in_organizer.rb +0 -52
@@ -35,9 +35,25 @@ module ConvenientService
35
35
  #
36
36
  stack.use(
37
37
  proc do |env|
38
- entity.__send__(method, *env[:args], **env[:kwargs], &env[:block])
39
- .tap { |value| @chain_value = value }
40
- .tap { @chain_arguments = {args: env[:args], kwargs: env[:kwargs], block: env[:block]} }
38
+ @chain_arguments = {args: env[:args], kwargs: env[:kwargs], block: env[:block]}
39
+
40
+ ##
41
+ # IMPORTANT: Forces Ruby to define `@chain_value` instance variable.
42
+ #
43
+ # NOTE: If `@chain_value` is still set to `Support::UNDEFINED` after running the begin block - an exception was raised by `chain.next`. See `chain_called?` for more info.
44
+ #
45
+ @chain_value = Support::UNDEFINED
46
+
47
+ begin
48
+ @chain_value = entity.__send__(method, *env[:args], **env[:kwargs], &env[:block])
49
+ rescue => exception
50
+ @chain_exception = exception
51
+
52
+ ##
53
+ # NOTE: `raise` with no args inside `rescue` reraises rescued exception.
54
+ #
55
+ raise
56
+ end
41
57
  end
42
58
  )
43
59
  end
@@ -107,6 +123,16 @@ module ConvenientService
107
123
 
108
124
  @chain_arguments[:block]
109
125
  end
126
+
127
+ ##
128
+ # @return [StandardError, nil]
129
+ # @raise [ConvenientService::RSpec::Helpers::Custom::WrapMethod::Errors::ChainAttributePreliminaryAccess]
130
+ #
131
+ def chain_exception
132
+ raise Errors::ChainAttributePreliminaryAccess.new(attribute: :exception) unless chain_called?
133
+
134
+ @chain_exception
135
+ end
110
136
  end
111
137
  end
112
138
  end
@@ -30,7 +30,7 @@ module ConvenientService
30
30
  end
31
31
 
32
32
  ##
33
- # NOTE: `failure_message` is only called when `mathces?` returns `false`.
33
+ # NOTE: `failure_message` is only called when `matches?` returns `false`.
34
34
  # https://rubydoc.info/github/rspec/rspec-expectations/RSpec/Matchers/MatcherProtocol#failure_message-instance_method
35
35
  #
36
36
  def failure_message
@@ -38,7 +38,7 @@ module ConvenientService
38
38
  end
39
39
 
40
40
  ##
41
- # NOTE: `failure_message_when_negated` is only called when `mathces?` returns `false`.
41
+ # NOTE: `failure_message_when_negated` is only called when `matches?` returns `false`.
42
42
  # https://rubydoc.info/github/rspec/rspec-expectations/RSpec/Matchers/MatcherProtocol#failure_message-instance_method
43
43
  #
44
44
  def failure_message_when_negated
@@ -30,7 +30,7 @@ module ConvenientService
30
30
  end
31
31
 
32
32
  ##
33
- # NOTE: `failure_message` is only called when `mathces?` returns `false`.
33
+ # NOTE: `failure_message` is only called when `matches?` returns `false`.
34
34
  # https://rubydoc.info/github/rspec/rspec-expectations/RSpec/Matchers/MatcherProtocol#failure_message-instance_method
35
35
  #
36
36
  def failure_message
@@ -38,7 +38,7 @@ module ConvenientService
38
38
  end
39
39
 
40
40
  ##
41
- # NOTE: `failure_message_when_negated` is only called when `mathces?` returns `false`.
41
+ # NOTE: `failure_message_when_negated` is only called when `matches?` returns `false`.
42
42
  # https://rubydoc.info/github/rspec/rspec-expectations/RSpec/Matchers/MatcherProtocol#failure_message-instance_method
43
43
  #
44
44
  def failure_message_when_negated
@@ -94,6 +94,15 @@ module ConvenientService
94
94
  self
95
95
  end
96
96
 
97
+ ##
98
+ # TODO: `and_return`.
99
+ #
100
+ # def and_return(...)
101
+ # matcher.and_return(...)
102
+ #
103
+ # self
104
+ # end
105
+
97
106
  ##
98
107
  # @return [ConvenientService::RSpec::Matchers::Custom::DelegateTo]
99
108
  #
@@ -0,0 +1,74 @@
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 FindResultMethodStep < Support::Command
11
+ ##
12
+ # @!attribute result [r]
13
+ # @return [ConvenientService::Service::Plugins::HasResult::Entities::Result]
14
+ #
15
+ attr_reader :result
16
+
17
+ ##
18
+ # @!attribute method_name [r]
19
+ # @return [Symbol]
20
+ #
21
+ attr_reader :method_name
22
+
23
+ ##
24
+ # @param result [ConvenientService::Service::Plugins::HasResult::Entities::Result]
25
+ # @param method_name [Symbol]
26
+ # @return [void]
27
+ #
28
+ def initialize(result:, method_name:)
29
+ @result = result
30
+ @method_name = method_name
31
+ end
32
+
33
+ ##
34
+ # @return [ConvenientService::Service::Plugins::HasResultSteps::Entities::Method]
35
+ #
36
+ def call
37
+ return nil unless result.step
38
+
39
+ result.step.inputs.find { |input| match_service_class?(input) && match_key?(input) && match_value?(input) }
40
+ end
41
+
42
+ private
43
+
44
+ ##
45
+ # @param input [ConvenientService::Service::Plugins::HasResultSteps::Entities::Method]
46
+ # @return [Boolean]
47
+ #
48
+ def match_service_class?(input)
49
+ result.step.service_class == Services::RunMethodInOrganizer
50
+ end
51
+
52
+ ##
53
+ # @param input [ConvenientService::Service::Plugins::HasResultSteps::Entities::Method]
54
+ # @return [Boolean]
55
+ #
56
+ def match_key?(input)
57
+ input.key.to_sym == :method_name
58
+ end
59
+
60
+ ##
61
+ # @param input [ConvenientService::Service::Plugins::HasResultSteps::Entities::Method]
62
+ # @return [Boolean]
63
+ #
64
+ def match_value?(input)
65
+ input.value.to_sym == method_name
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,66 @@
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 FindResultResultMethodStep < Support::Command
11
+ ##
12
+ # @!attribute result [r]
13
+ # @return [ConvenientService::Service::Plugins::HasResult::Entities::Result]
14
+ #
15
+ attr_reader :result
16
+
17
+ ##
18
+ # @param result [ConvenientService::Service::Plugins::HasResult::Entities::Result]
19
+ # @return [void]
20
+ #
21
+ def initialize(result:)
22
+ @result = result
23
+ end
24
+
25
+ ##
26
+ # @return [ConvenientService::Service::Plugins::HasResultSteps::Entities::Method]
27
+ #
28
+ def call
29
+ return nil unless result.step
30
+
31
+ result.step.inputs.find { |input| match_service_class?(input) && match_key?(input) && match_value?(input) }
32
+ end
33
+
34
+ private
35
+
36
+ ##
37
+ # @param input [ConvenientService::Service::Plugins::HasResultSteps::Entities::Method]
38
+ # @return [Boolean]
39
+ #
40
+ def match_service_class?(input)
41
+ result.step.service_class == Services::RunOwnMethodInOrganizer
42
+ end
43
+
44
+ ##
45
+ # @param input [ConvenientService::Service::Plugins::HasResultSteps::Entities::Method]
46
+ # @return [Boolean]
47
+ #
48
+ def match_key?(input)
49
+ input.key.to_sym == :method_name
50
+ end
51
+
52
+ ##
53
+ # @param input [ConvenientService::Service::Plugins::HasResultSteps::Entities::Method]
54
+ # @return [Boolean]
55
+ #
56
+ def match_value?(input)
57
+ input.value.to_sym == :result
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,48 @@
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 FindResultServiceStep < Support::Command
11
+ ##
12
+ # @!attribute result [r]
13
+ # @return [ConvenientService::Service::Plugins::HasResult::Entities::Result]
14
+ #
15
+ attr_reader :result
16
+
17
+ ##
18
+ # @!attribute service_class [r]
19
+ # @return [Class]
20
+ #
21
+ attr_reader :service_class
22
+
23
+ ##
24
+ # @param result [ConvenientService::Service::Plugins::HasResult::Entities::Result]
25
+ # @param service_class [Class]
26
+ # @return [void]
27
+ #
28
+ def initialize(result:, service_class:)
29
+ @result = result
30
+ @service_class = service_class
31
+ end
32
+
33
+ ##
34
+ # @return [ConvenientService::Service::Plugins::HasResultSteps::Entities::Method]
35
+ #
36
+ def call
37
+ return nil unless result.step
38
+
39
+ result.step.service_class == service_class
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,42 @@
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 GenerateExpectedStepPart < Support::Command
11
+ ##
12
+ # @!attribute step [r]
13
+ # @return [Class, Symbol]
14
+ #
15
+ attr_reader :step
16
+
17
+ ##
18
+ # @param step [Class, Symbol]
19
+ # @return [void]
20
+ #
21
+ def initialize(step:)
22
+ @step = step
23
+ end
24
+
25
+ ##
26
+ # @return [String]
27
+ #
28
+ def call
29
+ if step.nil?
30
+ "without step"
31
+ else
32
+ "of step `#{step}`"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,42 @@
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 GenerateGotStepPart < Support::Command
11
+ ##
12
+ # @!attribute result [r]
13
+ # @return [ConvenientService::Service::Plugins::HasResult::Entities::Result]
14
+ #
15
+ attr_reader :result
16
+
17
+ ##
18
+ # @param result [ConvenientService::Service::Plugins::HasResult::Entities::Result]
19
+ # @return [void]
20
+ #
21
+ def initialize(result:)
22
+ @result = result
23
+ end
24
+
25
+ ##
26
+ # @return [String]
27
+ #
28
+ def call
29
+ if result.step.nil?
30
+ "without step"
31
+ else
32
+ "of step `#{result.step.service.klass}`"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -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
@@ -23,8 +26,14 @@ module ConvenientService
23
26
  rules = []
24
27
 
25
28
  rules << ->(result) { result.class.include?(Service::Plugins::HasResult::Entities::Result::Concern) }
29
+
30
+ ##
31
+ # IMPORTANT: Result status is NOT marked as checked intentionally, since it is a mutable operation.
32
+ #
26
33
  rules << ->(result) { result.status.in?(statuses) }
27
- rules << ->(result) { result.service.instance_of?(service_class) } if used_of?
34
+
35
+ rules << ->(result) { result.service.instance_of?(service_class) } if used_of_service?
36
+ rules << ->(result) { Commands::MatchResultStep.call(result: result, step: step) } if used_of_step?
28
37
  rules << ->(result) { result.unsafe_data == data } if used_data?
29
38
  rules << ->(result) { result.unsafe_message == message } if used_message?
30
39
  rules << ->(result) { result.unsafe_code == code } if used_code?
@@ -38,14 +47,14 @@ module ConvenientService
38
47
  # @return [String]
39
48
  #
40
49
  def description
41
- default_text
50
+ expected_parts
42
51
  end
43
52
 
44
53
  ##
45
54
  # @return [String]
46
55
  #
47
56
  def failure_message
48
- "expected that `#{result}` would #{default_text}"
57
+ "expected that `#{result.service.class}` result would #{default_text}"
49
58
  end
50
59
 
51
60
  ##
@@ -55,7 +64,7 @@ module ConvenientService
55
64
  # https://relishapp.com/rspec/rspec-expectations/v/3-11/docs/custom-matchers/define-a-custom-matcher#overriding-the-failure-message-when-negated
56
65
  #
57
66
  def failure_message_when_negated
58
- "expected that #{result} would NOT #{default_text}"
67
+ "expected that `#{result.service.class}` result would NOT #{default_text}"
59
68
  end
60
69
 
61
70
  ##
@@ -131,12 +140,31 @@ module ConvenientService
131
140
  # @param service_class [Class]
132
141
  # @return [ConvenientService::RSpec::Matchers::Custom::Results::Base]
133
142
  #
134
- def of(service_class)
143
+ def of_service(service_class)
135
144
  chain[:service_class] = service_class
136
145
 
137
146
  self
138
147
  end
139
148
 
149
+ ##
150
+ # @param step [Class, Symbol]
151
+ # @return [ConvenientService::RSpec::Matchers::Custom::Results::Base]
152
+ #
153
+ def of_step(step)
154
+ chain[:step] = step
155
+
156
+ self
157
+ end
158
+
159
+ ##
160
+ # @return [ConvenientService::RSpec::Matchers::Custom::Results::Base]
161
+ #
162
+ def without_step
163
+ chain[:step] = nil
164
+
165
+ self
166
+ end
167
+
140
168
  private
141
169
 
142
170
  ##
@@ -149,21 +177,45 @@ module ConvenientService
149
177
  # @return [String]
150
178
  #
151
179
  def default_text
180
+ expected_parts << "\n\n" << got_parts
181
+ end
182
+
183
+ ##
184
+ # @return [String]
185
+ #
186
+ # @internal
187
+ # TODO: Align for easier visual comparison.
188
+ # TODO: New line for each attribute.
189
+ #
190
+ def expected_parts
152
191
  parts = []
153
192
 
154
193
  parts << "be #{printable_statuses}"
155
- parts << "of `#{service_class}`" if used_of?
194
+ parts << "of service `#{service_class}`" if used_of_service?
195
+ parts << Commands::GenerateExpectedStepPart.call(step: step) if used_of_step?
156
196
  parts << "with data `#{data}`" if used_data?
157
197
  parts << "with message `#{message}`" if used_message?
158
198
  parts << "with code `#{code}`" if used_code?
159
199
 
160
- parts << "\n\n"
200
+ parts.join(" ")
201
+ end
202
+
203
+ ##
204
+ # @return [String]
205
+ #
206
+ # @internal
207
+ # TODO: Align for easier visual comparison.
208
+ # TODO: New line for each attribute.
209
+ #
210
+ def got_parts
211
+ parts = []
161
212
 
162
213
  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?
214
+ parts << "of service `#{result.service.class}`" if used_of_service?
215
+ parts << Commands::GenerateGotStepPart.call(result: result) if used_of_step?
216
+ parts << "with data `#{result.unsafe_data}`" if used_data?
217
+ parts << "with message `#{result.unsafe_message}`" if used_message?
218
+ parts << "with code `#{result.unsafe_code}`" if used_code?
167
219
 
168
220
  parts.join(" ")
169
221
  end
@@ -192,10 +244,17 @@ module ConvenientService
192
244
  ##
193
245
  # @return [Boolean]
194
246
  #
195
- def used_of?
247
+ def used_of_service?
196
248
  chain.key?(:service_class)
197
249
  end
198
250
 
251
+ ##
252
+ # @return [Boolean]
253
+ #
254
+ def used_of_step?
255
+ chain.key?(:step)
256
+ end
257
+
199
258
  ##
200
259
  # @return [Hash]
201
260
  #
@@ -224,6 +283,13 @@ module ConvenientService
224
283
  Utils::Object.instance_variable_fetch(self, :@service_class) { chain[:service_class] }
225
284
  end
226
285
 
286
+ ##
287
+ # @return [Class]
288
+ #
289
+ def step
290
+ Utils::Object.instance_variable_fetch(self, :@step) { chain[:step] }
291
+ end
292
+
227
293
  ##
228
294
  # @return [Hash]
229
295
  #