parametric 0.2.19 → 0.2.20
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/README.md +21 -0
- data/lib/parametric/field.rb +1 -1
- data/lib/parametric/field_dsl.rb +4 -0
- data/lib/parametric/nullable_policy.rb +57 -0
- data/lib/parametric/policies.rb +3 -0
- data/lib/parametric/policy_adapter.rb +8 -0
- data/lib/parametric/version.rb +1 -1
- data/spec/nullable_policy_spec.rb +111 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a4f53d13fdfe4476f9467127b58740f86b8f301979b56940eb9e228fd588225
|
4
|
+
data.tar.gz: 5b26af44589c43bc2825a75e988318eefc3147581183a4c4cc65af5b98a47fed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5f7fbdfee4363b05e2044439499bd17954552b6a8c9b95442a613969e4775dcc2d05ee2340ba06df3b55b12df2414a16b672fe76c5b1ee2485ba6dede5cbdf7
|
7
|
+
data.tar.gz: 9ea239bd608ef85e8f92a07060e10aff57b0552b92562b4e4ea1507e1a91a71173382565fd7f198d8f3a2595756b8a6badeb46638de14997fd15bf13250e4910
|
data/README.md
CHANGED
@@ -293,6 +293,21 @@ Like `:declared`, it stops the policy chain if a key is not in input, but it als
|
|
293
293
|
field(:name).policy(:declared_no_default).present
|
294
294
|
```
|
295
295
|
|
296
|
+
### :nullable
|
297
|
+
|
298
|
+
Check that key is present in input. If value is `nil`, processing and validations stop, but key is still included in output.
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
schema = Parametric::Schema.new do
|
302
|
+
field(:age).nullable.type(:integer).policy(:gt: 21)
|
303
|
+
end
|
304
|
+
|
305
|
+
schema.resolve(age: '22').output[:age] # 22
|
306
|
+
schema.resolve(age: 10).errors[:age] # has error because < 21
|
307
|
+
schema.resolve(age: nil).output[:age] # nil, no errors
|
308
|
+
schema.resolve({}).output[:age] # nil, no errors
|
309
|
+
```
|
310
|
+
|
296
311
|
### :gt
|
297
312
|
|
298
313
|
Validate that the value is greater than a number
|
@@ -387,6 +402,12 @@ class MyPolicyRunner
|
|
387
402
|
true
|
388
403
|
end
|
389
404
|
|
405
|
+
# If this policy is not eligible, should the key and value be included in the output?
|
406
|
+
# @return [Boolean]
|
407
|
+
def include_non_eligible_in_ouput?
|
408
|
+
true
|
409
|
+
end
|
410
|
+
|
390
411
|
# If [false], add [#message] to result errors and halt processing field.
|
391
412
|
# @return [Boolean]
|
392
413
|
def valid?
|
data/lib/parametric/field.rb
CHANGED
@@ -88,7 +88,7 @@ module Parametric
|
|
88
88
|
begin
|
89
89
|
pol = policy.build(key, value, payload:, context:)
|
90
90
|
if !pol.eligible?
|
91
|
-
eligible =
|
91
|
+
eligible = pol.include_non_eligible_in_ouput?
|
92
92
|
if has_default?
|
93
93
|
eligible = true
|
94
94
|
value = default_block.call(key, payload, context)
|
data/lib/parametric/field_dsl.rb
CHANGED
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Parametric
|
4
|
+
# A policy that allows a field to be nullable.
|
5
|
+
# Fields with nil values are not processed further, and the value is returned as-is.
|
6
|
+
# @example
|
7
|
+
# field(:age).nullable.type(:integer)
|
8
|
+
# field(:age).nullable.type(:integer).required
|
9
|
+
#
|
10
|
+
class NullablePolicy
|
11
|
+
def meta_data; {}; end
|
12
|
+
|
13
|
+
def build(key, value, payload:, context:)
|
14
|
+
Runner.new(key, value, payload, context)
|
15
|
+
end
|
16
|
+
|
17
|
+
class Runner
|
18
|
+
def initialize(key, value, payload, context)
|
19
|
+
@key = key
|
20
|
+
@value = value
|
21
|
+
@payload = payload
|
22
|
+
@context = context
|
23
|
+
end
|
24
|
+
|
25
|
+
# Should this policy run at all?
|
26
|
+
# returning [false] halts the field policy chain.
|
27
|
+
# @return [Boolean]
|
28
|
+
def eligible?
|
29
|
+
@payload.key?(@key) && !@value.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
# If this policy is not eligible, should the key and value be included in the output?
|
33
|
+
# @return [Boolean]
|
34
|
+
def include_non_eligible_in_ouput?
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
# If [false], add [#message] to result errors and halt processing field.
|
39
|
+
# @return [Boolean]
|
40
|
+
def valid?
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
# Coerce the value, or return as-is.
|
45
|
+
# @return [Any]
|
46
|
+
def value
|
47
|
+
@value
|
48
|
+
end
|
49
|
+
|
50
|
+
# Error message for this policy
|
51
|
+
# @return [String]
|
52
|
+
def message
|
53
|
+
''
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/parametric/policies.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'parametric/nullable_policy'
|
4
|
+
|
3
5
|
module Parametric
|
4
6
|
module Policies
|
5
7
|
class Format
|
@@ -59,6 +61,7 @@ module Parametric
|
|
59
61
|
Parametric.policy :format, Policies::Format
|
60
62
|
Parametric.policy :email, Policies::Format.new(EMAIL_REGEXP, 'invalid email')
|
61
63
|
Parametric.policy :value, Policies::Value
|
64
|
+
Parametric.policy :nullable, Parametric::NullablePolicy
|
62
65
|
|
63
66
|
Parametric.policy :noop do
|
64
67
|
eligible do |value, key, payload|
|
@@ -14,6 +14,14 @@ module Parametric
|
|
14
14
|
@policy.eligible?(@raw_value, @key, @payload)
|
15
15
|
end
|
16
16
|
|
17
|
+
# If a policy is not #eligible?, use this to decide if its key
|
18
|
+
# should still be included in output hash.
|
19
|
+
#
|
20
|
+
# @return [Boolean]
|
21
|
+
def include_non_eligible_in_ouput?
|
22
|
+
false
|
23
|
+
end
|
24
|
+
|
17
25
|
# @return [Boolean]
|
18
26
|
def valid?
|
19
27
|
@policy.valid?(value, @key, @payload)
|
data/lib/parametric/version.rb
CHANGED
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'nullable policy' do
|
6
|
+
specify 'dealing with nil values' do
|
7
|
+
schema = Parametric::Schema.new do
|
8
|
+
field(:age).nullable.type(:integer)
|
9
|
+
end
|
10
|
+
|
11
|
+
expect(schema.resolve({ age: 10 }).output[:age]).to eq 10
|
12
|
+
expect(schema.resolve({ age: '10' }).output[:age]).to eq 10
|
13
|
+
expect(schema.resolve({ age: nil }).output[:age]).to eq nil
|
14
|
+
expect(schema.resolve({ age: false }).output[:age]).to be false
|
15
|
+
expect(schema.resolve({ nope: 1 }).output.key?(:age)).to be true
|
16
|
+
end
|
17
|
+
|
18
|
+
specify 'with required/present types' do
|
19
|
+
schema = Parametric::Schema.new do
|
20
|
+
field(:age).nullable.type(:integer).present.policy(:gt, 9)
|
21
|
+
end
|
22
|
+
|
23
|
+
schema.resolve({ age: '10' }).tap do |r|
|
24
|
+
expect(r.output[:age]).to eq 10
|
25
|
+
expect(r.errors.any?).to be false
|
26
|
+
end
|
27
|
+
|
28
|
+
schema.resolve({ age: '7' }).tap do |r|
|
29
|
+
expect(r.output[:age]).to eq 7
|
30
|
+
expect(r.errors.any?).to be true
|
31
|
+
end
|
32
|
+
|
33
|
+
schema.resolve({ age: nil }).tap do |r|
|
34
|
+
expect(r.output[:age]).to eq nil
|
35
|
+
expect(r.errors.any?).to be false
|
36
|
+
end
|
37
|
+
|
38
|
+
schema.resolve({}).tap do |r|
|
39
|
+
expect(r.output.key?(:age)).to be true
|
40
|
+
expect(r.output[:age]).to eq nil
|
41
|
+
expect(r.errors.any?).to be false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
specify 'interacting with custom types that validate' do
|
46
|
+
Parametric.policy :validating_integer do
|
47
|
+
exp = /^\d+$/
|
48
|
+
|
49
|
+
validate do |value, _key, _context|
|
50
|
+
!!(value.to_s =~ exp)
|
51
|
+
end
|
52
|
+
|
53
|
+
coerce do |value, _key, _context|
|
54
|
+
if value.to_s =~ exp
|
55
|
+
value.to_i
|
56
|
+
else
|
57
|
+
value
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
message do
|
62
|
+
'error!'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
schema = Parametric::Schema.new do
|
67
|
+
field(:age).nullable.type(:validating_integer)
|
68
|
+
end
|
69
|
+
|
70
|
+
expect(schema.resolve({ age: 10 }).output[:age]).to eq 10
|
71
|
+
expect(schema.resolve({ age: '10' }).output[:age]).to eq 10
|
72
|
+
schema.resolve({ age: 'nope' }).tap do |r|
|
73
|
+
expect(r.output[:age]).to eq 'nope'
|
74
|
+
expect(r.errors.any?).to be true
|
75
|
+
end
|
76
|
+
schema.resolve({ age: nil }).tap do |r|
|
77
|
+
expect(r.output.key?(:age)).to be(true)
|
78
|
+
expect(r.output[:age]).to eq nil
|
79
|
+
expect(r.errors.any?).to be false
|
80
|
+
end
|
81
|
+
expect(schema.resolve({ age: nil }).output[:age]).to eq nil
|
82
|
+
expect(schema.resolve({ nope: 1 }).output.key?(:age)).to be true
|
83
|
+
end
|
84
|
+
|
85
|
+
specify 'interacting with required fields' do
|
86
|
+
schema = Parametric::Schema.new do
|
87
|
+
field(:age).nullable.type(:integer).required
|
88
|
+
end
|
89
|
+
|
90
|
+
result = schema.resolve({})
|
91
|
+
expect(result.output.key?(:age)).to be(true)
|
92
|
+
expect(result.output[:age]).to eq nil
|
93
|
+
expect(result.errors['$.age']).to eq nil
|
94
|
+
end
|
95
|
+
|
96
|
+
specify 'copying policies via Field#from' do
|
97
|
+
source_schema = Parametric::Schema.new do
|
98
|
+
field(:age).nullable.type(:integer).required
|
99
|
+
end
|
100
|
+
|
101
|
+
target_schema = Parametric::Schema.new do |sc, _|
|
102
|
+
source_schema.fields.each do |key, f|
|
103
|
+
sc.field(key).from(f)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
result = target_schema.resolve({})
|
108
|
+
expect(result.output[:age]).to eq nil
|
109
|
+
expect(result.errors['$.age']).to eq nil
|
110
|
+
end
|
111
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parametric
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ismael Celis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- lib/parametric/dsl.rb
|
77
77
|
- lib/parametric/field.rb
|
78
78
|
- lib/parametric/field_dsl.rb
|
79
|
+
- lib/parametric/nullable_policy.rb
|
79
80
|
- lib/parametric/policies.rb
|
80
81
|
- lib/parametric/policy_adapter.rb
|
81
82
|
- lib/parametric/registry.rb
|
@@ -89,6 +90,7 @@ files:
|
|
89
90
|
- spec/dsl_spec.rb
|
90
91
|
- spec/expand_spec.rb
|
91
92
|
- spec/field_spec.rb
|
93
|
+
- spec/nullable_policy_spec.rb
|
92
94
|
- spec/policies_spec.rb
|
93
95
|
- spec/schema_lifecycle_hooks_spec.rb
|
94
96
|
- spec/schema_spec.rb
|
@@ -115,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
117
|
- !ruby/object:Gem::Version
|
116
118
|
version: '0'
|
117
119
|
requirements: []
|
118
|
-
rubygems_version: 3.4.
|
120
|
+
rubygems_version: 3.4.22
|
119
121
|
signing_key:
|
120
122
|
specification_version: 4
|
121
123
|
summary: DSL for declaring allowed parameters with options, regexp patern and default
|
@@ -125,6 +127,7 @@ test_files:
|
|
125
127
|
- spec/dsl_spec.rb
|
126
128
|
- spec/expand_spec.rb
|
127
129
|
- spec/field_spec.rb
|
130
|
+
- spec/nullable_policy_spec.rb
|
128
131
|
- spec/policies_spec.rb
|
129
132
|
- spec/schema_lifecycle_hooks_spec.rb
|
130
133
|
- spec/schema_spec.rb
|