convenient_service 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -4
  3. data/lib/convenient_service/aliases.rb +113 -1
  4. data/lib/convenient_service/common/plugins/aliases.rb +69 -0
  5. data/lib/convenient_service/common/plugins/can_have_callbacks/entities/type_collection.rb +2 -2
  6. data/lib/convenient_service/common/plugins/has_instance_proxy/entities/instance_proxy.rb +8 -8
  7. data/lib/convenient_service/common.rb +14 -0
  8. data/lib/convenient_service/config.rb +8 -0
  9. data/lib/convenient_service/core/aliases.rb +84 -0
  10. data/lib/convenient_service/dependencies/built_in.rb +15 -1
  11. data/lib/convenient_service/dependencies/only_queries.rb +0 -6
  12. data/lib/convenient_service/dependencies/queries/gems/minitest.rb +55 -0
  13. data/lib/convenient_service/dependencies/queries/gems/rspec.rb +1 -1
  14. data/lib/convenient_service/dependencies/queries/gems.rb +2 -0
  15. data/lib/convenient_service/dependencies/queries/ruby.rb +2 -2
  16. data/lib/convenient_service/dependencies/queries.rb +67 -16
  17. data/lib/convenient_service/dependencies.rb +6 -6
  18. data/lib/convenient_service/extras/alias.rb +4 -1
  19. data/lib/convenient_service/feature/configs/standard.rb +34 -13
  20. data/lib/convenient_service/feature/core.rb +41 -0
  21. data/lib/convenient_service/feature/plugins/aliases.rb +29 -0
  22. data/lib/convenient_service/feature/plugins/can_have_rspec_stubbed_entries/concern.rb +34 -0
  23. data/lib/convenient_service/{rspec/helpers/classes/stub_entry/entities.rb → feature/plugins/can_have_rspec_stubbed_entries.rb} +1 -2
  24. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/commands/delete_feature_stubbed_entry.rb +71 -0
  25. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/commands/fetch_all_features_stubbed_entries_cache.rb +16 -2
  26. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/commands/fetch_feature_stubbed_entries_cache.rb +1 -1
  27. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/commands.rb +2 -0
  28. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/concern.rb +23 -0
  29. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/entities/feature_stub.rb +123 -0
  30. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/entities/feature_unstub.rb +122 -0
  31. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/entities/value_mock.rb +118 -0
  32. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/entities/value_unmock.rb +88 -0
  33. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries/entities.rb +12 -0
  34. data/lib/convenient_service/feature/plugins/can_have_stubbed_entries.rb +1 -14
  35. data/lib/convenient_service/feature/plugins/has_amazing_print_inspect/concern.rb +34 -0
  36. data/lib/convenient_service/feature/{configs/standard/commands.rb → plugins/has_amazing_print_inspect.rb} +1 -2
  37. data/lib/convenient_service/feature/plugins/has_awesome_print_inspect/concern.rb +34 -0
  38. data/lib/convenient_service/{rspec/helpers/classes/stub_service/entities.rb → feature/plugins/has_awesome_print_inspect.rb} +1 -2
  39. data/lib/convenient_service/feature/plugins/has_inspect/concern.rb +27 -0
  40. data/lib/convenient_service/{service/configs/standard/commands.rb → feature/plugins/has_inspect.rb} +1 -2
  41. data/lib/convenient_service/feature/plugins.rb +1 -0
  42. data/lib/convenient_service/feature.rb +16 -0
  43. data/lib/convenient_service/logger.rb +11 -12
  44. data/lib/convenient_service/rspec/helpers/classes.rb +0 -2
  45. data/lib/convenient_service/rspec/helpers/stub_entry.rb +23 -5
  46. data/lib/convenient_service/rspec/helpers/stub_service.rb +79 -11
  47. data/lib/convenient_service/rspec/matchers/classes/cache_its_value.rb +2 -1
  48. data/lib/convenient_service/rspec/matchers/classes/delegate_to.rb +3 -5
  49. data/lib/convenient_service/rspec/matchers/classes/include_config.rb +4 -0
  50. data/lib/convenient_service/service/configs/aliases.rb +42 -0
  51. data/lib/convenient_service/service/configs/standard/aliases.rb +24 -0
  52. data/lib/convenient_service/service/configs/standard/v1.rb +17 -0
  53. data/lib/convenient_service/service/configs/standard.rb +50 -25
  54. data/lib/convenient_service/service/core.rb +39 -0
  55. data/lib/convenient_service/service/plugins/aliases.rb +48 -0
  56. data/lib/convenient_service/service/plugins/can_have_rollbacks/middleware.rb +33 -2
  57. data/lib/convenient_service/service/plugins/can_have_rspec_stubbed_results/concern.rb +34 -0
  58. data/lib/convenient_service/service/plugins/can_have_rspec_stubbed_results.rb +8 -0
  59. data/lib/convenient_service/service/plugins/can_have_stubbed_results/commands/delete_service_stubbed_result.rb +63 -0
  60. data/lib/convenient_service/service/plugins/can_have_stubbed_results/commands/fetch_all_services_stubbed_results_cache.rb +15 -10
  61. data/lib/convenient_service/service/plugins/can_have_stubbed_results/commands/fetch_service_stubbed_results_cache.rb +3 -3
  62. data/lib/convenient_service/service/plugins/can_have_stubbed_results/commands.rb +2 -0
  63. data/lib/convenient_service/service/plugins/can_have_stubbed_results/concern.rb +25 -0
  64. data/lib/convenient_service/service/plugins/can_have_stubbed_results/entities/result_mock.rb +254 -0
  65. data/lib/convenient_service/service/plugins/can_have_stubbed_results/entities/result_unmock.rb +82 -0
  66. data/lib/convenient_service/service/plugins/can_have_stubbed_results/entities/service_stub.rb +135 -0
  67. data/lib/convenient_service/service/plugins/can_have_stubbed_results/entities/service_unstub.rb +113 -0
  68. data/lib/convenient_service/service/plugins/can_have_stubbed_results/entities.rb +12 -0
  69. data/lib/convenient_service/service/plugins/can_have_stubbed_results.rb +1 -14
  70. data/lib/convenient_service/service/plugins/forbids_convenient_service_entities_as_constructor_arguments/exceptions.rb +84 -0
  71. data/lib/convenient_service/service/plugins/forbids_convenient_service_entities_as_constructor_arguments/middleware.rb +84 -32
  72. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/concern.rb +42 -2
  73. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/can_be_called/exceptions.rb +3 -2
  74. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/status/concern/instance_methods.rb +5 -0
  75. data/lib/convenient_service/service.rb +16 -0
  76. data/lib/convenient_service/specification.rb +42 -12
  77. data/lib/convenient_service/support/backtrace_cleaner.rb +6 -7
  78. data/lib/convenient_service/support/middleware/stack_builder/entities/builders/custom.rb +4 -0
  79. data/lib/convenient_service/support/middleware/stack_builder/entities/builders/ruby_middleware.rb +4 -0
  80. data/lib/convenient_service/support/unique_value.rb +4 -1
  81. data/lib/convenient_service/support.rb +13 -0
  82. data/lib/convenient_service/utils/array/find_last.rb +18 -9
  83. data/lib/convenient_service/utils/class/display_name.rb +9 -9
  84. data/lib/convenient_service/utils/enumerable/find_last.rb +48 -0
  85. data/lib/convenient_service/utils/enumerable.rb +20 -0
  86. data/lib/convenient_service/utils/hash/assert_valid_keys.rb +4 -4
  87. data/lib/convenient_service/utils/hash/except.rb +5 -4
  88. data/lib/convenient_service/utils/hash/triple_equality_compare.rb +8 -8
  89. data/lib/convenient_service/utils/kernel/silence_warnings.rb +4 -4
  90. data/lib/convenient_service/utils/module/fetch_own_const.rb +36 -31
  91. data/lib/convenient_service/utils/module/get_namespace.rb +26 -21
  92. data/lib/convenient_service/utils/module/get_own_const.rb +21 -16
  93. data/lib/convenient_service/utils/object/clamp_class.rb +50 -47
  94. data/lib/convenient_service/utils/object/duck_class.rb +84 -81
  95. data/lib/convenient_service/utils/object/get_own_method.rb +1 -1
  96. data/lib/convenient_service/utils/object/instance_variable_delete.rb +0 -3
  97. data/lib/convenient_service/utils/object/instance_variable_fetch.rb +0 -3
  98. data/lib/convenient_service/utils/object/memoize_including_falsy_values.rb +0 -3
  99. data/lib/convenient_service/utils/object/resolve_type.rb +13 -11
  100. data/lib/convenient_service/utils/object/safe_send.rb +2 -0
  101. data/lib/convenient_service/utils/string/enclose.rb +11 -11
  102. data/lib/convenient_service/utils/string/tab.rb +60 -0
  103. data/lib/convenient_service/utils/string.rb +5 -0
  104. data/lib/convenient_service/utils.rb +9 -0
  105. data/lib/convenient_service/version.rb +8 -1
  106. data/lib/convenient_service.rb +232 -14
  107. metadata +37 -754
  108. data/lib/convenient_service/feature/configs/standard/commands/is_feature.rb +0 -39
  109. data/lib/convenient_service/feature/configs/standard/commands/is_feature_class.rb +0 -41
  110. data/lib/convenient_service/rspec/helpers/classes/stub_entry/constants.rb +0 -25
  111. data/lib/convenient_service/rspec/helpers/classes/stub_entry/entities/stubbed_feature.rb +0 -128
  112. data/lib/convenient_service/rspec/helpers/classes/stub_entry/entities/value_spec.rb +0 -79
  113. data/lib/convenient_service/rspec/helpers/classes/stub_entry.rb +0 -48
  114. data/lib/convenient_service/rspec/helpers/classes/stub_service/constants.rb +0 -25
  115. data/lib/convenient_service/rspec/helpers/classes/stub_service/entities/result_spec.rb +0 -211
  116. data/lib/convenient_service/rspec/helpers/classes/stub_service/entities/stubbed_service.rb +0 -119
  117. data/lib/convenient_service/rspec/helpers/classes/stub_service.rb +0 -43
  118. data/lib/convenient_service/service/configs/standard/commands/is_service.rb +0 -39
  119. data/lib/convenient_service/service/configs/standard/commands/is_service_class.rb +0 -41
@@ -10,18 +10,36 @@ module ConvenientService
10
10
  module Helpers
11
11
  module StubEntry
12
12
  ##
13
- # @return [ConvenientService::RSpec::Helpers::StubEntry::Classes::StubEntry]
13
+ # @param feature_class [Class<ConvenientService::Feature>]
14
+ # @param entry_name [Symbol, String]
15
+ # @return [ConvenientService::Feature::Plugins::CanHaveStubbedEntries::Entities::EntryStub]
14
16
  #
15
- def stub_entry(...)
16
- Classes::StubEntry.call(...)
17
+ def stub_entry(feature_class, entry_name)
18
+ feature_class.stub_entry(entry_name)
19
+ end
20
+
21
+ ##
22
+ # @param feature_class [Class<ConvenientService::Feature>]
23
+ # @param entry_name [Symbol, String]
24
+ # @return [ConvenientService::Feature::Plugins::CanHaveStubbedEntries::Entities::EntryUnstub]
25
+ #
26
+ def unstub_entry(feature_class, entry_name)
27
+ feature_class.unstub_entry(entry_name)
17
28
  end
18
29
 
19
30
  ##
20
31
  # @param value [Object] Can be any type.
21
- # @return [ConvenientService::RSpec::Helpers::StubEntry::Classes::StubEntry::Entities::ValueSpec]
32
+ # @return [ConvenientService::Feature::Plugins::CanHaveStubbedEntries::Entities::ValueMock]
22
33
  #
23
34
  def return_value(value)
24
- Classes::StubEntry::Entities::ValueSpec.new(value: value)
35
+ ConvenientService::Feature::Plugins::CanHaveStubbedEntries::Entities::ValueMock.new(value: value)
36
+ end
37
+
38
+ ##
39
+ # @return [ConvenientService::Feature::Plugins::CanHaveStubbedEntries::Entities::ValueUnmock]
40
+ #
41
+ def return_value_mock
42
+ ConvenientService::Feature::Plugins::CanHaveStubbedEntries::Entities::ValueUnmock.new
25
43
  end
26
44
  end
27
45
  end
@@ -10,39 +10,107 @@ module ConvenientService
10
10
  module Helpers
11
11
  module StubService
12
12
  ##
13
- # @return [ConvenientService::RSpec::Helpers::StubEntry::Classes::StubService]
13
+ # Stubs service if it was NOT stubbed before, otherwise - overrides the previous stub.
14
14
  #
15
- def stub_service(...)
16
- Classes::StubService.call(...)
15
+ # @api public
16
+ # @since 1.0.0
17
+ #
18
+ # @param service_class [Class<ConvenientService::Service>]
19
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ServiceStub]
20
+ #
21
+ # @example Unstub service with any arguments.
22
+ # class Service
23
+ # include ConvenientService::Standard::Config
24
+ #
25
+ # def result
26
+ # success
27
+ # end
28
+ # end
29
+ #
30
+ # RSpec.describe Service do
31
+ # include ConvenientService::RSpec::Helpers::StubService
32
+ # include ConvenientService::RSpec::Matchers::Results
33
+ #
34
+ # it "works" do
35
+ # stub_service(Service).to return_error.with_code(:custom_code)
36
+ #
37
+ # expect(Service).to be_error.with_code(:custom_code)
38
+ # end
39
+ # end
40
+ #
41
+ def stub_service(service_class)
42
+ service_class.stub_result
43
+ end
44
+
45
+ ##
46
+ # Unstubs service if it was stubbed before, otherwise - does nothing.
47
+ #
48
+ # @api public
49
+ # @since 1.0.0
50
+ #
51
+ # @param service_class [Class<ConvenientService::Service>]
52
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ServiceUnstub]
53
+ #
54
+ # @example Unstub service with any arguments.
55
+ # class Service
56
+ # include ConvenientService::Standard::Config
57
+ #
58
+ # def result
59
+ # success
60
+ # end
61
+ # end
62
+ #
63
+ # RSpec.describe Service do
64
+ # include ConvenientService::RSpec::Helpers::StubService
65
+ # include ConvenientService::RSpec::Matchers::Results
66
+ #
67
+ # it "works" do
68
+ # stub_service(Service).to return_error.with_code(:custom_code)
69
+ #
70
+ # unstub_service(Service).to return_result_mock
71
+ #
72
+ # expect(Service).to be_success.without_data
73
+ # end
74
+ # end
75
+ #
76
+ def unstub_service(service_class)
77
+ service_class.unstub_result
17
78
  end
18
79
 
19
80
  ##
20
81
  # @param status [Symbol]
21
- # @return [ConvenientService::RSpec::Helpers::StubEntry::Classes::StubService::Entities::ResultSpec]
82
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultMock]
22
83
  #
23
84
  def return_result(status)
24
- Classes::StubService::Entities::ResultSpec.new(status: status)
85
+ ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultMock.new(status: status)
25
86
  end
26
87
 
27
88
  ##
28
- # @return [ConvenientService::RSpec::Helpers::StubEntry::Classes::StubService::Entities::ResultSpec]
89
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultMock]
29
90
  #
30
91
  def return_success
31
- Classes::StubService::Entities::ResultSpec.new(status: :success)
92
+ ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultMock.new(status: :success)
32
93
  end
33
94
 
34
95
  ##
35
- # @return [ConvenientService::RSpec::Helpers::StubEntry::Classes::StubService::Entities::ResultSpec]
96
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultMock]
36
97
  #
37
98
  def return_failure
38
- Classes::StubService::Entities::ResultSpec.new(status: :failure)
99
+ ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultMock.new(status: :failure)
39
100
  end
40
101
 
41
102
  ##
42
- # @return [ConvenientService::RSpec::Helpers::StubEntry::Classes::StubService::Entities::ResultSpec]
103
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultMock]
43
104
  #
44
105
  def return_error
45
- Classes::StubService::Entities::ResultSpec.new(status: :error)
106
+ ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultMock.new(status: :error)
107
+ end
108
+
109
+ ##
110
+ # @return [ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultUnmock]
111
+ #
112
+ def return_result_mock
113
+ ConvenientService::Service::Plugins::CanHaveStubbedResults::Entities::ResultUnmock.new
46
114
  end
47
115
  end
48
116
  end
@@ -34,7 +34,8 @@ module ConvenientService
34
34
  @block_expectation = block_expectation
35
35
 
36
36
  ##
37
- # NOTE: Identical to `block_expectation.call.object_id == block_expectation.call.object_id`.
37
+ # NOTE: Avoid comparing object ids. Prefer `equal?`.
38
+ # - https://bugs.ruby-lang.org/issues/15408
38
39
  #
39
40
  block_expectation.call.equal?(block_expectation.call)
40
41
  end
@@ -9,11 +9,6 @@ require_relative "delegate_to/commands"
9
9
  require_relative "delegate_to/entities"
10
10
  require_relative "delegate_to/exceptions"
11
11
 
12
- ##
13
- # @internal
14
- # IMPORTANT: This matcher has a dedicated end-user doc. Do NOT forget to update it when needed.
15
- # - https://github.com/marian13/convenient_service_docs/blob/main/docs/api/tests/rspec/matchers/delegate_to.mdx
16
- #
17
12
  module ConvenientService
18
13
  module RSpec
19
14
  module Matchers
@@ -37,6 +32,9 @@ module ConvenientService
37
32
  # NOTE: A similar (with different behaviour) matcher exists in `saharspec`.
38
33
  # - https://github.com/zverok/saharspec#send_messageobject-method-matcher
39
34
  #
35
+ # IMPORTANT: This matcher has a dedicated end-user doc. Do NOT forget to update it when needed.
36
+ # - https://github.com/marian13/convenient_service_docs/blob/main/docs/api/tests/rspec/matchers/delegate_to.mdx
37
+ #
40
38
  class DelegateTo
41
39
  ##
42
40
  # @api private
@@ -24,11 +24,15 @@ module ConvenientService
24
24
  # @internal
25
25
  # TODO: Util `include_module?`.
26
26
  #
27
+ # NOTE: `any?(arg)` compares with `===`. For this method `==` is mandatory.
28
+ #
29
+ # rubocop:disable Performance/RedundantEqualityComparisonBlock
27
30
  def matches?(klass)
28
31
  @klass = klass
29
32
 
30
33
  klass.ancestors.drop_while { |ancestor| ancestor != klass }.any? { |mod| config == mod }
31
34
  end
35
+ # rubocop:enable Performance/RedundantEqualityComparisonBlock
32
36
 
33
37
  ##
34
38
  # @return [String]
@@ -6,7 +6,49 @@
6
6
  ##
7
7
 
8
8
  module ConvenientService
9
+ ##
10
+ # Intermediate module to access `ConvenientService::Standard::Config` by the end-users.
11
+ #
12
+ # @api public
13
+ # @since 1.0.0
14
+ #
9
15
  module Standard
16
+ ##
17
+ # Convenient Service main entrypoint.
18
+ #
19
+ # @api public
20
+ # @since 1.0.0
21
+ #
22
+ # @note See `ConvenientService::Standard::Config.default_options` for default options.
23
+ # @note See `ConvenientService::Standard::Config.available_options` for all available options.
24
+ #
25
+ # @example Allows to define services.
26
+ # class Service
27
+ # include ConvenientService::Standard::Config
28
+ #
29
+ # def result
30
+ # success
31
+ # end
32
+ # end
33
+ #
34
+ # @example Can be customized by `with`, `without`, `with_defaults`, `without_defaults` options.
35
+ # class Service
36
+ # include ConvenientService::Standard::Config
37
+ # .with(:fault_tolerance)
38
+ # .without(:short_syntax)
39
+ #
40
+ # def result
41
+ # success
42
+ # end
43
+ # end
44
+ #
45
+ # @example Can be tested in RSpec.
46
+ # RSpec.describe Service do
47
+ # include ConvenientService::RSpec::Matchers::IncludeConfig
48
+ #
49
+ # specify { expect(Service).to include_module(ConvenientService::Config.with(:fault_tolerance).without(:short_syntax)) }
50
+ # end
51
+ #
10
52
  Config = ::ConvenientService::Service::Configs::Standard
11
53
  end
12
54
  end
@@ -7,7 +7,31 @@
7
7
 
8
8
  module ConvenientService
9
9
  module Standard
10
+ ##
11
+ # Intermediate module to access `ConvenientService::Standard::V1::Config` by the end-users.
12
+ #
13
+ # @api public
14
+ # @since 1.0.0
15
+ # @deprecated Refactor your code or use a backport.
16
+ # @see https://userdocs.convenientservice.org/deprecations/jsend_meaning_of_failure_and_error
17
+ #
10
18
  module V1
19
+ ##
20
+ # Deprecated Convenient Service main entrypoint.
21
+ #
22
+ # @api public
23
+ # @since 1.0.0
24
+ # @deprecated Refactor your code or use a backport.
25
+ # @see https://userdocs.convenientservice.org/deprecations/jsend_meaning_of_failure_and_error
26
+ # @example Allows to define services.
27
+ # class Service
28
+ # include ConvenientService::Standard::V1::Config
29
+ #
30
+ # def result
31
+ # success
32
+ # end
33
+ # end
34
+ #
11
35
  Config = ::ConvenientService::Service::Configs::Standard::V1
12
36
  end
13
37
  end
@@ -15,6 +15,23 @@ module ConvenientService
15
15
  module V1
16
16
  include ConvenientService::Config
17
17
 
18
+ available_options do
19
+ [
20
+ :essential,
21
+ :callbacks,
22
+ :inspect,
23
+ :recalculation,
24
+ :result_parents_trace,
25
+ :code_review_automation,
26
+ :short_syntax,
27
+ :type_safety,
28
+ :exception_services_trace,
29
+ :per_instance_caching,
30
+ :backtrace_cleaner,
31
+ :rspec
32
+ ]
33
+ end
34
+
18
35
  default_options do
19
36
  [
20
37
  :essential,
@@ -5,8 +5,6 @@
5
5
  # @license LGPLv3 <https://www.gnu.org/licenses/lgpl-3.0.html>
6
6
  ##
7
7
 
8
- require_relative "standard/commands"
9
-
10
8
  require_relative "standard/v1"
11
9
  require_relative "standard/aliases"
12
10
 
@@ -19,13 +17,42 @@ module ConvenientService
19
17
  module Standard
20
18
  include ConvenientService::Config
21
19
 
20
+ available_options do
21
+ [
22
+ :essential,
23
+ :callbacks,
24
+ :fallbacks,
25
+ :rollbacks,
26
+ :fault_tolerance,
27
+ :inspect,
28
+ :recalculation,
29
+ :result_parents_trace,
30
+ :code_review_automation,
31
+ :short_syntax,
32
+ :type_safety,
33
+ :exception_services_trace,
34
+ :per_instance_caching,
35
+ :backtrace_cleaner,
36
+ :active_model_attribute_assignment,
37
+ :dry_initializer,
38
+ :active_model_attributes,
39
+ :active_model_validations,
40
+ :dry_validation,
41
+ :memo_wise,
42
+ :has_amazing_print_inspect,
43
+ :has_awesome_print_inspect,
44
+ :not_passed_arguments,
45
+ :finite_loop,
46
+ :test,
47
+ :rspec
48
+ ]
49
+ end
50
+
22
51
  default_options do
23
52
  [
24
53
  :essential,
25
54
  :callbacks,
26
55
  :fallbacks,
27
- # :rollbacks,
28
- # :fault_tolerance,
29
56
  :inspect,
30
57
  :recalculation,
31
58
  :result_parents_trace,
@@ -35,14 +62,7 @@ module ConvenientService
35
62
  :exception_services_trace,
36
63
  :per_instance_caching,
37
64
  :backtrace_cleaner,
38
- # :active_model_attribute_assignment,
39
- # :dry_initializer,
40
- # :active_model_attributes,
41
- # :active_model_validations,
42
- # :dry_validation,
43
- # :memo_wise,
44
- # :not_passed_arguments,
45
- # :finite_loop,
65
+ test: Dependencies.rspec.loaded? || Dependencies.minitest.loaded?,
46
66
  rspec: Dependencies.rspec.loaded?
47
67
  ]
48
68
  end
@@ -55,12 +75,12 @@ module ConvenientService
55
75
  # That is why `entity :Result do` is used.
56
76
  # - https://stackoverflow.com/a/51965126/12201472
57
77
  #
58
- # rubocop:disable Lint/ConstantDefinitionInBlock
59
78
  included do
60
79
  include ConvenientService::Service::Core
61
80
 
62
81
  concerns do
63
- use ConvenientService::Plugins::Service::CanHaveStubbedResults::Concern if options.enabled?(:rspec)
82
+ use ConvenientService::Plugins::Service::CanHaveStubbedResults::Concern if options.enabled?(:test) || options.enabled?(:rspec)
83
+ use ConvenientService::Plugins::Service::CanHaveRSpecStubbedResults::Concern if options.enabled?(:rspec)
64
84
  use ConvenientService::Plugins::Common::HasInternals::Concern if options.enabled?(:essential)
65
85
  use ConvenientService::Plugins::Common::HasConstructor::Concern if options.enabled?(:essential)
66
86
  use ConvenientService::Plugins::Common::HasConstructorWithoutInitialize::Concern if options.enabled?(:essential)
@@ -99,15 +119,15 @@ module ConvenientService
99
119
  use ConvenientService::Plugins::Common::CleansExceptionBacktrace::Middleware if options.enabled?(:backtrace_cleaner)
100
120
  use ConvenientService::Plugins::Service::CanHaveSteps::Middleware if options.enabled?(:essential)
101
121
  use ConvenientService::Plugins::Common::AssignsAttributesInConstructor::UsingActiveModelAttributeAssignment::Middleware if options.enabled?(:active_model_attribute_assignment)
102
- use ConvenientService::Service::Plugins::ForbidsConvenientServiceEntitiesAsConstructorArguments::Middleware if options.enabled?(:code_review_automation)
122
+ use ConvenientService::Plugins::Service::ForbidsConvenientServiceEntitiesAsConstructorArguments::Middleware if options.enabled?(:code_review_automation)
103
123
  end
104
124
 
105
125
  middlewares :result do
106
126
  use ConvenientService::Plugins::Common::CachesReturnValue::Middleware if options.enabled?(:per_instance_caching)
107
127
  use ConvenientService::Plugins::Service::CollectsServicesInException::Middleware if options.enabled?(:exception_services_trace)
108
- use ConvenientService::Plugins::Service::CanHaveStubbedResults::Middleware if options.enabled?(:rspec)
128
+ use ConvenientService::Plugins::Service::CanHaveStubbedResults::Middleware if options.enabled?(:test) || options.enabled?(:rspec)
109
129
  use ConvenientService::Plugins::Common::CanHaveCallbacks::Middleware if options.enabled?(:callbacks)
110
- use ConvenientService::Service::Plugins::CanHaveRollbacks::Middleware if options.enabled?(:rollbacks)
130
+ use ConvenientService::Plugins::Service::CanHaveRollbacks::Middleware if options.enabled?(:rollbacks)
111
131
  use ConvenientService::Plugins::Service::SetsParentToForeignResult::Middleware if options.enabled?(:result_parents_trace)
112
132
  use ConvenientService::Plugins::Service::RaisesOnNotResultReturnValue::Middleware if options.enabled?(:type_safety)
113
133
  use ConvenientService::Plugins::Service::RescuesResultUnhandledExceptions::Middleware if options.enabled?(:fault_tolerance)
@@ -174,7 +194,7 @@ module ConvenientService
174
194
  end
175
195
 
176
196
  middlewares :result, scope: :class do
177
- use ConvenientService::Plugins::Service::CanHaveStubbedResults::Middleware if options.enabled?(:rspec)
197
+ use ConvenientService::Plugins::Service::CanHaveStubbedResults::Middleware if options.enabled?(:test) || options.enabled?(:rspec)
178
198
  use ConvenientService::Plugins::Service::RescuesResultUnhandledExceptions::Middleware if options.enabled?(:fault_tolerance)
179
199
  end
180
200
 
@@ -209,7 +229,7 @@ module ConvenientService
209
229
  use ConvenientService::Plugins::Result::HasAmazingPrintInspect::Concern if options.enabled?(:amazing_print_inspect)
210
230
  use ConvenientService::Plugins::Result::CanBeOwnResult::Concern if options.enabled?(:result_parents_trace)
211
231
  use ConvenientService::Plugins::Result::CanHaveParentResult::Concern if options.enabled?(:result_parents_trace)
212
- use ConvenientService::Plugins::Result::CanBeStubbedResult::Concern if options.enabled?(:rspec)
232
+ use ConvenientService::Plugins::Result::CanBeStubbedResult::Concern if options.enabled?(:test) || options.enabled?(:rspec)
213
233
  use ConvenientService::Plugins::Result::CanHaveCheckedStatus::Concern if options.enabled?(:code_review_automation)
214
234
  use ConvenientService::Plugins::Common::HasJSendResultDuckShortSyntax::Concern if options.enabled?(:short_syntax)
215
235
  # use ConvenientService::Plugins::Result::HelpsToLearnSimilaritiesWithCommonObjects::Concern
@@ -364,7 +384,6 @@ module ConvenientService
364
384
  # use ConvenientService::Plugins::Service::RaisesOnDoubleResult::Middleware
365
385
  # end
366
386
  end
367
- # rubocop:enable Lint/ConstantDefinitionInBlock
368
387
 
369
388
  class << self
370
389
  ##
@@ -387,11 +406,16 @@ module ConvenientService
387
406
  # ConvenientService::Service::Configs::Standard.service_class?(Service)
388
407
  # # => true
389
408
  #
409
+ # ConvenientService::Service::Configs::Standard.service_class?(Service.new)
410
+ # # => false
411
+ #
390
412
  # ConvenientService::Service::Configs::Standard.service_class?(42)
391
413
  # # => false
392
414
  #
393
415
  def service_class?(service_class)
394
- Commands::IsServiceClass[service_class: service_class]
416
+ return false unless service_class.instance_of?(::Class)
417
+
418
+ service_class.include?(Service::Core)
395
419
  end
396
420
 
397
421
  ##
@@ -411,16 +435,17 @@ module ConvenientService
411
435
  # end
412
436
  # end
413
437
  #
414
- # service = Service.new
415
- #
416
- # ConvenientService::Service::Configs::Standard.service?(service)
438
+ # ConvenientService::Service::Configs::Standard.service?(Service.new)
417
439
  # # => true
418
440
  #
441
+ # ConvenientService::Service::Configs::Standard.service?(Service)
442
+ # # => false
443
+ #
419
444
  # ConvenientService::Service::Configs::Standard.service?(42)
420
445
  # # => false
421
446
  #
422
447
  def service?(service)
423
- Commands::IsService[service: service]
448
+ service_class?(service.class)
424
449
  end
425
450
  end
426
451
  end
@@ -13,6 +13,45 @@ module ConvenientService
13
13
  included do
14
14
  include ::ConvenientService::Core
15
15
  end
16
+
17
+ instance_methods do
18
+ ##
19
+ # Returns string representation of service.
20
+ #
21
+ # @api public
22
+ # @since 1.0.0
23
+ #
24
+ # @param format [Symbol]
25
+ # @return [String]
26
+ #
27
+ # @note Intended to be used for debugging purposes.
28
+ #
29
+ # @example Common usage.
30
+ # class Service
31
+ # include ConvenientService::Standard::Config
32
+ #
33
+ # def result
34
+ # success
35
+ # end
36
+ # end
37
+ #
38
+ # puts Service.new
39
+ # # <Service>
40
+ # # => nil
41
+ #
42
+ # Service.new.to_s
43
+ # # => "<Service>"
44
+ #
45
+ # Service.new.to_s(format: :inspect)
46
+ # # => "<Service>"
47
+ #
48
+ # Service.new.to_s(format: :original)
49
+ # # => "#<Service:0x00005639cd363000>"
50
+ #
51
+ def to_s(format: :inspect)
52
+ (format == :inspect) ? inspect : super()
53
+ end
54
+ end
16
55
  end
17
56
  end
18
57
  end
@@ -7,6 +7,54 @@
7
7
 
8
8
  module ConvenientService
9
9
  module Plugins
10
+ ##
11
+ # Intermediate module/namespace to access plugins that can be applied only to services.
12
+ #
13
+ # @api public
14
+ # @since 1.0.0
15
+ # @return [Module]
16
+ #
17
+ # @example Service plugin `CanHaveRollbacks` can be used only by services.
18
+ # class Service
19
+ # include ConvenientService::Standard::Config
20
+ #
21
+ # middlewares :result do
22
+ # insert_after \
23
+ # ConvenientService::Plugins::Common::CanHaveCallbacks::Middleware,
24
+ # ConvenientService::Plugins::Service::CanHaveRollbacks::Middleware
25
+ # end
26
+ #
27
+ # def result
28
+ # success
29
+ # end
30
+ #
31
+ # ##
32
+ # # Is called in case of `failure` or `error` from `result`, since `CanHaveRollbacks` is now enabled.
33
+ # #
34
+ # def rollback_result
35
+ # puts "from `rollback_result`"
36
+ # end
37
+ # end
38
+ #
39
+ # @example Shorter way to add `CanHaveRollbacks` plugin.
40
+ # ##
41
+ # # Some service plugin groups like `:rollbacks` can be added by config option.
42
+ # #
43
+ # class Service
44
+ # include ConvenientService::Standard::Config.with(:rollbacks)
45
+ #
46
+ # def result
47
+ # success
48
+ # end
49
+ #
50
+ # ##
51
+ # # Is called in case of `failure` or `error` from `result`, since `CanHaveRollbacks` is now enabled.
52
+ # #
53
+ # def rollback_result
54
+ # puts "from `rollback_result`"
55
+ # end
56
+ # end
57
+ #
10
58
  Service = ::ConvenientService::Service::Plugins
11
59
  end
12
60
  end
@@ -37,17 +37,48 @@ module ConvenientService
37
37
  end
38
38
 
39
39
  ##
40
- # Calls service own rollback.
40
+ # Calls service rollback.
41
41
  #
42
42
  # @param service [ConvenientService::Service]
43
43
  # @return [void]
44
44
  #
45
+ # @note All rollback exceptions are automatically rescued. That is done to NOT skip the rest of rollbacks just because one of them raises exception. Such skipping usually leads to the worse and even more inconsistent system state.
46
+ #
47
+ # @note Rollback exception log.
48
+ # class Service
49
+ # include ConvenientService::Standard::Config.with(:rollbacks)
50
+ #
51
+ # step OtherService
52
+ #
53
+ # def rollback_result
54
+ # puts "Hello from `Service` rollback!" # Still executed although `OtherService` rollback raises exception.
55
+ # end
56
+ # end
57
+ #
58
+ # class OtherService
59
+ # include ConvenientService::Standard::Config.with(:rollbacks)
60
+ #
61
+ # def result
62
+ # 16 / 0 # Service raises `ZeroDivisionError` exception to trigger rollback.
63
+ #
64
+ # success
65
+ # end
66
+ #
67
+ # def rollback_result
68
+ # [].keys # Rollback raises `NoMethodError` exception that is ignored by other rollbacks, but still can be logged by the end-user in `rescue` statement.
69
+ # rescue => exception
70
+ # puts exception.class
71
+ # puts exception.message
72
+ # puts exception.backtrace.to_a.take(10)
73
+ # end
74
+ # end
75
+ #
45
76
  def rollback_service(service)
46
77
  Utils::Object.safe_send(service, :rollback_result)
47
78
  end
48
79
 
49
80
  ##
50
- # Calls organizer own rollback.
81
+ # Calls organizer rollback.
51
82
  # Then calls organizer steps rollbacks with nestings in the reverse order.
52
83
  #
53
84
  # @param organizer [ConvenientService::Service]
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # @author Marian Kostyk <mariankostyk13895@gmail.com>
5
+ # @license LGPLv3 <https://www.gnu.org/licenses/lgpl-3.0.html>
6
+ ##
7
+
8
+ module ConvenientService
9
+ module Service
10
+ module Plugins
11
+ module CanHaveRSpecStubbedResults
12
+ module Concern
13
+ include Support::Concern
14
+
15
+ class_methods do
16
+ ##
17
+ # @return [RSpec::Core::Example, nil]
18
+ #
19
+ # @internal
20
+ # NOTE: `::RSpec.current_example` docs.
21
+ # - https://www.rubydoc.info/github/rspec/rspec-core/RSpec.current_example
22
+ # - https://github.com/rspec/rspec-core/blob/v3.12.0/lib/rspec/core.rb#L122
23
+ # - https://github.com/rspec/rspec-support/blob/v3.12.0/lib/rspec/support.rb#L92
24
+ # - https://relishapp.com/rspec/rspec-core/docs/metadata/current-example
25
+ #
26
+ def stubbed_results_store
27
+ Dependencies.rspec.current_example
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end