convenient_service 0.6.0 → 0.8.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 (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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ec5188e0830cb8a97b589ff6985d4aa1e361bce486dba86a1a1f697924d0be7
4
- data.tar.gz: ab763a1c604849509f5557938768bf019b5d962dd5d6fa62771b17e3c524025d
3
+ metadata.gz: d53f96dab5d2b97b26168f4859dc0daefe41c8768e83e607d13234c2c7d77101
4
+ data.tar.gz: c6d5a9d30e5c3c768f556eb7d84b558099fcbeb96dbff655b7bd2b553435a26a
5
5
  SHA512:
6
- metadata.gz: 32cf7296bf8a5ff16d7bfed6c20a855831e27b0300edede75ba7c737f357ed6ddf462641d7cacc9c5f7a65c64c3a4e59b04a60cee0ad9793f173fca7e9c0ad24
7
- data.tar.gz: 71aadf20b54f0f507eb6721999b2192630eb2265d660d40ecc461de311fb930376883d1546c9c030c03f15e90e0c02e172066adc2213cb61140cc3f8b45b5137
6
+ metadata.gz: 9f3fb867003d44c6786446fdb2baac4550bd6ac8f34ee9196ee310912c4eb2084f40dc731dce8a2af7ac8a963d6a3579c6e886ad28251c4bf5a9a08ca290a6d2
7
+ data.tar.gz: e24704e463ac31d3f65a4c9a5777617157bdebb62ab785e92f3f18125d8968e5c3a6d44368553c706c9f8bab0ce7bd8f938ce53ebc1df68585493738533ef2cb
data/CHANGELOG.md CHANGED
@@ -1,5 +1,63 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.8.0](https://github.com/marian13/convenient_service/compare/v0.7.0...v0.8.0) (2023-02-20)
4
+
5
+
6
+ ### Features
7
+
8
+ * **aliases:** expose middlewares ([aacb6fd](https://github.com/marian13/convenient_service/commit/aacb6fda4c63e1d82e33c523885bd61397cfb583))
9
+ * **configs:** introduce Minimal config ([70b0ca8](https://github.com/marian13/convenient_service/commit/70b0ca82679fc89099aee733d91807e371bbed39))
10
+ * **rescues_result_unhandled_exceptions:** introduce rescues_result_unhandled_exceptions ([fd0b444](https://github.com/marian13/convenient_service/commit/fd0b4447e5abf81d971cd93a8333a89b363ef1ff))
11
+ * **rescues_result_unhandled_exceptions:** return original exception in data + formatted exception as message ([45bc55e](https://github.com/marian13/convenient_service/commit/45bc55ec245df1b95769be761337a3cb2558a878))
12
+ * **undefined:** introduce undefined ([2f93bdc](https://github.com/marian13/convenient_service/commit/2f93bdc86d81c9a819bbc1c4a76a0ef291a59b17))
13
+ * **wrap_method:** introduce WrappedMethod#chain_exception ([1db33af](https://github.com/marian13/convenient_service/commit/1db33afc3a0e0713700b0bf5385900085af0a2df))
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * **wrapped_method:** define chain value even if chain.next raises an exception ([8c4cf95](https://github.com/marian13/convenient_service/commit/8c4cf9534a07e9614fdc73f0d0c019f9c3f0ea54))
19
+ * **wrapped_method:** reraise rescued exception ([31f7ab6](https://github.com/marian13/convenient_service/commit/31f7ab6df0b34980656942992d3ecf7a67461d06))
20
+
21
+ ## [0.7.0](https://github.com/marian13/convenient_service/compare/v0.6.0...v0.7.0) (2023-02-13)
22
+
23
+
24
+ ### ⚠ BREAKING CHANGES
25
+
26
+ * **be_result:** introduce #of_step, #of_service, remove #of
27
+ * **has_result:** use callbacks before result
28
+
29
+ ### Features
30
+
31
+ * **be_result:** introduce #of_step, #of_service, remove #of ([0d9ba16](https://github.com/marian13/convenient_service/commit/0d9ba16f035ef50268fdf484b0fd83c58dbb328a))
32
+ * **be_result:** of_step supports method steps ([9127301](https://github.com/marian13/convenient_service/commit/9127301f41549fbb8c48b718e410ebd7c100e2e9))
33
+ * **can_have_parent_Result:** introduce CanHaveParentResult plugin ([55f0b0f](https://github.com/marian13/convenient_service/commit/55f0b0f558e2edb8b0fdc56a2d8b52bc44995a2f))
34
+ * **command:** expose command ([6abcb1a](https://github.com/marian13/convenient_service/commit/6abcb1ad481cad66eba2d4d409e3ce16b0f6591d))
35
+ * **configs:** add around callbacks for steps ([cb9d342](https://github.com/marian13/convenient_service/commit/cb9d34204d63a96e89ebebe2991e8ab77b2624f0))
36
+ * **has_around_callbacks:** pass arguments to around callbacks ([f682f9a](https://github.com/marian13/convenient_service/commit/f682f9a6fb3ef6e8ab50ccf0f7f3ba375a63092e))
37
+ * **has_callbacks:** pass arguments to callbacks ([2d7f720](https://github.com/marian13/convenient_service/commit/2d7f720e37a15874ec89167e46fb67a0631ec923))
38
+ * **has_jsend_status_and_attributes:** introduce Data#to_s ([c1e20c0](https://github.com/marian13/convenient_service/commit/c1e20c093ec4575a939645a2d951fe4e035154b8))
39
+ * **has_result_steps:** add callback trigger for step ([475d46a](https://github.com/marian13/convenient_service/commit/475d46a5abaf6fa85260cef90d78db60146b86d9))
40
+ * **has_result_steps:** introduce Step#original_result ([8891247](https://github.com/marian13/convenient_service/commit/8891247e5f0339d9e96e733d05b29e45a2e87e71))
41
+ * **has_step:** introduce HasStep plugin ([e6eee96](https://github.com/marian13/convenient_service/commit/e6eee965c8707b7378173f228b9b212834be434b))
42
+ * **not_passed:** add better #inspect ([d7ce5d9](https://github.com/marian13/convenient_service/commit/d7ce5d93a3aa5f139f6b7ee578975c1da52488c0))
43
+
44
+
45
+ ### Bug Fixes
46
+
47
+ * **be_descendant_of:** fix typo ([58e0f73](https://github.com/marian13/convenient_service/commit/58e0f73f74685614d24e0ee3c8208a5626f7ef42))
48
+ * **be_direct_descendant_of:** fix typo ([bda7d06](https://github.com/marian13/convenient_service/commit/bda7d063d1801309a58b5e4d43d738ebab5fef59))
49
+ * **ci:** change the version of yard ([185c23c](https://github.com/marian13/convenient_service/commit/185c23c40dacf997e29d0b7defd10020c22dc196))
50
+ * **copyable:** do not mutate input params ([0809592](https://github.com/marian13/convenient_service/commit/08095927ea03c60a00eb3b0d0323458b482827b0))
51
+ * **dependency_container:** fix typo ([b1cf420](https://github.com/marian13/convenient_service/commit/b1cf420a2e69cc51e928a8a1ad885a65ad7fb4fe))
52
+ * **has_result_steps:** use unsafe attributes in to_kwargs ([6c2b1d3](https://github.com/marian13/convenient_service/commit/6c2b1d3912106f6848b875d06a4d7ce1d79c4edb))
53
+ * **has_result_steps:** use unsafe_data ([e00c346](https://github.com/marian13/convenient_service/commit/e00c3468f5761e20678c7019f0d13f2569778b19))
54
+ * **has_result:** use callbacks before result ([eb46444](https://github.com/marian13/convenient_service/commit/eb46444536a7cf4aab869aa009c1a7c896c00c11))
55
+
56
+
57
+ ### Miscellaneous Chores
58
+
59
+ * release 0.7.0 ([6433f5a](https://github.com/marian13/convenient_service/commit/6433f5a67c3f21c620d500186e0308fb7b098efc))
60
+
3
61
  ## [0.6.0](https://github.com/marian13/convenient_service/compare/v0.5.0...v0.6.0) (2023-01-22)
4
62
 
5
63
 
data/ROADMAP.md CHANGED
@@ -32,7 +32,7 @@
32
32
  | High | 🚧 | Optimize `stack.dup` in `MethodMiddlewares#call` | Core v3 |
33
33
  | Medium | 🚧 | Make a decision of what to do with `printable_block` in custom RSpec matchers | |
34
34
  | Medium | 🚧 | User-friendly exception messages | |
35
- | High | 🚧 | Factories for POROs in specs ❗❗❗ | Start with `result_class`, `class self::Result`, `service_class`, `step_class`, `organizer_class` |
35
+ | High | 🚧 | Factory for POROs in specs ❗❗❗ | Start with `result_class`, `class self::Result`, `service_class`, `step_class`, `organizer_class` |
36
36
  | High | 🚧 | Resolve warning during specs | |
37
37
  | Medium | 🚧 | Consider to change/rewrite `delegate` backend to minify its interface | |
38
38
  | Medium | 🚧 | Same order of attr macros, delegators, initialize, class methods, attr methods, queries, actions, `to_*`, comparison, inspect | |
@@ -64,5 +64,18 @@
64
64
  | Medium | 🚧 | Add `shoulda-context` to test conditionals when `RSpec` is not loaded | [shoulda-context](https://github.com/thoughtbot/shoulda-context) |
65
65
  | High | 🚧 | Abstract factory for `CastMethod` | |
66
66
  | Medium | 🚧 | `delegate_to` - option to specify of how to compare blocks | |
67
+ | High | 🚧 | Add specs for [Reassignment::Commands::DefineMethodInContainer](https://github.com/marian13/convenient_service/blob/v0.6.0/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment/commands/define_method_in_container.rb#L13) | |
68
+ | High | 🚧 | Example for dependency containers | |
69
+ | Low | 🚧 | `delegate_to.and_return_value` | |
70
+ | Medium | 🚧 | Support two Cache implementations, array-based and hash-based | |
71
+ | Low | 🚧 | `delegate_to_service` | |
72
+ | High | 🚧 | Intentionally disable plugins to document dependencies | |
73
+ | Low | 🚧 | `.and_return_value_should be_instance_of(expected)` | |
74
+ | Low | 🚧 | `ConvenientService::Config.delegate_to_diff_argorithm = :diffy` | |
75
+ | Low | 🚧 | Rubocop cop that complains when a service name does NOT start with a verb | |
76
+ | Low | 🚧 | Generator to create a spec default structure | |
77
+ | Low | 🚧 | Rubocop cop that complains when a service does NOT have its own suite of specs | |
78
+ | High | 🚧 | Add specs for `WrappedMethod#call` | |
79
+ | High | 🚧 | Check whether ignoring error was used properly | |
67
80
 
68
81
  Search for `TODO`s in the codebase for more tasks.
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
33
33
  spec.add_development_dependency "awesome_print"
34
34
  spec.add_development_dependency "byebug", "~> 10.0"
35
35
  spec.add_development_dependency "commonmarker"
36
+ spec.add_development_dependency "faker"
36
37
  spec.add_development_dependency "gem-release"
37
38
  spec.add_development_dependency "inch"
38
39
  spec.add_development_dependency "json"
@@ -49,6 +50,6 @@ Gem::Specification.new do |spec|
49
50
  spec.add_development_dependency "simplecov"
50
51
  spec.add_development_dependency "simplecov-lcov"
51
52
  spec.add_development_dependency "webrick"
52
- spec.add_development_dependency "yard"
53
+ spec.add_development_dependency "yard", "~> 0.9.28"
53
54
  spec.add_development_dependency "yard-junk"
54
55
  end
@@ -1,6 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ ##
4
+ # @internal
5
+ # NOTE: Aliases hide the full constants path from the end-users in order to increase DX.
6
+ # - https://en.wikipedia.org/wiki/User_experience#Developer_experience
7
+ #
3
8
  module ConvenientService
9
+ Command = ::ConvenientService::Support::Command
4
10
  Concern = ::ConvenientService::Support::Concern
5
11
  DependencyContainer = ::ConvenientService::Support::DependencyContainer
12
+
13
+ ClassicMiddleware = ::ConvenientService::Core::Entities::ClassicMiddleware
14
+ ConcernMiddleware = ::ConvenientService::Core::Entities::Config::Entities::Concerns::Entities::Middleware
15
+ MethodChainMiddleware = ::ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Middleware
6
16
  end
@@ -5,7 +5,11 @@ module ConvenientService
5
5
  module Plugins
6
6
  module HasAroundCallbacks
7
7
  class Middleware < Core::MethodChainMiddleware
8
- def next(...)
8
+ include Support::DependencyContainer::Import
9
+
10
+ import :"entities.Callback", from: Common::Plugins::HasCallbacks::Container
11
+
12
+ def next(*args, **kwargs, &block)
9
13
  ##
10
14
  # A variable that stores return value of middleware `chain.next` aka `original_value`.
11
15
  # It is reassigned later by the `initial_around_callback`.
@@ -15,14 +19,30 @@ module ConvenientService
15
19
  ##
16
20
  # A list of around callbacks.
17
21
  #
22
+ # class Service
23
+ # around do |chain|
24
+ # # part before `chain.yield`
25
+ # original_value = chain.yield
26
+ # # part after `chain.yield`
27
+ # end
28
+ # end
29
+ #
30
+ # class Service
31
+ # around do |chain, arguments|
32
+ # # part before `chain.yield`
33
+ # original_value = chain.yield
34
+ # # part after `chain.yield`
35
+ # end
36
+ # end
37
+ #
18
38
  around_callbacks = entity.callbacks.for([:around, method])
19
39
 
20
40
  ##
21
41
  #
22
42
  #
23
- initial_around_callback = Plugins::HasCallbacks::Entities::Callback.new(
43
+ initial_around_callback = entities.Callback.new(
24
44
  types: [:around, method],
25
- block: proc { original_value = chain.next(...) }
45
+ block: proc { original_value = chain.next(*args, **kwargs, &block) }
26
46
  )
27
47
 
28
48
  ##
@@ -76,7 +96,7 @@ module ConvenientService
76
96
  # rubocop:disable Style/Semicolon
77
97
  composed =
78
98
  around_callbacks.reverse.reduce(initial_around_callback) do |composed, callback|
79
- proc { callback.call_in_context(entity, composed); original_value }
99
+ proc { callback.call_in_context_with_value_and_arguments(entity, composed, *args, **kwargs, &block); original_value }
80
100
  end
81
101
  # rubocop:enable Style/Semicolon
82
102
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Common
5
+ module Plugins
6
+ module HasCallbacks
7
+ module Container
8
+ include Support::DependencyContainer::Export
9
+
10
+ export :"entities.Callback" do
11
+ Entities::Callback
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -6,33 +6,99 @@ module ConvenientService
6
6
  module HasCallbacks
7
7
  module Entities
8
8
  class Callback
9
- attr_reader :types, :block
9
+ ##
10
+ # @!attribute [r] types
11
+ # @return [ConvenientService::Common::Plugins::HasCallbacks::Entities::TypeCollection]
12
+ #
13
+ attr_reader :types
10
14
 
15
+ ##
16
+ # @!attribute [r] block
17
+ # @return [Proc]
18
+ #
19
+ attr_reader :block
20
+
21
+ ##
22
+ # @param types [ConvenientService::Common::Plugins::HasCallbacks::Entities::TypeCollection]
23
+ # @param block [Proc]
24
+ # @return [void]
25
+ #
11
26
  def initialize(types:, block:)
12
27
  @types = Entities::TypeCollection.new(types: types)
13
28
  @block = block
14
29
  end
15
30
 
31
+ ##
32
+ # @return [Boolean]
33
+ #
16
34
  def called?
17
35
  Utils::Bool.to_bool(@called)
18
36
  end
19
37
 
38
+ ##
39
+ # @return [Boolean]
40
+ #
20
41
  def not_called?
21
42
  !called?
22
43
  end
23
44
 
24
- def call(*args, **kwargs)
25
- block.call(*args, **kwargs).tap { mark_as_called }
45
+ ##
46
+ # @return [Object] Can be any type.
47
+ #
48
+ def call(...)
49
+ call_callback(...)
26
50
  end
27
51
 
52
+ ##
53
+ # @return [Object] Can be any type.
54
+ #
28
55
  alias_method :yield, :call
56
+
57
+ ##
58
+ # @return [Object] Can be any type.
59
+ #
29
60
  alias_method :[], :call
61
+
62
+ ##
63
+ # @return [Object] Can be any type.
64
+ #
30
65
  alias_method :===, :call
31
66
 
32
- def call_in_context(context, *args, **kwargs)
33
- context.instance_exec(*args, **kwargs, &block).tap { mark_as_called }
67
+ ##
68
+ # @param context [Object] Can be any type.
69
+ # @return [ConvenientService::Common::Plugins::HasCallbacks::Entities::Callback]
70
+ #
71
+ def call_in_context(context)
72
+ call_callback_in_context(context)
73
+ end
74
+
75
+ ##
76
+ # @param context [Object] Can be any type.
77
+ # @param args [Array]
78
+ # @param kwargs [Hash]
79
+ # @param block [Proc]
80
+ # @return [ConvenientService::Common::Plugins::HasCallbacks::Entities::Callback]
81
+ #
82
+ def call_in_context_with_arguments(context, *args, **kwargs, &block)
83
+ call_callback_in_context(context, arguments(*args, **kwargs, &block))
84
+ end
85
+
86
+ ##
87
+ # @param context [Object] Can be any type.
88
+ # @param value [Object] Can be any type.
89
+ # @param args [Array]
90
+ # @param kwargs [Hash]
91
+ # @param block [Proc]
92
+ # @return [ConvenientService::Common::Plugins::HasCallbacks::Entities::Callback]
93
+ #
94
+ def call_in_context_with_value_and_arguments(context, value, *args, **kwargs, &block)
95
+ call_callback_in_context(context, value, arguments(*args, **kwargs, &block))
34
96
  end
35
97
 
98
+ ##
99
+ # @param other [Object] Can be any type.
100
+ # @return [Boolead]
101
+ #
36
102
  def ==(other)
37
103
  return unless other.instance_of?(self.class)
38
104
 
@@ -42,15 +108,42 @@ module ConvenientService
42
108
  true
43
109
  end
44
110
 
111
+ ##
112
+ # @return [Proc]
113
+ #
45
114
  def to_proc
46
115
  block
47
116
  end
48
117
 
49
118
  private
50
119
 
120
+ ##
121
+ # @return [Boolean]
122
+ #
51
123
  def mark_as_called
52
124
  @called = true
53
125
  end
126
+
127
+ ##
128
+ # @return [ConvenientService::Support::Arguments]
129
+ #
130
+ def arguments(...)
131
+ Support::Arguments.new(...)
132
+ end
133
+
134
+ ##
135
+ # @return [Object] Can be any type.
136
+ #
137
+ def call_callback(...)
138
+ block.call(...).tap { mark_as_called }
139
+ end
140
+
141
+ ##
142
+ # @return [Object] Can be any type.
143
+ #
144
+ def call_callback_in_context(context, *args)
145
+ context.instance_exec(*args, &block).tap { mark_as_called }
146
+ end
54
147
  end
55
148
  end
56
149
  end
@@ -5,12 +5,33 @@ module ConvenientService
5
5
  module Plugins
6
6
  module HasCallbacks
7
7
  class Middleware < Core::MethodChainMiddleware
8
- def next(...)
9
- entity.callbacks.for([:before, method]).each { |callback| callback.call_in_context(entity) }
8
+ def next(*args, **kwargs, &block)
9
+ ##
10
+ # class Service
11
+ # before :result do
12
+ # end
13
+ #
14
+ # before :result do |arguments|
15
+ # end
16
+ # end
17
+ #
18
+ entity.callbacks.for([:before, method]).each { |callback| callback.call_in_context_with_arguments(entity, *args, **kwargs, &block) }
10
19
 
11
- original_value = chain.next(...)
20
+ original_value = chain.next(*args, **kwargs, &block)
12
21
 
13
- entity.callbacks.for([:after, method]).reverse_each { |callback| callback.call_in_context(entity, original_value) }
22
+ ##
23
+ # class Service
24
+ # after :result do
25
+ # end
26
+ #
27
+ # after :result do |result|
28
+ # end
29
+ #
30
+ # after :result do |result, arguments|
31
+ # end
32
+ # end
33
+ #
34
+ entity.callbacks.for([:after, method]).reverse_each { |callback| callback.call_in_context_with_value_and_arguments(entity, original_value, *args, **kwargs, &block) }
14
35
 
15
36
  original_value
16
37
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "has_callbacks/concern"
4
+ require_relative "has_callbacks/container"
4
5
  require_relative "has_callbacks/entities"
5
6
  require_relative "has_callbacks/middleware"
@@ -13,6 +13,25 @@ module ConvenientService
13
13
  # @since 0.2.0
14
14
  #
15
15
  # @internal
16
+ # NOTE: `allocate` creates an uninitialized object and allocates memory for it.
17
+ #
18
+ # NOTE: Pseudocode for default `new` implementation.
19
+ # def new
20
+ # instance = allocate
21
+ #
22
+ # instance.send(:initialize)
23
+ #
24
+ # instance
25
+ # end
26
+ #
27
+ # NOTE: Code for `new_without_initialize`.
28
+ # def new_without_initialize
29
+ # allocate
30
+ # end
31
+ #
32
+ # NOTE: `create` is used instead of `new` in order to avoid the accidental feeling that `new_without_initialize` is Ruby's built-in method.
33
+ #
34
+ # NOTE: Check the following links for more info.
16
35
  # - https://ruby-doc.org/core-2.5.0/Class.html#method-i-allocate
17
36
  # - https://frontdeveloper.pl/2018/11/ruby-allocate-method/
18
37
  #
@@ -8,8 +8,8 @@ require_relative "plugins/normalizes_env"
8
8
  require_relative "plugins/caches_constructor_params"
9
9
  require_relative "plugins/caches_return_value"
10
10
  require_relative "plugins/can_be_copied"
11
- require_relative "plugins/has_around_callbacks"
12
11
  require_relative "plugins/has_callbacks"
12
+ require_relative "plugins/has_around_callbacks"
13
13
  require_relative "plugins/has_constructor"
14
14
  require_relative "plugins/has_constructor_without_initialize"
15
15
  require_relative "plugins/has_internals"
@@ -0,0 +1,176 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Configs
5
+ ##
6
+ # Defines minimal configuration that adds a constructor, JSend-inspired result, steps, basic inspects, and internals to services.
7
+ #
8
+ # @note: This config is NOT intented for the end-user usage. Use `Standard` instead.
9
+ #
10
+ # @internal
11
+ # Heavily used in specs to test concerns and middlewares in isolation.
12
+ #
13
+ module Minimal
14
+ include Support::Concern
15
+
16
+ ##
17
+ # @internal
18
+ # IMPORTANT: Order of plugins matters.
19
+ #
20
+ # NOTE: `class_exec` (that is used under the hood by `included`) defines `class Result` in the global namespace.
21
+ # That is why `class self::Result` is used.
22
+ # - https://stackoverflow.com/a/51965126/12201472
23
+ #
24
+ # rubocop:disable Lint/ConstantDefinitionInBlock
25
+ included do
26
+ include Core
27
+
28
+ concerns do
29
+ use Plugins::Common::HasInternals::Concern
30
+
31
+ use Plugins::Service::HasInspect::Concern
32
+
33
+ use Plugins::Common::HasConstructor::Concern
34
+ use Plugins::Common::HasConstructorWithoutInitialize::Concern
35
+
36
+ use Plugins::Service::HasResult::Concern
37
+ use Plugins::Service::HasResultSteps::Concern
38
+ end
39
+
40
+ middlewares :initialize do
41
+ use Plugins::Common::NormalizesEnv::Middleware
42
+ end
43
+
44
+ middlewares :result do
45
+ use Plugins::Common::NormalizesEnv::Middleware
46
+
47
+ use Plugins::Service::HasResult::Middleware
48
+ use Plugins::Service::HasResultSteps::Middleware
49
+ end
50
+
51
+ middlewares :step do
52
+ use Plugins::Common::NormalizesEnv::Middleware
53
+ end
54
+
55
+ middlewares :success do
56
+ use Plugins::Common::NormalizesEnv::Middleware
57
+ end
58
+
59
+ middlewares :failure do
60
+ use Plugins::Common::NormalizesEnv::Middleware
61
+ end
62
+
63
+ middlewares :error do
64
+ use Plugins::Common::NormalizesEnv::Middleware
65
+ end
66
+
67
+ middlewares :result, scope: :class do
68
+ use Plugins::Common::NormalizesEnv::Middleware
69
+ end
70
+
71
+ middlewares :step, scope: :class do
72
+ use Plugins::Common::NormalizesEnv::Middleware
73
+ end
74
+
75
+ class self::Internals
76
+ include Core
77
+
78
+ concerns do
79
+ use Plugins::Internals::HasCache::Concern
80
+ end
81
+ end
82
+
83
+ class self::Result
84
+ include Core
85
+
86
+ concerns do
87
+ use Plugins::Common::HasInternals::Concern
88
+
89
+ use Plugins::Result::HasInspect::Concern
90
+
91
+ use Plugins::Common::HasConstructor::Concern
92
+
93
+ use Plugins::Result::HasJsendStatusAndAttributes::Concern
94
+ end
95
+
96
+ middlewares :initialize do
97
+ use Plugins::Common::NormalizesEnv::Middleware
98
+
99
+ use Plugins::Result::HasJsendStatusAndAttributes::Middleware
100
+ end
101
+
102
+ middlewares :success? do
103
+ use Plugins::Common::NormalizesEnv::Middleware
104
+ end
105
+
106
+ middlewares :failure? do
107
+ use Plugins::Common::NormalizesEnv::Middleware
108
+ end
109
+
110
+ middlewares :error? do
111
+ use Plugins::Common::NormalizesEnv::Middleware
112
+ end
113
+
114
+ middlewares :not_success? do
115
+ use Plugins::Common::NormalizesEnv::Middleware
116
+ end
117
+
118
+ middlewares :not_failure? do
119
+ use Plugins::Common::NormalizesEnv::Middleware
120
+ end
121
+
122
+ middlewares :not_error? do
123
+ use Plugins::Common::NormalizesEnv::Middleware
124
+ end
125
+
126
+ middlewares :data do
127
+ use Plugins::Common::NormalizesEnv::Middleware
128
+ end
129
+
130
+ middlewares :message do
131
+ use Plugins::Common::NormalizesEnv::Middleware
132
+ end
133
+
134
+ middlewares :code do
135
+ use Plugins::Common::NormalizesEnv::Middleware
136
+ end
137
+
138
+ middlewares :to_kwargs do
139
+ use Plugins::Common::NormalizesEnv::Middleware
140
+ end
141
+
142
+ class self::Internals
143
+ include Core
144
+
145
+ concerns do
146
+ use Plugins::Internals::HasCache::Concern
147
+ end
148
+ end
149
+ end
150
+
151
+ class self::Step
152
+ include Core
153
+
154
+ concerns do
155
+ use Plugins::Common::HasInternals::Concern
156
+
157
+ use Plugins::Step::HasInspect::Concern
158
+ end
159
+
160
+ middlewares :calculate_result do
161
+ use Plugins::Common::NormalizesEnv::Middleware
162
+ end
163
+
164
+ class self::Internals
165
+ include Core
166
+
167
+ concerns do
168
+ use Plugins::Internals::HasCache::Concern
169
+ end
170
+ end
171
+ end
172
+ end
173
+ # rubocop:enable Lint/ConstantDefinitionInBlock
174
+ end
175
+ end
176
+ end