convenient_service 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +6 -6
- data/CHANGELOG.md +9 -0
- data/ROADMAP.md +3 -0
- data/Taskfile.yml +3 -3
- data/env.rb +4 -0
- data/lib/convenient_service/examples/dry/gemfile/dry_service/config.rb +3 -1
- data/lib/convenient_service/examples/dry/gemfile/services/assert_file_exists.rb +1 -1
- data/lib/convenient_service/examples/dry/gemfile/services/assert_file_not_empty.rb +1 -1
- data/lib/convenient_service/examples/dry/gemfile/services/assert_npm_package_available.rb +1 -1
- data/lib/convenient_service/examples/dry/gemfile/services/parse_content.rb +1 -1
- data/lib/convenient_service/examples/dry/gemfile/services/print_shell_command.rb +1 -1
- data/lib/convenient_service/examples/dry/gemfile/services/read_file_content.rb +1 -1
- data/lib/convenient_service/examples/dry/gemfile/services/run_shell.rb +1 -1
- data/lib/convenient_service/examples/dry/gemfile/services/strip_comments.rb +1 -1
- data/lib/convenient_service/examples/rails/gemfile/rails_service/config.rb +3 -1
- data/lib/convenient_service/rspec/matchers/custom/cache_its_value.rb +7 -7
- data/lib/convenient_service/rspec/matchers/custom/delegate_to.rb +50 -12
- data/lib/convenient_service/service/plugins/has_result/entities/result/plugins/has_jsend_status_and_attributes/concern/instance_methods.rb +29 -17
- data/lib/convenient_service/service/plugins/has_result_params_validations/using_dry_validation/middleware.rb +19 -9
- data/lib/convenient_service/service/plugins/has_result_steps/middleware.rb +1 -1
- data/lib/convenient_service/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70d36eabeb3ea9598979a7158d06e0bfc627398066abc5180411f13fce9142e8
|
4
|
+
data.tar.gz: 6c6ea0ce690bb915c32f2e810afe70f87e74961f7a3c01b4e3a6389b8f98b1dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa610f3ac041e97849914d6bf15e626cceef9d8abd9aed0e5244b112595c89c9ac1eb91438bf67a84065bc8b90e91ebd8fff19cbcfb3c4a77e9b1246100b25fd
|
7
|
+
data.tar.gz: d704307543e1a14efa13f2701a109ee2748af75ed2260bbf9e4e64bc06b5bbe2a23ac208eabea1ec2d536578c9b9ec97c76541fa79181b9e896f4f844594d743
|
data/.github/workflows/ci.yml
CHANGED
@@ -128,14 +128,14 @@ jobs:
|
|
128
128
|
run: task rspec:standard
|
129
129
|
- name: Install dependencies for appraisals
|
130
130
|
run: task deps:install
|
131
|
-
- name: Run RSpec with Rails 5.2
|
132
|
-
run: task rspec:rails_5.2
|
133
|
-
- name: Run RSpec with Rails 6.0
|
134
|
-
run: task rspec:rails_6.0
|
135
|
-
- name: Run RSpec with Rails 6.1
|
136
|
-
run: task rspec:rails_6.1
|
137
131
|
- name: Run RSpec with Rails 7.0
|
138
132
|
run: task rspec:rails_7.0
|
133
|
+
- name: Run RSpec with Rails 6.1
|
134
|
+
run: task rspec:rails_6.1
|
135
|
+
- name: Run RSpec with Rails 6.0
|
136
|
+
run: task rspec:rails_6.0
|
137
|
+
- name: Run RSpec with Rails 5.2
|
138
|
+
run: task rspec:rails_5.2
|
139
139
|
- name: Run RSpec with Dry
|
140
140
|
run: task rspec:dry
|
141
141
|
##
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [0.2.1](https://github.com/marian13/convenient_service/compare/v0.2.0...v0.2.1) (2022-12-14)
|
4
|
+
|
5
|
+
|
6
|
+
### Bug Fixes
|
7
|
+
|
8
|
+
* **has_result_steps:** return step copy to have fresh state ([55cc368](https://github.com/marian13/convenient_service/commit/55cc368484641040c0c76ecb38872cc9a268397c), [fc7cebb](https://github.com/marian13/convenient_service/commit/fc7cebb4e159af7b35eac3cf8c25c7009e14c9d1))
|
9
|
+
* **standard:** place UsingActiveModelValidations before HasResultSteps ([4c43205](https://github.com/marian13/convenient_service/commit/4c43205382da2e7ae395fea6639c2bcc43d1eec2))
|
10
|
+
* **standard:** place UsingDryValidation before HasResultSteps ([63c31c0](https://github.com/marian13/convenient_service/commit/63c31c04ac7c2581defd3557aad13db3188806ba))
|
11
|
+
|
3
12
|
## [0.2.0](https://github.com/marian13/convenient_service/compare/v0.1.0...v0.2.0) (2022-11-26)
|
4
13
|
|
5
14
|
|
data/ROADMAP.md
CHANGED
@@ -48,5 +48,8 @@
|
|
48
48
|
| Low | 🚧 | [Receive Counts](https://relishapp.com/rspec/rspec-mocks/docs/setting-constraints/receive-counts) for `delegate_to` | |
|
49
49
|
| Low | 🚧 | Prefer versioning instead of modification plugin | |
|
50
50
|
| Low | 🚧 | Consider to move `__steps__` and `__callbacks__` to `internals_class` | Benefit? |
|
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
|
+
| High | 🚧 | A plugin that catches `StandardError` and returns `failure` | Should be the lowest in the stack |
|
53
|
+
| High | 🚧 | `Support::Command` alias | Should be visible to the end user |
|
51
54
|
|
52
55
|
Search for `TODO`s in the codebase for more tasks.
|
data/Taskfile.yml
CHANGED
@@ -201,10 +201,10 @@ tasks:
|
|
201
201
|
rspec:
|
202
202
|
cmds:
|
203
203
|
- task: rspec:standard
|
204
|
-
- task: rspec:rails_5.2
|
205
|
-
- task: rspec:rails_6.0
|
206
|
-
- task: rspec:rails_6.1
|
207
204
|
- task: rspec:rails_7.0
|
205
|
+
- task: rspec:rails_6.1
|
206
|
+
- task: rspec:rails_6.0
|
207
|
+
- task: rspec:rails_5.2
|
208
208
|
- task: rspec:dry
|
209
209
|
|
210
210
|
##
|
data/env.rb
CHANGED
@@ -12,8 +12,12 @@
|
|
12
12
|
#
|
13
13
|
ENV["APPRAISAL_NAME"] ||= ENV["BUNDLE_GEMFILE"].to_s.then(&File.method(:basename)).then { |name| name.end_with?(".gemfile") ? name.delete_suffix(".gemfile") : "" }
|
14
14
|
|
15
|
+
puts "ENV[\"APPRAISAL_NAME\"] -> `#{ENV["APPRAISAL_NAME"]}`"
|
16
|
+
|
15
17
|
##
|
16
18
|
# NOTE: Ruby version may be set by docker.
|
17
19
|
# https://github.com/docker-library/ruby/blob/master/3.1/alpine3.16/Dockerfile#L30
|
18
20
|
#
|
19
21
|
ENV["RUBY_VERSION"] ||= ::RUBY_VERSION
|
22
|
+
|
23
|
+
puts "ENV[\"RUBY_VERSION\"] -> `#{ENV["RUBY_VERSION"]}`"
|
@@ -31,7 +31,9 @@ module ConvenientService
|
|
31
31
|
end
|
32
32
|
|
33
33
|
middlewares :result do
|
34
|
-
|
34
|
+
insert_before \
|
35
|
+
Plugins::Service::HasResultSteps::Middleware,
|
36
|
+
Plugins::Service::HasResultParamsValidations::UsingDryValidation::Middleware
|
35
37
|
end
|
36
38
|
end
|
37
39
|
end
|
@@ -42,7 +42,9 @@ module ConvenientService
|
|
42
42
|
end
|
43
43
|
|
44
44
|
middlewares :result do
|
45
|
-
|
45
|
+
insert_before \
|
46
|
+
Plugins::Service::HasResultSteps::Middleware,
|
47
|
+
Plugins::Service::HasResultParamsValidations::UsingActiveModelValidations::Middleware
|
46
48
|
end
|
47
49
|
end
|
48
50
|
end
|
@@ -23,26 +23,26 @@ module ConvenientService
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def failure_message
|
26
|
-
"expected #{
|
26
|
+
"expected #{printable_block_expectation} to cache its value"
|
27
27
|
end
|
28
28
|
|
29
29
|
def failure_message_when_negated
|
30
|
-
"expected #{
|
30
|
+
"expected #{printable_block_expectation} NOT to cache its value"
|
31
31
|
end
|
32
32
|
|
33
33
|
##
|
34
34
|
# NOTE: An example of how RSpec extracts block source, but they marked it as private.
|
35
35
|
# https://github.com/rspec/rspec-expectations/blob/311aaf245f2c5493572bf683b8c441cb5f7e44c8/lib/rspec/matchers/built_in/change.rb#L437
|
36
36
|
#
|
37
|
-
# TODO: `
|
37
|
+
# TODO: `printable_block_expectation` when `method_source` is available.
|
38
38
|
# https://github.com/banister/method_source
|
39
39
|
#
|
40
|
-
# def
|
41
|
-
# @
|
40
|
+
# def printable_block_expectation
|
41
|
+
# @printable_block_expectation ||= block_expectation.source
|
42
42
|
# end
|
43
43
|
#
|
44
|
-
def
|
45
|
-
@
|
44
|
+
def printable_block_expectation
|
45
|
+
@printable_block_expectation ||= "{ ... }"
|
46
46
|
end
|
47
47
|
|
48
48
|
private
|
@@ -1,5 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
##
|
4
|
+
# IMPORTANT: This matcher has a dedicated end-user doc. Do NOT forget to update it when needed.
|
5
|
+
# https://github.com/marian13/convenient_service_docs/blob/main/docs/api/tests/rspec/matchers/delegate_to.mdx
|
6
|
+
#
|
7
|
+
# TODO: Refactor into composition:
|
8
|
+
# - Ability to compose when `delegate_to` is used `without_arguments`.
|
9
|
+
# - Ability to compose when `delegate_to` is used `with_arguments`.
|
10
|
+
# - Ability to compose when `delegate_to` is used `and_return_its_value`.
|
11
|
+
#
|
12
|
+
# TODO: Refactor to NOT use `expect` inside this matcher.
|
13
|
+
# This way the matcher will return true or false, but never raise exceptions (descendant of Exception, not StandardError).
|
14
|
+
# Then it will be easier to developer a fully comprehensive spec suite for `delegate_to`.
|
15
|
+
#
|
3
16
|
module ConvenientService
|
4
17
|
module RSpec
|
5
18
|
module Matchers
|
@@ -81,15 +94,7 @@ module ConvenientService
|
|
81
94
|
# https://relishapp.com/rspec/rspec-mocks/docs/configuring-responses/wrapping-the-original-implementation
|
82
95
|
#
|
83
96
|
allow(object).to receive(method).and_wrap_original do |original, *actual_args, **actual_kwargs, &actual_block|
|
84
|
-
|
85
|
-
# TODO: Provide customized error messages?
|
86
|
-
# https://relishapp.com/rspec/rspec-expectations/docs/customized-message
|
87
|
-
#
|
88
|
-
# NOTE: `delegate_to` expects that delegation is executed only once during `block_expectation`.
|
89
|
-
#
|
90
|
-
expect(actual_args).to eq(expected_args)
|
91
|
-
expect(actual_kwargs).to eq(expected_kwargs)
|
92
|
-
expect(actual_block).to eq(expected_block)
|
97
|
+
actual_arguments_collection << [actual_args, actual_kwargs, actual_block]
|
93
98
|
|
94
99
|
##
|
95
100
|
# NOTE: Imitates `and_call_original`.
|
@@ -108,7 +113,7 @@ module ConvenientService
|
|
108
113
|
##
|
109
114
|
# NOTE: If this expectation fails, it means `delegate_to` is NOT met.
|
110
115
|
#
|
111
|
-
expect(object).to have_received(method)
|
116
|
+
expect(object).to have_received(method).at_least(1) unless used_with_arguments?
|
112
117
|
|
113
118
|
##
|
114
119
|
# IMPORTANT: `and_return_its_value` works only when `delegate_to` checks a pure function.
|
@@ -166,7 +171,13 @@ module ConvenientService
|
|
166
171
|
# NOTE: RSpec raises exception when any `expect` is NOT satisfied.
|
167
172
|
# So, this `true` is returned only when all `expect` are successful.
|
168
173
|
#
|
169
|
-
|
174
|
+
if used_with_arguments?
|
175
|
+
actual_arguments_collection.any? do |(actual_args, actual_kwargs, actual_block)|
|
176
|
+
actual_args == expected_args && actual_kwargs == expected_kwargs && actual_block == expected_block
|
177
|
+
end
|
178
|
+
else
|
179
|
+
true
|
180
|
+
end
|
170
181
|
end
|
171
182
|
|
172
183
|
##
|
@@ -184,8 +195,16 @@ module ConvenientService
|
|
184
195
|
"delegate to `#{printable_method}`"
|
185
196
|
end
|
186
197
|
|
198
|
+
def failure_message
|
199
|
+
if used_with_arguments?
|
200
|
+
"expected `#{printable_block_expectation}` to delegate to `#{printable_method}` with expected arguments at least once, but it didn't."
|
201
|
+
else
|
202
|
+
"expected `#{printable_block_expectation}` to delegate to `#{printable_method}` at least once, but it didn't."
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
187
206
|
##
|
188
|
-
# IMPORTANT: `
|
207
|
+
# IMPORTANT: `failure_message_when_negated` is NOT supported yet.
|
189
208
|
#
|
190
209
|
|
191
210
|
def with_arguments(*args, **kwargs, &block)
|
@@ -248,6 +267,25 @@ module ConvenientService
|
|
248
267
|
end
|
249
268
|
|
250
269
|
alias_method :expected_block, :block
|
270
|
+
|
271
|
+
def actual_arguments_collection
|
272
|
+
@actual_arguments_collection ||= []
|
273
|
+
end
|
274
|
+
|
275
|
+
##
|
276
|
+
# NOTE: An example of how RSpec extracts block source, but they marked it as private.
|
277
|
+
# https://github.com/rspec/rspec-expectations/blob/311aaf245f2c5493572bf683b8c441cb5f7e44c8/lib/rspec/matchers/built_in/change.rb#L437
|
278
|
+
#
|
279
|
+
# TODO: `printable_block_expectation` when `method_source` is available.
|
280
|
+
# https://github.com/banister/method_source
|
281
|
+
#
|
282
|
+
# def printable_block_expectation
|
283
|
+
# @printable_block_expectation ||= block_expectation.source
|
284
|
+
# end
|
285
|
+
#
|
286
|
+
def printable_block_expectation
|
287
|
+
@printable_block_expectation ||= "{ ... }"
|
288
|
+
end
|
251
289
|
end
|
252
290
|
end
|
253
291
|
end
|
@@ -49,36 +49,48 @@ module ConvenientService
|
|
49
49
|
##
|
50
50
|
# @return [Class]
|
51
51
|
#
|
52
|
-
|
53
|
-
internals.cache[:jsend_attributes].service
|
54
|
-
end
|
52
|
+
delegate :service, to: :jsend_attributes
|
55
53
|
|
56
54
|
##
|
57
55
|
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJsendStatusAndAttributes::Entities::Status]
|
58
56
|
#
|
59
|
-
|
60
|
-
internals.cache[:jsend_attributes].status
|
61
|
-
end
|
57
|
+
delegate :status, to: :jsend_attributes
|
62
58
|
|
63
59
|
##
|
64
60
|
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJsendStatusAndAttributes::Entities::Data]
|
65
61
|
#
|
66
|
-
|
67
|
-
|
68
|
-
|
62
|
+
delegate :data, to: :jsend_attributes
|
63
|
+
|
64
|
+
##
|
65
|
+
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJsendStatusAndAttributes::Entities::Data]
|
66
|
+
#
|
67
|
+
alias_method :unsafe_data, :data
|
69
68
|
|
70
69
|
##
|
71
70
|
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJsendStatusAndAttributes::Entities::Message]
|
72
71
|
#
|
73
|
-
|
74
|
-
|
75
|
-
|
72
|
+
delegate :message, to: :jsend_attributes
|
73
|
+
|
74
|
+
##
|
75
|
+
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJsendStatusAndAttributes::Entities::Message]
|
76
|
+
#
|
77
|
+
alias_method :unsafe_message, :message
|
76
78
|
|
77
79
|
##
|
78
80
|
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJsendStatusAndAttributes::Entities::Code]
|
79
81
|
#
|
80
|
-
|
81
|
-
|
82
|
+
delegate :code, to: :jsend_attributes
|
83
|
+
|
84
|
+
##
|
85
|
+
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJsendStatusAndAttributes::Entities::Code]
|
86
|
+
#
|
87
|
+
alias_method :unsafe_code, :code
|
88
|
+
|
89
|
+
##
|
90
|
+
# @return [ConvenientService::Service::Plugins::HasResult::Entities::Result::Plugins::HasJsendStatusAndAttributes::Structs::JSendAttributes]
|
91
|
+
#
|
92
|
+
def jsend_attributes
|
93
|
+
internals.cache[:jsend_attributes]
|
82
94
|
end
|
83
95
|
|
84
96
|
##
|
@@ -90,9 +102,9 @@ module ConvenientService
|
|
90
102
|
|
91
103
|
return false if service.class != other.service.class
|
92
104
|
return false if status != other.status
|
93
|
-
return false if
|
94
|
-
return false if
|
95
|
-
return false if
|
105
|
+
return false if unsafe_data != other.unsafe_data
|
106
|
+
return false if unsafe_message != other.unsafe_message
|
107
|
+
return false if unsafe_code != other.unsafe_code
|
96
108
|
|
97
109
|
true
|
98
110
|
end
|
@@ -21,15 +21,25 @@ module ConvenientService
|
|
21
21
|
# TODO: Return one or all errors?
|
22
22
|
#
|
23
23
|
def errors
|
24
|
-
@errors ||=
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
24
|
+
@errors ||= resolve_errors
|
25
|
+
end
|
26
|
+
|
27
|
+
def constructor_kwargs
|
28
|
+
@constructor_kwargs ||= entity.constructor_params.kwargs
|
29
|
+
end
|
30
|
+
|
31
|
+
def contract
|
32
|
+
@contract ||= entity.class.contract
|
33
|
+
end
|
34
|
+
|
35
|
+
def resolve_errors
|
36
|
+
return {} unless contract.schema
|
37
|
+
|
38
|
+
contract.new
|
39
|
+
.call(constructor_kwargs)
|
40
|
+
.errors
|
41
|
+
.to_h
|
42
|
+
.transform_values(&:first)
|
33
43
|
end
|
34
44
|
end
|
35
45
|
end
|
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.2.
|
4
|
+
version: 0.2.1
|
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-
|
11
|
+
date: 2022-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: appraisal
|