dry-validation 0.13.3 → 1.3.1
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 +233 -12
- data/LICENSE +1 -1
- data/README.md +13 -9
- data/config/errors.yml +3 -88
- data/lib/dry-validation.rb +2 -0
- data/lib/dry/validation.rb +47 -28
- data/lib/dry/validation/config.rb +24 -0
- data/lib/dry/validation/constants.rb +43 -0
- data/lib/dry/validation/contract.rb +160 -0
- data/lib/dry/validation/contract/class_interface.rb +223 -0
- data/lib/dry/validation/evaluator.rb +197 -0
- data/lib/dry/validation/extensions/hints.rb +69 -0
- data/lib/dry/validation/extensions/monads.rb +23 -7
- data/lib/dry/validation/extensions/predicates_as_macros.rb +75 -0
- data/lib/dry/validation/failures.rb +58 -0
- data/lib/dry/validation/function.rb +44 -0
- data/lib/dry/validation/macro.rb +38 -0
- data/lib/dry/validation/macros.rb +104 -0
- data/lib/dry/validation/message.rb +79 -79
- data/lib/dry/validation/message_set.rb +108 -88
- data/lib/dry/validation/messages/resolver.rb +79 -0
- data/lib/dry/validation/result.rb +154 -42
- data/lib/dry/validation/rule.rb +129 -0
- data/lib/dry/validation/schema_ext.rb +46 -0
- data/lib/dry/validation/values.rb +94 -0
- data/lib/dry/validation/version.rb +3 -1
- metadata +41 -336
- data/.codeclimate.yml +0 -17
- data/.gitignore +0 -9
- data/.rspec +0 -3
- data/.travis.yml +0 -29
- data/CONTRIBUTING.md +0 -31
- data/Gemfile +0 -25
- data/Rakefile +0 -22
- data/benchmarks/benchmark_form_invalid.rb +0 -64
- data/benchmarks/benchmark_form_valid.rb +0 -64
- data/benchmarks/benchmark_schema_invalid_huge.rb +0 -52
- data/benchmarks/profile_schema_call_invalid.rb +0 -20
- data/benchmarks/profile_schema_call_valid.rb +0 -20
- data/benchmarks/profile_schema_definition.rb +0 -14
- data/benchmarks/profile_schema_huge_invalid.rb +0 -30
- data/benchmarks/profile_schema_messages_invalid.rb +0 -20
- data/benchmarks/suite.rb +0 -5
- data/dry-validation.gemspec +0 -28
- data/examples/basic.rb +0 -15
- data/examples/each.rb +0 -14
- data/examples/json.rb +0 -12
- data/examples/multiple.rb +0 -27
- data/examples/nested.rb +0 -22
- data/examples/params.rb +0 -11
- data/lib/dry/validation/compat/form.rb +0 -67
- data/lib/dry/validation/deprecations.rb +0 -24
- data/lib/dry/validation/executor.rb +0 -91
- data/lib/dry/validation/extensions.rb +0 -7
- data/lib/dry/validation/extensions/struct.rb +0 -32
- data/lib/dry/validation/input_processor_compiler.rb +0 -137
- data/lib/dry/validation/input_processor_compiler/json.rb +0 -45
- data/lib/dry/validation/input_processor_compiler/params.rb +0 -49
- data/lib/dry/validation/input_processor_compiler/sanitizer.rb +0 -47
- data/lib/dry/validation/message_compiler.rb +0 -188
- data/lib/dry/validation/message_compiler/visitor_opts.rb +0 -37
- data/lib/dry/validation/messages.rb +0 -14
- data/lib/dry/validation/messages/abstract.rb +0 -119
- data/lib/dry/validation/messages/i18n.rb +0 -47
- data/lib/dry/validation/messages/namespaced.rb +0 -39
- data/lib/dry/validation/messages/yaml.rb +0 -61
- data/lib/dry/validation/predicate_registry.rb +0 -115
- data/lib/dry/validation/predicates.rb +0 -19
- data/lib/dry/validation/schema.rb +0 -126
- data/lib/dry/validation/schema/check.rb +0 -37
- data/lib/dry/validation/schema/class_interface.rb +0 -190
- data/lib/dry/validation/schema/deprecated.rb +0 -30
- data/lib/dry/validation/schema/dsl.rb +0 -118
- data/lib/dry/validation/schema/form.rb +0 -9
- data/lib/dry/validation/schema/json.rb +0 -21
- data/lib/dry/validation/schema/key.rb +0 -71
- data/lib/dry/validation/schema/params.rb +0 -22
- data/lib/dry/validation/schema/rule.rb +0 -202
- data/lib/dry/validation/schema/value.rb +0 -211
- data/lib/dry/validation/schema_compiler.rb +0 -81
- data/lib/dry/validation/template.rb +0 -66
- data/lib/dry/validation/type_specs.rb +0 -70
- data/spec/extensions/monads/result_spec.rb +0 -40
- data/spec/extensions/struct/schema_spec.rb +0 -32
- data/spec/fixtures/locales/en.yml +0 -8
- data/spec/fixtures/locales/pl.yml +0 -22
- data/spec/integration/custom_error_messages_spec.rb +0 -54
- data/spec/integration/custom_predicates_spec.rb +0 -228
- data/spec/integration/hints_spec.rb +0 -170
- data/spec/integration/injecting_rules_spec.rb +0 -30
- data/spec/integration/json/defining_base_schema_spec.rb +0 -41
- data/spec/integration/localized_error_messages_spec.rb +0 -72
- data/spec/integration/message_compiler_spec.rb +0 -405
- data/spec/integration/messages/i18n_spec.rb +0 -104
- data/spec/integration/optional_keys_spec.rb +0 -28
- data/spec/integration/params/predicates/array_spec.rb +0 -287
- data/spec/integration/params/predicates/empty_spec.rb +0 -263
- data/spec/integration/params/predicates/eql_spec.rb +0 -327
- data/spec/integration/params/predicates/even_spec.rb +0 -455
- data/spec/integration/params/predicates/excluded_from_spec.rb +0 -455
- data/spec/integration/params/predicates/excludes_spec.rb +0 -391
- data/spec/integration/params/predicates/false_spec.rb +0 -455
- data/spec/integration/params/predicates/filled_spec.rb +0 -467
- data/spec/integration/params/predicates/format_spec.rb +0 -454
- data/spec/integration/params/predicates/gt_spec.rb +0 -519
- data/spec/integration/params/predicates/gteq_spec.rb +0 -519
- data/spec/integration/params/predicates/included_in_spec.rb +0 -455
- data/spec/integration/params/predicates/includes_spec.rb +0 -391
- data/spec/integration/params/predicates/key_spec.rb +0 -67
- data/spec/integration/params/predicates/lt_spec.rb +0 -519
- data/spec/integration/params/predicates/lteq_spec.rb +0 -519
- data/spec/integration/params/predicates/max_size_spec.rb +0 -391
- data/spec/integration/params/predicates/min_size_spec.rb +0 -391
- data/spec/integration/params/predicates/none_spec.rb +0 -265
- data/spec/integration/params/predicates/not_eql_spec.rb +0 -327
- data/spec/integration/params/predicates/odd_spec.rb +0 -455
- data/spec/integration/params/predicates/size/fixed_spec.rb +0 -393
- data/spec/integration/params/predicates/size/range_spec.rb +0 -396
- data/spec/integration/params/predicates/true_spec.rb +0 -455
- data/spec/integration/params/predicates/type_spec.rb +0 -391
- data/spec/integration/result_spec.rb +0 -81
- data/spec/integration/schema/array_schema_spec.rb +0 -59
- data/spec/integration/schema/check_rules_spec.rb +0 -119
- data/spec/integration/schema/check_with_nested_el_spec.rb +0 -37
- data/spec/integration/schema/check_with_nth_el_spec.rb +0 -25
- data/spec/integration/schema/default_settings_spec.rb +0 -11
- data/spec/integration/schema/defining_base_schema_spec.rb +0 -41
- data/spec/integration/schema/dynamic_predicate_args_spec.rb +0 -43
- data/spec/integration/schema/each_with_set_spec.rb +0 -70
- data/spec/integration/schema/extending_dsl_spec.rb +0 -27
- data/spec/integration/schema/form_spec.rb +0 -236
- data/spec/integration/schema/hash_schema_spec.rb +0 -47
- data/spec/integration/schema/inheriting_schema_spec.rb +0 -31
- data/spec/integration/schema/input_processor_spec.rb +0 -46
- data/spec/integration/schema/json/explicit_types_spec.rb +0 -157
- data/spec/integration/schema/json_spec.rb +0 -163
- data/spec/integration/schema/macros/confirmation_spec.rb +0 -35
- data/spec/integration/schema/macros/each_spec.rb +0 -268
- data/spec/integration/schema/macros/filled_spec.rb +0 -87
- data/spec/integration/schema/macros/input_spec.rb +0 -139
- data/spec/integration/schema/macros/maybe_spec.rb +0 -99
- data/spec/integration/schema/macros/rule_spec.rb +0 -75
- data/spec/integration/schema/macros/value_spec.rb +0 -119
- data/spec/integration/schema/macros/when_spec.rb +0 -62
- data/spec/integration/schema/nested_schemas_spec.rb +0 -236
- data/spec/integration/schema/nested_values_spec.rb +0 -46
- data/spec/integration/schema/not_spec.rb +0 -34
- data/spec/integration/schema/numbers_spec.rb +0 -19
- data/spec/integration/schema/option_with_default_spec.rb +0 -64
- data/spec/integration/schema/or_spec.rb +0 -87
- data/spec/integration/schema/params/defining_base_schema_spec.rb +0 -41
- data/spec/integration/schema/params/explicit_types_spec.rb +0 -195
- data/spec/integration/schema/params_spec.rb +0 -234
- data/spec/integration/schema/predicate_verification_spec.rb +0 -9
- data/spec/integration/schema/predicates/array_spec.rb +0 -295
- data/spec/integration/schema/predicates/custom_spec.rb +0 -103
- data/spec/integration/schema/predicates/empty_spec.rb +0 -263
- data/spec/integration/schema/predicates/eql_spec.rb +0 -327
- data/spec/integration/schema/predicates/even_spec.rb +0 -455
- data/spec/integration/schema/predicates/excluded_from/array_spec.rb +0 -459
- data/spec/integration/schema/predicates/excluded_from/range_spec.rb +0 -459
- data/spec/integration/schema/predicates/excludes_spec.rb +0 -391
- data/spec/integration/schema/predicates/filled_spec.rb +0 -467
- data/spec/integration/schema/predicates/format_spec.rb +0 -455
- data/spec/integration/schema/predicates/gt_spec.rb +0 -519
- data/spec/integration/schema/predicates/gteq_spec.rb +0 -519
- data/spec/integration/schema/predicates/hash_spec.rb +0 -69
- data/spec/integration/schema/predicates/included_in/array_spec.rb +0 -459
- data/spec/integration/schema/predicates/included_in/range_spec.rb +0 -459
- data/spec/integration/schema/predicates/includes_spec.rb +0 -391
- data/spec/integration/schema/predicates/key_spec.rb +0 -88
- data/spec/integration/schema/predicates/lt_spec.rb +0 -520
- data/spec/integration/schema/predicates/lteq_spec.rb +0 -519
- data/spec/integration/schema/predicates/max_size_spec.rb +0 -391
- data/spec/integration/schema/predicates/min_size_spec.rb +0 -391
- data/spec/integration/schema/predicates/none_spec.rb +0 -265
- data/spec/integration/schema/predicates/not_eql_spec.rb +0 -391
- data/spec/integration/schema/predicates/odd_spec.rb +0 -455
- data/spec/integration/schema/predicates/size/fixed_spec.rb +0 -398
- data/spec/integration/schema/predicates/size/range_spec.rb +0 -395
- data/spec/integration/schema/predicates/type_spec.rb +0 -413
- data/spec/integration/schema/reusing_schema_spec.rb +0 -33
- data/spec/integration/schema/using_types_spec.rb +0 -135
- data/spec/integration/schema/validate_spec.rb +0 -120
- data/spec/integration/schema/xor_spec.rb +0 -35
- data/spec/integration/schema_builders_spec.rb +0 -17
- data/spec/integration/schema_spec.rb +0 -173
- data/spec/shared/message_compiler.rb +0 -11
- data/spec/shared/predicate_helper.rb +0 -15
- data/spec/shared/rule_compiler.rb +0 -8
- data/spec/spec_helper.rb +0 -62
- data/spec/support/define_struct.rb +0 -25
- data/spec/support/matchers.rb +0 -38
- data/spec/support/mutant.rb +0 -9
- data/spec/support/predicates_integration.rb +0 -7
- data/spec/unit/input_processor_compiler/json_spec.rb +0 -283
- data/spec/unit/input_processor_compiler/params_spec.rb +0 -328
- data/spec/unit/message_compiler/visit_failure_spec.rb +0 -38
- data/spec/unit/message_compiler/visit_spec.rb +0 -16
- data/spec/unit/message_compiler_spec.rb +0 -7
- data/spec/unit/predicate_registry_spec.rb +0 -34
- data/spec/unit/schema/key_spec.rb +0 -38
- data/spec/unit/schema/rule_spec.rb +0 -42
- data/spec/unit/schema/value_spec.rb +0 -131
- data/spec/unit/schema_spec.rb +0 -35
@@ -1,170 +0,0 @@
|
|
1
|
-
require 'dry/validation/messages/i18n'
|
2
|
-
|
3
|
-
RSpec.describe 'Validation hints' do
|
4
|
-
shared_context '#messages' do
|
5
|
-
it 'provides hints for additional rules that were not checked' do
|
6
|
-
expect(schema.(age: '17').messages).to eql(
|
7
|
-
age: ['must be an integer', 'must be greater than 18']
|
8
|
-
)
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'skips type-check rules' do
|
12
|
-
expect(schema.(age: 17).messages).to eql(
|
13
|
-
age: ['must be greater than 18']
|
14
|
-
)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'with yaml messages' do
|
19
|
-
subject(:schema) do
|
20
|
-
Dry::Validation.Schema do
|
21
|
-
required(:age).maybe(:int?, gt?: 18)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
include_context '#messages'
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'with i18n messages' do
|
29
|
-
subject(:schema) do
|
30
|
-
Dry::Validation.Schema do
|
31
|
-
configure { configure { |c| c.messages = :i18n } }
|
32
|
-
|
33
|
-
required(:age).maybe(:int?, gt?: 18)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
include_context '#messages'
|
38
|
-
end
|
39
|
-
|
40
|
-
context 'when type expectation is specified' do
|
41
|
-
subject(:schema) do
|
42
|
-
Dry::Validation.Schema do
|
43
|
-
required(:email).filled
|
44
|
-
required(:name).filled(:str?, size?: 5..25)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'infers message for specific type' do
|
49
|
-
expect(schema.(email: 'jane@doe', name: 'HN').messages).to eql(
|
50
|
-
name: ['length must be within 5 - 25']
|
51
|
-
)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
context 'when predicate failed and there is a corresponding hint generated' do
|
56
|
-
subject(:schema) do
|
57
|
-
Dry::Validation.Schema do
|
58
|
-
required(:age).value(lt?: 23)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'provides only failure error message' do
|
63
|
-
result = schema.call(age: 23)
|
64
|
-
expect(result.messages).to eql(age: ['must be less than 23'])
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
context 'with a nested schema with same rule names' do
|
69
|
-
subject(:schema) do
|
70
|
-
Dry::Validation.Schema do
|
71
|
-
required(:code).filled(:str?, eql?: 'foo')
|
72
|
-
|
73
|
-
required(:nested).schema do
|
74
|
-
required(:code).filled(:str?, eql?: 'bar')
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'provides error messages' do
|
80
|
-
result = schema.call(code: 'x', nested: { code: 'y' })
|
81
|
-
|
82
|
-
expect(result.messages).to eql(
|
83
|
-
code: ['must be equal to foo'],
|
84
|
-
nested: {
|
85
|
-
code: ['must be equal to bar']
|
86
|
-
}
|
87
|
-
)
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'provides hints' do
|
91
|
-
result = schema.call(code: '', nested: { code: '' })
|
92
|
-
|
93
|
-
expect(result.messages).to eql(
|
94
|
-
code: ['must be filled', 'must be equal to foo'],
|
95
|
-
nested: {
|
96
|
-
code: ['must be filled', 'must be equal to bar']
|
97
|
-
}
|
98
|
-
)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
context 'with an each rule' do
|
103
|
-
subject(:schema) do
|
104
|
-
Dry::Validation.Schema do
|
105
|
-
required(:nums).each(:int?, gt?: 0)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
it 'provides hints for each element' do
|
110
|
-
expect(schema.(nums: [1, 'foo', 0]).messages).to eql(
|
111
|
-
nums: {
|
112
|
-
1 => ['must be an integer', 'must be greater than 0'],
|
113
|
-
2 => ['must be greater than 0']
|
114
|
-
}
|
115
|
-
)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
context 'with a format? predicate' do
|
120
|
-
subject(:schema) do
|
121
|
-
Dry::Validation.Schema do
|
122
|
-
required(:name).value(size?: 2, format?: /xy/)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
it 'skips hints' do
|
127
|
-
expect(schema.(name: 'x').messages[:name]).to_not include('is in invalid format')
|
128
|
-
expect(schema.(name: 'ab').messages[:name]).to include('is in invalid format')
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
context 'when the message uses input value' do
|
133
|
-
subject(:schema) do
|
134
|
-
Dry::Validation.Schema do
|
135
|
-
configure do
|
136
|
-
def self.messages
|
137
|
-
Messages.default.merge(
|
138
|
-
en: {
|
139
|
-
errors: {
|
140
|
-
blue?: {
|
141
|
-
failure: '%{value} is not equal to blue',
|
142
|
-
hint: 'must be equal to blue'
|
143
|
-
}
|
144
|
-
}
|
145
|
-
}
|
146
|
-
)
|
147
|
-
end
|
148
|
-
|
149
|
-
def blue?(value)
|
150
|
-
value == 'blue'
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
required(:pill).filled(:blue?)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
it 'provides a correct failure message' do
|
159
|
-
expect(schema.(pill: 'red').messages).to eql(
|
160
|
-
pill: ['red is not equal to blue']
|
161
|
-
)
|
162
|
-
end
|
163
|
-
|
164
|
-
it 'provides a correct hint' do
|
165
|
-
expect(schema.(pill: nil).messages).to eql(
|
166
|
-
pill: ['must be filled', 'must be equal to blue']
|
167
|
-
)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
RSpec.describe 'Schema / Injecting Rules' do
|
2
|
-
subject(:schema) do
|
3
|
-
Dry::Validation.Schema(rules: other.class.rules) do
|
4
|
-
required(:email).maybe
|
5
|
-
|
6
|
-
rule(:email) { value(:login).true? > value(:email).filled? }
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:other) do
|
11
|
-
Dry::Validation.Schema do
|
12
|
-
required(:login) { |value| value.bool? }
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'appends rules from another schema' do
|
17
|
-
expect(schema.(login: true, email: 'jane@doe')).to be_success
|
18
|
-
expect(schema.(login: false, email: nil)).to be_success
|
19
|
-
expect(schema.(login: true, email: nil)).to_not be_success
|
20
|
-
expect(schema.(login: nil, email: 'jane@doe')).to_not be_success
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'keeps the original schema rules intact' do
|
24
|
-
expect(other.class.rules.size).to eq(1)
|
25
|
-
|
26
|
-
schema.(login: true, email: 'jane@doe')
|
27
|
-
|
28
|
-
expect(other.class.rules.size).to eq(1)
|
29
|
-
end
|
30
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'dry/validation/messages/i18n'
|
2
|
-
require 'i18n'
|
3
|
-
|
4
|
-
RSpec.describe 'Defining base schema class' do
|
5
|
-
subject(:schema) do
|
6
|
-
Dry::Validation.JSON(BaseSchema) do
|
7
|
-
required(:email).filled(:email?)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
before do
|
12
|
-
class BaseSchema < Dry::Validation::Schema
|
13
|
-
configure do |config|
|
14
|
-
config.messages_file = SPEC_ROOT.join('fixtures/locales/en.yml')
|
15
|
-
config.messages = :i18n
|
16
|
-
end
|
17
|
-
|
18
|
-
def email?(value)
|
19
|
-
true
|
20
|
-
end
|
21
|
-
|
22
|
-
define! do
|
23
|
-
required(:name).filled
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
after do
|
29
|
-
Object.send(:remove_const, :BaseSchema)
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'inherits predicates' do
|
33
|
-
expect(schema).to respond_to(:email?)
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'inherits rules' do
|
37
|
-
expect(schema.('name' => '').messages).to eql(
|
38
|
-
name: ['must be filled'], email: ['is missing', 'must be an email']
|
39
|
-
)
|
40
|
-
end
|
41
|
-
end
|
@@ -1,72 +0,0 @@
|
|
1
|
-
require 'dry/validation/messages/i18n'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Validation, 'with localized messages' do
|
4
|
-
before do
|
5
|
-
I18n.config.available_locales_set << :pl
|
6
|
-
I18n.load_path.concat(%w(en pl).map { |l| SPEC_ROOT.join("fixtures/locales/#{l}.yml") })
|
7
|
-
I18n.backend.load_translations
|
8
|
-
end
|
9
|
-
|
10
|
-
describe 'defining schema' do
|
11
|
-
context 'without a namespace' do
|
12
|
-
subject(:schema) do
|
13
|
-
Dry::Validation.Schema do
|
14
|
-
configure do
|
15
|
-
config.messages = :i18n
|
16
|
-
end
|
17
|
-
|
18
|
-
required(:email) { |email| email.filled? }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe '#messages' do
|
23
|
-
it 'returns localized error messages' do
|
24
|
-
expect(schema.(email: '').messages(locale: :pl)).to eql(
|
25
|
-
email: ['Proszę podać adres email']
|
26
|
-
)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context 'with a namespace' do
|
32
|
-
subject(:schema) do
|
33
|
-
Dry::Validation.Schema do
|
34
|
-
configure do
|
35
|
-
configure do |config|
|
36
|
-
config.messages = :i18n
|
37
|
-
config.namespace = :user
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
required(:email) { |email| email.filled? }
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe '#messages' do
|
46
|
-
it 'returns localized error messages' do
|
47
|
-
expect(schema.(email: '').messages(locale: :pl)).to eql(
|
48
|
-
email: ['Hej user! Dawaj ten email no!']
|
49
|
-
)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe '#errors' do
|
54
|
-
context 'with different locale' do
|
55
|
-
before do
|
56
|
-
I18n.locale = :pl
|
57
|
-
end
|
58
|
-
|
59
|
-
after do
|
60
|
-
I18n.locale = :en
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'contains the localized errors' do
|
64
|
-
expect(schema.(email: '').errors).to eql(
|
65
|
-
{ email: ['Hej user! Dawaj ten email no!'] }
|
66
|
-
)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
@@ -1,405 +0,0 @@
|
|
1
|
-
require 'dry/validation/message_compiler'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Validation::MessageCompiler do
|
4
|
-
subject(:message_compiler) { MessageCompiler.new(messages) }
|
5
|
-
|
6
|
-
include_context 'predicate helper'
|
7
|
-
|
8
|
-
let(:messages) do
|
9
|
-
Messages.default.merge(
|
10
|
-
en: {
|
11
|
-
errors: {
|
12
|
-
key?: {
|
13
|
-
arg: {
|
14
|
-
default: '+%{name}+ key is missing in the hash',
|
15
|
-
},
|
16
|
-
value: {
|
17
|
-
gender: 'Please provide your gender'
|
18
|
-
}
|
19
|
-
},
|
20
|
-
rules: {
|
21
|
-
address: {
|
22
|
-
filled?: 'Please provide your address'
|
23
|
-
}
|
24
|
-
}
|
25
|
-
}
|
26
|
-
},
|
27
|
-
pl: {
|
28
|
-
rules: {
|
29
|
-
email: 'adres email'
|
30
|
-
},
|
31
|
-
errors: {
|
32
|
-
email?: 'nie jest poprawny'
|
33
|
-
}
|
34
|
-
}
|
35
|
-
)
|
36
|
-
end
|
37
|
-
|
38
|
-
describe '#call with flat inputs' do
|
39
|
-
let(:ast) do
|
40
|
-
[
|
41
|
-
[:failure, [:name, p(:key?, :name)]],
|
42
|
-
[:failure, [:gender, p(:key?, :gender)]],
|
43
|
-
[:key, [:age, [:failure, [:age, p(:gt?, 18)]]]],
|
44
|
-
[:key, [:email, [:failure, [:email, p(:filled?, '')]]]],
|
45
|
-
[:key, [:address, [:failure, [:address, p(:filled?, '')]]]]
|
46
|
-
]
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'converts error ast into another format' do
|
50
|
-
expect(message_compiler.(ast).to_h).to eql(
|
51
|
-
name: ["+name+ key is missing in the hash"],
|
52
|
-
gender: ["Please provide your gender"],
|
53
|
-
age: ["must be greater than 18"],
|
54
|
-
email: ["must be filled"],
|
55
|
-
address: ["Please provide your address"]
|
56
|
-
)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
describe '#visit with an :input node' do
|
61
|
-
context 'full message' do
|
62
|
-
it 'returns full message including rule name' do
|
63
|
-
msg = message_compiler.with(full: true).visit(
|
64
|
-
[:failure, [:num, [:key, [:num, p(:int?, '2')]]]]
|
65
|
-
)
|
66
|
-
|
67
|
-
expect(msg).to eql('num must be an integer')
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'rule name translations' do
|
72
|
-
it 'translates rule name and its message' do
|
73
|
-
msg = message_compiler.with(locale: :pl, full: true).visit(
|
74
|
-
[:failure, [:email, [:key, [:email, p(:email?, 'oops')]]]]
|
75
|
-
)
|
76
|
-
|
77
|
-
expect(msg).to eql('adres email nie jest poprawny')
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
describe ':empty?' do
|
82
|
-
it 'returns valid message' do
|
83
|
-
msg = message_compiler.visit(
|
84
|
-
[:failure, [:tags, [:key, [:tags, p(:empty?, nil)]]]]
|
85
|
-
)
|
86
|
-
|
87
|
-
expect(msg).to eql('must be empty')
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
describe ':excluded_from?' do
|
92
|
-
it 'returns valid message' do
|
93
|
-
msg = message_compiler.visit(
|
94
|
-
[:failure, [:num, [:key, [:num, p(:excluded_from?, [1, 2, 3], 2)]]]]
|
95
|
-
)
|
96
|
-
|
97
|
-
expect(msg).to eql('must not be one of: 1, 2, 3')
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
describe ':excludes?' do
|
102
|
-
it 'returns valid message' do
|
103
|
-
msg = message_compiler.visit(
|
104
|
-
[:failure, [:array, [:key, [:array, p(:excludes?, 2, [1, 2])]]]]
|
105
|
-
)
|
106
|
-
|
107
|
-
expect(msg).to eql('must not include 2')
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
describe ':included_in?' do
|
112
|
-
it 'returns valid message' do
|
113
|
-
msg = message_compiler.visit(
|
114
|
-
[:failure, [:num, [:key, [:num, p(:included_in?, [1, 2, 3], :num)]]]]
|
115
|
-
)
|
116
|
-
|
117
|
-
expect(msg).to eql('must be one of: 1, 2, 3')
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
describe ':includes?' do
|
122
|
-
it 'returns valid message' do
|
123
|
-
msg = message_compiler.visit(
|
124
|
-
[:failure, [:num, [:key, [:num, p(:includes?, 2, [1])]]]]
|
125
|
-
)
|
126
|
-
|
127
|
-
expect(msg).to eql('must include 2')
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
describe ':gt?' do
|
132
|
-
it 'returns valid message' do
|
133
|
-
msg = message_compiler.visit(
|
134
|
-
[:failure, [:num, [:key, [:num, p(:gt?, 3, 2)]]]]
|
135
|
-
)
|
136
|
-
|
137
|
-
expect(msg).to eql('must be greater than 3')
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
describe ':gteq?' do
|
142
|
-
it 'returns valid message' do
|
143
|
-
msg = message_compiler.visit(
|
144
|
-
[:failure, [:num, [:key, [:num, p(:gteq?, 3, 2)]]]]
|
145
|
-
)
|
146
|
-
|
147
|
-
expect(msg).to eql('must be greater than or equal to 3')
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
describe ':lt?' do
|
152
|
-
it 'returns valid message' do
|
153
|
-
msg = message_compiler.visit(
|
154
|
-
[:failure, [:num, [:key, [:num, p(:lt?, 3, 2)]]]]
|
155
|
-
)
|
156
|
-
|
157
|
-
expect(msg).to eql('must be less than 3')
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
describe ':lteq?' do
|
162
|
-
it 'returns valid message' do
|
163
|
-
msg = message_compiler.visit(
|
164
|
-
[:failure, [:num, [:key, [:num, p(:lteq?, 3, 2)]]]]
|
165
|
-
)
|
166
|
-
|
167
|
-
expect(msg).to eql('must be less than or equal to 3')
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
describe ':hash?' do
|
172
|
-
it 'returns valid message' do
|
173
|
-
msg = message_compiler.visit(
|
174
|
-
[:failure, [:address, [:key, [:address, p(:hash?, '')]]]]
|
175
|
-
)
|
176
|
-
|
177
|
-
expect(msg).to eql('must be a hash')
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
describe ':array?' do
|
182
|
-
it 'returns valid message' do
|
183
|
-
msg = message_compiler.visit(
|
184
|
-
[:failure, [:phone_numbers, [:key, [:phone, p(:array?,'')]]]]
|
185
|
-
)
|
186
|
-
|
187
|
-
expect(msg).to eql('must be an array')
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
describe ':int?' do
|
192
|
-
it 'returns valid message' do
|
193
|
-
msg = message_compiler.visit(
|
194
|
-
[:failure, [:num, [:key, [:num, p(:int?, '2')]]]]
|
195
|
-
)
|
196
|
-
|
197
|
-
expect(msg).to eql('must be an integer')
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
describe ':float?' do
|
202
|
-
it 'returns valid message' do
|
203
|
-
msg = message_compiler.visit(
|
204
|
-
[:failure, [:num, [:key, [:num, p(:float?, '2')]]]]
|
205
|
-
)
|
206
|
-
|
207
|
-
expect(msg).to eql('must be a float')
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
describe ':decimal?' do
|
212
|
-
it 'returns valid message' do
|
213
|
-
msg = message_compiler.visit(
|
214
|
-
[:failure, [:num, [:key, [:num, p(:decimal?, '2')]]]]
|
215
|
-
)
|
216
|
-
|
217
|
-
expect(msg).to eql('must be a decimal')
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
describe ':date?' do
|
222
|
-
it 'returns valid message' do
|
223
|
-
msg = message_compiler.visit(
|
224
|
-
[:failure, [:num, [:key, [:num, p(:date?, '2')]]]]
|
225
|
-
)
|
226
|
-
|
227
|
-
expect(msg).to eql('must be a date')
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
describe ':date_time?' do
|
232
|
-
it 'returns valid message' do
|
233
|
-
msg = message_compiler.visit(
|
234
|
-
[:failure, [:num, [:key, [:num, p(:date_time?, '2')]]]]
|
235
|
-
)
|
236
|
-
|
237
|
-
expect(msg).to eql('must be a date time')
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
describe ':time?' do
|
242
|
-
it 'returns valid message' do
|
243
|
-
msg = message_compiler.visit(
|
244
|
-
[:failure, [:num, [:key, [:num, p(:time?, '2')]]]]
|
245
|
-
)
|
246
|
-
|
247
|
-
expect(msg).to eql('must be a time')
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
describe ':max_size?' do
|
252
|
-
it 'returns valid message' do
|
253
|
-
msg = message_compiler.visit(
|
254
|
-
[:failure, [:num, [:key, [:num, p(:max_size?, 3, 'abcd')]]]]
|
255
|
-
)
|
256
|
-
|
257
|
-
expect(msg).to eql('size cannot be greater than 3')
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
describe ':min_size?' do
|
262
|
-
it 'returns valid message' do
|
263
|
-
msg = message_compiler.visit(
|
264
|
-
[:failure, [:num, [:key, [:num, p(:min_size?, 3, 'ab')]]]]
|
265
|
-
)
|
266
|
-
|
267
|
-
expect(msg).to eql('size cannot be less than 3')
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
describe ':none?' do
|
272
|
-
it 'returns valid message' do
|
273
|
-
msg = message_compiler.visit(
|
274
|
-
[:failure, [:num, [:key, [:num, p(:none?, nil)]]]]
|
275
|
-
)
|
276
|
-
|
277
|
-
expect(msg).to eql('cannot be defined')
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
describe ':size?' do
|
282
|
-
it 'returns valid message when val is array and arg is int' do
|
283
|
-
msg = message_compiler.visit(
|
284
|
-
[:failure, [:numbers, [:key, [:numbers, p(:size?, 3, [1])]]]]
|
285
|
-
)
|
286
|
-
|
287
|
-
expect(msg).to eql('size must be 3')
|
288
|
-
end
|
289
|
-
|
290
|
-
it 'returns valid message when val is array and arg is range' do
|
291
|
-
msg = message_compiler.visit(
|
292
|
-
[:failure, [:numbers, [:key, [:numbers, p(:size?, 3..4, [1])]]]]
|
293
|
-
)
|
294
|
-
|
295
|
-
expect(msg).to eql('size must be within 3 - 4')
|
296
|
-
end
|
297
|
-
|
298
|
-
it 'returns valid message when arg is int' do
|
299
|
-
msg = message_compiler.visit(
|
300
|
-
[:failure, [:num, [:key, [:num, p(:size?, 3, 'ab')]]]]
|
301
|
-
)
|
302
|
-
|
303
|
-
expect(msg).to eql('length must be 3')
|
304
|
-
end
|
305
|
-
|
306
|
-
it 'returns valid message when arg is range' do
|
307
|
-
msg = message_compiler.visit(
|
308
|
-
[:failure, [:num, [:key, [:num, p(:size?, 3..4, 'ab')]]]]
|
309
|
-
)
|
310
|
-
|
311
|
-
expect(msg).to eql('length must be within 3 - 4')
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
describe ':str?' do
|
316
|
-
it 'returns valid message' do
|
317
|
-
msg = message_compiler.visit(
|
318
|
-
[:failure, [:num, [:key, [:num, p(:str?, 3)]]]]
|
319
|
-
)
|
320
|
-
|
321
|
-
expect(msg).to eql('must be a string')
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
describe ':bool?' do
|
326
|
-
it 'returns valid message' do
|
327
|
-
msg = message_compiler.visit(
|
328
|
-
[:failure, [:num, [:key, [:num, p(:bool?, 3)]]]]
|
329
|
-
)
|
330
|
-
|
331
|
-
expect(msg).to eql('must be boolean')
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
|
-
describe ':format?' do
|
336
|
-
it 'returns valid message' do
|
337
|
-
msg = message_compiler.visit(
|
338
|
-
[:failure, [:str, [:key, [:str, p(:format?, /^F/, 'Bar')]]]]
|
339
|
-
)
|
340
|
-
|
341
|
-
expect(msg).to eql('is in invalid format')
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
describe ':number?' do
|
346
|
-
it 'returns valid message' do
|
347
|
-
msg = message_compiler.visit(
|
348
|
-
[:failure, [:str, [:key, [:str, p(:number?, 'not a number')]]]]
|
349
|
-
)
|
350
|
-
|
351
|
-
expect(msg).to eql('must be a number')
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
describe ':odd?' do
|
356
|
-
it 'returns valid message' do
|
357
|
-
msg = message_compiler.visit(
|
358
|
-
[:failure, [:str, [:key, [:str, p(:odd?, 1)]]]]
|
359
|
-
)
|
360
|
-
|
361
|
-
expect(msg).to eql('must be odd')
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
|
-
describe ':even?' do
|
366
|
-
it 'returns valid message' do
|
367
|
-
msg = message_compiler.visit(
|
368
|
-
[:failure, [:str, [:key, [:str, p(:even?, 2)]]]]
|
369
|
-
)
|
370
|
-
|
371
|
-
expect(msg).to eql('must be even')
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
describe ':eql?' do
|
376
|
-
it 'returns valid message' do
|
377
|
-
msg = message_compiler.visit(
|
378
|
-
[:failure, [:str, [:key, [:str, p(:eql?, 'Bar', 'Foo')]]]]
|
379
|
-
)
|
380
|
-
|
381
|
-
expect(msg).to eql('must be equal to Bar')
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
385
|
-
describe ':not_eql?' do
|
386
|
-
it 'returns valid message' do
|
387
|
-
msg = message_compiler.visit(
|
388
|
-
[:failure, [:str, [:key, [:str, p(:not_eql?, 'Foo', 'Foo')]]]]
|
389
|
-
)
|
390
|
-
|
391
|
-
expect(msg).to eql('must not be equal to Foo')
|
392
|
-
end
|
393
|
-
end
|
394
|
-
|
395
|
-
describe ':type?' do
|
396
|
-
it 'returns valid message' do
|
397
|
-
msg = message_compiler.visit(
|
398
|
-
[:failure, [:age, [:key, [:age, p(:type?, Integer, '1')]]]]
|
399
|
-
)
|
400
|
-
|
401
|
-
expect(msg).to eql('must be Integer')
|
402
|
-
end
|
403
|
-
end
|
404
|
-
end
|
405
|
-
end
|