dry-validation 0.7.3 → 0.7.4
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 +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
|