convenient_service 0.2.1 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/ROADMAP.md +2 -0
- data/lib/convenient_service/configs/standard.rb +16 -0
- data/lib/convenient_service/dependencies/built_in.rb +8 -0
- data/lib/convenient_service/dependencies.rb +37 -0
- data/lib/convenient_service/examples/rails/gemfile/services/assert_file_exists.rb +1 -1
- data/lib/convenient_service/examples/rails/gemfile/services/assert_file_not_empty.rb +1 -1
- data/lib/convenient_service/examples/rails/gemfile/services/assert_npm_package_available.rb +1 -1
- data/lib/convenient_service/examples/rails/gemfile/services/parse_content.rb +1 -1
- data/lib/convenient_service/examples/rails/gemfile/services/print_shell_command.rb +1 -1
- data/lib/convenient_service/examples/rails/gemfile/services/read_file_content.rb +1 -1
- data/lib/convenient_service/examples/rails/gemfile/services/run_shell.rb +1 -1
- data/lib/convenient_service/examples/rails/gemfile/services/strip_comments.rb +1 -1
- data/lib/convenient_service/rspec/helpers/custom/stub_service/entities/result_spec.rb +17 -1
- data/lib/convenient_service/rspec/helpers/custom/stub_service/entities/stubbed_service.rb +47 -53
- data/lib/convenient_service/service/plugins/can_have_stubbed_result/concern.rb +32 -0
- data/lib/convenient_service/service/plugins/can_have_stubbed_result/middleware.rb +36 -0
- data/lib/convenient_service/service/plugins/can_have_stubbed_result.rb +4 -0
- data/lib/convenient_service/service/plugins.rb +1 -0
- data/lib/convenient_service/support/cache.rb +26 -0
- data/lib/convenient_service/support/gems/active_model.rb +36 -0
- data/lib/convenient_service/support/gems/rspec.rb +36 -0
- data/lib/convenient_service/support/gems.rb +4 -0
- data/lib/convenient_service/support/ruby.rb +22 -0
- data/lib/convenient_service/support/version/null_version.rb +78 -0
- data/lib/convenient_service/support/version.rb +65 -0
- data/lib/convenient_service/support.rb +3 -0
- data/lib/convenient_service/utils/object/instance_variable_fetch.rb +53 -0
- data/lib/convenient_service/utils/object.rb +9 -0
- data/lib/convenient_service/version.rb +1 -1
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6eab7876ae6995ff2a0f2f4322a972ad05aae9b4ef3beea93daee900779dc39
|
4
|
+
data.tar.gz: 11d7e604831dda483449dc2b2513c0fc5817fd6172740836e5e3929b7d6fbcd4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b422032aa3b32d20579fdcc7e540a5d48e6dd18b3b69182b4b7bc456bbd8a381dd1cdab5654662e1074e095a124d15751aa001d15a36c21518dba0a1683f7130
|
7
|
+
data.tar.gz: bc8142c8d9df3971efb3476131608aae89477a46ecbe2efe42e31555f52e2425930c122ff93f8d941f4b44aa1c81b291079b5e11ea0249cfea0d0dd47a0846b7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [0.3.0](https://github.com/marian13/convenient_service/compare/v0.2.1...v0.3.0) (2022-12-17)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* **stub_service:** stub_service supports stubbing with different arguments ([766eb5a](https://github.com/marian13/convenient_service/commit/766eb5a25cfbd49b699ca5c0c0ffa5524dc46548))
|
9
|
+
|
3
10
|
## [0.2.1](https://github.com/marian13/convenient_service/compare/v0.2.0...v0.2.1) (2022-12-14)
|
4
11
|
|
5
12
|
|
data/ROADMAP.md
CHANGED
@@ -51,5 +51,7 @@
|
|
51
51
|
| Medium | 🚧 | User friendly `raise` that removes lib backtrace from caller | Should have a `debug` mode. Should work well with examples. Check RSpec `CallerFilter.first_non_rspec_line` |
|
52
52
|
| High | 🚧 | A plugin that catches `StandardError` and returns `failure` | Should be the lowest in the stack |
|
53
53
|
| High | 🚧 | `Support::Command` alias | Should be visible to the end user |
|
54
|
+
| Low | 🚧 | Parallel steps | A killer feature |
|
55
|
+
| Medium | 🚧 | Add Ruby 3.2 support to Docker and CI | |
|
54
56
|
|
55
57
|
Search for `TODO`s in the codebase for more tasks.
|
@@ -81,6 +81,10 @@ module ConvenientService
|
|
81
81
|
use Plugins::Service::HasResultShortSyntax::Error::Middleware
|
82
82
|
end
|
83
83
|
|
84
|
+
middlewares :result, scope: :class do
|
85
|
+
use Plugins::Common::NormalizesEnv::Middleware
|
86
|
+
end
|
87
|
+
|
84
88
|
middlewares :step, scope: :class do
|
85
89
|
use Plugins::Common::NormalizesEnv::Middleware
|
86
90
|
|
@@ -202,6 +206,18 @@ module ConvenientService
|
|
202
206
|
end
|
203
207
|
end
|
204
208
|
end
|
209
|
+
|
210
|
+
if Dependencies.rspec.loaded?
|
211
|
+
concerns do
|
212
|
+
insert_before 0, Plugins::Service::CanHaveStubbedResult::Concern
|
213
|
+
end
|
214
|
+
|
215
|
+
middlewares :result, scope: :class do
|
216
|
+
insert_after \
|
217
|
+
Plugins::Common::NormalizesEnv::Middleware,
|
218
|
+
Plugins::Service::CanHaveStubbedResult::Middleware
|
219
|
+
end
|
220
|
+
end
|
205
221
|
end
|
206
222
|
# rubocop:enable Lint/ConstantDefinitionInBlock
|
207
223
|
end
|
@@ -28,6 +28,14 @@ require "logger"
|
|
28
28
|
#
|
29
29
|
require "ostruct"
|
30
30
|
|
31
|
+
##
|
32
|
+
# @internal
|
33
|
+
# - https://ruby-doc.org/stdlib-2.7.0/libdoc/rubygems/rdoc/Gem/Version.html
|
34
|
+
# - https://github.com/rubygems/rubygems
|
35
|
+
# - https://github.com/rubygems/rubygems/blob/master/lib/rubygems/version.rb
|
36
|
+
#
|
37
|
+
require "rubygems"
|
38
|
+
|
31
39
|
##
|
32
40
|
# @internal
|
33
41
|
# - https://ruby-doc.org/stdlib-2.7.0/libdoc/singleton/rdoc/Singleton.html
|
@@ -42,10 +42,23 @@ module ConvenientService
|
|
42
42
|
require_relative "common/plugins/has_attributes/using_active_model_attributes"
|
43
43
|
end
|
44
44
|
|
45
|
+
##
|
46
|
+
# @return [Boolean]
|
47
|
+
# @api private
|
48
|
+
#
|
49
|
+
def support_has_result_params_validations_using_active_model_validations?
|
50
|
+
return false unless active_model.loaded?
|
51
|
+
return false if ruby.version >= 3.0 && active_model.version < 6.0
|
52
|
+
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
45
56
|
##
|
46
57
|
# @return [Boolean]
|
47
58
|
# @note Expected to be called from app entry points like `initializers` in Rails.
|
48
59
|
#
|
60
|
+
# @see https://marian13.github.io/convenient_service_docs/troubleshooting/i18n_translate_wrong_number_of_arguments
|
61
|
+
#
|
49
62
|
def require_has_result_params_validations_using_active_model_validations
|
50
63
|
require "active_model"
|
51
64
|
|
@@ -129,6 +142,30 @@ module ConvenientService
|
|
129
142
|
|
130
143
|
require_relative "examples/dry/gemfile"
|
131
144
|
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# @return [ConvenientService::Support::Ruby]
|
148
|
+
# @api private
|
149
|
+
#
|
150
|
+
def ruby
|
151
|
+
Support::Ruby
|
152
|
+
end
|
153
|
+
|
154
|
+
##
|
155
|
+
# @return [ConvenientService::Support::RSpec]
|
156
|
+
# @api private
|
157
|
+
#
|
158
|
+
def rspec
|
159
|
+
Support::Gems::RSpec
|
160
|
+
end
|
161
|
+
|
162
|
+
##
|
163
|
+
# @return [ConvenientService::Support::Gems::ActiveModel]
|
164
|
+
# @api private
|
165
|
+
#
|
166
|
+
def active_model
|
167
|
+
Support::Gems::ActiveModel
|
168
|
+
end
|
132
169
|
end
|
133
170
|
end
|
134
171
|
end
|
@@ -10,7 +10,7 @@ module ConvenientService
|
|
10
10
|
|
11
11
|
attribute :path, :string
|
12
12
|
|
13
|
-
validates :path, presence: true
|
13
|
+
validates :path, presence: true if ConvenientService::Dependencies.support_has_result_params_validations_using_active_model_validations?
|
14
14
|
|
15
15
|
def result
|
16
16
|
return error("File with path `#{path}` does NOT exist") unless ::File.exist?(path)
|
@@ -10,7 +10,7 @@ module ConvenientService
|
|
10
10
|
|
11
11
|
attribute :path, :string
|
12
12
|
|
13
|
-
validates :path, presence: true
|
13
|
+
validates :path, presence: true if ConvenientService::Dependencies.support_has_result_params_validations_using_active_model_validations?
|
14
14
|
|
15
15
|
def result
|
16
16
|
return error(message: "File with path `#{path}` is empty") if ::File.zero?(path)
|
@@ -15,7 +15,7 @@ module ConvenientService
|
|
15
15
|
|
16
16
|
attribute :name, :string
|
17
17
|
|
18
|
-
validates :name, presence: true
|
18
|
+
validates :name, presence: true if ConvenientService::Dependencies.support_has_result_params_validations_using_active_model_validations?
|
19
19
|
|
20
20
|
step Services::AssertNodeAvailable
|
21
21
|
|
@@ -42,7 +42,7 @@ module ConvenientService
|
|
42
42
|
|
43
43
|
attribute :content, :string
|
44
44
|
|
45
|
-
validates :content, presence: true
|
45
|
+
validates :content, presence: true if ConvenientService::Dependencies.support_has_result_params_validations_using_active_model_validations?
|
46
46
|
|
47
47
|
step Services::AssertValidRubySyntax, in: :content
|
48
48
|
step :result, in: :content, out: :parsed_content
|
@@ -16,7 +16,7 @@ module ConvenientService
|
|
16
16
|
attribute :text, :string
|
17
17
|
attribute :out, default: $stdout
|
18
18
|
|
19
|
-
validates :text, presence: true
|
19
|
+
validates :text, presence: true if ConvenientService::Dependencies.support_has_result_params_validations_using_active_model_validations?
|
20
20
|
|
21
21
|
def result
|
22
22
|
out.puts
|
@@ -10,7 +10,7 @@ module ConvenientService
|
|
10
10
|
|
11
11
|
attribute :path, :string
|
12
12
|
|
13
|
-
validates :path, presence: true
|
13
|
+
validates :path, presence: true if ConvenientService::Dependencies.support_has_result_params_validations_using_active_model_validations?
|
14
14
|
|
15
15
|
step Services::AssertFileExists, in: :path
|
16
16
|
step Services::AssertFileNotEmpty, in: :path
|
@@ -11,7 +11,7 @@ module ConvenientService
|
|
11
11
|
attribute :command, :string
|
12
12
|
attribute :debug, :boolean, default: false
|
13
13
|
|
14
|
-
validates :command, presence: true
|
14
|
+
validates :command, presence: true if ConvenientService::Dependencies.support_has_result_params_validations_using_active_model_validations?
|
15
15
|
|
16
16
|
def result
|
17
17
|
Services::PrintShellCommand.result(text: command) if debug
|
@@ -15,7 +15,7 @@ module ConvenientService
|
|
15
15
|
|
16
16
|
attribute :content, :string
|
17
17
|
|
18
|
-
validates :content, presence: true
|
18
|
+
validates :content, presence: true if ConvenientService::Dependencies.support_has_result_params_validations_using_active_model_validations?
|
19
19
|
|
20
20
|
alias_method :content_with_comments, :content
|
21
21
|
|
@@ -109,7 +109,21 @@ module ConvenientService
|
|
109
109
|
service_class.__send__(status, **kwargs)
|
110
110
|
end
|
111
111
|
|
112
|
-
|
112
|
+
##
|
113
|
+
# @param other [Object] Can be any type.
|
114
|
+
# @return [Boolean, nil]
|
115
|
+
#
|
116
|
+
def ==(other)
|
117
|
+
return unless other.instance_of?(self.class)
|
118
|
+
|
119
|
+
return false if status != other.status
|
120
|
+
return false if service_class != other.service_class
|
121
|
+
return false if chain != other.chain
|
122
|
+
|
123
|
+
true
|
124
|
+
end
|
125
|
+
|
126
|
+
protected
|
113
127
|
|
114
128
|
##
|
115
129
|
# @!attribute [r] status
|
@@ -129,6 +143,8 @@ module ConvenientService
|
|
129
143
|
#
|
130
144
|
attr_reader :chain
|
131
145
|
|
146
|
+
private
|
147
|
+
|
132
148
|
##
|
133
149
|
# @return [Hash]
|
134
150
|
#
|
@@ -6,90 +6,84 @@ module ConvenientService
|
|
6
6
|
module Custom
|
7
7
|
class StubService < Support::Command
|
8
8
|
module Entities
|
9
|
-
##
|
10
|
-
# TODO: Specs.
|
11
|
-
#
|
12
9
|
class StubbedService < Support::Command
|
13
10
|
##
|
14
|
-
#
|
15
|
-
#
|
16
|
-
# - https://github.com/rspec/rspec-expectations/blob/main/lib/rspec/matchers.rb
|
11
|
+
# @param service_class [Class]
|
12
|
+
# @return [void]
|
17
13
|
#
|
18
|
-
|
14
|
+
def initialize(service_class:)
|
15
|
+
@service_class = service_class
|
16
|
+
@arguments = {args: [], kwargs: {}, block: nil}
|
17
|
+
end
|
19
18
|
|
20
19
|
##
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
20
|
+
# @param args [Array]
|
21
|
+
# @param kwargs [Hash]
|
22
|
+
# @param block [Block]
|
23
|
+
# @return [ConvenientService::RSpec::Helpers::Custom::StubService::Entities::StubService]
|
24
24
|
#
|
25
|
-
|
25
|
+
def with_arguments(*args, **kwargs, &block)
|
26
|
+
@arguments = {args: args, kwargs: kwargs, block: block}
|
26
27
|
|
27
|
-
|
28
|
-
@service_class = service_class
|
28
|
+
self
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
##
|
32
|
+
# @return [ConvenientService::RSpec::Helpers::Custom::StubService::Entities::StubService]
|
33
|
+
#
|
34
|
+
def without_arguments
|
35
|
+
@arguments = {args: [], kwargs: {}, block: nil}
|
33
36
|
|
34
37
|
self
|
35
38
|
end
|
36
39
|
|
40
|
+
##
|
41
|
+
# @param result_spec [ConvenientService::RSpec::Helpers::Custom::StubService::Entities::ResultSpec]
|
42
|
+
# @return [ConvenientService::RSpec::Helpers::Custom::StubService::Entities::StubService]
|
43
|
+
#
|
37
44
|
def to(result_spec)
|
38
45
|
@result_spec = result_spec
|
39
46
|
|
40
47
|
service_class.commit_config!
|
41
48
|
|
42
|
-
|
43
|
-
allow(service_class).to receive(:result).and_wrap_original do |original, *actual_args, **actual_kwargs, &actual_block|
|
44
|
-
expect(actual_args).to eq(expected_args)
|
45
|
-
expect(actual_kwargs).to eq(expected_kwargs)
|
46
|
-
expect(actual_block).to eq(expected_block)
|
49
|
+
service_class.stubbed_results[key] = result_value
|
47
50
|
|
48
|
-
|
49
|
-
end
|
50
|
-
else
|
51
|
-
allow(service_class).to receive(:result).and_return(result_value)
|
52
|
-
end
|
51
|
+
self
|
53
52
|
end
|
54
53
|
|
55
54
|
private
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
def used_with_arguments?
|
64
|
-
chain.key?(:with_arguments)
|
65
|
-
end
|
66
|
-
|
67
|
-
def chain
|
68
|
-
@chain ||= {}
|
69
|
-
end
|
56
|
+
##
|
57
|
+
# @!attribute [r] service_class
|
58
|
+
# @return [Class]
|
59
|
+
#
|
60
|
+
attr_reader :service_class
|
70
61
|
|
71
|
-
|
72
|
-
|
73
|
-
|
62
|
+
##
|
63
|
+
# @!attribute [r] arguments
|
64
|
+
# @return [Hash]
|
65
|
+
#
|
66
|
+
attr_reader :arguments
|
74
67
|
|
75
|
-
|
68
|
+
##
|
69
|
+
# @!attribute [r] result_spec
|
70
|
+
# @return [ConvenientService::RSpec::Helpers::Custom::StubService::Entities::ResultSpec]
|
71
|
+
#
|
72
|
+
attr_reader :result_spec
|
76
73
|
|
77
|
-
|
78
|
-
|
74
|
+
##
|
75
|
+
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result]
|
76
|
+
#
|
77
|
+
def result_value
|
78
|
+
@result_value ||= result_spec.for(service_class).calculate_value
|
79
79
|
end
|
80
80
|
|
81
|
-
alias_method :expected_kwargs, :kwargs
|
82
|
-
|
83
81
|
##
|
84
|
-
#
|
82
|
+
# @return [ConvenientService::Support::Cache::Key]
|
85
83
|
#
|
86
|
-
def
|
87
|
-
|
88
|
-
|
89
|
-
@block = chain.dig(:with_arguments, :block)
|
84
|
+
def key
|
85
|
+
@key ||= service_class.stubbed_results.keygen(*arguments[:args], **arguments[:kwargs], &arguments[:block])
|
90
86
|
end
|
91
|
-
|
92
|
-
alias_method :expected_block, :block
|
93
87
|
end
|
94
88
|
end
|
95
89
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Service
|
5
|
+
module Plugins
|
6
|
+
module CanHaveStubbedResult
|
7
|
+
module Concern
|
8
|
+
include Support::Concern
|
9
|
+
|
10
|
+
class_methods do
|
11
|
+
##
|
12
|
+
# @return [ConvenientService::Support::Cache]
|
13
|
+
#
|
14
|
+
# @internal
|
15
|
+
# `::RSpec.current_example` docs:
|
16
|
+
# - https://www.rubydoc.info/github/rspec/rspec-core/RSpec.current_example
|
17
|
+
# - https://github.com/rspec/rspec-core/blob/v3.12.0/lib/rspec/core.rb#L122
|
18
|
+
# - https://relishapp.com/rspec/rspec-core/docs/metadata/current-example
|
19
|
+
#
|
20
|
+
# TODO: Mutex for thread-safety when parallel steps will be supported.
|
21
|
+
#
|
22
|
+
def stubbed_results
|
23
|
+
cache = Utils::Object.instance_variable_fetch(::RSpec.current_example, :@__convenient_service_stubbed_results__) { Support::Cache.new }
|
24
|
+
|
25
|
+
cache.scope(self)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Service
|
5
|
+
module Plugins
|
6
|
+
module CanHaveStubbedResult
|
7
|
+
class Middleware < Core::MethodChainMiddleware
|
8
|
+
##
|
9
|
+
# @param args [Array]
|
10
|
+
# @param kwargs [Hash]
|
11
|
+
# @param block [Proc]
|
12
|
+
# @return [Object] Can be any type.
|
13
|
+
#
|
14
|
+
def next(*args, **kwargs, &block)
|
15
|
+
key_with_arguments = cache.keygen(*args, **kwargs, &block)
|
16
|
+
key_without_arguments = cache.keygen
|
17
|
+
|
18
|
+
return cache[key_with_arguments] if cache.exist?(key_with_arguments)
|
19
|
+
return cache[key_without_arguments] if cache.exist?(key_without_arguments)
|
20
|
+
|
21
|
+
chain.next(*args, **kwargs, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
##
|
27
|
+
# @return [ConvenientService::Support::Cache]
|
28
|
+
#
|
29
|
+
def cache
|
30
|
+
entity.stubbed_results
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -21,6 +21,16 @@ module ConvenientService
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
##
|
25
|
+
# @return [Boolean]
|
26
|
+
#
|
27
|
+
# @internal
|
28
|
+
# https://ruby-doc.org/core-2.7.0/Hash.html#method-i-empty-3F
|
29
|
+
#
|
30
|
+
def empty?
|
31
|
+
hash.empty?
|
32
|
+
end
|
33
|
+
|
24
34
|
##
|
25
35
|
# @return [Boolean]
|
26
36
|
#
|
@@ -100,6 +110,22 @@ module ConvenientService
|
|
100
110
|
exist?(key) ? read(key) : write(key, block.call)
|
101
111
|
end
|
102
112
|
|
113
|
+
##
|
114
|
+
# @return [ConvenientService::Support::Cache]
|
115
|
+
#
|
116
|
+
def clear
|
117
|
+
hash.clear
|
118
|
+
|
119
|
+
self
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# @return [ConvenientService::Support::Cache]
|
124
|
+
#
|
125
|
+
def scope(key)
|
126
|
+
fetch(key) { Support::Cache.new }
|
127
|
+
end
|
128
|
+
|
103
129
|
##
|
104
130
|
# @return [ConvenientService::Support::Cache::Key]
|
105
131
|
#
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module Gems
|
6
|
+
##
|
7
|
+
# @api private
|
8
|
+
#
|
9
|
+
class ActiveModel
|
10
|
+
class << self
|
11
|
+
##
|
12
|
+
# @return [Boolean]
|
13
|
+
#
|
14
|
+
# @internal
|
15
|
+
# `Style/TernaryParentheses` is disabled since `defined?` has too low priority without parentheses.
|
16
|
+
#
|
17
|
+
# rubocop:disable Style/TernaryParentheses
|
18
|
+
def loaded?
|
19
|
+
(defined? ::ActiveModel) ? true : false
|
20
|
+
end
|
21
|
+
# rubocop:enable Style/TernaryParentheses
|
22
|
+
|
23
|
+
##
|
24
|
+
# @return [ConvenientService::Support::Version]
|
25
|
+
#
|
26
|
+
# @internal
|
27
|
+
# https://github.com/rails/rails/blob/main/activemodel/lib/active_model/version.rb
|
28
|
+
#
|
29
|
+
def version
|
30
|
+
loaded? ? Support::Version.new(::ActiveModel.version) : Support::Version.null_version
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module Gems
|
6
|
+
##
|
7
|
+
# @api private
|
8
|
+
#
|
9
|
+
class RSpec
|
10
|
+
class << self
|
11
|
+
##
|
12
|
+
# @return [Boolean]
|
13
|
+
#
|
14
|
+
# @internal
|
15
|
+
# `Style/TernaryParentheses` is disabled since `defined?` has too low priority without parentheses.
|
16
|
+
#
|
17
|
+
# rubocop:disable Style/TernaryParentheses
|
18
|
+
def loaded?
|
19
|
+
(defined? ::RSpec) ? true : false
|
20
|
+
end
|
21
|
+
# rubocop:enable Style/TernaryParentheses
|
22
|
+
|
23
|
+
##
|
24
|
+
# @return [ConvenientService::Support::Version]
|
25
|
+
#
|
26
|
+
# @internal
|
27
|
+
# https://github.com/rspec/rspec-core/blob/main/lib/rspec/core/version.rb
|
28
|
+
#
|
29
|
+
def version
|
30
|
+
loaded? ? Support::Version.new(::RSpec::Core::Version::STRING) : Support::Version.null_version
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
##
|
6
|
+
# @api private
|
7
|
+
#
|
8
|
+
class Ruby
|
9
|
+
class << self
|
10
|
+
##
|
11
|
+
# @return [ConvenientService::Support::Version]
|
12
|
+
#
|
13
|
+
# @internal
|
14
|
+
# https://ruby-doc.org/core-2.7.2/doc/globals_rdoc.html
|
15
|
+
#
|
16
|
+
def version
|
17
|
+
@version ||= Support::Version.new(::RUBY_VERSION)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
class Version
|
6
|
+
##
|
7
|
+
# @api private
|
8
|
+
#
|
9
|
+
# @internal
|
10
|
+
# - https://thoughtbot.com/blog/rails-refactoring-example-introduce-null-object
|
11
|
+
# - https://avdi.codes/null-objects-and-falsiness/
|
12
|
+
#
|
13
|
+
class NullVersion
|
14
|
+
##
|
15
|
+
# @return [nil]
|
16
|
+
#
|
17
|
+
def gem_version
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# @param other [Object] Can be any type.
|
23
|
+
# @return [nil]
|
24
|
+
#
|
25
|
+
def <=>(other)
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# @param other [Object] Can be any type.
|
31
|
+
# @return [nil]
|
32
|
+
#
|
33
|
+
def <(other)
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# @param other [Object] Can be any type.
|
39
|
+
# @return [nil]
|
40
|
+
#
|
41
|
+
def <=(other)
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# @param other [Object] Can be any type.
|
47
|
+
# @return [nil]
|
48
|
+
#
|
49
|
+
def ==(other)
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# @param other [Object] Can be any type.
|
55
|
+
# @return [nil]
|
56
|
+
#
|
57
|
+
def >(other)
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# @param other [Object] Can be any type.
|
63
|
+
# @return [nil]
|
64
|
+
#
|
65
|
+
def >=(other)
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# @return [String]
|
71
|
+
#
|
72
|
+
def to_s
|
73
|
+
""
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "version/null_version"
|
4
|
+
|
5
|
+
module ConvenientService
|
6
|
+
module Support
|
7
|
+
class Version
|
8
|
+
include ::Comparable
|
9
|
+
|
10
|
+
undef_method :between?
|
11
|
+
|
12
|
+
undef_method :clamp
|
13
|
+
|
14
|
+
##
|
15
|
+
# @param value [String]
|
16
|
+
# @return [void]
|
17
|
+
#
|
18
|
+
def initialize(value)
|
19
|
+
@value = value
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
##
|
24
|
+
# @return [ConvenientService::Support::Version::NullVersion]
|
25
|
+
#
|
26
|
+
def null_version
|
27
|
+
@null_version ||= NullVersion.new
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# @return [Gem::Version, nil]
|
33
|
+
#
|
34
|
+
def gem_version
|
35
|
+
cast_gem_version(value)
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# @param other [Object] Can be any type.
|
40
|
+
# @return [Boolean, nil]
|
41
|
+
#
|
42
|
+
def <=>(other)
|
43
|
+
gem_version <=> cast_gem_version(other)
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# @return [String]
|
48
|
+
#
|
49
|
+
def to_s
|
50
|
+
gem_version.to_s
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
attr_reader :value
|
56
|
+
|
57
|
+
##
|
58
|
+
# @return [Gem::Version, nil]
|
59
|
+
#
|
60
|
+
def cast_gem_version(value)
|
61
|
+
::Gem::Version.create(value.to_s) if ::Gem::Version.correct?(value.to_s)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -9,4 +9,7 @@ require_relative "support/command"
|
|
9
9
|
require_relative "support/copyable"
|
10
10
|
require_relative "support/delegate"
|
11
11
|
require_relative "support/finite_loop"
|
12
|
+
require_relative "support/gems"
|
12
13
|
require_relative "support/middleware"
|
14
|
+
require_relative "support/ruby"
|
15
|
+
require_relative "support/version"
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
##
|
4
|
+
#
|
5
|
+
#
|
6
|
+
module ConvenientService
|
7
|
+
module Utils
|
8
|
+
module Object
|
9
|
+
class InstanceVariableFetch < Support::Command
|
10
|
+
##
|
11
|
+
# @!attribute [r] object
|
12
|
+
# @return [Object]
|
13
|
+
#
|
14
|
+
attr_reader :object
|
15
|
+
|
16
|
+
##
|
17
|
+
# @!attribute [r] ivar_name
|
18
|
+
# @return [Symbol, String]
|
19
|
+
#
|
20
|
+
attr_reader :ivar_name
|
21
|
+
|
22
|
+
##
|
23
|
+
# @!attribute [r] fallback_block
|
24
|
+
# @return [Proc, nil]
|
25
|
+
#
|
26
|
+
attr_reader :fallback_block
|
27
|
+
|
28
|
+
##
|
29
|
+
# @param object [Object]
|
30
|
+
# @param ivar_name [Symbol]
|
31
|
+
# @param fallback_block [Proc]
|
32
|
+
# @return [void]
|
33
|
+
#
|
34
|
+
def initialize(object, ivar_name, &fallback_block)
|
35
|
+
@object = object
|
36
|
+
@ivar_name = ivar_name
|
37
|
+
@fallback_block = fallback_block
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# @return [Object] Value of ivar. Can be any type.
|
42
|
+
#
|
43
|
+
def call
|
44
|
+
return object.instance_variable_get(ivar_name) if object.instance_variable_defined?(ivar_name)
|
45
|
+
|
46
|
+
return object.instance_variable_set(ivar_name, fallback_block.call) if fallback_block
|
47
|
+
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,11 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "object/instance_variable_fetch"
|
3
4
|
require_relative "object/resolve_type"
|
4
5
|
|
5
6
|
module ConvenientService
|
6
7
|
module Utils
|
7
8
|
module Object
|
8
9
|
class << self
|
10
|
+
##
|
11
|
+
# @example
|
12
|
+
# ConvenientService::Utils::Object.instance_variable_fetch("abc", :@foo) { :bar }
|
13
|
+
#
|
14
|
+
def instance_variable_fetch(...)
|
15
|
+
InstanceVariableFetch.call(...)
|
16
|
+
end
|
17
|
+
|
9
18
|
##
|
10
19
|
# @example
|
11
20
|
# ConvenientService::Utils::Object.resolve_type("foo")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: convenient_service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marian Kostyk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-12-
|
11
|
+
date: 2022-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: appraisal
|
@@ -548,6 +548,9 @@ files:
|
|
548
548
|
- lib/convenient_service/service.rb
|
549
549
|
- lib/convenient_service/service/plugins.rb
|
550
550
|
- lib/convenient_service/service/plugins/aliases.rb
|
551
|
+
- lib/convenient_service/service/plugins/can_have_stubbed_result.rb
|
552
|
+
- lib/convenient_service/service/plugins/can_have_stubbed_result/concern.rb
|
553
|
+
- lib/convenient_service/service/plugins/can_have_stubbed_result/middleware.rb
|
551
554
|
- lib/convenient_service/service/plugins/can_recalculate_result.rb
|
552
555
|
- lib/convenient_service/service/plugins/can_recalculate_result/concern.rb
|
553
556
|
- lib/convenient_service/service/plugins/has_inspect.rb
|
@@ -694,8 +697,14 @@ files:
|
|
694
697
|
- lib/convenient_service/support/copyable.rb
|
695
698
|
- lib/convenient_service/support/delegate.rb
|
696
699
|
- lib/convenient_service/support/finite_loop.rb
|
700
|
+
- lib/convenient_service/support/gems.rb
|
701
|
+
- lib/convenient_service/support/gems/active_model.rb
|
702
|
+
- lib/convenient_service/support/gems/rspec.rb
|
697
703
|
- lib/convenient_service/support/middleware.rb
|
698
704
|
- lib/convenient_service/support/middleware/stack_builder.rb
|
705
|
+
- lib/convenient_service/support/ruby.rb
|
706
|
+
- lib/convenient_service/support/version.rb
|
707
|
+
- lib/convenient_service/support/version/null_version.rb
|
699
708
|
- lib/convenient_service/utils.rb
|
700
709
|
- lib/convenient_service/utils/array.rb
|
701
710
|
- lib/convenient_service/utils/array/contain_exactly.rb
|
@@ -720,6 +729,7 @@ files:
|
|
720
729
|
- lib/convenient_service/utils/module/has_own_instance_method.rb
|
721
730
|
- lib/convenient_service/utils/module/instance_method_defined.rb
|
722
731
|
- lib/convenient_service/utils/object.rb
|
732
|
+
- lib/convenient_service/utils/object/instance_variable_fetch.rb
|
723
733
|
- lib/convenient_service/utils/object/resolve_type.rb
|
724
734
|
- lib/convenient_service/utils/proc.rb
|
725
735
|
- lib/convenient_service/utils/proc/conjunct.rb
|