dry-validation 0.7.3 → 0.7.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/Gemfile +1 -3
- data/config/errors.yml +4 -0
- data/examples/json.rb +12 -0
- data/lib/dry/validation.rb +5 -0
- data/lib/dry/validation/input_processor_compiler.rb +1 -0
- data/lib/dry/validation/input_processor_compiler/json.rb +46 -0
- data/lib/dry/validation/schema.rb +2 -1
- data/lib/dry/validation/schema/dsl.rb +5 -0
- data/lib/dry/validation/schema/json.rb +11 -0
- data/lib/dry/validation/schema/rule.rb +5 -0
- data/lib/dry/validation/schema_compiler.rb +6 -2
- data/lib/dry/validation/version.rb +1 -1
- data/spec/integration/schema/check_with_nested_el_spec.rb +37 -0
- data/spec/integration/schema/json_spec.rb +162 -0
- data/spec/spec_helper.rb +0 -12
- data/spec/unit/input_processor_compiler/json_spec.rb +281 -0
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16d323de18e994f717e80abb07098dc2e82534af
|
4
|
+
data.tar.gz: ef0e116d3f56eb249b70315bf43af0d74a249c58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b9690fa21b55e46d09db96f93d4d58f07d7d5fe7291219d3107f154eda2597e6e7209049403fcb1f518936d025a62d31ed2315e8795a02e7bd017c9ead52b33
|
7
|
+
data.tar.gz: b8ac25905f1f1d602c0f930cc2895b9e6fd27d53fae3dfcc2794e46f255034417e14ce9407491ba19fd2c86276b3e820783890bdac10fb42bf190f72e9577ec3
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
# v0.7.4 2016-04-06
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
* `Schema.JSON` with json-specific coercions (coop)
|
6
|
+
* Support for error messages for `odd? and `even?` predicates (fran-worley)
|
7
|
+
|
8
|
+
### Fixed
|
9
|
+
|
10
|
+
* Depending on deeply nested values in high-level rules works now (solnic)
|
11
|
+
|
12
|
+
[Compare v0.7.3...v0.7.4](https://github.com/dryrb/dry-validation/compare/v0.7.3...v0.7.4)
|
13
|
+
|
1
14
|
# v0.7.3 2016-03-30
|
2
15
|
|
3
16
|
### Added
|
data/Gemfile
CHANGED
data/config/errors.yml
CHANGED
data/examples/json.rb
ADDED
data/lib/dry/validation.rb
CHANGED
@@ -4,6 +4,7 @@ require 'dry-container'
|
|
4
4
|
|
5
5
|
require 'dry/validation/schema'
|
6
6
|
require 'dry/validation/schema/form'
|
7
|
+
require 'dry/validation/schema/json'
|
7
8
|
|
8
9
|
module Dry
|
9
10
|
module Validation
|
@@ -40,5 +41,9 @@ module Dry
|
|
40
41
|
def self.Form(options = {}, &block)
|
41
42
|
Validation.Schema(Schema::Form, options, &block)
|
42
43
|
end
|
44
|
+
|
45
|
+
def self.JSON(options = {}, &block)
|
46
|
+
Validation.Schema(Schema::JSON, options, &block)
|
47
|
+
end
|
43
48
|
end
|
44
49
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Dry
|
2
|
+
module Validation
|
3
|
+
class InputProcessorCompiler::JSON < InputProcessorCompiler
|
4
|
+
PREDICATE_MAP = {
|
5
|
+
default: 'string',
|
6
|
+
none?: 'json.nil',
|
7
|
+
bool?: 'bool',
|
8
|
+
str?: 'string',
|
9
|
+
int?: 'int',
|
10
|
+
float?: 'float',
|
11
|
+
decimal?: 'json.decimal',
|
12
|
+
date?: 'json.date',
|
13
|
+
date_time?: 'json.date_time',
|
14
|
+
time?: 'json.time'
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
CONST_MAP = {
|
18
|
+
NilClass => 'nil',
|
19
|
+
String => 'string',
|
20
|
+
Fixnum => 'int',
|
21
|
+
Integer => 'int',
|
22
|
+
Float => 'float',
|
23
|
+
BigDecimal => 'json.decimal',
|
24
|
+
Array => 'json.array',
|
25
|
+
Hash => 'json.hash',
|
26
|
+
Date => 'json.date',
|
27
|
+
DateTime => 'json.date_time',
|
28
|
+
Time => 'json.time',
|
29
|
+
TrueClass => 'true',
|
30
|
+
FalseClass => 'false'
|
31
|
+
}.freeze
|
32
|
+
|
33
|
+
def identifier
|
34
|
+
:json
|
35
|
+
end
|
36
|
+
|
37
|
+
def hash_node(schema)
|
38
|
+
[:type, ['json.hash', [:symbolized, schema]]]
|
39
|
+
end
|
40
|
+
|
41
|
+
def array_node(members)
|
42
|
+
[:type, ['json.array', members]]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -33,7 +33,8 @@ module Dry
|
|
33
33
|
|
34
34
|
setting :input_processor_map, {
|
35
35
|
sanitizer: InputProcessorCompiler::Sanitizer.new,
|
36
|
-
|
36
|
+
json: InputProcessorCompiler::JSON.new,
|
37
|
+
form: InputProcessorCompiler::Form.new,
|
37
38
|
}.freeze
|
38
39
|
|
39
40
|
def self.inherited(klass)
|
@@ -13,6 +13,11 @@ module Dry
|
|
13
13
|
@options = options
|
14
14
|
end
|
15
15
|
|
16
|
+
def inspect
|
17
|
+
to_ast.inspect
|
18
|
+
end
|
19
|
+
alias_method :to_s, :inspect
|
20
|
+
|
16
21
|
def schema(other = nil, &block)
|
17
22
|
schema = Schema.create_class(target, other, &block)
|
18
23
|
rule = __send__(type, key(:hash?).and(key(schema)))
|
@@ -18,8 +18,12 @@ module Dry
|
|
18
18
|
|
19
19
|
def deps_valid?(results)
|
20
20
|
deps.all? do |path|
|
21
|
-
result =
|
22
|
-
|
21
|
+
result = nil
|
22
|
+
Array(path).each do |name|
|
23
|
+
curr = results[name]
|
24
|
+
result = curr.success? if curr.respond_to?(:success)
|
25
|
+
end
|
26
|
+
result
|
23
27
|
end
|
24
28
|
end
|
25
29
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
RSpec.describe 'Check depending on a nested value from a hash' do
|
2
|
+
subject(:schema) do
|
3
|
+
Dry::Validation.Schema do
|
4
|
+
key(:tag).schema do
|
5
|
+
key(:color).schema do
|
6
|
+
key(:value).required(:str?)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
rule(red: [[:tag, :color, :value]]) do |value|
|
11
|
+
value.eql?('red')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'passes when check passes' do
|
17
|
+
expect(schema.(tag: { color: { value: 'red' }})).to be_success
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'skips check when parent of the dependency failed' do
|
21
|
+
expect(schema.(tag: { color: :oops }).messages).to eql(
|
22
|
+
tag: { color: ['must be a hash'] }
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'skips check when dependency failed' do
|
27
|
+
expect(schema.(tag: { color: { value: :oops }}).messages).to eql(
|
28
|
+
tag: { color: { value: ['must be a string'] } }
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'fails when check fails' do
|
33
|
+
expect(schema.(tag: { color: { value: 'blue' }}).messages).to eql(
|
34
|
+
tag: { color: { value: ['must be equal to red'] } }
|
35
|
+
)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
RSpec.describe Dry::Validation::Schema::JSON, 'defining a schema' do
|
2
|
+
subject(:schema) do
|
3
|
+
Dry::Validation.JSON do
|
4
|
+
key(:email).required
|
5
|
+
|
6
|
+
key(:age).maybe(:int?, gt?: 18)
|
7
|
+
|
8
|
+
key(:address).schema do
|
9
|
+
key(:city).required
|
10
|
+
key(:street).required
|
11
|
+
|
12
|
+
key(:loc).schema do
|
13
|
+
key(:lat).required(:float?)
|
14
|
+
key(:lng).required(:float?)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
optional(:password).maybe.confirmation
|
19
|
+
|
20
|
+
optional(:phone_number).maybe(:int?, gt?: 0)
|
21
|
+
|
22
|
+
rule(:email_valid) { value(:email).email? }
|
23
|
+
|
24
|
+
configure do
|
25
|
+
def email?(value)
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#messages' do
|
33
|
+
it 'returns compiled error messages' do
|
34
|
+
result = schema.('email' => '', 'age' => 19)
|
35
|
+
|
36
|
+
expect(result.messages).to eql(
|
37
|
+
email: ['must be filled'],
|
38
|
+
address: ['is missing'],
|
39
|
+
)
|
40
|
+
|
41
|
+
expect(result.output).to eql(email: '', age: 19)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns hints for nested data' do
|
45
|
+
result = schema.(
|
46
|
+
'email' => 'jane@doe.org',
|
47
|
+
'age' => 19,
|
48
|
+
'address' => {
|
49
|
+
'city' => '',
|
50
|
+
'street' => 'Street 1/2',
|
51
|
+
'loc' => { 'lat' => '123.456', 'lng' => '' }
|
52
|
+
}
|
53
|
+
)
|
54
|
+
|
55
|
+
expect(result.messages).to eql(
|
56
|
+
address: {
|
57
|
+
loc: { lat: ['must be a float'], lng: ['must be filled'] },
|
58
|
+
city: ['must be filled']
|
59
|
+
}
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#call' do
|
65
|
+
it 'passes when attributes are valid' do
|
66
|
+
result = schema.(
|
67
|
+
'email' => 'jane@doe.org',
|
68
|
+
'age' => 19,
|
69
|
+
'address' => {
|
70
|
+
'city' => 'NYC',
|
71
|
+
'street' => 'Street 1/2',
|
72
|
+
'loc' => { 'lat' => 123.456, 'lng' => 456.123 }
|
73
|
+
}
|
74
|
+
)
|
75
|
+
|
76
|
+
expect(result).to be_success
|
77
|
+
|
78
|
+
expect(result.output).to eql(
|
79
|
+
email: 'jane@doe.org', age: 19,
|
80
|
+
address: {
|
81
|
+
city: 'NYC', street: 'Street 1/2',
|
82
|
+
loc: { lat: 123.456, lng: 456.123 }
|
83
|
+
}
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'validates presence of an email and min age value' do
|
88
|
+
result = schema.('email' => '', 'age' => 18)
|
89
|
+
|
90
|
+
expect(result.messages).to eql(
|
91
|
+
address: ['is missing'],
|
92
|
+
age: ['must be greater than 18'],
|
93
|
+
email: ['must be filled']
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'handles optionals' do
|
98
|
+
result = schema.(
|
99
|
+
'email' => 'jane@doe.org',
|
100
|
+
'age' => 19,
|
101
|
+
'phone_number' => 12,
|
102
|
+
'address' => {
|
103
|
+
'city' => 'NYC',
|
104
|
+
'street' => 'Street 1/2',
|
105
|
+
'loc' => { 'lat' => 123.456, 'lng' => 456.123 }
|
106
|
+
}
|
107
|
+
)
|
108
|
+
|
109
|
+
expect(result).to be_success
|
110
|
+
|
111
|
+
expect(result.output).to eql(
|
112
|
+
email: 'jane@doe.org', age: 19, phone_number: 12,
|
113
|
+
address: {
|
114
|
+
city: 'NYC', street: 'Street 1/2',
|
115
|
+
loc: { lat: 123.456, lng: 456.123 }
|
116
|
+
}
|
117
|
+
)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe 'with nested schema in a high-level rule' do
|
122
|
+
subject(:schema) do
|
123
|
+
Dry::Validation.JSON do
|
124
|
+
key(:address).maybe(:hash?)
|
125
|
+
|
126
|
+
key(:delivery).required(:bool?)
|
127
|
+
|
128
|
+
rule(address: [:delivery, :address]) do |delivery, address|
|
129
|
+
delivery.true?.then(address.schema(AddressSchema))
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
before do
|
135
|
+
AddressSchema = Dry::Validation.JSON do
|
136
|
+
key(:city).required
|
137
|
+
key(:zipcode).required(:int?)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
after do
|
142
|
+
Object.send(:remove_const, :AddressSchema)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'succeeds when nested form schema succeeds' do
|
146
|
+
result = schema.(delivery: true, address: { city: 'NYC', zipcode: 123 })
|
147
|
+
expect(result).to be_success
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'does not apply schema when there is no match' do
|
151
|
+
result = schema.(delivery: false, address: nil)
|
152
|
+
expect(result).to be_success
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'fails when nested schema fails' do
|
156
|
+
result = schema.(delivery: true, address: { city: 'NYC', zipcode: 'foo' })
|
157
|
+
expect(result.messages).to eql(
|
158
|
+
address: { zipcode: ['must be an integer'] }
|
159
|
+
)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -19,18 +19,6 @@ Dir[SPEC_ROOT.join('support/**/*.rb')].each(&method(:require))
|
|
19
19
|
|
20
20
|
include Dry::Validation
|
21
21
|
|
22
|
-
class Schema::DSL < BasicObject
|
23
|
-
def inspect
|
24
|
-
to_ast.inspect
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class Schema::Rule < BasicObject
|
29
|
-
def inspect
|
30
|
-
to_ast.inspect
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
22
|
RSpec.configure do |config|
|
35
23
|
config.disable_monkey_patching!
|
36
24
|
|
@@ -0,0 +1,281 @@
|
|
1
|
+
RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
|
2
|
+
subject(:compiler) { Dry::Validation::InputProcessorCompiler::JSON.new }
|
3
|
+
|
4
|
+
it 'supports arbitrary types via type?(const) => "json.const"' do
|
5
|
+
rule_ast = [
|
6
|
+
[
|
7
|
+
:and,
|
8
|
+
[
|
9
|
+
[:val, [:predicate, [:key?, [:age]]]],
|
10
|
+
[:key, [:age, [:predicate, [:type?, [Fixnum]]]]]
|
11
|
+
]
|
12
|
+
]
|
13
|
+
]
|
14
|
+
|
15
|
+
input_type = compiler.(rule_ast)
|
16
|
+
|
17
|
+
expect(input_type['age' => 21]).to eql(age: 21)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'supports arbitrary types via type?(conts)' do
|
21
|
+
rule_ast = [
|
22
|
+
[
|
23
|
+
:and,
|
24
|
+
[
|
25
|
+
[:val, [:predicate, [:key?, [:admin]]]],
|
26
|
+
[:key, [:admin, [:predicate, [:type?, ['Bool']]]]]
|
27
|
+
]
|
28
|
+
]
|
29
|
+
]
|
30
|
+
|
31
|
+
input_type = compiler.(rule_ast)
|
32
|
+
|
33
|
+
expect(input_type['admin' => false]).to eql(admin: false)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'supports str? => "string"' do
|
37
|
+
rule_ast = [
|
38
|
+
[
|
39
|
+
:and,
|
40
|
+
[
|
41
|
+
[:val, [:predicate, [:key?, [:email]]]],
|
42
|
+
[
|
43
|
+
:and, [
|
44
|
+
[:key, [:email, [:predicate, [:str?, []]]]],
|
45
|
+
[:key, [:email, [:predicate, [:filled?, []]]]]
|
46
|
+
]
|
47
|
+
]
|
48
|
+
]
|
49
|
+
]
|
50
|
+
]
|
51
|
+
|
52
|
+
input_type = compiler.(rule_ast)
|
53
|
+
|
54
|
+
expect(input_type['email' => 'jane@doe.org']).to eql(email: 'jane@doe.org')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'supports int? => "int"' do
|
58
|
+
rule_ast = [
|
59
|
+
[
|
60
|
+
:and,
|
61
|
+
[
|
62
|
+
[:val, [:predicate, [:key?, [:age]]]],
|
63
|
+
[:key, [:age, [:predicate, [:int?, []]]]],
|
64
|
+
]
|
65
|
+
]
|
66
|
+
]
|
67
|
+
|
68
|
+
input_type = compiler.(rule_ast)
|
69
|
+
|
70
|
+
expect(input_type['age' => 21]).to eql(age: 21)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'supports bool? => "bool"' do
|
74
|
+
rule_ast = [
|
75
|
+
[
|
76
|
+
:and,
|
77
|
+
[
|
78
|
+
[:val, [:predicate, [:key?, [:admin]]]],
|
79
|
+
[:key, [:admin, [:predicate, [:bool?, []]]]],
|
80
|
+
]
|
81
|
+
]
|
82
|
+
]
|
83
|
+
|
84
|
+
input_type = compiler.(rule_ast)
|
85
|
+
|
86
|
+
expect(input_type['admin' => true]).to eql(admin: true)
|
87
|
+
expect(input_type['admin' => false]).to eql(admin: false)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'supports none? => "int"' do
|
91
|
+
rule_ast = [
|
92
|
+
[
|
93
|
+
:and,
|
94
|
+
[
|
95
|
+
[:val, [:predicate, [:key?, [:age]]]],
|
96
|
+
[
|
97
|
+
:or, [
|
98
|
+
[:key, [:age, [:predicate, [:none?, []]]]],
|
99
|
+
[:key, [:age, [:predicate, [:int?, []]]]],
|
100
|
+
]
|
101
|
+
]
|
102
|
+
]
|
103
|
+
]
|
104
|
+
]
|
105
|
+
|
106
|
+
input_type = compiler.(rule_ast)
|
107
|
+
|
108
|
+
expect(input_type['age' => '']).to eql(age: nil)
|
109
|
+
expect(input_type['age' => 21]).to eql(age: 21)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'supports float? => "float"' do
|
113
|
+
rule_ast = [
|
114
|
+
[
|
115
|
+
:and,
|
116
|
+
[
|
117
|
+
[:val, [:predicate, [:key?, [:lat]]]],
|
118
|
+
[:key, [:lat, [:predicate, [:float?, []]]]],
|
119
|
+
]
|
120
|
+
]
|
121
|
+
]
|
122
|
+
|
123
|
+
input_type = compiler.(rule_ast)
|
124
|
+
|
125
|
+
expect(input_type['lat' => 21.12]).to eql(lat: 21.12)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'supports decimal? => "json.decimal"' do
|
129
|
+
rule_ast = [
|
130
|
+
[
|
131
|
+
:and,
|
132
|
+
[
|
133
|
+
[:val, [:predicate, [:key?, [:lat]]]],
|
134
|
+
[:key, [:lat, [:predicate, [:decimal?, []]]]],
|
135
|
+
]
|
136
|
+
]
|
137
|
+
]
|
138
|
+
|
139
|
+
input_type = compiler.(rule_ast)
|
140
|
+
|
141
|
+
expect(input_type['lat' => 21.12]).to eql(lat: 21.12.to_d)
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'supports date? => "json.date"' do
|
145
|
+
rule_ast = [
|
146
|
+
[
|
147
|
+
:and,
|
148
|
+
[
|
149
|
+
[:val, [:predicate, [:key?, [:bday]]]],
|
150
|
+
[:key, [:bday, [:predicate, [:date?, []]]]],
|
151
|
+
]
|
152
|
+
]
|
153
|
+
]
|
154
|
+
|
155
|
+
input_type = compiler.(rule_ast)
|
156
|
+
|
157
|
+
expect(input_type['bday' => '2012-01-23']).to eql(bday: Date.new(2012, 1, 23))
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'supports date_time? => "json.date_time"' do
|
161
|
+
rule_ast = [
|
162
|
+
[
|
163
|
+
:and,
|
164
|
+
[
|
165
|
+
[:val, [:predicate, [:key?, [:bday]]]],
|
166
|
+
[:key, [:bday, [:predicate, [:date_time?, []]]]],
|
167
|
+
]
|
168
|
+
]
|
169
|
+
]
|
170
|
+
|
171
|
+
input_type = compiler.(rule_ast)
|
172
|
+
|
173
|
+
expect(input_type['bday' => '2012-01-23 11:07']).to eql(bday: DateTime.new(2012, 1, 23, 11, 7))
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'supports time? => "json.time"' do
|
177
|
+
rule_ast = [
|
178
|
+
[
|
179
|
+
:and,
|
180
|
+
[
|
181
|
+
[:val, [:predicate, [:key?, [:bday]]]],
|
182
|
+
[:key, [:bday, [:predicate, [:time?, []]]]],
|
183
|
+
]
|
184
|
+
]
|
185
|
+
]
|
186
|
+
|
187
|
+
input_type = compiler.(rule_ast)
|
188
|
+
|
189
|
+
expect(input_type['bday' => '2012-01-23 11:07']).to eql(bday: Time.new(2012, 1, 23, 11, 7))
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'supports each rule' do
|
193
|
+
rule_ast = [
|
194
|
+
[
|
195
|
+
:and, [
|
196
|
+
[:val, [:predicate, [:key?, [:author]]]],
|
197
|
+
[:set, [
|
198
|
+
[:and, [
|
199
|
+
[:val, [:predicate, [:key?, [:books]]]],
|
200
|
+
[
|
201
|
+
:each, [
|
202
|
+
:set, [
|
203
|
+
[
|
204
|
+
:and, [
|
205
|
+
[:val, [:predicate, [:key?, [:published]]]],
|
206
|
+
[:key, [:published, [:predicate, [:bool?, []]]]]
|
207
|
+
]
|
208
|
+
]
|
209
|
+
]
|
210
|
+
]
|
211
|
+
]
|
212
|
+
]]
|
213
|
+
]]
|
214
|
+
]
|
215
|
+
]
|
216
|
+
]
|
217
|
+
|
218
|
+
input_type = compiler.(rule_ast)
|
219
|
+
|
220
|
+
expect(input_type['author' => { 'books' => [{ 'published' => true }] }]).to eql(
|
221
|
+
author: { books: [published: true] }
|
222
|
+
)
|
223
|
+
|
224
|
+
expect(input_type['author' => { 'books' => [{ 'published' => false }] }]).to eql(
|
225
|
+
author: { books: [published: false] }
|
226
|
+
)
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'supports array? with an each rule' do
|
230
|
+
rule_ast = [
|
231
|
+
[
|
232
|
+
:and, [
|
233
|
+
[:val, [:predicate, [:key?, [:ids]]]],
|
234
|
+
[:and, [
|
235
|
+
[:key, [:ids, [:predicate, [:array?, []]]]],
|
236
|
+
[:each, [:val, [:predicate, [:int?, []]]]]
|
237
|
+
]]
|
238
|
+
]
|
239
|
+
]
|
240
|
+
]
|
241
|
+
|
242
|
+
input_type = compiler.(rule_ast)
|
243
|
+
|
244
|
+
expect(input_type.('ids' => 'oops')).to eql(ids: 'oops')
|
245
|
+
|
246
|
+
expect(input_type.('ids' => [1, 2, 3])).to eql(ids: [1, 2, 3])
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'supports hash? with a set rule' do
|
250
|
+
rule_ast = [
|
251
|
+
[
|
252
|
+
:and, [
|
253
|
+
[:val, [:predicate, [:key?, [:address]]]],
|
254
|
+
[
|
255
|
+
:and, [
|
256
|
+
[:key, [:address, [:predicate, [:hash?, []]]]],
|
257
|
+
[
|
258
|
+
:set, [
|
259
|
+
[
|
260
|
+
:and, [
|
261
|
+
[:val, [:predicate, [:key?, [:street]]]],
|
262
|
+
[:key, [:street, [:predicate, [:filled?, []]]]]
|
263
|
+
]
|
264
|
+
]
|
265
|
+
]
|
266
|
+
]
|
267
|
+
]
|
268
|
+
]
|
269
|
+
]
|
270
|
+
]
|
271
|
+
]
|
272
|
+
|
273
|
+
input_type = compiler.(rule_ast)
|
274
|
+
|
275
|
+
expect(input_type.('address' => 'oops')).to eql(address: 'oops')
|
276
|
+
|
277
|
+
expect(input_type.('address' => { 'street' => 'ok' })).to eql(
|
278
|
+
address: { street: 'ok' }
|
279
|
+
)
|
280
|
+
end
|
281
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-validation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Holland
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-04-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: concurrent-ruby
|
@@ -183,6 +183,7 @@ files:
|
|
183
183
|
- examples/basic.rb
|
184
184
|
- examples/each.rb
|
185
185
|
- examples/form.rb
|
186
|
+
- examples/json.rb
|
186
187
|
- examples/nested.rb
|
187
188
|
- examples/rule_ast.rb
|
188
189
|
- lib/dry-validation.rb
|
@@ -193,6 +194,7 @@ files:
|
|
193
194
|
- lib/dry/validation/hint_compiler.rb
|
194
195
|
- lib/dry/validation/input_processor_compiler.rb
|
195
196
|
- lib/dry/validation/input_processor_compiler/form.rb
|
197
|
+
- lib/dry/validation/input_processor_compiler/json.rb
|
196
198
|
- lib/dry/validation/input_processor_compiler/sanitizer.rb
|
197
199
|
- lib/dry/validation/messages.rb
|
198
200
|
- lib/dry/validation/messages/abstract.rb
|
@@ -205,6 +207,7 @@ files:
|
|
205
207
|
- lib/dry/validation/schema/check.rb
|
206
208
|
- lib/dry/validation/schema/dsl.rb
|
207
209
|
- lib/dry/validation/schema/form.rb
|
210
|
+
- lib/dry/validation/schema/json.rb
|
208
211
|
- lib/dry/validation/schema/key.rb
|
209
212
|
- lib/dry/validation/schema/rule.rb
|
210
213
|
- lib/dry/validation/schema/value.rb
|
@@ -223,11 +226,13 @@ files:
|
|
223
226
|
- spec/integration/optional_keys_spec.rb
|
224
227
|
- spec/integration/schema/array_schema_spec.rb
|
225
228
|
- spec/integration/schema/check_rules_spec.rb
|
229
|
+
- spec/integration/schema/check_with_nested_el_spec.rb
|
226
230
|
- spec/integration/schema/check_with_nth_el_spec.rb
|
227
231
|
- spec/integration/schema/each_with_set_spec.rb
|
228
232
|
- spec/integration/schema/form_spec.rb
|
229
233
|
- spec/integration/schema/inheriting_schema_spec.rb
|
230
234
|
- spec/integration/schema/input_processor_spec.rb
|
235
|
+
- spec/integration/schema/json_spec.rb
|
231
236
|
- spec/integration/schema/macros/confirmation_spec.rb
|
232
237
|
- spec/integration/schema/macros/each_spec.rb
|
233
238
|
- spec/integration/schema/macros/maybe_spec.rb
|
@@ -247,6 +252,7 @@ files:
|
|
247
252
|
- spec/unit/error_compiler_spec.rb
|
248
253
|
- spec/unit/hint_compiler_spec.rb
|
249
254
|
- spec/unit/input_processor_compiler/form_spec.rb
|
255
|
+
- spec/unit/input_processor_compiler/json_spec.rb
|
250
256
|
- spec/unit/schema/key_spec.rb
|
251
257
|
- spec/unit/schema/rule_spec.rb
|
252
258
|
- spec/unit/schema/value_spec.rb
|
@@ -289,11 +295,13 @@ test_files:
|
|
289
295
|
- spec/integration/optional_keys_spec.rb
|
290
296
|
- spec/integration/schema/array_schema_spec.rb
|
291
297
|
- spec/integration/schema/check_rules_spec.rb
|
298
|
+
- spec/integration/schema/check_with_nested_el_spec.rb
|
292
299
|
- spec/integration/schema/check_with_nth_el_spec.rb
|
293
300
|
- spec/integration/schema/each_with_set_spec.rb
|
294
301
|
- spec/integration/schema/form_spec.rb
|
295
302
|
- spec/integration/schema/inheriting_schema_spec.rb
|
296
303
|
- spec/integration/schema/input_processor_spec.rb
|
304
|
+
- spec/integration/schema/json_spec.rb
|
297
305
|
- spec/integration/schema/macros/confirmation_spec.rb
|
298
306
|
- spec/integration/schema/macros/each_spec.rb
|
299
307
|
- spec/integration/schema/macros/maybe_spec.rb
|
@@ -313,6 +321,7 @@ test_files:
|
|
313
321
|
- spec/unit/error_compiler_spec.rb
|
314
322
|
- spec/unit/hint_compiler_spec.rb
|
315
323
|
- spec/unit/input_processor_compiler/form_spec.rb
|
324
|
+
- spec/unit/input_processor_compiler/json_spec.rb
|
316
325
|
- spec/unit/schema/key_spec.rb
|
317
326
|
- spec/unit/schema/rule_spec.rb
|
318
327
|
- spec/unit/schema/value_spec.rb
|