dry-validation 0.9.2 → 0.9.3
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 +18 -0
- data/Gemfile +5 -0
- data/config/errors.yml +8 -2
- data/lib/dry/validation/error_compiler.rb +9 -4
- data/lib/dry/validation/message_set.rb +32 -11
- data/lib/dry/validation/result.rb +11 -18
- data/lib/dry/validation/schema/class_interface.rb +1 -1
- data/lib/dry/validation/schema/value.rb +2 -2
- data/lib/dry/validation/version.rb +1 -1
- data/spec/integration/result_spec.rb +59 -0
- data/spec/integration/schema/macros/rule_spec.rb +74 -0
- data/spec/integration/schema/predicates/excluded_from/array_spec.rb +459 -0
- data/spec/integration/schema/predicates/excluded_from/range_spec.rb +459 -0
- data/spec/integration/schema/predicates/included_in/array_spec.rb +459 -0
- data/spec/integration/schema/predicates/included_in/range_spec.rb +459 -0
- data/spec/support/mutant.rb +9 -0
- metadata +16 -6
- data/spec/integration/schema/predicates/excluded_from_spec.rb +0 -455
- data/spec/integration/schema/predicates/included_in_spec.rb +0 -455
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d65d8862d070db6d2641c69e7077b4d2b9a97ee9
|
4
|
+
data.tar.gz: 25ce604442b2886454a39e13180b52dfc498598c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ff29e904cf720763e48e4e329a85e81695e9e2a17b093f1581ce46b295f4abf1116b216abb7f8ca9703b0ccd86473591dfa38d41d92b8da621c9abc729a3447
|
7
|
+
data.tar.gz: 97169242904d4bd1c05efc41ef54021b10a304b2bd92ff074632a37053e81ccaab415d228c8391fb916acd73768029cf5adc065c7c29d7eb6e0e47870d1c4830
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
# v0.9.3 2016-07-22
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
* Support for range arg in error messages for `excluded_from?` and `included_in?` (mrbongiolo)
|
6
|
+
* `Result#message_set` returns raw message set object (solnic)
|
7
|
+
|
8
|
+
### Fixed
|
9
|
+
|
10
|
+
* Error messages for high-level rules in nested schemas are nested correctly (solnic)
|
11
|
+
* Dumping error messages works with high-level rules relying on the same value (solnic)
|
12
|
+
|
13
|
+
### Changed
|
14
|
+
|
15
|
+
* `#messages` is no longer memoized (solnic)
|
16
|
+
|
17
|
+
[Compare v0.9.2...v0.9.3](https://github.com/dryrb/dry-validation/compare/v0.9.2...v0.9.3)
|
18
|
+
|
1
19
|
# v0.9.2 2016-07-13
|
2
20
|
|
3
21
|
### Fixed
|
data/Gemfile
CHANGED
data/config/errors.yml
CHANGED
@@ -6,7 +6,10 @@ en:
|
|
6
6
|
|
7
7
|
excludes?: "must not include %{value}"
|
8
8
|
|
9
|
-
excluded_from?:
|
9
|
+
excluded_from?:
|
10
|
+
arg:
|
11
|
+
default: "must not be one of: %{list}"
|
12
|
+
range: "must not be one of: %{list_left} - %{list_right}"
|
10
13
|
exclusion?: "must not be one of: %{list}"
|
11
14
|
|
12
15
|
eql?: "must be equal to %{left}"
|
@@ -29,7 +32,10 @@ en:
|
|
29
32
|
|
30
33
|
hash?: "must be a hash"
|
31
34
|
|
32
|
-
included_in?:
|
35
|
+
included_in?:
|
36
|
+
arg:
|
37
|
+
default: "must be one of: %{list}"
|
38
|
+
range: "must be one of: %{list_left} - %{list_right}"
|
33
39
|
inclusion?: "must be one of: %{list}"
|
34
40
|
|
35
41
|
includes?: "must include %{value}"
|
@@ -23,7 +23,7 @@ module Dry
|
|
23
23
|
|
24
24
|
path.compact!
|
25
25
|
|
26
|
-
template = messages[rule, default_lookup_options]
|
26
|
+
template = messages[rule.is_a?(Array) ? rule.last : rule, default_lookup_options]
|
27
27
|
|
28
28
|
if template
|
29
29
|
predicate, args, tokens = visit(error, opts.merge(path: path, message: false))
|
@@ -60,13 +60,18 @@ module Dry
|
|
60
60
|
opts[:path] << path.last
|
61
61
|
visit(other, opts)
|
62
62
|
else
|
63
|
-
visit(other, opts.merge(path: [path]))
|
63
|
+
visit(other, opts.merge(path: [path], schema: true))
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
67
|
def visit_check(node, opts = EMPTY_HASH)
|
68
|
-
|
69
|
-
|
68
|
+
name, other = node
|
69
|
+
|
70
|
+
if opts[:schema]
|
71
|
+
visit(other, opts)
|
72
|
+
else
|
73
|
+
visit(other, opts.merge(path: Array(name)))
|
74
|
+
end
|
70
75
|
end
|
71
76
|
|
72
77
|
def lookup_options(opts, arg_vals = [])
|
@@ -18,36 +18,57 @@ module Dry
|
|
18
18
|
initialize_placeholders!
|
19
19
|
end
|
20
20
|
|
21
|
+
def dump
|
22
|
+
root? ? to_a : to_h
|
23
|
+
end
|
24
|
+
|
21
25
|
def empty?
|
22
26
|
messages.empty?
|
23
27
|
end
|
24
28
|
|
29
|
+
def root?
|
30
|
+
!empty? && messages.all?(&:root?)
|
31
|
+
end
|
32
|
+
|
25
33
|
def each(&block)
|
26
34
|
return to_enum unless block
|
27
35
|
messages.each(&block)
|
28
36
|
end
|
29
37
|
|
30
38
|
def with_hints!(hints)
|
31
|
-
@hints
|
32
|
-
|
39
|
+
@hints.update(hints.group_by(&:index_path))
|
40
|
+
self
|
33
41
|
end
|
34
42
|
|
35
43
|
def to_h
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
node =
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
+
if root?
|
45
|
+
{ nil => map(&:to_s) }
|
46
|
+
else
|
47
|
+
group_by(&:path).reduce(placeholders) do |hash, (path, msgs)|
|
48
|
+
node = path.reduce(hash) { |a, e| a[e] }
|
49
|
+
|
50
|
+
msgs.each do |msg|
|
51
|
+
node << msg
|
52
|
+
msg_hints = hints[msg.index_path]
|
53
|
+
|
54
|
+
if msg_hints
|
55
|
+
node.concat(msg_hints)
|
56
|
+
node.uniq!(&:signature)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
44
60
|
node.map!(&:to_s)
|
61
|
+
|
62
|
+
hash
|
45
63
|
end
|
46
|
-
hash
|
47
64
|
end
|
48
65
|
end
|
49
66
|
alias_method :to_hash, :to_h
|
50
67
|
|
68
|
+
def to_a
|
69
|
+
to_h.values.flatten
|
70
|
+
end
|
71
|
+
|
51
72
|
private
|
52
73
|
|
53
74
|
def initialize_placeholders!
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'dry/validation/constants'
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
module Validation
|
3
5
|
class Result
|
@@ -12,13 +14,12 @@ module Dry
|
|
12
14
|
alias_method :to_hash, :output
|
13
15
|
alias_method :to_h, :output # for MRI 2.0, remove it when drop support
|
14
16
|
|
15
|
-
EMPTY_MESSAGES = {}.freeze
|
16
|
-
|
17
17
|
def initialize(output, errors, error_compiler, hint_compiler)
|
18
18
|
@output = output
|
19
19
|
@errors = errors
|
20
20
|
@error_compiler = error_compiler
|
21
21
|
@hint_compiler = hint_compiler
|
22
|
+
@messages = EMPTY_HASH if success?
|
22
23
|
end
|
23
24
|
|
24
25
|
def each(&block)
|
@@ -37,22 +38,14 @@ module Dry
|
|
37
38
|
!success?
|
38
39
|
end
|
39
40
|
|
40
|
-
def messages(options =
|
41
|
-
|
42
|
-
|
43
|
-
return EMPTY_MESSAGES if success?
|
44
|
-
hints = hint_compiler.with(options).call
|
45
|
-
msg_set = error_compiler.with(options).(error_ast).with_hints!(hints)
|
46
|
-
|
47
|
-
as_hash = options.fetch(:as_hash, true)
|
41
|
+
def messages(options = EMPTY_HASH)
|
42
|
+
message_set(options).dump
|
43
|
+
end
|
48
44
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
msg_set
|
54
|
-
end
|
55
|
-
end
|
45
|
+
def message_set(options = EMPTY_HASH)
|
46
|
+
error_compiler
|
47
|
+
.with(options).(error_ast)
|
48
|
+
.with_hints!(hint_compiler.with(options).())
|
56
49
|
end
|
57
50
|
|
58
51
|
def to_ast
|
@@ -62,7 +55,7 @@ module Dry
|
|
62
55
|
private
|
63
56
|
|
64
57
|
def error_ast
|
65
|
-
errors.map { |error| error.to_ast }
|
58
|
+
@error_ast ||= errors.map { |error| error.to_ast }
|
66
59
|
end
|
67
60
|
end
|
68
61
|
end
|
@@ -48,7 +48,7 @@ module Dry
|
|
48
48
|
target = dsl.schema_class
|
49
49
|
|
50
50
|
if config.input
|
51
|
-
config.input_rule = dsl.
|
51
|
+
config.input_rule = dsl.infer_predicates(Array(target.config.input))
|
52
52
|
end
|
53
53
|
|
54
54
|
rules = target.config.rules + (options.fetch(:rules, []) + dsl.rules)
|
@@ -171,8 +171,6 @@ module Dry
|
|
171
171
|
self.class.public_methods.include?(name)
|
172
172
|
end
|
173
173
|
|
174
|
-
private
|
175
|
-
|
176
174
|
def infer_predicates(predicates, infer_on = self)
|
177
175
|
predicates.map { |predicate|
|
178
176
|
name, *args = ::Kernel.Array(predicate).first
|
@@ -187,6 +185,8 @@ module Dry
|
|
187
185
|
}.reduce(:and)
|
188
186
|
end
|
189
187
|
|
188
|
+
private
|
189
|
+
|
190
190
|
def method_missing(meth, *args, &block)
|
191
191
|
return schema_class.instance_method(meth) if dyn_arg?(meth)
|
192
192
|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
RSpec.describe Dry::Validation::Result do
|
2
|
+
subject(:result) { schema.(input) }
|
3
|
+
|
4
|
+
let(:schema) { Dry::Validation.Schema { required(:name).filled(:str?) } }
|
5
|
+
|
6
|
+
context 'with valid input' do
|
7
|
+
let(:input) { { name: 'Jane' } }
|
8
|
+
|
9
|
+
it 'is successful' do
|
10
|
+
expect(result).to be_successful
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'is not a failure' do
|
14
|
+
expect(result).to_not be_failure
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'coerces to validated hash' do
|
18
|
+
expect(Hash(result)).to eql(name: 'Jane')
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#messages' do
|
22
|
+
it 'returns an empty hash' do
|
23
|
+
expect(result.messages).to be_empty
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with invalid input' do
|
29
|
+
let(:input) { { name: '' } }
|
30
|
+
|
31
|
+
it 'is not successful' do
|
32
|
+
expect(result).to_not be_successful
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'is failure' do
|
36
|
+
expect(result).to be_failure
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'coerces to validated hash' do
|
40
|
+
expect(Hash(result)).to eql(name: '')
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#messages' do
|
44
|
+
it 'returns a hash with error messages' do
|
45
|
+
expect(result.messages).to eql(name: ['must be filled'])
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'with full: true returns full messages' do
|
49
|
+
expect(result.messages(full: true)).to eql(name: ['name must be filled'])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#message_set' do
|
54
|
+
it 'returns message set' do
|
55
|
+
expect(result.message_set.to_h).to eql(name: ['must be filled'])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
RSpec.describe 'Macros / rule' do
|
2
|
+
shared_context 'password confirmation high-level rule' do
|
3
|
+
subject(:schema) { schema_class.new }
|
4
|
+
|
5
|
+
let(:schema_class) do
|
6
|
+
Dry::Validation.Schema(build: false) do
|
7
|
+
required(:user).schema do
|
8
|
+
required(:password).filled
|
9
|
+
required(:password_confirmation).filled
|
10
|
+
|
11
|
+
rule(password_confirmation: %i[password_confirmation password]) do |pc, p|
|
12
|
+
pc.eql?(p)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'passes when input is valid' do
|
19
|
+
expect(schema.(user: { password: 'foo', password_confirmation: 'foo' })).to be_successful
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'fails when the rule failed' do
|
23
|
+
expect(schema.(user: { password: 'foo', password_confirmation: 'bar' }).messages).to eql(
|
24
|
+
user: { password_confirmation: [error_message] }
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'with the default message' do
|
30
|
+
let(:error_message) { 'must be equal to foo' }
|
31
|
+
|
32
|
+
include_context 'password confirmation high-level rule'
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'with a custom message' do
|
36
|
+
let(:error_message) { 'does not match' }
|
37
|
+
|
38
|
+
before do
|
39
|
+
schema_class.class_eval do
|
40
|
+
def self.messages
|
41
|
+
default_messages.merge(en: { errors: { password_confirmation: 'does not match' } })
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
include_context 'password confirmation high-level rule'
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with two rules relying on the same value' do
|
50
|
+
subject(:schema) do
|
51
|
+
Dry::Validation.Schema do
|
52
|
+
required(:x).filled(:int?)
|
53
|
+
|
54
|
+
rule(a: [:x]) do |x|
|
55
|
+
x.gt?(3)
|
56
|
+
end
|
57
|
+
|
58
|
+
rule(b: [:x]) do |x|
|
59
|
+
x.gt?(5)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'passes when input is valid' do
|
65
|
+
expect(schema.(x: 6)).to be_successful
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'fails when rules failed' do
|
69
|
+
expect(schema.(x: 2).messages).to eql(
|
70
|
+
x: ['must be greater than 3', 'must be greater than 5']
|
71
|
+
)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,459 @@
|
|
1
|
+
RSpec.describe 'Predicates: Excluded From' do
|
2
|
+
|
3
|
+
context "Array" do
|
4
|
+
|
5
|
+
context 'with required' do
|
6
|
+
subject(:schema) do
|
7
|
+
Dry::Validation.Schema do
|
8
|
+
required(:foo) { excluded_from?([1, 3, 5]) }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'with valid input' do
|
13
|
+
let(:input) { { foo: 2 } }
|
14
|
+
|
15
|
+
it 'is successful' do
|
16
|
+
expect(result).to be_successful
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with missing input' do
|
21
|
+
let(:input) { {} }
|
22
|
+
|
23
|
+
it 'is not successful' do
|
24
|
+
expect(result).to be_failing ['is missing', 'must not be one of: 1, 3, 5']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with nil input' do
|
29
|
+
let(:input) { { foo: nil } }
|
30
|
+
|
31
|
+
it 'is successful' do
|
32
|
+
expect(result).to be_successful
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'with blank input' do
|
37
|
+
let(:input) { { foo: '' } }
|
38
|
+
|
39
|
+
it 'is successful' do
|
40
|
+
expect(result).to be_successful
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'with invalid type' do
|
45
|
+
let(:input) { { foo: { a: 1 } } }
|
46
|
+
|
47
|
+
it 'is successful' do
|
48
|
+
expect(result).to be_successful
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'with invalid input' do
|
53
|
+
let(:input) { { foo: 5 } }
|
54
|
+
|
55
|
+
it 'is not successful' do
|
56
|
+
expect(result).to be_failing ['must not be one of: 1, 3, 5']
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with optional' do
|
62
|
+
subject(:schema) do
|
63
|
+
Dry::Validation.Schema do
|
64
|
+
optional(:foo) { excluded_from?([1, 3, 5]) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'with valid input' do
|
69
|
+
let(:input) { { foo: 2 } }
|
70
|
+
|
71
|
+
it 'is successful' do
|
72
|
+
expect(result).to be_successful
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'with missing input' do
|
77
|
+
let(:input) { {} }
|
78
|
+
|
79
|
+
it 'is successful' do
|
80
|
+
expect(result).to be_successful
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'with nil input' do
|
85
|
+
let(:input) { { foo: nil } }
|
86
|
+
|
87
|
+
it 'is successful' do
|
88
|
+
expect(result).to be_successful
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'with blank input' do
|
93
|
+
let(:input) { { foo: '' } }
|
94
|
+
|
95
|
+
it 'is successful' do
|
96
|
+
expect(result).to be_successful
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'with invalid type' do
|
101
|
+
let(:input) { { foo: { a: 1 } } }
|
102
|
+
|
103
|
+
it 'is successful' do
|
104
|
+
expect(result).to be_successful
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'with invalid input' do
|
109
|
+
let(:input) { { foo: 5 } }
|
110
|
+
|
111
|
+
it 'is not successful' do
|
112
|
+
expect(result).to be_failing ['must not be one of: 1, 3, 5']
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'as macro' do
|
118
|
+
context 'with required' do
|
119
|
+
context 'with value' do
|
120
|
+
subject(:schema) do
|
121
|
+
Dry::Validation.Schema do
|
122
|
+
required(:foo).value(excluded_from?: [1, 3, 5])
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context 'with valid input' do
|
127
|
+
let(:input) { { foo: 2 } }
|
128
|
+
|
129
|
+
it 'is successful' do
|
130
|
+
expect(result).to be_successful
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context 'with missing input' do
|
135
|
+
let(:input) { {} }
|
136
|
+
|
137
|
+
it 'is not successful' do
|
138
|
+
expect(result).to be_failing ['is missing', 'must not be one of: 1, 3, 5']
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'with nil input' do
|
143
|
+
let(:input) { { foo: nil } }
|
144
|
+
|
145
|
+
it 'is successful' do
|
146
|
+
expect(result).to be_successful
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'with blank input' do
|
151
|
+
let(:input) { { foo: '' } }
|
152
|
+
|
153
|
+
it 'is successful' do
|
154
|
+
expect(result).to be_successful
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'with invalid type' do
|
159
|
+
let(:input) { { foo: { a: 1 } } }
|
160
|
+
|
161
|
+
it 'is successful' do
|
162
|
+
expect(result).to be_successful
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'with invalid input' do
|
167
|
+
let(:input) { { foo: 5 } }
|
168
|
+
|
169
|
+
it 'is not successful' do
|
170
|
+
expect(result).to be_failing ['must not be one of: 1, 3, 5']
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'with filled' do
|
176
|
+
subject(:schema) do
|
177
|
+
Dry::Validation.Schema do
|
178
|
+
required(:foo).filled(excluded_from?: [1, 3, 5])
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'with valid input' do
|
183
|
+
let(:input) { { foo: 2 } }
|
184
|
+
|
185
|
+
it 'is successful' do
|
186
|
+
expect(result).to be_successful
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'with missing input' do
|
191
|
+
let(:input) { {} }
|
192
|
+
|
193
|
+
it 'is not successful' do
|
194
|
+
expect(result).to be_failing ['is missing', 'must not be one of: 1, 3, 5']
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context 'with nil input' do
|
199
|
+
let(:input) { { foo: nil } }
|
200
|
+
|
201
|
+
it 'is not successful' do
|
202
|
+
expect(result).to be_failing ['must be filled', 'must not be one of: 1, 3, 5']
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'with blank input' do
|
207
|
+
let(:input) { { foo: '' } }
|
208
|
+
|
209
|
+
it 'is not successful' do
|
210
|
+
expect(result).to be_failing ['must be filled', 'must not be one of: 1, 3, 5']
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context 'with invalid type' do
|
215
|
+
let(:input) { { foo: { a: 1 } } }
|
216
|
+
|
217
|
+
it 'is successful' do
|
218
|
+
expect(result).to be_successful
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context 'with invalid input' do
|
223
|
+
let(:input) { { foo: 5 } }
|
224
|
+
|
225
|
+
it 'is not successful' do
|
226
|
+
expect(result).to be_failing ['must not be one of: 1, 3, 5']
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context 'with maybe' do
|
232
|
+
subject(:schema) do
|
233
|
+
Dry::Validation.Schema do
|
234
|
+
required(:foo).maybe(excluded_from?: [1, 3, 5])
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context 'with valid input' do
|
239
|
+
let(:input) { { foo: 2 } }
|
240
|
+
|
241
|
+
it 'is successful' do
|
242
|
+
expect(result).to be_successful
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context 'with missing input' do
|
247
|
+
let(:input) { {} }
|
248
|
+
|
249
|
+
it 'is not successful' do
|
250
|
+
expect(result).to be_failing ['is missing', 'must not be one of: 1, 3, 5']
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context 'with nil input' do
|
255
|
+
let(:input) { { foo: nil } }
|
256
|
+
|
257
|
+
it 'is successful' do
|
258
|
+
expect(result).to be_successful
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
context 'with blank input' do
|
263
|
+
let(:input) { { foo: '' } }
|
264
|
+
|
265
|
+
it 'is successful' do
|
266
|
+
expect(result).to be_successful
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context 'with invalid type' do
|
271
|
+
let(:input) { { foo: { a: 1 } } }
|
272
|
+
|
273
|
+
it 'is successful' do
|
274
|
+
expect(result).to be_successful
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
context 'with invalid input' do
|
279
|
+
let(:input) { { foo: 5 } }
|
280
|
+
|
281
|
+
it 'is not successful' do
|
282
|
+
expect(result).to be_failing ['must not be one of: 1, 3, 5']
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
context 'with optional' do
|
289
|
+
context 'with value' do
|
290
|
+
subject(:schema) do
|
291
|
+
Dry::Validation.Schema do
|
292
|
+
optional(:foo).value(excluded_from?: [1, 3, 5])
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
context 'with valid input' do
|
297
|
+
let(:input) { { foo: 2 } }
|
298
|
+
|
299
|
+
it 'is successful' do
|
300
|
+
expect(result).to be_successful
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
context 'with missing input' do
|
305
|
+
let(:input) { {} }
|
306
|
+
|
307
|
+
it 'is successful' do
|
308
|
+
expect(result).to be_successful
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
context 'with nil input' do
|
313
|
+
let(:input) { { foo: nil } }
|
314
|
+
|
315
|
+
it 'is successful' do
|
316
|
+
expect(result).to be_successful
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
context 'with blank input' do
|
321
|
+
let(:input) { { foo: '' } }
|
322
|
+
|
323
|
+
it 'is successful' do
|
324
|
+
expect(result).to be_successful
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
context 'with invalid type' do
|
329
|
+
let(:input) { { foo: { a: 1 } } }
|
330
|
+
|
331
|
+
it 'is successful' do
|
332
|
+
expect(result).to be_successful
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
context 'with invalid input' do
|
337
|
+
let(:input) { { foo: 5 } }
|
338
|
+
|
339
|
+
it 'is not successful' do
|
340
|
+
expect(result).to be_failing ['must not be one of: 1, 3, 5']
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
context 'with filled' do
|
346
|
+
subject(:schema) do
|
347
|
+
Dry::Validation.Schema do
|
348
|
+
optional(:foo).filled(excluded_from?: [1, 3, 5])
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
context 'with valid input' do
|
353
|
+
let(:input) { { foo: 2 } }
|
354
|
+
|
355
|
+
it 'is successful' do
|
356
|
+
expect(result).to be_successful
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
context 'with missing input' do
|
361
|
+
let(:input) { {} }
|
362
|
+
|
363
|
+
it 'is successful' do
|
364
|
+
expect(result).to be_successful
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
context 'with nil input' do
|
369
|
+
let(:input) { { foo: nil } }
|
370
|
+
|
371
|
+
it 'is not successful' do
|
372
|
+
expect(result).to be_failing ['must be filled', 'must not be one of: 1, 3, 5']
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
context 'with blank input' do
|
377
|
+
let(:input) { { foo: '' } }
|
378
|
+
|
379
|
+
it 'is not successful' do
|
380
|
+
expect(result).to be_failing ['must be filled', 'must not be one of: 1, 3, 5']
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
context 'with invalid type' do
|
385
|
+
let(:input) { { foo: { a: 1 } } }
|
386
|
+
|
387
|
+
it 'is successful' do
|
388
|
+
expect(result).to be_successful
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
context 'with invalid input' do
|
393
|
+
let(:input) { { foo: 5 } }
|
394
|
+
|
395
|
+
it 'is not successful' do
|
396
|
+
expect(result).to be_failing ['must not be one of: 1, 3, 5']
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
context 'with maybe' do
|
402
|
+
subject(:schema) do
|
403
|
+
Dry::Validation.Schema do
|
404
|
+
optional(:foo).maybe(excluded_from?: [1, 3, 5])
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
context 'with valid input' do
|
409
|
+
let(:input) { { foo: 2 } }
|
410
|
+
|
411
|
+
it 'is successful' do
|
412
|
+
expect(result).to be_successful
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
context 'with missing input' do
|
417
|
+
let(:input) { {} }
|
418
|
+
|
419
|
+
it 'is successful' do
|
420
|
+
expect(result).to be_successful
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
context 'with nil input' do
|
425
|
+
let(:input) { { foo: nil } }
|
426
|
+
|
427
|
+
it 'is successful' do
|
428
|
+
expect(result).to be_successful
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
context 'with blank input' do
|
433
|
+
let(:input) { { foo: '' } }
|
434
|
+
|
435
|
+
it 'is successful' do
|
436
|
+
expect(result).to be_successful
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
context 'with invalid type' do
|
441
|
+
let(:input) { { foo: { a: 1 } } }
|
442
|
+
|
443
|
+
it 'is successful' do
|
444
|
+
expect(result).to be_successful
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
context 'with invalid input' do
|
449
|
+
let(:input) { { foo: 5 } }
|
450
|
+
|
451
|
+
it 'is not successful' do
|
452
|
+
expect(result).to be_failing ['must not be one of: 1, 3, 5']
|
453
|
+
end
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|