servactory 2.0.0.rc2 → 2.0.0.rc3
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/config/locales/en.yml +2 -1
- data/config/locales/ru.yml +2 -1
- data/lib/servactory/inputs/validations/base.rb +1 -1
- data/lib/servactory/inputs/validations/inclusion.rb +1 -1
- data/lib/servactory/inputs/validations/must.rb +2 -2
- data/lib/servactory/inputs/validations/required.rb +1 -1
- data/lib/servactory/inputs/validations/type.rb +13 -114
- data/lib/servactory/internals/validations/base.rb +1 -1
- data/lib/servactory/internals/validations/type.rb +6 -124
- data/lib/servactory/maintenance/validations/collection.rb +66 -0
- data/lib/servactory/maintenance/validations/object_schema.rb +14 -17
- data/lib/servactory/maintenance/validations/types.rb +164 -0
- data/lib/servactory/outputs/validations/base.rb +1 -1
- data/lib/servactory/outputs/validations/type.rb +6 -124
- data/lib/servactory/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cdc12e7e579fdacbd13a9d7d4997113023dd0f3acb9be1050bf88d3c83c324a9
|
4
|
+
data.tar.gz: dbfb8137159dce0ae2fa37a143b9a7b75d1f6a758852fd580567615aa1081bc3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7696c3a4c46fc4dc72980fcb513d39a0a7f69a5e64d4ec2e6244f3c4f950e27cf25faa583c2b1a36dda2d91b33402588a24fc64d294b3fc83bd3f3bc227fcc1
|
7
|
+
data.tar.gz: 0531261cbd2a5e9b0af78c7775cbf08cd45f635b328788510d435bdaf361080931f4f6c7b3d1953e8538288c276fc35a4383e9276bc015ef88600f6591e49593
|
data/config/locales/en.yml
CHANGED
@@ -17,7 +17,8 @@ en:
|
|
17
17
|
type:
|
18
18
|
default_error:
|
19
19
|
default: "[%{service_class_name}] Wrong type of input `%{input_name}`, expected `%{expected_type}`, got `%{given_type}`"
|
20
|
-
for_collection:
|
20
|
+
for_collection:
|
21
|
+
wrong_element_type: "[%{service_class_name}] Wrong type in input collection `%{input_name}`, expected `%{expected_type}`, got `%{given_type}`"
|
21
22
|
for_hash:
|
22
23
|
wrong_element_type: "[%{service_class_name}] Wrong type in input hash `%{input_name}`, expected `%{expected_type}` for `%{key_name}`, got `%{given_type}`"
|
23
24
|
tools:
|
data/config/locales/ru.yml
CHANGED
@@ -17,7 +17,8 @@ ru:
|
|
17
17
|
type:
|
18
18
|
default_error:
|
19
19
|
default: "[%{service_class_name}] Неправильный тип инпута `%{input_name}`, ожидалось `%{expected_type}`, получено `%{given_type}`"
|
20
|
-
for_collection:
|
20
|
+
for_collection:
|
21
|
+
wrong_element_type: "[%{service_class_name}] Неправильный тип в коллекции инпута `%{input_name}`, ожидалось `%{expected_type}`, получено `%{given_type}`"
|
21
22
|
for_hash:
|
22
23
|
wrong_element_type: "[%{service_class_name}] Неправильный тип в хеше инпута `%{input_name}`, для `%{key_name}` ожидалось `%{expected_type}`, получено `%{given_type}`"
|
23
24
|
|
@@ -75,7 +75,7 @@ module Servactory
|
|
75
75
|
|
76
76
|
def add_error_with(message, code)
|
77
77
|
add_error(
|
78
|
-
message,
|
78
|
+
message: message,
|
79
79
|
service_class_name: @context.class.name,
|
80
80
|
input: @input,
|
81
81
|
value: @input.value,
|
@@ -85,7 +85,7 @@ module Servactory
|
|
85
85
|
|
86
86
|
def add_syntax_error_with(message, code, exception_message)
|
87
87
|
add_error(
|
88
|
-
message,
|
88
|
+
message: message,
|
89
89
|
service_class_name: @context.class.name,
|
90
90
|
input: @input,
|
91
91
|
value: @input.value,
|
@@ -3,50 +3,11 @@
|
|
3
3
|
module Servactory
|
4
4
|
module Inputs
|
5
5
|
module Validations
|
6
|
-
class Type < Base
|
7
|
-
|
8
|
-
if input.collection_mode?
|
9
|
-
collection_message = input.consists_of.fetch(:message)
|
10
|
-
|
11
|
-
if collection_message.is_a?(Proc)
|
12
|
-
collection_message.call(input: input, expected_type: expected_type)
|
13
|
-
elsif collection_message.is_a?(String) && collection_message.present?
|
14
|
-
collection_message
|
15
|
-
else
|
16
|
-
I18n.t(
|
17
|
-
"servactory.inputs.checks.type.default_error.for_collection",
|
18
|
-
service_class_name: service_class_name,
|
19
|
-
input_name: input.name,
|
20
|
-
expected_type: expected_type,
|
21
|
-
given_type: given_type
|
22
|
-
)
|
23
|
-
end
|
24
|
-
elsif input.hash_mode? && key_name.present?
|
25
|
-
I18n.t(
|
26
|
-
"servactory.inputs.checks.type.default_error.for_hash.wrong_element_type",
|
27
|
-
service_class_name: service_class_name,
|
28
|
-
input_name: input.name,
|
29
|
-
key_name: key_name,
|
30
|
-
expected_type: expected_type,
|
31
|
-
given_type: given_type
|
32
|
-
)
|
33
|
-
else
|
34
|
-
I18n.t(
|
35
|
-
"servactory.inputs.checks.type.default_error.default",
|
36
|
-
service_class_name: service_class_name,
|
37
|
-
input_name: input.name,
|
38
|
-
expected_type: expected_type,
|
39
|
-
given_type: given_type
|
40
|
-
)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
private_constant :DEFAULT_MESSAGE
|
45
|
-
|
46
|
-
def self.check(context:, input:, check_key:, check_options:)
|
6
|
+
class Type < Base
|
7
|
+
def self.check(context:, input:, check_key:, **)
|
47
8
|
return unless should_be_checked_for?(input, check_key)
|
48
9
|
|
49
|
-
new(context: context, input: input
|
10
|
+
new(context: context, input: input).check
|
50
11
|
end
|
51
12
|
|
52
13
|
def self.should_be_checked_for?(input, check_key)
|
@@ -59,62 +20,24 @@ module Servactory
|
|
59
20
|
)
|
60
21
|
end
|
61
22
|
|
62
|
-
|
63
|
-
|
64
|
-
def initialize(context:, input:, types:)
|
23
|
+
def initialize(context:, input:)
|
65
24
|
super()
|
66
25
|
|
67
26
|
@context = context
|
68
27
|
@input = input
|
69
|
-
@types = types
|
70
|
-
end
|
71
|
-
|
72
|
-
def check # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
73
|
-
object_schema_validator = nil
|
74
|
-
|
75
|
-
return if prepared_types.any? do |type|
|
76
|
-
if @input.collection_mode?
|
77
|
-
prepared_value.is_a?(@types.fetch(0, Array)) &&
|
78
|
-
prepared_value.respond_to?(:all?) && prepared_value.all?(type)
|
79
|
-
elsif @input.hash_mode?
|
80
|
-
object_schema_validator = Servactory::Maintenance::Validations::ObjectSchema.validate(
|
81
|
-
object: prepared_value,
|
82
|
-
schema: @input.schema
|
83
|
-
)
|
84
|
-
|
85
|
-
object_schema_validator.valid?
|
86
|
-
else
|
87
|
-
prepared_value.is_a?(type)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
if (first_error = object_schema_validator&.errors&.first).present?
|
92
|
-
return add_default_object_error_with(first_error)
|
93
|
-
end
|
94
|
-
|
95
|
-
add_default_error
|
96
28
|
end
|
97
29
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
30
|
+
def check
|
31
|
+
Servactory::Maintenance::Validations::Types.validate!(
|
32
|
+
context: @context,
|
33
|
+
attribute: @input,
|
34
|
+
types: @input.types,
|
35
|
+
value: prepared_value,
|
36
|
+
error_callback: ->(**args) { add_error(**args) }
|
37
|
+
)
|
107
38
|
end
|
108
39
|
|
109
|
-
|
110
|
-
types.map do |type|
|
111
|
-
if type.is_a?(String)
|
112
|
-
Object.const_get(type)
|
113
|
-
else
|
114
|
-
type
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
40
|
+
private
|
118
41
|
|
119
42
|
def prepared_value
|
120
43
|
@prepared_value ||= if @input.optional? && !@input.default.nil? && @input.value.blank?
|
@@ -123,30 +46,6 @@ module Servactory
|
|
123
46
|
@input.value
|
124
47
|
end
|
125
48
|
end
|
126
|
-
|
127
|
-
private
|
128
|
-
|
129
|
-
def add_default_object_error_with(error)
|
130
|
-
add_error(
|
131
|
-
DEFAULT_MESSAGE,
|
132
|
-
service_class_name: @context.class.name,
|
133
|
-
input: @input,
|
134
|
-
key_name: error.fetch(:name),
|
135
|
-
expected_type: error.fetch(:expected_type),
|
136
|
-
given_type: error.fetch(:given_type)
|
137
|
-
)
|
138
|
-
end
|
139
|
-
|
140
|
-
def add_default_error
|
141
|
-
add_error(
|
142
|
-
DEFAULT_MESSAGE,
|
143
|
-
service_class_name: @context.class.name,
|
144
|
-
input: @input,
|
145
|
-
key_name: nil,
|
146
|
-
expected_type: prepared_types.join(", "),
|
147
|
-
given_type: prepared_value.class.name
|
148
|
-
)
|
149
|
-
end
|
150
49
|
end
|
151
50
|
end
|
152
51
|
end
|
@@ -6,7 +6,7 @@ module Servactory
|
|
6
6
|
class Base
|
7
7
|
protected
|
8
8
|
|
9
|
-
def raise_error_with(message
|
9
|
+
def raise_error_with(message:, **attributes)
|
10
10
|
message = message.call(**attributes) if message.is_a?(Proc)
|
11
11
|
|
12
12
|
raise @context.class.config.internal_error_class.new(message: message)
|
@@ -4,65 +4,10 @@ module Servactory
|
|
4
4
|
module Internals
|
5
5
|
module Validations
|
6
6
|
class Type < Base
|
7
|
-
DEFAULT_MESSAGE = lambda do |service_class_name:, internal:, value:, key_name:, expected_type:, given_type:| # rubocop:disable Metrics/BlockLength
|
8
|
-
if internal.collection_mode?
|
9
|
-
collection_message = internal.consists_of.fetch(:message)
|
10
|
-
|
11
|
-
if collection_message.is_a?(Proc)
|
12
|
-
collection_message.call(internal: internal, expected_type: expected_type)
|
13
|
-
elsif collection_message.is_a?(String) && collection_message.present?
|
14
|
-
collection_message
|
15
|
-
elsif value.is_a?(internal.types.fetch(0, Array))
|
16
|
-
I18n.t(
|
17
|
-
"servactory.internals.checks.type.default_error.for_collection.wrong_element_type",
|
18
|
-
service_class_name: service_class_name,
|
19
|
-
internal_name: internal.name,
|
20
|
-
expected_type: expected_type,
|
21
|
-
given_type: given_type
|
22
|
-
)
|
23
|
-
else
|
24
|
-
I18n.t(
|
25
|
-
"servactory.internals.checks.type.default_error.for_collection.wrong_type",
|
26
|
-
service_class_name: service_class_name,
|
27
|
-
internal_name: internal.name,
|
28
|
-
expected_type: internal.types.fetch(0, Array),
|
29
|
-
given_type: value.class.name
|
30
|
-
)
|
31
|
-
end
|
32
|
-
elsif internal.hash_mode? && key_name.present?
|
33
|
-
I18n.t(
|
34
|
-
"servactory.internals.checks.type.default_error.for_hash.wrong_element_type",
|
35
|
-
service_class_name: service_class_name,
|
36
|
-
internal_name: internal.name,
|
37
|
-
key_name: key_name,
|
38
|
-
expected_type: expected_type,
|
39
|
-
given_type: given_type
|
40
|
-
)
|
41
|
-
else
|
42
|
-
I18n.t(
|
43
|
-
"servactory.internals.checks.type.default_error.default",
|
44
|
-
service_class_name: service_class_name,
|
45
|
-
internal_name: internal.name,
|
46
|
-
expected_type: expected_type,
|
47
|
-
given_type: given_type
|
48
|
-
)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
private_constant :DEFAULT_MESSAGE
|
53
|
-
|
54
7
|
def self.validate!(...)
|
55
|
-
return unless should_be_checked?
|
56
|
-
|
57
8
|
new(...).validate!
|
58
9
|
end
|
59
10
|
|
60
|
-
def self.should_be_checked?
|
61
|
-
true
|
62
|
-
end
|
63
|
-
|
64
|
-
##########################################################################
|
65
|
-
|
66
11
|
def initialize(context:, internal:, value:)
|
67
12
|
super()
|
68
13
|
|
@@ -71,76 +16,13 @@ module Servactory
|
|
71
16
|
@value = value
|
72
17
|
end
|
73
18
|
|
74
|
-
def validate!
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
@value.is_a?(@internal.types.fetch(0, Array)) &&
|
80
|
-
@value.respond_to?(:all?) && @value.all?(type)
|
81
|
-
elsif @internal.hash_mode?
|
82
|
-
object_schema_validator = Servactory::Maintenance::Validations::ObjectSchema.validate(
|
83
|
-
object: @value,
|
84
|
-
schema: @internal.schema
|
85
|
-
)
|
86
|
-
|
87
|
-
object_schema_validator.valid?
|
88
|
-
else
|
89
|
-
@value.is_a?(type)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
if (first_error = object_schema_validator&.errors&.first).present?
|
94
|
-
raise_default_object_error_with(first_error)
|
95
|
-
end
|
96
|
-
|
97
|
-
raise_default_error
|
98
|
-
end
|
99
|
-
|
100
|
-
private
|
101
|
-
|
102
|
-
def prepared_types
|
103
|
-
@prepared_types ||=
|
104
|
-
if @internal.collection_mode?
|
105
|
-
prepared_types_from(Array(@internal.consists_of.fetch(:type, [])))
|
106
|
-
else
|
107
|
-
prepared_types_from(@internal.types)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def prepared_types_from(types)
|
112
|
-
types.map do |type|
|
113
|
-
if type.is_a?(String)
|
114
|
-
Object.const_get(type)
|
115
|
-
else
|
116
|
-
type
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
########################################################################
|
122
|
-
|
123
|
-
def raise_default_object_error_with(error)
|
124
|
-
raise_error_with(
|
125
|
-
DEFAULT_MESSAGE,
|
126
|
-
service_class_name: @context.class.name,
|
127
|
-
internal: @internal,
|
128
|
-
value: @value,
|
129
|
-
key_name: error.fetch(:name),
|
130
|
-
expected_type: error.fetch(:expected_type),
|
131
|
-
given_type: error.fetch(:given_type)
|
132
|
-
)
|
133
|
-
end
|
134
|
-
|
135
|
-
def raise_default_error
|
136
|
-
raise_error_with(
|
137
|
-
DEFAULT_MESSAGE,
|
138
|
-
service_class_name: @context.class.name,
|
139
|
-
internal: @internal,
|
19
|
+
def validate!
|
20
|
+
Servactory::Maintenance::Validations::Types.validate!(
|
21
|
+
context: @context,
|
22
|
+
attribute: @internal,
|
23
|
+
types: @internal.types,
|
140
24
|
value: @value,
|
141
|
-
|
142
|
-
expected_type: prepared_types.join(", "),
|
143
|
-
given_type: @value.class.name
|
25
|
+
error_callback: ->(**args) { raise_error_with(**args) }
|
144
26
|
)
|
145
27
|
end
|
146
28
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Maintenance
|
5
|
+
module Validations
|
6
|
+
class Collection
|
7
|
+
attr_reader :errors
|
8
|
+
|
9
|
+
def self.validate(...)
|
10
|
+
new(...).validate
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(value:, types:, type:)
|
14
|
+
@value = value
|
15
|
+
@types = types
|
16
|
+
@type = type
|
17
|
+
|
18
|
+
@errors = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def validate
|
22
|
+
unless @value.is_a?(prepared_type)
|
23
|
+
add_error(
|
24
|
+
expected_type: prepared_type.name,
|
25
|
+
given_type: @value.class.name
|
26
|
+
)
|
27
|
+
|
28
|
+
return self
|
29
|
+
end
|
30
|
+
|
31
|
+
validate_value!
|
32
|
+
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def valid?
|
37
|
+
@errors.empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def prepared_type
|
43
|
+
@prepared_type ||= @types.fetch(0, Array)
|
44
|
+
end
|
45
|
+
|
46
|
+
def validate_value!
|
47
|
+
@value.each do |value_item|
|
48
|
+
next if value_item.is_a?(@type)
|
49
|
+
|
50
|
+
add_error(
|
51
|
+
expected_type: @type,
|
52
|
+
given_type: value_item.class.name
|
53
|
+
)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_error(expected_type:, given_type:)
|
58
|
+
@errors << {
|
59
|
+
expected_type: expected_type,
|
60
|
+
given_type: given_type
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -17,29 +17,28 @@ module Servactory
|
|
17
17
|
@object = object
|
18
18
|
@schema = schema
|
19
19
|
|
20
|
-
@valid = false
|
21
20
|
@errors = []
|
22
21
|
end
|
23
22
|
|
24
23
|
def validate
|
25
|
-
|
24
|
+
validate_for(object: @object, schema: @schema)
|
26
25
|
|
27
26
|
self
|
28
27
|
end
|
29
28
|
|
30
29
|
def valid?
|
31
|
-
@
|
30
|
+
@errors.empty?
|
32
31
|
end
|
33
32
|
|
34
33
|
private
|
35
34
|
|
36
|
-
def validate_for(object:, schema:, root_schema_key: nil) # rubocop:disable Metrics/MethodLength
|
35
|
+
def validate_for(object:, schema:, root_schema_key: nil) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
37
36
|
unless object.respond_to?(:fetch)
|
38
|
-
add_error(
|
39
|
-
return
|
37
|
+
add_error(key_name: root_schema_key, expected_type: Hash.name, given_type: object.class.name)
|
38
|
+
return
|
40
39
|
end
|
41
40
|
|
42
|
-
schema.
|
41
|
+
schema.each do |schema_key, schema_value|
|
43
42
|
attribute_type = schema_value.fetch(:type, String)
|
44
43
|
|
45
44
|
if attribute_type == Hash
|
@@ -57,15 +56,13 @@ module Servactory
|
|
57
56
|
attribute_required: schema_value.fetch(:required, true)
|
58
57
|
)
|
59
58
|
|
60
|
-
|
61
|
-
add_error(
|
62
|
-
name: schema_key,
|
63
|
-
expected_type: attribute_type,
|
64
|
-
given_type: object.fetch(schema_key, nil).class
|
65
|
-
)
|
66
|
-
end
|
59
|
+
next if is_success
|
67
60
|
|
68
|
-
|
61
|
+
add_error(
|
62
|
+
key_name: schema_key,
|
63
|
+
expected_type: attribute_type,
|
64
|
+
given_type: object.fetch(schema_key, nil).class.name
|
65
|
+
)
|
69
66
|
end
|
70
67
|
end
|
71
68
|
end
|
@@ -106,9 +103,9 @@ module Servactory
|
|
106
103
|
value.fetch(:default, nil)
|
107
104
|
end
|
108
105
|
|
109
|
-
def add_error(
|
106
|
+
def add_error(key_name:, expected_type:, given_type:)
|
110
107
|
@errors << {
|
111
|
-
|
108
|
+
key_name: key_name,
|
112
109
|
expected_type: expected_type,
|
113
110
|
given_type: given_type
|
114
111
|
}
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Maintenance
|
5
|
+
module Validations
|
6
|
+
class Types # rubocop:disable Metrics/ClassLength
|
7
|
+
DEFAULT_MESSAGE = lambda do | # rubocop:disable Metrics/BlockLength
|
8
|
+
service_class_name:,
|
9
|
+
attribute_system_name:,
|
10
|
+
attribute:,
|
11
|
+
value:,
|
12
|
+
key_name:,
|
13
|
+
expected_type:,
|
14
|
+
given_type:
|
15
|
+
| # do
|
16
|
+
if attribute.collection_mode?
|
17
|
+
collection_message = attribute.consists_of.fetch(:message)
|
18
|
+
|
19
|
+
if collection_message.is_a?(Proc)
|
20
|
+
collection_message.call(attribute_system_name => attribute, expected_type: expected_type)
|
21
|
+
elsif collection_message.is_a?(String) && collection_message.present?
|
22
|
+
collection_message
|
23
|
+
elsif value.is_a?(attribute.types.fetch(0, Array))
|
24
|
+
I18n.t(
|
25
|
+
"servactory.#{attribute_system_name.to_s.pluralize}.checks.type.default_error.for_collection.wrong_element_type", # rubocop:disable Layout/LineLength
|
26
|
+
service_class_name: service_class_name,
|
27
|
+
"#{attribute_system_name}_name": attribute.name,
|
28
|
+
expected_type: expected_type,
|
29
|
+
given_type: given_type
|
30
|
+
)
|
31
|
+
else
|
32
|
+
I18n.t(
|
33
|
+
"servactory.#{attribute_system_name.to_s.pluralize}.checks.type.default_error.for_collection.wrong_type", # rubocop:disable Layout/LineLength
|
34
|
+
service_class_name: service_class_name,
|
35
|
+
"#{attribute_system_name}_name": attribute.name,
|
36
|
+
expected_type: attribute.types.fetch(0, Array),
|
37
|
+
given_type: value.class.name
|
38
|
+
)
|
39
|
+
end
|
40
|
+
elsif attribute.hash_mode? && key_name.present?
|
41
|
+
I18n.t(
|
42
|
+
"servactory.#{attribute_system_name.to_s.pluralize}.checks.type.default_error.for_hash.wrong_element_type", # rubocop:disable Layout/LineLength
|
43
|
+
service_class_name: service_class_name,
|
44
|
+
"#{attribute_system_name}_name": attribute.name,
|
45
|
+
key_name: key_name,
|
46
|
+
expected_type: expected_type,
|
47
|
+
given_type: given_type
|
48
|
+
)
|
49
|
+
else
|
50
|
+
I18n.t(
|
51
|
+
"servactory.#{attribute_system_name.to_s.pluralize}.checks.type.default_error.default",
|
52
|
+
service_class_name: service_class_name,
|
53
|
+
"#{attribute_system_name}_name": attribute.name,
|
54
|
+
expected_type: expected_type,
|
55
|
+
given_type: given_type
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private_constant :DEFAULT_MESSAGE
|
61
|
+
|
62
|
+
def self.validate!(...)
|
63
|
+
new(...).validate!
|
64
|
+
end
|
65
|
+
|
66
|
+
def initialize(context:, attribute:, types:, value:, error_callback:)
|
67
|
+
@context = context
|
68
|
+
@attribute = attribute
|
69
|
+
@types = types
|
70
|
+
@value = value
|
71
|
+
@error_callback = error_callback
|
72
|
+
end
|
73
|
+
|
74
|
+
def validate! # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
75
|
+
collection_validator = nil
|
76
|
+
object_schema_validator = nil
|
77
|
+
|
78
|
+
return if prepared_types.any? do |type|
|
79
|
+
if @attribute.collection_mode?
|
80
|
+
collection_validator = Servactory::Maintenance::Validations::Collection.validate(
|
81
|
+
value: @value,
|
82
|
+
types: @attribute.types,
|
83
|
+
type: type
|
84
|
+
)
|
85
|
+
|
86
|
+
collection_validator.valid?
|
87
|
+
elsif @attribute.hash_mode?
|
88
|
+
object_schema_validator = Servactory::Maintenance::Validations::ObjectSchema.validate(
|
89
|
+
object: @value,
|
90
|
+
schema: @attribute.schema
|
91
|
+
)
|
92
|
+
|
93
|
+
object_schema_validator.valid?
|
94
|
+
else
|
95
|
+
@value.is_a?(type)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
if (first_error = collection_validator&.errors&.first).present?
|
100
|
+
return @error_callback.call(
|
101
|
+
message: DEFAULT_MESSAGE,
|
102
|
+
service_class_name: @context.class.name,
|
103
|
+
attribute_system_name: attribute_system_name,
|
104
|
+
attribute: @attribute,
|
105
|
+
value: @value,
|
106
|
+
key_name: nil,
|
107
|
+
expected_type: first_error.fetch(:expected_type),
|
108
|
+
given_type: first_error.fetch(:given_type)
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
if (first_error = object_schema_validator&.errors&.first).present?
|
113
|
+
return @error_callback.call(
|
114
|
+
message: DEFAULT_MESSAGE,
|
115
|
+
service_class_name: @context.class.name,
|
116
|
+
attribute_system_name: attribute_system_name,
|
117
|
+
attribute: @attribute,
|
118
|
+
value: @value,
|
119
|
+
key_name: first_error.fetch(:key_name),
|
120
|
+
expected_type: first_error.fetch(:expected_type),
|
121
|
+
given_type: first_error.fetch(:given_type)
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
@error_callback.call(
|
126
|
+
message: DEFAULT_MESSAGE,
|
127
|
+
service_class_name: @context.class.name,
|
128
|
+
attribute_system_name: attribute_system_name,
|
129
|
+
attribute: @attribute,
|
130
|
+
value: @value,
|
131
|
+
key_name: nil,
|
132
|
+
expected_type: prepared_types.join(", "),
|
133
|
+
given_type: @value.class.name
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def attribute_system_name
|
140
|
+
@attribute.class.name.demodulize.downcase.to_sym
|
141
|
+
end
|
142
|
+
|
143
|
+
def prepared_types
|
144
|
+
@prepared_types ||=
|
145
|
+
if @attribute.collection_mode?
|
146
|
+
prepared_types_from(Array(@attribute.consists_of.fetch(:type, [])))
|
147
|
+
else
|
148
|
+
prepared_types_from(@types)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def prepared_types_from(types)
|
153
|
+
types.map do |type|
|
154
|
+
if type.is_a?(String)
|
155
|
+
Object.const_get(type)
|
156
|
+
else
|
157
|
+
type
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -6,7 +6,7 @@ module Servactory
|
|
6
6
|
class Base
|
7
7
|
protected
|
8
8
|
|
9
|
-
def raise_error_with(message
|
9
|
+
def raise_error_with(message:, **attributes)
|
10
10
|
message = message.call(**attributes) if message.is_a?(Proc)
|
11
11
|
|
12
12
|
raise @context.class.config.output_error_class.new(message: message)
|
@@ -4,65 +4,10 @@ module Servactory
|
|
4
4
|
module Outputs
|
5
5
|
module Validations
|
6
6
|
class Type < Base
|
7
|
-
DEFAULT_MESSAGE = lambda do |service_class_name:, output:, value:, key_name:, expected_type:, given_type:| # rubocop:disable Metrics/BlockLength
|
8
|
-
if output.collection_mode?
|
9
|
-
collection_message = output.consists_of.fetch(:message)
|
10
|
-
|
11
|
-
if collection_message.is_a?(Proc)
|
12
|
-
collection_message.call(output: output, expected_type: expected_type)
|
13
|
-
elsif collection_message.is_a?(String) && collection_message.present?
|
14
|
-
collection_message
|
15
|
-
elsif value.is_a?(output.types.fetch(0, Array))
|
16
|
-
I18n.t(
|
17
|
-
"servactory.outputs.checks.type.default_error.for_collection.wrong_element_type",
|
18
|
-
service_class_name: service_class_name,
|
19
|
-
output_name: output.name,
|
20
|
-
expected_type: expected_type,
|
21
|
-
given_type: given_type
|
22
|
-
)
|
23
|
-
else
|
24
|
-
I18n.t(
|
25
|
-
"servactory.outputs.checks.type.default_error.for_collection.wrong_type",
|
26
|
-
service_class_name: service_class_name,
|
27
|
-
output_name: output.name,
|
28
|
-
expected_type: output.types.fetch(0, Array),
|
29
|
-
given_type: value.class.name
|
30
|
-
)
|
31
|
-
end
|
32
|
-
elsif output.hash_mode? && key_name.present?
|
33
|
-
I18n.t(
|
34
|
-
"servactory.outputs.checks.type.default_error.for_hash.wrong_element_type",
|
35
|
-
service_class_name: service_class_name,
|
36
|
-
output_name: output.name,
|
37
|
-
key_name: key_name,
|
38
|
-
expected_type: expected_type,
|
39
|
-
given_type: given_type
|
40
|
-
)
|
41
|
-
else
|
42
|
-
I18n.t(
|
43
|
-
"servactory.outputs.checks.type.default_error.default",
|
44
|
-
service_class_name: service_class_name,
|
45
|
-
output_name: output.name,
|
46
|
-
expected_type: expected_type,
|
47
|
-
given_type: given_type
|
48
|
-
)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
private_constant :DEFAULT_MESSAGE
|
53
|
-
|
54
7
|
def self.validate!(...)
|
55
|
-
return unless should_be_checked?
|
56
|
-
|
57
8
|
new(...).validate!
|
58
9
|
end
|
59
10
|
|
60
|
-
def self.should_be_checked?
|
61
|
-
true
|
62
|
-
end
|
63
|
-
|
64
|
-
##########################################################################
|
65
|
-
|
66
11
|
def initialize(context:, output:, value:)
|
67
12
|
super()
|
68
13
|
|
@@ -71,76 +16,13 @@ module Servactory
|
|
71
16
|
@value = value
|
72
17
|
end
|
73
18
|
|
74
|
-
def validate!
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
@value.is_a?(@output.types.fetch(0, Array)) &&
|
80
|
-
@value.respond_to?(:all?) && @value.all?(type)
|
81
|
-
elsif @output.hash_mode?
|
82
|
-
object_schema_validator = Servactory::Maintenance::Validations::ObjectSchema.validate(
|
83
|
-
object: @value,
|
84
|
-
schema: @output.schema
|
85
|
-
)
|
86
|
-
|
87
|
-
object_schema_validator.valid?
|
88
|
-
else
|
89
|
-
@value.is_a?(type)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
if (first_error = object_schema_validator&.errors&.first).present?
|
94
|
-
raise_default_object_error_with(first_error)
|
95
|
-
end
|
96
|
-
|
97
|
-
raise_default_error
|
98
|
-
end
|
99
|
-
|
100
|
-
private
|
101
|
-
|
102
|
-
def prepared_types
|
103
|
-
@prepared_types ||=
|
104
|
-
if @output.collection_mode?
|
105
|
-
prepared_types_from(Array(@output.consists_of.fetch(:type, [])))
|
106
|
-
else
|
107
|
-
prepared_types_from(@output.types)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def prepared_types_from(types)
|
112
|
-
types.map do |type|
|
113
|
-
if type.is_a?(String)
|
114
|
-
Object.const_get(type)
|
115
|
-
else
|
116
|
-
type
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
########################################################################
|
122
|
-
|
123
|
-
def raise_default_object_error_with(error)
|
124
|
-
raise_error_with(
|
125
|
-
DEFAULT_MESSAGE,
|
126
|
-
service_class_name: @context.class.name,
|
127
|
-
output: @output,
|
128
|
-
value: @value,
|
129
|
-
key_name: error.fetch(:name),
|
130
|
-
expected_type: error.fetch(:expected_type),
|
131
|
-
given_type: error.fetch(:given_type)
|
132
|
-
)
|
133
|
-
end
|
134
|
-
|
135
|
-
def raise_default_error
|
136
|
-
raise_error_with(
|
137
|
-
DEFAULT_MESSAGE,
|
138
|
-
service_class_name: @context.class.name,
|
139
|
-
output: @output,
|
19
|
+
def validate!
|
20
|
+
Servactory::Maintenance::Validations::Types.validate!(
|
21
|
+
context: @context,
|
22
|
+
attribute: @output,
|
23
|
+
types: @output.types,
|
140
24
|
value: @value,
|
141
|
-
|
142
|
-
expected_type: prepared_types.join(", "),
|
143
|
-
given_type: @value.class.name
|
25
|
+
error_callback: ->(**args) { raise_error_with(**args) }
|
144
26
|
)
|
145
27
|
end
|
146
28
|
end
|
data/lib/servactory/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: servactory
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.rc3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anton Sokolov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-10-
|
11
|
+
date: 2023-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -251,7 +251,9 @@ files:
|
|
251
251
|
- lib/servactory/maintenance/attributes/options_collection.rb
|
252
252
|
- lib/servactory/maintenance/collection_mode/class_names_collection.rb
|
253
253
|
- lib/servactory/maintenance/hash_mode/class_names_collection.rb
|
254
|
+
- lib/servactory/maintenance/validations/collection.rb
|
254
255
|
- lib/servactory/maintenance/validations/object_schema.rb
|
256
|
+
- lib/servactory/maintenance/validations/types.rb
|
255
257
|
- lib/servactory/methods/aliases_for_make/collection.rb
|
256
258
|
- lib/servactory/methods/dsl.rb
|
257
259
|
- lib/servactory/methods/method.rb
|