convenient_service 0.16.0 → 0.17.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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/README.md +1 -1
  4. data/convenient_service.gemspec +24 -5
  5. data/lib/convenient_service/common/plugins/can_have_user_provided_entity/commands/find_or_create_entity.rb +7 -2
  6. data/lib/convenient_service/common/plugins/can_have_user_provided_entity/exceptions.rb +4 -4
  7. data/lib/convenient_service/common/plugins/has_around_callbacks/exceptions.rb +2 -2
  8. data/lib/convenient_service/common/plugins/has_around_callbacks/middleware.rb +2 -2
  9. data/lib/convenient_service/common/plugins/has_instance_proxy/commands/create_instance_proxy_class.rb +83 -0
  10. data/lib/convenient_service/common/plugins/has_instance_proxy/commands.rb +3 -0
  11. data/lib/convenient_service/common/plugins/has_instance_proxy/concern.rb +22 -0
  12. data/lib/convenient_service/common/plugins/has_instance_proxy/entities/instance_proxy.rb +76 -0
  13. data/lib/convenient_service/common/plugins/has_instance_proxy/entities.rb +3 -0
  14. data/lib/convenient_service/common/plugins/has_instance_proxy/middleware.rb +20 -0
  15. data/lib/convenient_service/common/plugins/has_instance_proxy.rb +6 -0
  16. data/lib/convenient_service/common/plugins.rb +1 -0
  17. data/lib/convenient_service/core/concern/class_methods.rb +7 -2
  18. data/lib/convenient_service/core/concern/instance_methods.rb +7 -2
  19. data/lib/convenient_service/core/entities/config/commands/track_method_missing_commit_trigger.rb +1 -1
  20. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/caller/commands/define_method_middlewares_caller.rb +2 -2
  21. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middlewares/base/commands/create_observable_middleware.rb +3 -0
  22. data/lib/convenient_service/core/entities/config/exceptions.rb +4 -4
  23. data/lib/convenient_service/core/entities/config.rb +1 -1
  24. data/lib/convenient_service/dependencies/extractions/active_support_backtrace_cleaner/backtrace_cleaner.rb +28 -8
  25. data/lib/convenient_service/dependencies/extractions/active_support_backtrace_cleaner.rb +3 -3
  26. data/lib/convenient_service/dependencies/extractions/b.rb +2 -0
  27. data/lib/convenient_service/dependencies/extractions/ce.rb +16 -0
  28. data/lib/convenient_service/dependencies/extractions.rb +1 -0
  29. data/lib/convenient_service/dependencies.rb +6 -1
  30. data/lib/convenient_service/examples/standard/request_params.rb +0 -1
  31. data/lib/convenient_service/examples/standard/v1/request_params.rb +0 -1
  32. data/lib/convenient_service/exception.rb +98 -10
  33. data/lib/convenient_service/feature/configs/standard.rb +8 -0
  34. data/lib/convenient_service/feature/plugins/can_have_entries/commands/define_entries.rb +49 -0
  35. data/lib/convenient_service/feature/plugins/can_have_entries/commands/define_entry.rb +18 -4
  36. data/lib/convenient_service/feature/plugins/can_have_entries/commands.rb +1 -0
  37. data/lib/convenient_service/feature/plugins/can_have_entries/concern.rb +13 -4
  38. data/lib/convenient_service/feature/plugins/can_have_entries/exceptions.rb +14 -4
  39. data/lib/convenient_service/logger.rb +4 -1
  40. data/lib/convenient_service/rspec/helpers/classes/stub_service/entities/result_spec.rb +0 -8
  41. data/lib/convenient_service/rspec/helpers/classes/wrap_method/entities/wrapped_method.rb +5 -5
  42. data/lib/convenient_service/rspec/helpers/classes/wrap_method/exceptions.rb +2 -2
  43. data/lib/convenient_service/rspec/matchers/classes/results/base/entities/validator/commands/validate_result_step.rb +1 -1
  44. data/lib/convenient_service/rspec/matchers/classes/results/base/exceptions.rb +2 -2
  45. data/lib/convenient_service/rspec/primitive_helpers/classes/ignoring_exception/exceptions.rb +2 -2
  46. data/lib/convenient_service/rspec/primitive_helpers/classes/ignoring_exception.rb +1 -1
  47. data/lib/convenient_service/rspec/primitive_matchers/classes/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments/commands/apply_stub_to_track_delegations.rb +4 -0
  48. data/lib/convenient_service/rspec/primitive_matchers/classes/delegate_to/entities/matcher/entities/chainings_collection/exceptions.rb +7 -7
  49. data/lib/convenient_service/rspec/primitive_matchers/classes/delegate_to/entities/matcher/entities/chainings_collection.rb +3 -3
  50. data/lib/convenient_service/service/plugins/can_have_fallbacks/concern.rb +2 -2
  51. data/lib/convenient_service/service/plugins/can_have_fallbacks/exceptions.rb +4 -4
  52. data/lib/convenient_service/service/plugins/can_have_fallbacks/middleware.rb +1 -1
  53. data/lib/convenient_service/service/plugins/can_have_steps/concern.rb +3 -3
  54. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/commands/define_method_in_container.rb +2 -2
  55. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/concern/instance_methods.rb +1 -1
  56. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/callers/alias.rb +2 -2
  57. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/callers/proc.rb +1 -1
  58. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/callers/raw.rb +1 -1
  59. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/callers/reassignment.rb +2 -2
  60. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/callers/usual.rb +2 -2
  61. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/directions/input.rb +2 -2
  62. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/directions/output.rb +1 -1
  63. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/exceptions.rb +26 -26
  64. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/concern/instance_methods.rb +1 -1
  65. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/exceptions.rb +2 -2
  66. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_be_result_step/can_be_executed/exceptions.rb +2 -2
  67. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_be_result_step/can_be_executed/middleware.rb +1 -1
  68. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/raises_on_not_result_return_value/exceptions.rb +2 -2
  69. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/raises_on_not_result_return_value/middleware.rb +1 -1
  70. data/lib/convenient_service/service/plugins/has_inspect/concern.rb +0 -1
  71. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/concern/instance_methods.rb +7 -0
  72. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/data/concern/instance_methods.rb +1 -1
  73. 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 +14 -0
  74. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/exceptions.rb +2 -2
  75. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/raises_on_not_checked_result_status/exceptions.rb +2 -2
  76. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/raises_on_not_checked_result_status/middleware.rb +1 -1
  77. data/lib/convenient_service/service/plugins/has_j_send_result/exceptions.rb +2 -2
  78. data/lib/convenient_service/service/plugins/has_j_send_result.rb +39 -0
  79. data/lib/convenient_service/service/plugins/has_j_send_result_short_syntax/error/exceptions.rb +6 -6
  80. data/lib/convenient_service/service/plugins/has_j_send_result_short_syntax/error/middleware.rb +3 -3
  81. data/lib/convenient_service/service/plugins/has_j_send_result_short_syntax/failure/exceptions.rb +6 -6
  82. data/lib/convenient_service/service/plugins/has_j_send_result_short_syntax/failure/middleware.rb +3 -3
  83. data/lib/convenient_service/service/plugins/has_j_send_result_short_syntax/success/commands/refute_kwargs_contain_j_send_and_extra_keys.rb +1 -1
  84. data/lib/convenient_service/service/plugins/has_j_send_result_short_syntax/success/exceptions.rb +2 -2
  85. data/lib/convenient_service/service/plugins/has_j_send_result_status_check_short_syntax/concern.rb +0 -8
  86. data/lib/convenient_service/service/plugins/has_result/concern.rb +1 -1
  87. data/lib/convenient_service/service/plugins/has_result/exceptions.rb +2 -2
  88. data/lib/convenient_service/service/plugins/raises_on_double_result/exceptions.rb +2 -2
  89. data/lib/convenient_service/service/plugins/raises_on_double_result/middleware.rb +1 -1
  90. data/lib/convenient_service/service/plugins/raises_on_not_result_return_value/exceptions.rb +2 -2
  91. data/lib/convenient_service/service/plugins/raises_on_not_result_return_value/middleware.rb +1 -1
  92. data/lib/convenient_service/support/abstract_method/exceptions.rb +2 -2
  93. data/lib/convenient_service/support/abstract_method.rb +1 -1
  94. data/lib/convenient_service/support/backtrace_cleaner.rb +123 -0
  95. data/lib/convenient_service/support/cache/exceptions.rb +2 -2
  96. data/lib/convenient_service/support/cache.rb +1 -1
  97. data/lib/convenient_service/support/castable/exceptions.rb +4 -4
  98. data/lib/convenient_service/support/castable.rb +1 -1
  99. data/lib/convenient_service/support/command.rb +3 -3
  100. data/lib/convenient_service/support/counter.rb +6 -6
  101. data/lib/convenient_service/support/dependency_container/commands/assert_valid_container.rb +1 -1
  102. data/lib/convenient_service/support/dependency_container/commands/assert_valid_method.rb +1 -1
  103. data/lib/convenient_service/support/dependency_container/commands/assert_valid_scope.rb +1 -1
  104. data/lib/convenient_service/support/dependency_container/exceptions.rb +8 -8
  105. data/lib/convenient_service/support/dependency_container/export.rb +1 -1
  106. data/lib/convenient_service/support/finite_loop.rb +6 -6
  107. data/lib/convenient_service/support.rb +1 -0
  108. data/lib/convenient_service/utils/array/exceptions.rb +2 -2
  109. data/lib/convenient_service/utils/array/merge.rb +1 -1
  110. data/lib/convenient_service/utils/hash/assert_valid_keys.rb +1 -1
  111. data/lib/convenient_service/version.rb +1 -1
  112. data/lib/convenient_service.rb +98 -0
  113. metadata +22 -41
  114. data/lib/convenient_service/examples/standard/v1/gemfile/services/print_shell_command.rb +0 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f1f1683a178b667d76adabe5735fa7361e7946f3a9aa7d3bcfffca62ed4d7b4
4
- data.tar.gz: 0d64f2e78e0ef56707d8efcdcb66dafd9386a118c44d96139c699a4517cb7bcb
3
+ metadata.gz: f24d02cddcb69e9108cf7d810c85f4ccf338201b8a31bbc7da0be1ef92bd91a9
4
+ data.tar.gz: 89c019fa64f6fe8194c9b74a676d367e390cc5cb33efef361a4fcb448cd72d17
5
5
  SHA512:
6
- metadata.gz: e16ab9be69fb6721ec9fdc290c857d8da8db77bc46702aad4179f6ce04df3d73a0119befec63c13d04d0c24d15ad5d46310fd243f4d3bb214b7153dfdc1d688e
7
- data.tar.gz: cef563d9e931f10f766e6ae5f7eb0136a96ab0c892f28a13ddf9db3860a19fcb984a7e514f6b6430750df8287ec9da4df0f4d75ea7a7e620321a72569b08c29e
6
+ metadata.gz: a53a4a7fee700e8128eeea830ac57cee73e6a6034d36e61dd224584e06f08ef4d944cdc513bfbac17187866b09969a4f63f31e316745546de032a24965bad6dd
7
+ data.tar.gz: 47a180d8079468f98eadcfbddc2654323fabeae0d7f8b47febc7c13f80d43d30a30583d7104d60d486b02f6e024155487fe3ce5c20bd1eea39f214ee326dc9ff
data/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.17.0](https://github.com/marian13/convenient_service/compare/v0.16.0...v0.17.0) (2024-01-14)
4
+
5
+
6
+ ### Features
7
+
8
+ * **backtrace_cleaner:** introduce add_convenient_service_silencer ([07ce10f](https://github.com/marian13/convenient_service/commit/07ce10fbd96c7e6b3074922d0ca8af6547416725))
9
+ * **backtrace_cleaner:** upgrade to Rails 7.1.2 Backtrace Cleaner ([6416691](https://github.com/marian13/convenient_service/commit/6416691d99d3b22544b78ea81aed5a3a4aa513fe))
10
+ * **core:** clean backtrace in method_missing ([0642198](https://github.com/marian13/convenient_service/commit/06421981ccf39d2d0b07f2bce30284c604bba950))
11
+ * **core:** clean backtrace in method_missing ([81d0531](https://github.com/marian13/convenient_service/commit/81d05317d842d9afa2ef7034b34b850034a8f1dd))
12
+ * **core:** clean backtrace in method_missing ([f07c354](https://github.com/marian13/convenient_service/commit/f07c354e8fc14f1062df68f938b9d4b9fa8484c5))
13
+ * **entry:** allow to define multiple entries at once ([a9bca88](https://github.com/marian13/convenient_service/commit/a9bca880da4849866f6afc30b3f099be88834f64))
14
+ * **exception:** allow to pass message or kwargs or no arguments ([a92a040](https://github.com/marian13/convenient_service/commit/a92a04002687c878618479804d0176e69b3d4fa4))
15
+ * **exceptions:** use backtrace_cleaner ([7bc566e](https://github.com/marian13/convenient_service/commit/7bc566e78cfa3fcc28b6b2318ca955ff4d797ce8))
16
+ * **exceptions:** use backtrace_cleaner ([b8d87a5](https://github.com/marian13/convenient_service/commit/b8d87a56cb4afda043ba0de6c1ba3cd967d2aa7c))
17
+ * **feature:** allow to use middlewares for all entries at once ([a2025dc](https://github.com/marian13/convenient_service/commit/a2025dccbf660cdc313f9db7df155ccd7a4cd3b8))
18
+ * **has_instance_proxy:** delegate to target missing proxy methods ([6be8d3b](https://github.com/marian13/convenient_service/commit/6be8d3b6bf556bc2af9ff29a7b0782b352a8effb))
19
+ * **has_instance_proxy:** introduce #inspect ([078d219](https://github.com/marian13/convenient_service/commit/078d21927b1b523b266e85d945f87aa3030de0f4))
20
+ * **has_j_send_result:** expose result? ([f4d5f7f](https://github.com/marian13/convenient_service/commit/f4d5f7fb9afde955295602db022d12f084f60d9e))
21
+ * **has_j_send_status_and_attributes:** introduce #to_bool ([ec5ee1e](https://github.com/marian13/convenient_service/commit/ec5ee1ec0f4a540a109f80e3ffafa1b937d1af60))
22
+ * **root:** introduce ConvenientService.raise and ConvenientService.reraise ([65f0148](https://github.com/marian13/convenient_service/commit/65f0148d052c31c3e305470b2b9daee5c746794e))
23
+ * **root:** introduce ConvenientService.root ([dc5af36](https://github.com/marian13/convenient_service/commit/dc5af365374a76d615fa09613b59bb9cd080bc1b))
24
+ * **support:** add initial backtrace cleaner ([14733f3](https://github.com/marian13/convenient_service/commit/14733f3d5b622c08aec1fe0b80a2b7c5699b4d4f))
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * **backtrace_cleaner:** resolve JRuby incompatibilites ([3ff9055](https://github.com/marian13/convenient_service/commit/3ff90555a0f78f1ba51fa7c538cc84c7c4e69bdb))
30
+ * **rescues_result_unhandled_exceptions:** fix false-positive test ([e792c01](https://github.com/marian13/convenient_service/commit/e792c01613a74da529f2f7833248527c40f1ac7b))
31
+ * **specs:** remove did_you_mean flakiness ([709faf6](https://github.com/marian13/convenient_service/commit/709faf6c8ac9eb28451f3ea734d5588159481648))
32
+
3
33
  ## [0.16.0](https://github.com/marian13/convenient_service/compare/v0.15.0...v0.16.0) (2023-12-05)
4
34
 
5
35
 
data/README.md CHANGED
@@ -49,7 +49,7 @@ This library is under heavy development. Public API may be subject to change. Th
49
49
 
50
50
  - Visit the [All-in-One Presentation](https://marian13.github.io/static_content/convenient_service/presentations/all_in_one) to get a quick overview.
51
51
 
52
- - Check out [Convenient Service Official User Docs](https://marian13.github.io/convenient_service_docs) for installation, requirements, and usage guides.
52
+ - Check out [Convenient Service Official User Docs](https://userdocs.convenientservice.org/) for installation, requirements, and usage guides.
53
53
 
54
54
  - Read [the API docs](https://marian13.github.io/convenient_service) to get familiar with the newest functionality that is not documented yet.
55
55
 
@@ -72,10 +72,15 @@ Gem::Specification.new do |spec|
72
72
  spec.add_development_dependency "byebug", "~> 10.0" unless ConvenientService::Support::Ruby.jruby?
73
73
 
74
74
  ##
75
+ # Used for parsing Markdown in YARD docs.
76
+ # - https://github.com/gjtorikian/commonmarker
77
+ #
75
78
  # NOTE: `commonmarker` has C extensions, that is why it is NOT supported in JRuby.
76
79
  # - https://github.com/gjtorikian/commonmarker/tree/main/ext/commonmarker
77
80
  #
78
- spec.add_development_dependency "commonmarker" unless ConvenientService::Support::Ruby.jruby?
81
+ # TODO: `commonmarker` v1 does NOT work with `yard-junk`.
82
+ #
83
+ spec.add_development_dependency "commonmarker", "~> 0.23.10" unless ConvenientService::Support::Ruby.jruby?
79
84
 
80
85
  ##
81
86
  # Used for debugging CRuby code.
@@ -122,8 +127,13 @@ Gem::Specification.new do |spec|
122
127
  # - https://github.com/mbj/mutant/blob/main/docs/mutant-rspec.md
123
128
  # - https://github.com/mbj/mutant/blob/main/docs/incremental.md
124
129
  #
125
- spec.add_development_dependency "mutant", "~> 0.11.21"
126
- spec.add_development_dependency "mutant-rspec", "~> 0.11.21"
130
+ # NOTE: How to get a licence key?
131
+ # - https://github.com/mbj/mutant/issues/1396
132
+ #
133
+ if ::ENV["CONVENIENT_SERVICE_MUTANT_LICENCE_KEY"]
134
+ spec.add_development_dependency "mutant", "~> 0.11.21"
135
+ spec.add_development_dependency "mutant-rspec", "~> 0.11.21"
136
+ end
127
137
 
128
138
  ##
129
139
  # Used for coloring logs.
@@ -190,9 +200,18 @@ Gem::Specification.new do |spec|
190
200
 
191
201
  spec.add_development_dependency "webrick"
192
202
 
193
- spec.add_development_dependency "yard", "~> 0.9.28"
203
+ ##
204
+ # Used for generation of API docs for Ruby code.
205
+ # - https://github.com/lsegal/yard
206
+ # - https://yardoc.org
207
+ #
208
+ spec.add_development_dependency "yard", "~> 0.9.34"
194
209
 
195
- spec.add_development_dependency "yard-junk"
210
+ ##
211
+ # Used for linting YARD docs.
212
+ # - https://github.com/zverok/yard-junk
213
+ #
214
+ spec.add_development_dependency "yard-junk", "~> 0.0.9"
196
215
 
197
216
  ##
198
217
  # The following gems are Convenient Service alternatives.
@@ -32,8 +32,8 @@ module ConvenientService
32
32
  # @return [void]
33
33
  #
34
34
  def call
35
- raise Exceptions::ProtoEntityHasNoName.new(proto_entity: proto_entity) unless proto_entity_name
36
- raise Exceptions::ProtoEntityHasNoConcern.new(proto_entity: proto_entity) unless proto_entity_concern
35
+ ::ConvenientService.raise Exceptions::ProtoEntityHasNoName.new(proto_entity: proto_entity) unless proto_entity_name
36
+ ::ConvenientService.raise Exceptions::ProtoEntityHasNoConcern.new(proto_entity: proto_entity) unless proto_entity_concern
37
37
 
38
38
  entity.include Core
39
39
 
@@ -71,6 +71,11 @@ module ConvenientService
71
71
  #
72
72
  entity.class_exec(proto_entity) do |proto_entity|
73
73
  define_singleton_method(:proto_entity) { proto_entity }
74
+
75
+ ##
76
+ # @internal
77
+ # TODO: Try `self.proto_entity == other.proto_entity if self < proto_entity_concern`.
78
+ #
74
79
  define_singleton_method(:==) { |other| self.proto_entity == other.proto_entity if other.respond_to?(:proto_entity) }
75
80
 
76
81
  ##
@@ -6,7 +6,7 @@ module ConvenientService
6
6
  module CanHaveUserProvidedEntity
7
7
  module Exceptions
8
8
  class ProtoEntityHasNoName < ::ConvenientService::Exception
9
- def initialize(proto_entity:)
9
+ def initialize_with_kwargs(proto_entity:)
10
10
  message = <<~TEXT
11
11
  Proto entity `#{proto_entity}` has no name.
12
12
 
@@ -18,12 +18,12 @@ module ConvenientService
18
18
  NOTE: Anonymous classes do NOT have names. Are you passing an anonymous class?
19
19
  TEXT
20
20
 
21
- super(message)
21
+ initialize(message)
22
22
  end
23
23
  end
24
24
 
25
25
  class ProtoEntityHasNoConcern < ::ConvenientService::Exception
26
- def initialize(proto_entity:)
26
+ def initialize_with_kwargs(proto_entity:)
27
27
  message = <<~TEXT
28
28
  Proto entity `#{proto_entity}` has no concern.
29
29
 
@@ -32,7 +32,7 @@ module ConvenientService
32
32
  It is an example of a valid proto entity.
33
33
  TEXT
34
34
 
35
- super(message)
35
+ initialize(message)
36
36
  end
37
37
  end
38
38
  end
@@ -6,7 +6,7 @@ module ConvenientService
6
6
  module HasAroundCallbacks
7
7
  module Exceptions
8
8
  class AroundCallbackChainIsNotContinued < ::ConvenientService::Exception
9
- def initialize(callback:)
9
+ def initialize_with_kwargs(callback:)
10
10
  message = <<~TEXT
11
11
  Around callback chain is NOT continued from `#{callback.block.source_location}`.
12
12
 
@@ -19,7 +19,7 @@ module ConvenientService
19
19
  end
20
20
  TEXT
21
21
 
22
- super(message)
22
+ initialize(message)
23
23
  end
24
24
  end
25
25
  end
@@ -123,12 +123,12 @@ module ConvenientService
123
123
  ##
124
124
  #
125
125
  #
126
- raise Exceptions::AroundCallbackChainIsNotContinued.new(callback: Utils::Array.find_last(around_callbacks, &:called?)) if around_callbacks.any?(&:not_called?)
126
+ ::ConvenientService.raise Exceptions::AroundCallbackChainIsNotContinued.new(callback: Utils::Array.find_last(around_callbacks, &:called?)) if around_callbacks.any?(&:not_called?)
127
127
 
128
128
  ##
129
129
  #
130
130
  #
131
- raise Exceptions::AroundCallbackChainIsNotContinued.new(callback: around_callbacks.last) if initial_around_callback.not_called?
131
+ ::ConvenientService.raise Exceptions::AroundCallbackChainIsNotContinued.new(callback: around_callbacks.last) if initial_around_callback.not_called?
132
132
 
133
133
  original_value
134
134
  end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Common
5
+ module Plugins
6
+ module HasInstanceProxy
7
+ module Commands
8
+ class CreateInstanceProxyClass < Support::Command
9
+ ##
10
+ # @!attribute [r] target_class
11
+ # @return [Class]
12
+ #
13
+ attr_reader :target_class
14
+
15
+ ##
16
+ # @param target_class [Class]
17
+ # @return [void]
18
+ #
19
+ def initialize(target_class:)
20
+ @target_class = target_class
21
+ end
22
+
23
+ ##
24
+ # @return [void]
25
+ #
26
+ def call
27
+ klass = ::Class.new(Entities::InstanceProxy)
28
+
29
+ ##
30
+ # @example Result for feature.
31
+ #
32
+ # klass = ConvenientService::Common::Plugins::HasInstanceProxy::Commands::CreateInstanceProxyClass.call(
33
+ # target_class: SomeFeature
34
+ # )
35
+ #
36
+ # ##
37
+ # # `klass` is something like:
38
+ # #
39
+ # # class InstanceProxy < ConvenientService::Service::Plugins::HasInstanceProxy::Entities::InstanceProxy
40
+ # # class << self
41
+ # # def target_class
42
+ # # ##
43
+ # # # NOTE: Returns `target_class` passed to `CreateInstanceProxyClass`.
44
+ # # #
45
+ # # target_class
46
+ # # end
47
+ # #
48
+ # # def ==(other)
49
+ # # return unless other.respond_to?(:target_class)
50
+ # #
51
+ # # self.target_class == other.target_class
52
+ # # end
53
+ # # end
54
+ # # end
55
+ #
56
+ klass.class_exec(target_class) do |target_class|
57
+ ##
58
+ # @return [Class]
59
+ #
60
+ define_singleton_method(:target_class) { target_class }
61
+
62
+ ##
63
+ # @return [Boolean, nil]
64
+ #
65
+ # @internal
66
+ # TODO: Try `self.target_class == other.target_class if self < ::ConvenientService::Common::Plugins::HasInstanceProxy::Entities::InstanceProxy`.
67
+ #
68
+ define_singleton_method(:==) { |other| self.target_class == other.target_class if other.respond_to?(:target_class) }
69
+
70
+ ##
71
+ # @return [String]
72
+ #
73
+ define_singleton_method(:inspect) { "#{target_class}::InstanceProxy" }
74
+ end
75
+
76
+ klass
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "commands/create_instance_proxy_class"
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Common
5
+ module Plugins
6
+ module HasInstanceProxy
7
+ module Concern
8
+ include Support::Concern
9
+
10
+ class_methods do
11
+ ##
12
+ # @return [Class] Can be any type.
13
+ #
14
+ def instance_proxy_class
15
+ @instance_proxy_class ||= Commands::CreateInstanceProxyClass[target_class: self]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Common
5
+ module Plugins
6
+ module HasInstanceProxy
7
+ module Entities
8
+ class InstanceProxy
9
+ ##
10
+ # @api private
11
+ #
12
+ # @param target [Object] Can be any type.
13
+ # @return [void]
14
+ #
15
+ def initialize(target:)
16
+ @__convenient_service_instance_proxy_target__ = target
17
+ end
18
+
19
+ ##
20
+ # @api public
21
+ #
22
+ # @return [Object] Can be any type.
23
+ #
24
+ def instance_proxy_target
25
+ @__convenient_service_instance_proxy_target__
26
+ end
27
+
28
+ ##
29
+ # @api public
30
+ #
31
+ # @param other [Object] Can be any type.
32
+ # @return [Boolean, nil]
33
+ #
34
+ # @internal
35
+ # TODO: Direct Specs.
36
+ #
37
+ def ==(other)
38
+ return unless other.instance_of?(self.class)
39
+
40
+ return false if instance_proxy_target != other.instance_proxy_target
41
+
42
+ true
43
+ end
44
+
45
+ private
46
+
47
+ ##
48
+ # @see https://thoughtbot.com/blog/always-define-respond-to-missing-when-overriding
49
+ # @see https://blog.marc-andre.ca/2010/11/15/methodmissing-politely
50
+ # @see https://stackoverflow.com/a/3304683/12201472
51
+ #
52
+ # @param method_name [Symbol, String]
53
+ # @param include_private [Boolean]
54
+ # @return [Boolean]
55
+ #
56
+ # @internal
57
+ # IMPORTANT: `respond_to_missing?` is like `initialize`. It is always `private`.
58
+ # - https://ruby-doc.org/core-2.7.0/Object.html#method-i-respond_to_missing-3F
59
+ # - https://github.com/ruby/spec/blob/master/language/def_spec.rb#L65
60
+ #
61
+ def respond_to_missing?(method_name, include_private = false)
62
+ instance_proxy_target.respond_to?(method_name, include_private)
63
+ end
64
+
65
+ ##
66
+ # @return [Object] Can be any type.
67
+ #
68
+ def method_missing(...)
69
+ instance_proxy_target.public_send(...)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "entities/instance_proxy"
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Common
5
+ module Plugins
6
+ module HasInstanceProxy
7
+ class Middleware < MethodChainMiddleware
8
+ intended_for :new, scope: :class, entity: any_entity
9
+
10
+ ##
11
+ # @return [ConvenientService::Common::Plugins::HasInstanceProxy::Entities::InstanceProxy]
12
+ #
13
+ def next(...)
14
+ entity.instance_proxy_class.new(target: chain.next(...))
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "has_instance_proxy/commands"
4
+ require_relative "has_instance_proxy/concern"
5
+ require_relative "has_instance_proxy/entities"
6
+ require_relative "has_instance_proxy/middleware"
@@ -14,6 +14,7 @@ require_relative "plugins/has_around_callbacks"
14
14
  require_relative "plugins/has_constructor"
15
15
  require_relative "plugins/has_constructor_without_initialize"
16
16
  require_relative "plugins/has_internals"
17
+ require_relative "plugins/has_instance_proxy"
17
18
  require_relative "plugins/has_j_send_result_duck_short_syntax"
18
19
 
19
20
  require_relative "plugins/aliases"
@@ -70,6 +70,7 @@ module ConvenientService
70
70
 
71
71
  ##
72
72
  # @see https://thoughtbot.com/blog/always-define-respond-to-missing-when-overriding
73
+ # @see https://blog.marc-andre.ca/2010/11/15/methodmissing-politely
73
74
  # @see https://stackoverflow.com/a/3304683/12201472
74
75
  #
75
76
  # @param method_name [Symbol, String]
@@ -112,12 +113,16 @@ module ConvenientService
112
113
  #
113
114
  # TODO: Include `method` into trigger metadata.
114
115
  #
116
+ # IMPORTANT: Ruby 2.7 and Ruby 3.0+ invoke this `method_missing` differently, check the following files/links:
117
+ # - `lib/convenient_service/core/entities/config/entities/method_middlewares/entities/caller/commands/define_method_middlewares_caller.rb`
118
+ # - https://gist.github.com/marian13/9c25041f835564e945d978839097d419
119
+ #
115
120
  def method_missing(method, *args, **kwargs, &block)
116
121
  commit_config!(trigger: Constants::Triggers::CLASS_METHOD_MISSING)
117
122
 
118
- return super unless Utils::Module.class_method_defined?(self, method, public: true, protected: false, private: false)
123
+ return ::ConvenientService.reraise { super } unless Utils::Module.class_method_defined?(self, method, public: true, protected: false, private: false)
119
124
 
120
- return super if middlewares(method, scope: :class).defined_without_super_method?
125
+ return ::ConvenientService.reraise { super } if middlewares(method, scope: :class).defined_without_super_method?
121
126
 
122
127
  ConvenientService.logger.debug { "[Core] Committed config for `#{self}` | Triggered by `method_missing` | Method: `.#{method}`" }
123
128
 
@@ -17,6 +17,7 @@ module ConvenientService
17
17
 
18
18
  ##
19
19
  # @see https://thoughtbot.com/blog/always-define-respond-to-missing-when-overriding
20
+ # @see https://blog.marc-andre.ca/2010/11/15/methodmissing-politely
20
21
  # @see https://stackoverflow.com/a/3304683/12201472
21
22
  #
22
23
  # @param method_name [Symbol, String]
@@ -59,12 +60,16 @@ module ConvenientService
59
60
  #
60
61
  # TODO: Include `method` into trigger metadata.
61
62
  #
63
+ # IMPORTANT: Ruby 2.7 and Ruby 3.0+ invoke this `method_missing` differently, check the following files/links:
64
+ # - `lib/convenient_service/core/entities/config/entities/method_middlewares/entities/caller/commands/define_method_middlewares_caller.rb`
65
+ # - https://gist.github.com/marian13/9c25041f835564e945d978839097d419
66
+ #
62
67
  def method_missing(method, *args, **kwargs, &block)
63
68
  self.class.commit_config!(trigger: Constants::Triggers::INSTANCE_METHOD_MISSING)
64
69
 
65
- return super unless Utils::Module.instance_method_defined?(self.class, method, public: true, protected: false, private: false)
70
+ return ::ConvenientService.reraise { super } unless Utils::Module.instance_method_defined?(self.class, method, public: true, protected: false, private: false)
66
71
 
67
- return super if self.class.middlewares(method, scope: :instance).defined_without_super_method?
72
+ return ::ConvenientService.reraise { super } if self.class.middlewares(method, scope: :instance).defined_without_super_method?
68
73
 
69
74
  ConvenientService.logger.debug { "[Core] Committed config for `#{self.class}` | Triggered by `method_missing` | Method: `##{method}`" }
70
75
 
@@ -35,7 +35,7 @@ module ConvenientService
35
35
  return unless method_missing_trigger_valid?
36
36
  return if method_missing_commits_counter_incremented?
37
37
 
38
- raise Exceptions::TooManyCommitsFromMethodMissing.new(config: config)
38
+ ::ConvenientService.raise Exceptions::TooManyCommitsFromMethodMissing.new(config: config)
39
39
  end
40
40
 
41
41
  ##
@@ -90,9 +90,9 @@ module ConvenientService
90
90
  # prefix = "#{prefix}"
91
91
  #
92
92
  # NOTE: Check the following link in order to get an idea why two versions of `define_method_middlewares_caller` exist.
93
- # https://gist.github.com/marian13/9c25041f835564e945d978839097d419
93
+ # - https://gist.github.com/marian13/9c25041f835564e945d978839097d419
94
94
  #
95
- if ::RUBY_VERSION >= "3.0"
95
+ if Dependencies.ruby.version >= 3.0
96
96
  def define_method_middlewares_caller
97
97
  <<~RUBY.tap { |code| methods_middlewares_callers.module_eval(code, __FILE__, __LINE__ + 1) }
98
98
  def #{method}(*args, **kwargs, &block)
@@ -39,6 +39,9 @@ module ConvenientService
39
39
  # @param other [Object] Can be any type.
40
40
  # @return [Boolean, nil]
41
41
  #
42
+ # @internal
43
+ # TODO: Try `self.middleware == other.middleware if self < ::ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Middlewares::Base`.
44
+ #
42
45
  define_singleton_method(:==) { |other| self.middleware == other.middleware if other.respond_to?(:middleware) }
43
46
 
44
47
  ##
@@ -10,14 +10,14 @@ module ConvenientService
10
10
  # @param config [ConvenientService::Core::Entities::Config]
11
11
  # @return [void]
12
12
  #
13
- def initialize(config:)
13
+ def initialize_with_kwargs(config:)
14
14
  message = <<~TEXT
15
15
  Config for `#{config.klass}` is already committed. Only uncommitted configs can be modified.
16
16
 
17
17
  Did you accidentally call `concerns(&configuration_block)` or `middlewares(method, scope: scope, &configuration_block)` after using any plugin, after calling `commit_config!`?
18
18
  TEXT
19
19
 
20
- super(message)
20
+ initialize(message)
21
21
  end
22
22
  end
23
23
 
@@ -30,7 +30,7 @@ module ConvenientService
30
30
  # TODO: Create a troubleshooting page with possible reasons (preliminary RSpec mocks etc).
31
31
  # Append a link to it to the error message.
32
32
  #
33
- def initialize(config:)
33
+ def initialize_with_kwargs(config:)
34
34
  message = <<~TEXT
35
35
  `#{config.klass}` config is committed too many times from `method_missing`.
36
36
 
@@ -54,7 +54,7 @@ module ConvenientService
54
54
  end
55
55
  TEXT
56
56
 
57
- super(message)
57
+ initialize(message)
58
58
  end
59
59
  end
60
60
  end
@@ -162,7 +162,7 @@ module ConvenientService
162
162
  def assert_not_committed!
163
163
  return unless committed?
164
164
 
165
- raise Exceptions::ConfigIsCommitted.new(config: self)
165
+ ::ConvenientService.raise Exceptions::ConfigIsCommitted.new(config: self)
166
166
  end
167
167
  end
168
168
  end