dry-validation 0.6.0 → 0.7.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/.codeclimate.yml +1 -0
- data/.travis.yml +3 -2
- data/CHANGELOG.md +42 -0
- data/Gemfile +8 -1
- data/README.md +13 -89
- data/config/errors.yml +35 -29
- data/dry-validation.gemspec +2 -2
- data/examples/basic.rb +3 -7
- data/examples/each.rb +3 -8
- data/examples/form.rb +3 -6
- data/examples/nested.rb +7 -15
- data/lib/dry/validation.rb +33 -5
- data/lib/dry/validation/error.rb +10 -26
- data/lib/dry/validation/error_compiler.rb +69 -99
- data/lib/dry/validation/error_compiler/input.rb +148 -0
- data/lib/dry/validation/hint_compiler.rb +83 -33
- data/lib/dry/validation/input_processor_compiler.rb +98 -0
- data/lib/dry/validation/input_processor_compiler/form.rb +46 -0
- data/lib/dry/validation/input_processor_compiler/sanitizer.rb +46 -0
- data/lib/dry/validation/messages/abstract.rb +30 -10
- data/lib/dry/validation/messages/i18n.rb +2 -1
- data/lib/dry/validation/messages/namespaced.rb +1 -0
- data/lib/dry/validation/messages/yaml.rb +8 -5
- data/lib/dry/validation/result.rb +33 -25
- data/lib/dry/validation/schema.rb +168 -61
- data/lib/dry/validation/schema/attr.rb +5 -27
- data/lib/dry/validation/schema/check.rb +24 -0
- data/lib/dry/validation/schema/dsl.rb +97 -0
- data/lib/dry/validation/schema/form.rb +2 -26
- data/lib/dry/validation/schema/key.rb +32 -28
- data/lib/dry/validation/schema/rule.rb +88 -32
- data/lib/dry/validation/schema/value.rb +77 -27
- data/lib/dry/validation/schema_compiler.rb +38 -0
- data/lib/dry/validation/version.rb +1 -1
- data/spec/fixtures/locales/pl.yml +1 -1
- data/spec/integration/attr_spec.rb +122 -0
- data/spec/integration/custom_error_messages_spec.rb +9 -11
- data/spec/integration/custom_predicates_spec.rb +68 -18
- data/spec/integration/error_compiler_spec.rb +259 -65
- data/spec/integration/hints_spec.rb +28 -9
- data/spec/integration/injecting_rules_spec.rb +11 -12
- data/spec/integration/localized_error_messages_spec.rb +16 -16
- data/spec/integration/messages/i18n_spec.rb +9 -5
- data/spec/integration/optional_keys_spec.rb +9 -11
- data/spec/integration/schema/array_schema_spec.rb +23 -0
- data/spec/integration/schema/check_rules_spec.rb +39 -31
- data/spec/integration/schema/check_with_nth_el_spec.rb +25 -0
- data/spec/integration/schema/each_with_set_spec.rb +23 -24
- data/spec/integration/schema/form_spec.rb +122 -0
- data/spec/integration/schema/inheriting_schema_spec.rb +31 -0
- data/spec/integration/schema/input_processor_spec.rb +46 -0
- data/spec/integration/schema/macros/confirmation_spec.rb +33 -0
- data/spec/integration/schema/macros/maybe_spec.rb +32 -0
- data/spec/integration/schema/macros/required_spec.rb +59 -0
- data/spec/integration/schema/macros/when_spec.rb +65 -0
- data/spec/integration/schema/nested_values_spec.rb +41 -0
- data/spec/integration/schema/not_spec.rb +14 -14
- data/spec/integration/schema/option_with_default_spec.rb +30 -0
- data/spec/integration/schema/reusing_schema_spec.rb +33 -0
- data/spec/integration/schema/using_types_spec.rb +29 -0
- data/spec/integration/schema/xor_spec.rb +17 -14
- data/spec/integration/schema_spec.rb +75 -245
- data/spec/shared/rule_compiler.rb +8 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/unit/hint_compiler_spec.rb +10 -10
- data/spec/unit/{input_type_compiler_spec.rb → input_processor_compiler/form_spec.rb} +88 -73
- data/spec/unit/schema/key_spec.rb +33 -0
- data/spec/unit/schema/rule_spec.rb +7 -6
- data/spec/unit/schema/value_spec.rb +187 -54
- metadata +53 -31
- data/.rubocop.yml +0 -16
- data/.rubocop_todo.yml +0 -7
- data/lib/dry/validation/input_type_compiler.rb +0 -83
- data/lib/dry/validation/schema/definition.rb +0 -74
- data/lib/dry/validation/schema/result.rb +0 -68
- data/rakelib/rubocop.rake +0 -18
- data/spec/integration/rule_groups_spec.rb +0 -94
- data/spec/integration/schema/attrs_spec.rb +0 -38
- data/spec/integration/schema/default_key_behavior_spec.rb +0 -23
- data/spec/integration/schema/grouped_rules_spec.rb +0 -57
- data/spec/integration/schema/nested_spec.rb +0 -31
- data/spec/integration/schema_form_spec.rb +0 -97
@@ -1,19 +1,23 @@
|
|
1
1
|
require 'dry/validation/messages/i18n'
|
2
2
|
|
3
3
|
RSpec.describe 'Validation hints' do
|
4
|
-
subject(:validation) { schema.new }
|
5
|
-
|
6
4
|
shared_context '#messages' do
|
7
5
|
it 'provides hints for additional rules that were not checked' do
|
8
|
-
expect(
|
9
|
-
age: [
|
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']
|
10
14
|
)
|
11
15
|
end
|
12
16
|
end
|
13
17
|
|
14
18
|
context 'with yaml messages' do
|
15
|
-
|
16
|
-
|
19
|
+
subject(:schema) do
|
20
|
+
Dry::Validation.Schema do
|
17
21
|
key(:age) do |age|
|
18
22
|
age.none? | (age.int? & age.gt?(18))
|
19
23
|
end
|
@@ -24,9 +28,9 @@ RSpec.describe 'Validation hints' do
|
|
24
28
|
end
|
25
29
|
|
26
30
|
context 'with i18n messages' do
|
27
|
-
|
28
|
-
|
29
|
-
configure { |c| c.messages = :i18n }
|
31
|
+
subject(:schema) do
|
32
|
+
Dry::Validation.Schema do
|
33
|
+
configure { configure { |c| c.messages = :i18n } }
|
30
34
|
|
31
35
|
key(:age) do |age|
|
32
36
|
age.none? | (age.int? & age.gt?(18))
|
@@ -36,4 +40,19 @@ RSpec.describe 'Validation hints' do
|
|
36
40
|
|
37
41
|
include_context '#messages'
|
38
42
|
end
|
43
|
+
|
44
|
+
context 'when type expectation is specified' do
|
45
|
+
subject(:schema) do
|
46
|
+
Dry::Validation.Schema do
|
47
|
+
key(:email).required
|
48
|
+
key(:name).required(:str?, size?: 5..25)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'infers message for specific type' do
|
53
|
+
expect(schema.(email: 'jane@doe', name: 'HN').messages).to eql(
|
54
|
+
name: ['length must be within 5 - 25']
|
55
|
+
)
|
56
|
+
end
|
57
|
+
end
|
39
58
|
end
|
@@ -1,23 +1,22 @@
|
|
1
1
|
RSpec.describe 'Schema / Injecting Rules' do
|
2
|
-
|
2
|
+
subject(:schema) do
|
3
|
+
Dry::Validation.Schema(rules: other.class.rules) do
|
4
|
+
key(:email).maybe
|
3
5
|
|
4
|
-
|
5
|
-
Class.new(Dry::Validation::Schema) do
|
6
|
-
key(:login) { |value| value.bool? }
|
6
|
+
rule(:email) { value(:login).true? > value(:email).filled? }
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
let(:
|
11
|
-
|
12
|
-
key(:
|
13
|
-
|
14
|
-
rule(email: :filled?) { value(:login).true? > value(:email).filled? }
|
10
|
+
let(:other) do
|
11
|
+
Dry::Validation.Schema do
|
12
|
+
key(:login) { |value| value.bool? }
|
15
13
|
end
|
16
14
|
end
|
17
15
|
|
18
16
|
it 'appends rules from another schema' do
|
19
|
-
expect(
|
20
|
-
expect(
|
21
|
-
expect(
|
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
|
22
21
|
end
|
23
22
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
require 'dry/validation/messages/i18n'
|
2
2
|
|
3
3
|
RSpec.describe Dry::Validation, 'with localized messages' do
|
4
|
-
subject(:validation) { schema.new }
|
5
|
-
|
6
4
|
before do
|
7
5
|
I18n.config.available_locales_set << :pl
|
8
6
|
I18n.load_path.concat(%w(en pl).map { |l| SPEC_ROOT.join("fixtures/locales/#{l}.yml") })
|
@@ -11,9 +9,9 @@ RSpec.describe Dry::Validation, 'with localized messages' do
|
|
11
9
|
|
12
10
|
describe 'defining schema' do
|
13
11
|
context 'without a namespace' do
|
14
|
-
|
15
|
-
|
16
|
-
configure do
|
12
|
+
subject(:schema) do
|
13
|
+
Dry::Validation.Schema do
|
14
|
+
configure do
|
17
15
|
config.messages = :i18n
|
18
16
|
end
|
19
17
|
|
@@ -23,19 +21,21 @@ RSpec.describe Dry::Validation, 'with localized messages' do
|
|
23
21
|
|
24
22
|
describe '#messages' do
|
25
23
|
it 'returns localized error messages' do
|
26
|
-
expect(
|
27
|
-
|
28
|
-
|
24
|
+
expect(schema.(email: '').messages(locale: :pl)).to eql(
|
25
|
+
email: ['Proszę podać adres email']
|
26
|
+
)
|
29
27
|
end
|
30
28
|
end
|
31
29
|
end
|
32
30
|
|
33
31
|
context 'with a namespace' do
|
34
|
-
|
35
|
-
|
36
|
-
configure do
|
37
|
-
|
38
|
-
|
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
39
|
end
|
40
40
|
|
41
41
|
key(:email) { |email| email.filled? }
|
@@ -44,9 +44,9 @@ RSpec.describe Dry::Validation, 'with localized messages' do
|
|
44
44
|
|
45
45
|
describe '#messages' do
|
46
46
|
it 'returns localized error messages' do
|
47
|
-
expect(
|
48
|
-
|
49
|
-
|
47
|
+
expect(schema.(email: '').messages(locale: :pl)).to eql(
|
48
|
+
email: ['Hej user! Dawaj ten email no!']
|
49
|
+
)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
@@ -11,10 +11,14 @@ RSpec.describe Messages::I18n do
|
|
11
11
|
|
12
12
|
describe '#[]' do
|
13
13
|
context 'with the default locale' do
|
14
|
+
it 'returns nil when message is not defined' do
|
15
|
+
expect(messages[:not_here, rule: :srsly]).to be(nil)
|
16
|
+
end
|
17
|
+
|
14
18
|
it 'returns a message for a predicate' do
|
15
19
|
message = messages[:filled?, rule: :name]
|
16
20
|
|
17
|
-
expect(message).to eql("
|
21
|
+
expect(message).to eql("must be filled")
|
18
22
|
end
|
19
23
|
|
20
24
|
it 'returns a message for a specific rule' do
|
@@ -26,19 +30,19 @@ RSpec.describe Messages::I18n do
|
|
26
30
|
it 'returns a message for a specific val type' do
|
27
31
|
message = messages[:size?, rule: :pages, val_type: String]
|
28
32
|
|
29
|
-
expect(message).to eql("
|
33
|
+
expect(message).to eql("length must be %{num}")
|
30
34
|
end
|
31
35
|
|
32
36
|
it 'returns a message for a specific rule and its default arg type' do
|
33
37
|
message = messages[:size?, rule: :pages]
|
34
38
|
|
35
|
-
expect(message).to eql("
|
39
|
+
expect(message).to eql("size must be %{num}")
|
36
40
|
end
|
37
41
|
|
38
42
|
it 'returns a message for a specific rule and its arg type' do
|
39
43
|
message = messages[:size?, rule: :pages, arg_type: Range]
|
40
44
|
|
41
|
-
expect(message).to eql("
|
45
|
+
expect(message).to eql("size must be within %{left} - %{right}")
|
42
46
|
end
|
43
47
|
end
|
44
48
|
|
@@ -46,7 +50,7 @@ RSpec.describe Messages::I18n do
|
|
46
50
|
it 'returns a message for a predicate' do
|
47
51
|
message = messages[:filled?, rule: :name, locale: :pl]
|
48
52
|
|
49
|
-
expect(message).to eql("
|
53
|
+
expect(message).to eql("nie może być pusty")
|
50
54
|
end
|
51
55
|
|
52
56
|
it 'returns a message for a specific rule' do
|
@@ -1,17 +1,15 @@
|
|
1
1
|
RSpec.describe Dry::Validation::Schema do
|
2
|
-
subject(:validation) { schema.new }
|
3
|
-
|
4
2
|
describe 'defining schema with optional keys' do
|
5
|
-
|
6
|
-
|
3
|
+
subject(:schema) do
|
4
|
+
Dry::Validation.Schema do
|
7
5
|
optional(:email) { |email| email.filled? }
|
8
6
|
|
9
|
-
key(:address) do
|
10
|
-
|
11
|
-
|
7
|
+
key(:address) do
|
8
|
+
key(:city, &:filled?)
|
9
|
+
key(:street, &:filled?)
|
12
10
|
|
13
|
-
|
14
|
-
|
11
|
+
optional(:phone_number) do
|
12
|
+
none? | str?
|
15
13
|
end
|
16
14
|
end
|
17
15
|
end
|
@@ -19,11 +17,11 @@ RSpec.describe Dry::Validation::Schema do
|
|
19
17
|
|
20
18
|
describe '#call' do
|
21
19
|
it 'skips rules when key is not present' do
|
22
|
-
expect(
|
20
|
+
expect(schema.(address: { city: 'NYC', street: 'Street 1/2' })).to be_success
|
23
21
|
end
|
24
22
|
|
25
23
|
it 'applies rules when key is present' do
|
26
|
-
expect(
|
24
|
+
expect(schema.(email: '')).to_not be_success
|
27
25
|
end
|
28
26
|
end
|
29
27
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
RSpec.describe Dry::Validation::Schema, 'for an array' do
|
2
|
+
subject(:schema) do
|
3
|
+
Dry::Validation.Schema do
|
4
|
+
each do
|
5
|
+
key(:prefix).required
|
6
|
+
key(:value).required
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'applies its rules to array input' do
|
12
|
+
result = schema.([{ prefix: 1, value: 123 }, { prefix: 2, value: 456 }])
|
13
|
+
|
14
|
+
expect(result).to be_success
|
15
|
+
|
16
|
+
result = schema.([{ prefix: 1, value: nil }, { prefix: nil, value: 456 }])
|
17
|
+
|
18
|
+
expect(result.messages).to eql(
|
19
|
+
0 => { value: ["must be filled"] },
|
20
|
+
1 => { prefix: ["must be filled"] }
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
@@ -1,49 +1,57 @@
|
|
1
1
|
RSpec.describe Schema, 'using high-level rules' do
|
2
|
-
subject(:validate) { schema.new }
|
3
|
-
|
4
2
|
context 'composing rules' do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
subject(:schema) do
|
4
|
+
Dry::Validation.Schema do
|
5
|
+
configure do
|
6
|
+
def self.messages
|
7
|
+
Messages.default.merge(
|
8
|
+
en: { errors: { destiny: 'you must select either red or blue' } }
|
9
|
+
)
|
10
|
+
end
|
11
11
|
end
|
12
12
|
|
13
|
-
optional(:red
|
14
|
-
optional(:blue
|
13
|
+
optional(:red).maybe
|
14
|
+
optional(:blue).maybe
|
15
15
|
|
16
|
-
rule(:
|
16
|
+
rule(destiny: [:red, :blue]) do |red, blue|
|
17
|
+
red.filled? | blue.filled?
|
18
|
+
end
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
20
22
|
it 'passes when only red is filled' do
|
21
|
-
expect(
|
23
|
+
expect(schema.(red: '1')).to be_success
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'fails when keys are missing' do
|
27
|
+
expect(schema.({})).to be_failure
|
22
28
|
end
|
23
29
|
|
24
30
|
it 'fails when red and blue are not filled ' do
|
25
|
-
expect(
|
26
|
-
[
|
31
|
+
expect(schema.(red: nil, blue: nil).messages[:destiny]).to eql(
|
32
|
+
['you must select either red or blue']
|
27
33
|
)
|
28
34
|
end
|
29
35
|
end
|
30
36
|
|
31
37
|
context 'composing specific predicates' do
|
32
38
|
let(:schema) do
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
39
|
+
Dry::Validation.Schema do
|
40
|
+
configure do
|
41
|
+
def self.messages
|
42
|
+
Messages.default.merge(
|
43
|
+
en: {
|
44
|
+
errors: {
|
45
|
+
email_presence: 'must be present when login is set to true',
|
46
|
+
email_absence: 'must not be present when login is set to false'
|
47
|
+
}
|
40
48
|
}
|
41
|
-
|
42
|
-
|
49
|
+
)
|
50
|
+
end
|
43
51
|
end
|
44
52
|
|
45
|
-
key(:login)
|
46
|
-
key(:email)
|
53
|
+
key(:login).required(:bool?)
|
54
|
+
key(:email).maybe
|
47
55
|
|
48
56
|
rule(:email_presence) { value(:login).true?.then(value(:email).filled?) }
|
49
57
|
|
@@ -52,22 +60,22 @@ RSpec.describe Schema, 'using high-level rules' do
|
|
52
60
|
end
|
53
61
|
|
54
62
|
it 'passes when login is false and email is nil' do
|
55
|
-
expect(
|
63
|
+
expect(schema.(login: false, email: nil)).to be_success
|
56
64
|
end
|
57
65
|
|
58
66
|
it 'fails when login is false and email is present' do
|
59
|
-
expect(
|
60
|
-
[
|
67
|
+
expect(schema.(login: false, email: 'jane@doe').messages).to eql(
|
68
|
+
email_absence: ['must not be present when login is set to false']
|
61
69
|
)
|
62
70
|
end
|
63
71
|
|
64
72
|
it 'passes when login is true and email is present' do
|
65
|
-
expect(
|
73
|
+
expect(schema.(login: true, email: 'jane@doe')).to be_success
|
66
74
|
end
|
67
75
|
|
68
76
|
it 'fails when login is true and email is not present' do
|
69
|
-
expect(
|
70
|
-
[
|
77
|
+
expect(schema.(login: true, email: nil).messages).to eql(
|
78
|
+
email_presence: ['must be present when login is set to true']
|
71
79
|
)
|
72
80
|
end
|
73
81
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
RSpec.describe 'Check depending on nth element in an array' do
|
2
|
+
subject(:schema) do
|
3
|
+
Dry::Validation.Schema do
|
4
|
+
key(:tags).each(:str?)
|
5
|
+
|
6
|
+
rule(red: [[:tags, 0]]) do |value|
|
7
|
+
value.eql?('red')
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'skips check when dependency failed' do
|
13
|
+
expect(schema.(tags: 'oops')).to be_failure
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'passes when check passes' do
|
17
|
+
expect(schema.(tags: %w(red green blue))).to be_success
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'fails when check fails' do
|
21
|
+
expect(schema.(tags: %w(blue green red)).messages).to eql(
|
22
|
+
tags: { 0 => ["must be equal to red"] }
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
@@ -1,20 +1,22 @@
|
|
1
1
|
RSpec.describe 'Schema with each and set rules' do
|
2
|
-
subject(:
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
payments.array? do
|
8
|
-
payments.each do |payment|
|
9
|
-
payment.key(:method, &:str?)
|
10
|
-
payment.key(:amount, &:float?)
|
11
|
-
end
|
12
|
-
end
|
2
|
+
subject(:schema) do
|
3
|
+
Dry::Validation.Schema do
|
4
|
+
key(:payments).each do
|
5
|
+
key(:method).required(:str?)
|
6
|
+
key(:amount).required(:float?)
|
13
7
|
end
|
14
8
|
end
|
15
9
|
end
|
16
10
|
|
17
11
|
describe '#messages' do
|
12
|
+
it 'validates using all rules' do
|
13
|
+
expect(schema.(payments: [{}]).messages).to eql(
|
14
|
+
{ payments: {
|
15
|
+
0 => { method: ['is missing'], amount: ['is missing'] }
|
16
|
+
}}
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
18
20
|
it 'validates each payment against its set of rules' do
|
19
21
|
input = {
|
20
22
|
payments: [
|
@@ -23,7 +25,7 @@ RSpec.describe 'Schema with each and set rules' do
|
|
23
25
|
]
|
24
26
|
}
|
25
27
|
|
26
|
-
expect(
|
28
|
+
expect(schema.(input).messages).to eql({})
|
27
29
|
end
|
28
30
|
|
29
31
|
it 'validates presence of the method key for each payment' do
|
@@ -34,10 +36,9 @@ RSpec.describe 'Schema with each and set rules' do
|
|
34
36
|
]
|
35
37
|
}
|
36
38
|
|
37
|
-
expect(
|
38
|
-
|
39
|
-
|
40
|
-
])
|
39
|
+
expect(schema.(input).messages).to eql(
|
40
|
+
payments: { 1 => { method: ['is missing'] } }
|
41
|
+
)
|
41
42
|
end
|
42
43
|
|
43
44
|
it 'validates type of the method value for each payment' do
|
@@ -48,10 +49,9 @@ RSpec.describe 'Schema with each and set rules' do
|
|
48
49
|
]
|
49
50
|
}
|
50
51
|
|
51
|
-
expect(
|
52
|
-
|
53
|
-
|
54
|
-
])
|
52
|
+
expect(schema.(input).messages).to eql(
|
53
|
+
payments: { 1 => { method: ['must be a string'] } }
|
54
|
+
)
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'validates type of the amount value for each payment' do
|
@@ -62,10 +62,9 @@ RSpec.describe 'Schema with each and set rules' do
|
|
62
62
|
]
|
63
63
|
}
|
64
64
|
|
65
|
-
expect(
|
66
|
-
|
67
|
-
|
68
|
-
])
|
65
|
+
expect(schema.(input).messages).to eql(
|
66
|
+
payments: { 1 => { amount: ['must be a float'] } }
|
67
|
+
)
|
69
68
|
end
|
70
69
|
end
|
71
70
|
end
|