servactory 1.5.1 → 1.6.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/README.md +87 -50
- data/config/locales/en.yml +5 -5
- data/lib/servactory/base.rb +4 -4
- data/lib/servactory/configuration/factory.rb +6 -6
- data/lib/servactory/configuration/setup.rb +6 -6
- data/lib/servactory/context/callable.rb +21 -22
- data/lib/servactory/context/configuration.rb +6 -6
- data/lib/servactory/context/workspace/inputs.rb +13 -0
- data/lib/servactory/context/workspace.rb +9 -7
- data/lib/servactory/errors/base.rb +2 -1
- data/lib/servactory/errors/collection.rb +25 -0
- data/lib/servactory/errors/failure.rb +11 -1
- data/lib/servactory/errors/input_error.rb +17 -0
- data/lib/servactory/errors/internal_error.rb +15 -0
- data/lib/servactory/errors/output_error.rb +15 -0
- data/lib/servactory/{input_arguments → inputs}/checks/base.rb +3 -3
- data/lib/servactory/{input_arguments → inputs}/checks/errors.rb +1 -1
- data/lib/servactory/{input_arguments → inputs}/checks/inclusion.rb +7 -4
- data/lib/servactory/{input_arguments → inputs}/checks/must.rb +3 -3
- data/lib/servactory/{input_arguments → inputs}/checks/required.rb +2 -2
- data/lib/servactory/{input_arguments → inputs}/checks/type.rb +3 -3
- data/lib/servactory/{input_arguments → inputs}/collection.rb +1 -1
- data/lib/servactory/{input_arguments → inputs}/define_input_conflict.rb +1 -1
- data/lib/servactory/{input_arguments → inputs}/define_input_method.rb +1 -1
- data/lib/servactory/inputs/dsl.rb +36 -0
- data/lib/servactory/{input_arguments/input_argument.rb → inputs/input.rb} +13 -12
- data/lib/servactory/{input_arguments → inputs}/option.rb +5 -3
- data/lib/servactory/{input_arguments → inputs}/options_collection.rb +1 -1
- data/lib/servactory/{input_arguments → inputs}/tools/check.rb +5 -5
- data/lib/servactory/{input_arguments → inputs}/tools/check_errors.rb +1 -1
- data/lib/servactory/{input_arguments → inputs}/tools/find_unnecessary.rb +6 -6
- data/lib/servactory/{input_arguments → inputs}/tools/prepare.rb +5 -5
- data/lib/servactory/inputs/tools/rules.rb +46 -0
- data/lib/servactory/{input_arguments → inputs}/workbench.rb +8 -8
- data/lib/servactory/internals/checks/base.rb +17 -0
- data/lib/servactory/{internal_arguments → internals}/checks/type.rb +8 -8
- data/lib/servactory/{output_arguments → internals}/collection.rb +1 -1
- data/lib/servactory/internals/dsl.rb +33 -0
- data/lib/servactory/{internal_arguments/internal_argument.rb → internals/internal.rb} +2 -2
- data/lib/servactory/internals/tools/prepare.rb +60 -0
- data/lib/servactory/{internal_arguments → internals}/workbench.rb +5 -5
- data/lib/servactory/{make_methods → methods}/collection.rb +1 -1
- data/lib/servactory/methods/dsl.rb +33 -0
- data/lib/servactory/{make_methods/make_method.rb → methods/method.rb} +2 -2
- data/lib/servactory/{make_methods → methods}/workbench.rb +5 -5
- data/lib/servactory/outputs/checks/base.rb +17 -0
- data/lib/servactory/{output_arguments → outputs}/checks/type.rb +8 -8
- data/lib/servactory/{internal_arguments → outputs}/collection.rb +1 -1
- data/lib/servactory/outputs/dsl.rb +33 -0
- data/lib/servactory/{output_arguments/output_argument.rb → outputs/output.rb} +2 -2
- data/lib/servactory/{output_arguments → outputs}/tools/conflicts.rb +7 -7
- data/lib/servactory/outputs/tools/prepare.rb +62 -0
- data/lib/servactory/outputs/workbench.rb +31 -0
- data/lib/servactory/result.rb +4 -4
- data/lib/servactory/utils.rb +2 -0
- data/lib/servactory/version.rb +2 -2
- metadata +59 -46
- data/lib/servactory/context/workspace/error.rb +0 -19
- data/lib/servactory/context/workspace/errors.rb +0 -33
- data/lib/servactory/errors/input_argument_error.rb +0 -7
- data/lib/servactory/errors/internal_argument_error.rb +0 -7
- data/lib/servactory/errors/output_argument_error.rb +0 -7
- data/lib/servactory/input_arguments/dsl.rb +0 -36
- data/lib/servactory/input_arguments/tools/rules.rb +0 -43
- data/lib/servactory/inputs.rb +0 -9
- data/lib/servactory/internal_arguments/checks/base.rb +0 -17
- data/lib/servactory/internal_arguments/dsl.rb +0 -33
- data/lib/servactory/internal_arguments/tools/prepare.rb +0 -60
- data/lib/servactory/make_methods/dsl.rb +0 -33
- data/lib/servactory/output_arguments/checks/base.rb +0 -17
- data/lib/servactory/output_arguments/dsl.rb +0 -33
- data/lib/servactory/output_arguments/tools/prepare.rb +0 -62
- data/lib/servactory/output_arguments/workbench.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd3981fb61af74a47cc5d5279a51796d78527c2b4b16c3bdb69f7bd94e32932f
|
4
|
+
data.tar.gz: ca8ad9beca25c5dd04a9f7bb584ced4cef6b3f35d6d14c68c0d297ef817b8025
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e95bffde026a1b55bca088e15d86c2ec2b78ff4838be5f683c574e9ea1ed148a993a3075c4fb7b72493d3667b7280b4fe177edd748262bd77193425571aabb96
|
7
|
+
data.tar.gz: c41af274f2c6c858f29cef27f7b9d0b61ebf106712f9a55ca739782f2bbb2e12758c51a4271901505fdd81028ec435b52308244a2d581ee8c82841b768169b7f
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ A set of tools for building reliable services of any complexity.
|
|
5
5
|
[](https://rubygems.org/gems/servactory)
|
6
6
|
[](https://github.com/afuno/servactory/releases)
|
7
7
|
|
8
|
-
##
|
8
|
+
## Table of contents
|
9
9
|
|
10
10
|
- [Requirements](#requirements)
|
11
11
|
- [Getting started](#getting-started)
|
@@ -16,18 +16,19 @@ A set of tools for building reliable services of any complexity.
|
|
16
16
|
- [Minimal example](#minimal-example)
|
17
17
|
- [Call](#call)
|
18
18
|
- [Result](#result)
|
19
|
-
- [Input
|
20
|
-
- [
|
21
|
-
- [
|
22
|
-
- [
|
23
|
-
- [
|
24
|
-
- [
|
25
|
-
- [Inclusion](#inclusion)
|
26
|
-
- [Must](#must)
|
27
|
-
- [Output
|
28
|
-
- [Internal
|
19
|
+
- [Input](#input)
|
20
|
+
- [Type](#option-type)
|
21
|
+
- [Required](#option-required)
|
22
|
+
- [Internal](#option-internal)
|
23
|
+
- [Internal name](#option-as)
|
24
|
+
- [Array](#option-array)
|
25
|
+
- [Inclusion](#option-inclusion)
|
26
|
+
- [Must](#option-must)
|
27
|
+
- [Output](#output)
|
28
|
+
- [Internal](#internal)
|
29
29
|
- [Make](#make)
|
30
30
|
- [Failures](#failures)
|
31
|
+
- [Inheritance](#inheritance)
|
31
32
|
- [I18n](#i18n)
|
32
33
|
- [Testing](#testing)
|
33
34
|
- [Thanks](#thanks)
|
@@ -69,9 +70,9 @@ As a first step, it is recommended to prepare the base class for further inherit
|
|
69
70
|
|
70
71
|
module ApplicationService
|
71
72
|
module Errors
|
72
|
-
class
|
73
|
-
class
|
74
|
-
class
|
73
|
+
class InputError < Servactory::Errors::InputError; end
|
74
|
+
class OutputError < Servactory::Errors::OutputError; end
|
75
|
+
class InternalError < Servactory::Errors::InternalError; end
|
75
76
|
|
76
77
|
class Failure < Servactory::Errors::Failure; end
|
77
78
|
end
|
@@ -86,9 +87,9 @@ end
|
|
86
87
|
module ApplicationService
|
87
88
|
class Base < Servactory::Base
|
88
89
|
configuration do
|
89
|
-
|
90
|
-
|
91
|
-
|
90
|
+
input_error_class ApplicationService::Errors::InputError
|
91
|
+
output_error_class ApplicationService::Errors::OutputError
|
92
|
+
internal_error_class ApplicationService::Errors::InternalError
|
92
93
|
|
93
94
|
failure_class ApplicationService::Errors::Failure
|
94
95
|
end
|
@@ -155,11 +156,45 @@ And then you can work with this result, for example, in this way:
|
|
155
156
|
Notification::SendJob.perform_later(service_result.user.id)
|
156
157
|
```
|
157
158
|
|
158
|
-
### Input
|
159
|
+
### Input
|
159
160
|
|
160
|
-
####
|
161
|
+
#### Option `type`
|
161
162
|
|
162
|
-
|
163
|
+
Always required to specify. May contain one or more classes.
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
class UsersService::Accept < ApplicationService::Base
|
167
|
+
input :user, type: User
|
168
|
+
|
169
|
+
# ...
|
170
|
+
end
|
171
|
+
```
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
class ToggleService < ApplicationService::Base
|
175
|
+
input :flag, type: [TrueClass, FalseClass]
|
176
|
+
|
177
|
+
# ...
|
178
|
+
end
|
179
|
+
```
|
180
|
+
|
181
|
+
#### Option `required`
|
182
|
+
|
183
|
+
By default, `required` is set to `true`.
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
class UsersService::Create < ApplicationService::Base
|
187
|
+
input :first_name, type: String
|
188
|
+
input :middle_name, type: String, required: false
|
189
|
+
input :last_name, type: String
|
190
|
+
|
191
|
+
# ...
|
192
|
+
end
|
193
|
+
```
|
194
|
+
|
195
|
+
#### Option `internal`
|
196
|
+
|
197
|
+
By default, `internal` is set to `false`.
|
163
198
|
|
164
199
|
```ruby
|
165
200
|
class UsersService::Accept < ApplicationService::Base
|
@@ -175,10 +210,6 @@ class UsersService::Accept < ApplicationService::Base
|
|
175
210
|
end
|
176
211
|
```
|
177
212
|
|
178
|
-
#### As an internal argument
|
179
|
-
|
180
|
-
With this approach, all input attributes are available from `inputs` as well as directly from the context.
|
181
|
-
|
182
213
|
```ruby
|
183
214
|
class UsersService::Accept < ApplicationService::Base
|
184
215
|
input :user, type: User, internal: true
|
@@ -193,21 +224,7 @@ class UsersService::Accept < ApplicationService::Base
|
|
193
224
|
end
|
194
225
|
```
|
195
226
|
|
196
|
-
####
|
197
|
-
|
198
|
-
By default, all inputs are required. To make an input optional, specify `false` in the `required` option.
|
199
|
-
|
200
|
-
```ruby
|
201
|
-
class UsersService::Create < ApplicationService::Base
|
202
|
-
input :first_name, type: String
|
203
|
-
input :middle_name, type: String, required: false
|
204
|
-
input :last_name, type: String
|
205
|
-
|
206
|
-
# ...
|
207
|
-
end
|
208
|
-
```
|
209
|
-
|
210
|
-
#### As (internal name)
|
227
|
+
#### Option `as`
|
211
228
|
|
212
229
|
This option changes the name of the input within the service.
|
213
230
|
|
@@ -227,7 +244,9 @@ class NotificationService::Create < ApplicationService::Base
|
|
227
244
|
end
|
228
245
|
```
|
229
246
|
|
230
|
-
####
|
247
|
+
#### Option `array`
|
248
|
+
|
249
|
+
Using this option will mean that the input argument is an array, each element of which has the specified type.
|
231
250
|
|
232
251
|
```ruby
|
233
252
|
class PymentsService::Send < ApplicationService::Base
|
@@ -237,7 +256,7 @@ class PymentsService::Send < ApplicationService::Base
|
|
237
256
|
end
|
238
257
|
```
|
239
258
|
|
240
|
-
####
|
259
|
+
#### Option `inclusion`
|
241
260
|
|
242
261
|
```ruby
|
243
262
|
class EventService::Send < ApplicationService::Base
|
@@ -247,7 +266,7 @@ class EventService::Send < ApplicationService::Base
|
|
247
266
|
end
|
248
267
|
```
|
249
268
|
|
250
|
-
####
|
269
|
+
#### Option `must`
|
251
270
|
|
252
271
|
Sometimes there are cases that require the implementation of a specific input attribute check. In such cases `must` can help.
|
253
272
|
|
@@ -266,7 +285,7 @@ class PymentsService::Send < ApplicationService::Base
|
|
266
285
|
end
|
267
286
|
```
|
268
287
|
|
269
|
-
### Output
|
288
|
+
### Output
|
270
289
|
|
271
290
|
```ruby
|
272
291
|
class NotificationService::Create < ApplicationService::Base
|
@@ -284,7 +303,7 @@ class NotificationService::Create < ApplicationService::Base
|
|
284
303
|
end
|
285
304
|
```
|
286
305
|
|
287
|
-
### Internal
|
306
|
+
### Internal
|
288
307
|
|
289
308
|
```ruby
|
290
309
|
class NotificationService::Create < ApplicationService::Base
|
@@ -351,10 +370,6 @@ def process_result
|
|
351
370
|
end
|
352
371
|
```
|
353
372
|
|
354
|
-
#### Inheritance
|
355
|
-
|
356
|
-
Service inheritance is also supported.
|
357
|
-
|
358
373
|
### Failures
|
359
374
|
|
360
375
|
The methods that are used in `make` may fail. In order to more informatively provide information about this outside the service, the following methods were prepared.
|
@@ -367,7 +382,7 @@ make :check!
|
|
367
382
|
def check!
|
368
383
|
return if inputs.invoice_number.start_with?("AA")
|
369
384
|
|
370
|
-
fail!("Invalid invoice number")
|
385
|
+
fail!(message: "Invalid invoice number")
|
371
386
|
end
|
372
387
|
```
|
373
388
|
|
@@ -379,10 +394,32 @@ make :check!
|
|
379
394
|
def check!
|
380
395
|
return if inputs.invoice_number.start_with?("AA")
|
381
396
|
|
382
|
-
fail_input!(:invoice_number, "Invalid invoice number")
|
397
|
+
fail_input!(:invoice_number, message: "Invalid invoice number")
|
383
398
|
end
|
384
399
|
```
|
385
400
|
|
401
|
+
#### Metadata
|
402
|
+
|
403
|
+
```ruby
|
404
|
+
fail!(
|
405
|
+
message: "Invalid invoice number",
|
406
|
+
meta: {
|
407
|
+
invoice_number: inputs.invoice_number
|
408
|
+
}
|
409
|
+
)
|
410
|
+
```
|
411
|
+
|
412
|
+
```ruby
|
413
|
+
exception.detailed_message # => Invalid invoice number (ApplicationService::Errors::Failure)
|
414
|
+
exception.message # => Invalid invoice number
|
415
|
+
exception.type # => :fail
|
416
|
+
exception.meta # => {:invoice_number=>"BB-7650AE"}
|
417
|
+
```
|
418
|
+
|
419
|
+
### Inheritance
|
420
|
+
|
421
|
+
Inheritance between services is also supported.
|
422
|
+
|
386
423
|
## I18n
|
387
424
|
|
388
425
|
All texts are stored in the localization file. All texts can be changed or supplemented by new locales.
|
data/config/locales/en.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
en:
|
2
2
|
servactory:
|
3
|
-
|
3
|
+
inputs:
|
4
4
|
checks:
|
5
5
|
inclusion:
|
6
6
|
default_error: "[%{service_class_name}] Wrong value in `%{input_name}`, must be one of `%{input_inclusion}`"
|
@@ -20,14 +20,14 @@ en:
|
|
20
20
|
error: "[%{service_class_name}] Unexpected attributes: `%{unnecessary_attributes}`"
|
21
21
|
rules:
|
22
22
|
error: "[%{service_class_name}] Conflict in `%{input_name}` input options: `%{conflict_code}`"
|
23
|
-
|
23
|
+
internals:
|
24
24
|
checks:
|
25
25
|
type:
|
26
|
-
default_error: "[%{service_class_name}] Wrong type of internal
|
27
|
-
|
26
|
+
default_error: "[%{service_class_name}] Wrong type of internal attribute `%{internal_name}`, expected `%{expected_type}`, got `%{given_type}`"
|
27
|
+
outputs:
|
28
28
|
checks:
|
29
29
|
type:
|
30
|
-
default_error: "[%{service_class_name}] Wrong type of output
|
30
|
+
default_error: "[%{service_class_name}] Wrong type of output attribute `%{output_name}`, expected `%{expected_type}`, got `%{given_type}`"
|
31
31
|
tools:
|
32
32
|
conflicts:
|
33
33
|
error: "[%{service_class_name}] Conflict between internal and output attributes `%{overlapping_attributes}`"
|
data/lib/servactory/base.rb
CHANGED
@@ -4,10 +4,10 @@ module Servactory
|
|
4
4
|
class Base
|
5
5
|
include Configuration::DSL
|
6
6
|
include Context::DSL
|
7
|
-
include
|
8
|
-
include
|
9
|
-
include
|
10
|
-
include
|
7
|
+
include Inputs::DSL
|
8
|
+
include Internals::DSL
|
9
|
+
include Outputs::DSL
|
10
|
+
include Methods::DSL
|
11
11
|
|
12
12
|
private_class_method :new
|
13
13
|
end
|
@@ -3,16 +3,16 @@
|
|
3
3
|
module Servactory
|
4
4
|
module Configuration
|
5
5
|
class Factory
|
6
|
-
def
|
7
|
-
Servactory.configuration.
|
6
|
+
def input_error_class(input_error_class)
|
7
|
+
Servactory.configuration.input_error_class = input_error_class
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
Servactory.configuration.
|
10
|
+
def output_error_class(output_error_class)
|
11
|
+
Servactory.configuration.output_error_class = output_error_class
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
Servactory.configuration.
|
14
|
+
def internal_error_class(internal_error_class)
|
15
|
+
Servactory.configuration.internal_error_class = internal_error_class
|
16
16
|
end
|
17
17
|
|
18
18
|
def failure_class(failure_class)
|
@@ -3,15 +3,15 @@
|
|
3
3
|
module Servactory
|
4
4
|
module Configuration
|
5
5
|
class Setup
|
6
|
-
attr_accessor :
|
7
|
-
:
|
8
|
-
:
|
6
|
+
attr_accessor :input_error_class,
|
7
|
+
:internal_error_class,
|
8
|
+
:output_error_class,
|
9
9
|
:failure_class
|
10
10
|
|
11
11
|
def initialize
|
12
|
-
@
|
13
|
-
@
|
14
|
-
@
|
12
|
+
@input_error_class = Servactory::Errors::InputError
|
13
|
+
@internal_error_class = Servactory::Errors::InternalError
|
14
|
+
@output_error_class = Servactory::Errors::OutputError
|
15
15
|
|
16
16
|
@failure_class = Servactory::Errors::Failure
|
17
17
|
end
|
@@ -8,23 +8,23 @@ module Servactory
|
|
8
8
|
|
9
9
|
assign_data_with(arguments)
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
inputs_workbench.find_unnecessary!
|
12
|
+
inputs_workbench.check_rules!
|
13
|
+
outputs_workbench.find_conflicts_in!(
|
14
|
+
collection_of_internals: collection_of_internals
|
15
15
|
)
|
16
16
|
|
17
17
|
prepare_data
|
18
18
|
|
19
|
-
|
19
|
+
inputs_workbench.check!
|
20
20
|
|
21
|
-
|
21
|
+
methods_workbench.run!
|
22
22
|
|
23
23
|
context_store.context.raise_first_fail
|
24
24
|
|
25
25
|
Servactory::Result.prepare_for(
|
26
26
|
context: context_store.context,
|
27
|
-
|
27
|
+
collection_of_outputs: collection_of_outputs
|
28
28
|
)
|
29
29
|
end
|
30
30
|
|
@@ -33,21 +33,21 @@ module Servactory
|
|
33
33
|
|
34
34
|
assign_data_with(arguments)
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
inputs_workbench.find_unnecessary!
|
37
|
+
inputs_workbench.check_rules!
|
38
|
+
outputs_workbench.find_conflicts_in!(
|
39
|
+
collection_of_internals: collection_of_internals
|
40
40
|
)
|
41
41
|
|
42
42
|
prepare_data
|
43
43
|
|
44
|
-
|
44
|
+
inputs_workbench.check!
|
45
45
|
|
46
|
-
|
46
|
+
methods_workbench.run!
|
47
47
|
|
48
48
|
Servactory::Result.prepare_for(
|
49
49
|
context: context_store.context,
|
50
|
-
|
50
|
+
collection_of_outputs: collection_of_outputs
|
51
51
|
)
|
52
52
|
end
|
53
53
|
|
@@ -56,21 +56,20 @@ module Servactory
|
|
56
56
|
attr_reader :context_store
|
57
57
|
|
58
58
|
def assign_data_with(arguments)
|
59
|
-
|
59
|
+
inputs_workbench.assign(
|
60
60
|
context: context_store.context,
|
61
61
|
arguments: arguments
|
62
62
|
)
|
63
63
|
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
internals_workbench.assign(context: context_store.context)
|
65
|
+
outputs_workbench.assign(context: context_store.context)
|
66
|
+
methods_workbench.assign(context: context_store.context)
|
67
67
|
end
|
68
68
|
|
69
69
|
def prepare_data
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
internal_arguments_workbench.prepare # 3
|
70
|
+
inputs_workbench.prepare # 1
|
71
|
+
outputs_workbench.prepare # 2
|
72
|
+
internals_workbench.prepare # 3
|
74
73
|
end
|
75
74
|
end
|
76
75
|
end
|
@@ -3,16 +3,16 @@
|
|
3
3
|
module Servactory
|
4
4
|
module Context
|
5
5
|
class Configuration
|
6
|
-
def
|
7
|
-
Servactory.configuration.
|
6
|
+
def input_error_class(input_error_class)
|
7
|
+
Servactory.configuration.input_error_class = input_error_class
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
Servactory.configuration.
|
10
|
+
def output_error_class(output_error_class)
|
11
|
+
Servactory.configuration.output_error_class = output_error_class
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
Servactory.configuration.
|
14
|
+
def internal_error_class(internal_error_class)
|
15
|
+
Servactory.configuration.internal_error_class = internal_error_class
|
16
16
|
end
|
17
17
|
|
18
18
|
def failure_class(failure_class)
|
@@ -6,26 +6,28 @@ module Servactory
|
|
6
6
|
attr_reader :inputs
|
7
7
|
|
8
8
|
def errors
|
9
|
-
@errors ||= Errors.new
|
9
|
+
@errors ||= Servactory::Errors::Collection.new
|
10
10
|
end
|
11
11
|
|
12
12
|
def assign_inputs(inputs)
|
13
13
|
@inputs = inputs
|
14
14
|
end
|
15
15
|
|
16
|
-
def fail_input!(
|
17
|
-
raise Servactory.configuration.
|
18
|
-
|
16
|
+
def fail_input!(input_name, message:)
|
17
|
+
raise Servactory.configuration.input_error_class.new(
|
18
|
+
input_name: input_name,
|
19
|
+
message: message
|
20
|
+
)
|
19
21
|
end
|
20
22
|
|
21
|
-
def fail!(
|
22
|
-
errors <<
|
23
|
+
def fail!(message:, meta: nil)
|
24
|
+
errors << Servactory.configuration.failure_class.new(message: message, meta: meta)
|
23
25
|
end
|
24
26
|
|
25
27
|
def raise_first_fail
|
26
28
|
return if (tmp_errors = errors.for_fails.not_blank).empty?
|
27
29
|
|
28
|
-
raise
|
30
|
+
raise tmp_errors.first
|
29
31
|
end
|
30
32
|
end
|
31
33
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Errors
|
5
|
+
class Collection
|
6
|
+
# NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :@collection, :<<, :to_a, :filter, :reject, :empty?, :first
|
9
|
+
|
10
|
+
def initialize(collection = Set.new)
|
11
|
+
@collection = collection
|
12
|
+
end
|
13
|
+
|
14
|
+
def not_blank
|
15
|
+
Collection.new(reject(&:blank?))
|
16
|
+
end
|
17
|
+
|
18
|
+
def for_fails
|
19
|
+
filtered = filter { |error| error.is_a?(Failure) }
|
20
|
+
|
21
|
+
Collection.new(filtered)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -2,6 +2,16 @@
|
|
2
2
|
|
3
3
|
module Servactory
|
4
4
|
module Errors
|
5
|
-
class Failure <
|
5
|
+
class Failure < Base
|
6
|
+
attr_reader :message,
|
7
|
+
:meta
|
8
|
+
|
9
|
+
def initialize(message:, meta: nil)
|
10
|
+
@message = message
|
11
|
+
@meta = meta
|
12
|
+
|
13
|
+
super(message)
|
14
|
+
end
|
15
|
+
end
|
6
16
|
end
|
7
17
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Errors
|
5
|
+
class InputError < Base
|
6
|
+
attr_reader :message,
|
7
|
+
:input_name
|
8
|
+
|
9
|
+
def initialize(message:, input_name: nil)
|
10
|
+
@message = message
|
11
|
+
@input_name = input_name&.to_sym
|
12
|
+
|
13
|
+
super(message)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Servactory
|
4
|
-
module
|
4
|
+
module Inputs
|
5
5
|
module Checks
|
6
6
|
class Base
|
7
7
|
protected
|
8
8
|
|
9
|
-
def add_error(message, **
|
10
|
-
message = message.call(**
|
9
|
+
def add_error(message, **attributes)
|
10
|
+
message = message.call(**attributes) if message.is_a?(Proc)
|
11
11
|
|
12
12
|
errors << message
|
13
13
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Servactory
|
4
|
-
module
|
4
|
+
module Inputs
|
5
5
|
module Checks
|
6
6
|
class Inclusion < Base
|
7
7
|
DEFAULT_MESSAGE = lambda do |service_class_name:, input:, value:|
|
8
8
|
I18n.t(
|
9
|
-
"servactory.
|
9
|
+
"servactory.inputs.checks.inclusion.default_error",
|
10
10
|
service_class_name: service_class_name,
|
11
11
|
input_name: input.name,
|
12
12
|
input_inclusion: input.inclusion[:in],
|
@@ -37,10 +37,13 @@ module Servactory
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def check
|
40
|
-
|
40
|
+
inclusion_in, message = @input.inclusion.values_at(:in, :message)
|
41
|
+
|
42
|
+
return if inclusion_in.nil?
|
43
|
+
return if inclusion_in.include?(@value)
|
41
44
|
|
42
45
|
add_error(
|
43
|
-
DEFAULT_MESSAGE,
|
46
|
+
message.presence || DEFAULT_MESSAGE,
|
44
47
|
service_class_name: @context.class.name,
|
45
48
|
input: @input,
|
46
49
|
value: @value
|