dry-validation 0.1.0 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +969 -1
- data/LICENSE +1 -1
- data/README.md +19 -286
- data/config/errors.yml +4 -35
- data/dry-validation.gemspec +38 -22
- data/lib/dry/validation/config.rb +24 -0
- data/lib/dry/validation/constants.rb +43 -0
- data/lib/dry/validation/contract/class_interface.rb +230 -0
- data/lib/dry/validation/contract.rb +173 -0
- data/lib/dry/validation/evaluator.rb +233 -0
- data/lib/dry/validation/extensions/hints.rb +67 -0
- data/lib/dry/validation/extensions/monads.rb +34 -0
- data/lib/dry/validation/extensions/predicates_as_macros.rb +75 -0
- data/lib/dry/validation/failures.rb +70 -0
- data/lib/dry/validation/function.rb +43 -0
- data/lib/dry/validation/macro.rb +38 -0
- data/lib/dry/validation/macros.rb +104 -0
- data/lib/dry/validation/message.rb +100 -0
- data/lib/dry/validation/message_set.rb +97 -0
- data/lib/dry/validation/messages/resolver.rb +129 -0
- data/lib/dry/validation/result.rb +206 -38
- data/lib/dry/validation/rule.rb +116 -106
- data/lib/dry/validation/schema_ext.rb +19 -0
- data/lib/dry/validation/values.rb +108 -0
- data/lib/dry/validation/version.rb +3 -1
- data/lib/dry/validation.rb +55 -7
- data/lib/dry-validation.rb +3 -1
- metadata +80 -106
- data/.gitignore +0 -8
- data/.rspec +0 -3
- data/.rubocop.yml +0 -16
- data/.rubocop_todo.yml +0 -7
- data/.travis.yml +0 -29
- data/Gemfile +0 -11
- data/Rakefile +0 -12
- data/examples/basic.rb +0 -21
- data/examples/nested.rb +0 -30
- data/examples/rule_ast.rb +0 -33
- data/lib/dry/validation/error.rb +0 -43
- data/lib/dry/validation/error_compiler.rb +0 -116
- data/lib/dry/validation/messages.rb +0 -71
- data/lib/dry/validation/predicate.rb +0 -39
- data/lib/dry/validation/predicate_set.rb +0 -22
- data/lib/dry/validation/predicates.rb +0 -88
- data/lib/dry/validation/rule_compiler.rb +0 -57
- data/lib/dry/validation/schema/definition.rb +0 -15
- data/lib/dry/validation/schema/key.rb +0 -39
- data/lib/dry/validation/schema/rule.rb +0 -28
- data/lib/dry/validation/schema/value.rb +0 -31
- data/lib/dry/validation/schema.rb +0 -74
- data/rakelib/rubocop.rake +0 -18
- data/spec/fixtures/errors.yml +0 -4
- data/spec/integration/custom_error_messages_spec.rb +0 -35
- data/spec/integration/custom_predicates_spec.rb +0 -57
- data/spec/integration/validation_spec.rb +0 -118
- data/spec/shared/predicates.rb +0 -31
- data/spec/spec_helper.rb +0 -18
- data/spec/unit/error_compiler_spec.rb +0 -165
- data/spec/unit/predicate_spec.rb +0 -37
- data/spec/unit/predicates/empty_spec.rb +0 -38
- data/spec/unit/predicates/eql_spec.rb +0 -21
- data/spec/unit/predicates/exclusion_spec.rb +0 -35
- data/spec/unit/predicates/filled_spec.rb +0 -38
- data/spec/unit/predicates/format_spec.rb +0 -21
- data/spec/unit/predicates/gt_spec.rb +0 -40
- data/spec/unit/predicates/gteq_spec.rb +0 -40
- data/spec/unit/predicates/inclusion_spec.rb +0 -35
- data/spec/unit/predicates/int_spec.rb +0 -34
- data/spec/unit/predicates/key_spec.rb +0 -29
- data/spec/unit/predicates/lt_spec.rb +0 -40
- data/spec/unit/predicates/lteq_spec.rb +0 -40
- data/spec/unit/predicates/max_size_spec.rb +0 -49
- data/spec/unit/predicates/min_size_spec.rb +0 -49
- data/spec/unit/predicates/nil_spec.rb +0 -28
- data/spec/unit/predicates/size_spec.rb +0 -49
- data/spec/unit/predicates/str_spec.rb +0 -32
- data/spec/unit/rule/each_spec.rb +0 -20
- data/spec/unit/rule/key_spec.rb +0 -27
- data/spec/unit/rule/set_spec.rb +0 -32
- data/spec/unit/rule/value_spec.rb +0 -42
- data/spec/unit/rule_compiler_spec.rb +0 -86
@@ -1,71 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'pathname'
|
3
|
-
|
4
|
-
module Dry
|
5
|
-
module Validation
|
6
|
-
class Messages
|
7
|
-
DEFAULT_PATH = Pathname(__dir__).join('../../../config/errors.yml').freeze
|
8
|
-
|
9
|
-
attr_reader :data
|
10
|
-
|
11
|
-
def self.default
|
12
|
-
load(DEFAULT_PATH)
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.load(path)
|
16
|
-
new(load_yaml(path))
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.load_yaml(path)
|
20
|
-
symbolize_keys(YAML.load_file(path))
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.symbolize_keys(hash)
|
24
|
-
hash.each_with_object({}) do |(k, v), r|
|
25
|
-
r[k.to_sym] = v.is_a?(Hash) ? symbolize_keys(v) : v
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
class Namespaced
|
30
|
-
attr_reader :namespace, :fallback
|
31
|
-
|
32
|
-
def initialize(namespace, fallback)
|
33
|
-
@namespace = namespace
|
34
|
-
@fallback = fallback
|
35
|
-
end
|
36
|
-
|
37
|
-
def lookup(*args)
|
38
|
-
namespace.lookup(*args) { fallback.lookup(*args) }
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def initialize(data)
|
43
|
-
@data = data
|
44
|
-
end
|
45
|
-
|
46
|
-
def merge(overrides)
|
47
|
-
if overrides.is_a?(Hash)
|
48
|
-
self.class.new(data.merge(overrides))
|
49
|
-
else
|
50
|
-
self.class.new(data.merge(Messages.load_yaml(overrides)))
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def namespaced(namespace)
|
55
|
-
Namespaced.new(Messages.new(data[namespace]), self)
|
56
|
-
end
|
57
|
-
|
58
|
-
def lookup(identifier, key, arg, &block)
|
59
|
-
message = data.fetch(:attributes, {}).fetch(key, {}).fetch(identifier) do
|
60
|
-
data.fetch(identifier, &block)
|
61
|
-
end
|
62
|
-
|
63
|
-
if message.is_a?(Hash)
|
64
|
-
message.fetch(arg.class.name.downcase.to_sym, message.fetch(:default))
|
65
|
-
else
|
66
|
-
message
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
module Dry
|
2
|
-
module Validation
|
3
|
-
def self.Predicate(block)
|
4
|
-
case block
|
5
|
-
when Method then Predicate.new(block.name, &block)
|
6
|
-
else raise ArgumentError, 'predicate needs an :id'
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
class Predicate
|
11
|
-
include Dry::Equalizer(:id)
|
12
|
-
|
13
|
-
attr_reader :id, :args, :fn
|
14
|
-
|
15
|
-
def initialize(id, *args, &block)
|
16
|
-
@id = id
|
17
|
-
@fn = block
|
18
|
-
@args = args
|
19
|
-
end
|
20
|
-
|
21
|
-
def call(*args)
|
22
|
-
fn.(*args)
|
23
|
-
end
|
24
|
-
|
25
|
-
def negation
|
26
|
-
self.class.new(:"not_#{id}") { |input| !fn.(input) }
|
27
|
-
end
|
28
|
-
|
29
|
-
def curry(*args)
|
30
|
-
self.class.new(id, *args, &fn.curry.(*args))
|
31
|
-
end
|
32
|
-
|
33
|
-
def to_ary
|
34
|
-
[:predicate, [id, args]]
|
35
|
-
end
|
36
|
-
alias_method :to_a, :to_ary
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'dry/validation/predicate'
|
2
|
-
|
3
|
-
module Dry
|
4
|
-
module Validation
|
5
|
-
module PredicateSet
|
6
|
-
module Methods
|
7
|
-
def predicate(name, &block)
|
8
|
-
register(name) { Predicate.new(name, &block) }
|
9
|
-
end
|
10
|
-
|
11
|
-
def import(predicate_set)
|
12
|
-
merge(predicate_set)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.extended(other)
|
17
|
-
super
|
18
|
-
other.extend(Methods, Dry::Container::Mixin)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
require 'dry/validation/predicate_set'
|
2
|
-
|
3
|
-
module Dry
|
4
|
-
module Validation
|
5
|
-
module Predicates
|
6
|
-
extend PredicateSet
|
7
|
-
|
8
|
-
def self.included(other)
|
9
|
-
super
|
10
|
-
other.extend(PredicateSet)
|
11
|
-
other.import(self)
|
12
|
-
end
|
13
|
-
|
14
|
-
predicate(:nil?) do |input|
|
15
|
-
input.nil?
|
16
|
-
end
|
17
|
-
|
18
|
-
predicate(:key?) do |name, input|
|
19
|
-
input.key?(name)
|
20
|
-
end
|
21
|
-
|
22
|
-
predicate(:empty?) do |input|
|
23
|
-
case input
|
24
|
-
when String, Array, Hash then input.empty?
|
25
|
-
when nil then true
|
26
|
-
else
|
27
|
-
false
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
predicate(:filled?) do |input|
|
32
|
-
!self[:empty?].(input)
|
33
|
-
end
|
34
|
-
|
35
|
-
predicate(:int?) do |input|
|
36
|
-
input.is_a?(Fixnum)
|
37
|
-
end
|
38
|
-
|
39
|
-
predicate(:str?) do |input|
|
40
|
-
input.is_a?(String)
|
41
|
-
end
|
42
|
-
|
43
|
-
predicate(:lt?) do |num, input|
|
44
|
-
input < num
|
45
|
-
end
|
46
|
-
|
47
|
-
predicate(:gt?) do |num, input|
|
48
|
-
input > num
|
49
|
-
end
|
50
|
-
|
51
|
-
predicate(:lteq?) do |num, input|
|
52
|
-
!self[:gt?].(num, input)
|
53
|
-
end
|
54
|
-
|
55
|
-
predicate(:gteq?) do |num, input|
|
56
|
-
!self[:lt?].(num, input)
|
57
|
-
end
|
58
|
-
|
59
|
-
predicate(:size?) do |num, input|
|
60
|
-
input.size == num
|
61
|
-
end
|
62
|
-
|
63
|
-
predicate(:min_size?) do |num, input|
|
64
|
-
input.size >= num
|
65
|
-
end
|
66
|
-
|
67
|
-
predicate(:max_size?) do |num, input|
|
68
|
-
input.size <= num
|
69
|
-
end
|
70
|
-
|
71
|
-
predicate(:inclusion?) do |list, input|
|
72
|
-
list.include?(input)
|
73
|
-
end
|
74
|
-
|
75
|
-
predicate(:exclusion?) do |list, input|
|
76
|
-
!self[:inclusion?].(list, input)
|
77
|
-
end
|
78
|
-
|
79
|
-
predicate(:eql?) do |left, right|
|
80
|
-
left.eql?(right)
|
81
|
-
end
|
82
|
-
|
83
|
-
predicate(:format?) do |regex, input|
|
84
|
-
!regex.match(input).nil?
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'dry/validation/rule'
|
2
|
-
|
3
|
-
module Dry
|
4
|
-
module Validation
|
5
|
-
class RuleCompiler
|
6
|
-
attr_reader :predicates
|
7
|
-
|
8
|
-
def initialize(predicates)
|
9
|
-
@predicates = predicates
|
10
|
-
end
|
11
|
-
|
12
|
-
def call(ast)
|
13
|
-
ast.map { |node| visit(node) }
|
14
|
-
end
|
15
|
-
|
16
|
-
def visit(node)
|
17
|
-
name, nodes = node
|
18
|
-
send(:"visit_#{name}", nodes)
|
19
|
-
end
|
20
|
-
|
21
|
-
def visit_key(node)
|
22
|
-
name, predicate = node
|
23
|
-
Rule::Key.new(name, visit(predicate))
|
24
|
-
end
|
25
|
-
|
26
|
-
def visit_val(node)
|
27
|
-
name, predicate = node
|
28
|
-
Rule::Value.new(name, visit(predicate))
|
29
|
-
end
|
30
|
-
|
31
|
-
def visit_set(node)
|
32
|
-
name, rules = node
|
33
|
-
Rule::Set.new(name, call(rules))
|
34
|
-
end
|
35
|
-
|
36
|
-
def visit_each(node)
|
37
|
-
name, rule = node
|
38
|
-
Rule::Each.new(name, visit(rule))
|
39
|
-
end
|
40
|
-
|
41
|
-
def visit_predicate(node)
|
42
|
-
name, args = node
|
43
|
-
predicates[name].curry(*args)
|
44
|
-
end
|
45
|
-
|
46
|
-
def visit_and(node)
|
47
|
-
left, right = node
|
48
|
-
visit(left) & visit(right)
|
49
|
-
end
|
50
|
-
|
51
|
-
def visit_or(node)
|
52
|
-
left, right = node
|
53
|
-
visit(left) | visit(right)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Dry
|
2
|
-
module Validation
|
3
|
-
class Schema
|
4
|
-
module Definition
|
5
|
-
def key(name, &block)
|
6
|
-
Key.new(name, rules).key?(&block)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
require 'dry/validation/schema/rule'
|
14
|
-
require 'dry/validation/schema/value'
|
15
|
-
require 'dry/validation/schema/key'
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'dry/validation/rule'
|
2
|
-
|
3
|
-
module Dry
|
4
|
-
module Validation
|
5
|
-
class Schema
|
6
|
-
class Key
|
7
|
-
attr_reader :name, :rules
|
8
|
-
|
9
|
-
def initialize(name, rules, &block)
|
10
|
-
@name = name
|
11
|
-
@rules = rules
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def method_missing(meth, *args, &block)
|
17
|
-
key_rule = [:key, [name, [:predicate, [meth, args]]]]
|
18
|
-
|
19
|
-
if block
|
20
|
-
val_rule = yield(Value.new(name))
|
21
|
-
|
22
|
-
rules <<
|
23
|
-
if val_rule.is_a?(Array)
|
24
|
-
Definition::Rule.new([:and, [key_rule, [:set, [name, val_rule.map(&:to_ary)]]]])
|
25
|
-
else
|
26
|
-
Definition::Rule.new([:and, [key_rule, val_rule.to_ary]])
|
27
|
-
end
|
28
|
-
else
|
29
|
-
Definition::Rule.new(key_rule)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def respond_to_missing?(meth, _include_private = false)
|
34
|
-
true
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module Dry
|
2
|
-
module Validation
|
3
|
-
class Schema
|
4
|
-
module Definition
|
5
|
-
class Rule
|
6
|
-
attr_reader :node
|
7
|
-
|
8
|
-
def initialize(node)
|
9
|
-
@node = node
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_ary
|
13
|
-
node
|
14
|
-
end
|
15
|
-
alias_method :to_a, :to_ary
|
16
|
-
|
17
|
-
def &(other)
|
18
|
-
self.class.new([:and, [node, other.to_ary]])
|
19
|
-
end
|
20
|
-
|
21
|
-
def |(other)
|
22
|
-
self.class.new([:or, [node, other.to_ary]])
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module Dry
|
2
|
-
module Validation
|
3
|
-
class Schema
|
4
|
-
class Value
|
5
|
-
include Schema::Definition
|
6
|
-
|
7
|
-
attr_reader :name, :rules
|
8
|
-
|
9
|
-
def initialize(name)
|
10
|
-
@name = name
|
11
|
-
@rules = []
|
12
|
-
end
|
13
|
-
|
14
|
-
def each(&block)
|
15
|
-
rule = yield(self).to_ary
|
16
|
-
Definition::Rule.new([:each, [name, rule]])
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def method_missing(meth, *args, &block)
|
22
|
-
Definition::Rule.new([:val, [name, [:predicate, [meth, args]]]])
|
23
|
-
end
|
24
|
-
|
25
|
-
def respond_to_missing?(meth, _include_private = false)
|
26
|
-
true
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'dry/validation/schema/definition'
|
2
|
-
require 'dry/validation/predicates'
|
3
|
-
require 'dry/validation/error'
|
4
|
-
require 'dry/validation/rule_compiler'
|
5
|
-
require 'dry/validation/messages'
|
6
|
-
require 'dry/validation/error_compiler'
|
7
|
-
|
8
|
-
module Dry
|
9
|
-
module Validation
|
10
|
-
class Schema
|
11
|
-
extend Dry::Configurable
|
12
|
-
extend Definition
|
13
|
-
|
14
|
-
setting :predicates, Predicates
|
15
|
-
setting :messages, Messages.default
|
16
|
-
setting :messages_file
|
17
|
-
setting :namespace
|
18
|
-
|
19
|
-
def self.predicates
|
20
|
-
config.predicates
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.error_compiler
|
24
|
-
ErrorCompiler.new(messages)
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.messages
|
28
|
-
default = config.messages
|
29
|
-
|
30
|
-
if config.messages_file && config.namespace
|
31
|
-
default.merge(config.messages_file).namespaced(config.namespace)
|
32
|
-
elsif config.messages_file
|
33
|
-
default.merge(config.messages_file)
|
34
|
-
elsif config.namespace
|
35
|
-
default.namespaced(config.namespace)
|
36
|
-
else
|
37
|
-
default
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.rules
|
42
|
-
@__rules__ ||= []
|
43
|
-
end
|
44
|
-
|
45
|
-
attr_reader :rules
|
46
|
-
|
47
|
-
attr_reader :error_compiler
|
48
|
-
|
49
|
-
def initialize(error_compiler = self.class.error_compiler)
|
50
|
-
@rules = RuleCompiler.new(self).(self.class.rules.map(&:to_ary))
|
51
|
-
@error_compiler = error_compiler
|
52
|
-
end
|
53
|
-
|
54
|
-
def call(input)
|
55
|
-
rules.each_with_object(Error::Set.new) do |rule, errors|
|
56
|
-
result = rule.(input)
|
57
|
-
errors << Error.new(result) if result.failure?
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def messages(input)
|
62
|
-
error_compiler.call(call(input).map(&:to_ary))
|
63
|
-
end
|
64
|
-
|
65
|
-
def [](name)
|
66
|
-
if methods.include?(name)
|
67
|
-
Predicate.new(name, &method(name))
|
68
|
-
else
|
69
|
-
self.class.predicates[name]
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
data/rakelib/rubocop.rake
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'rubocop/rake_task'
|
3
|
-
|
4
|
-
Rake::Task[:default].enhance [:rubocop]
|
5
|
-
|
6
|
-
RuboCop::RakeTask.new do |task|
|
7
|
-
task.options << '--display-cop-names'
|
8
|
-
end
|
9
|
-
|
10
|
-
namespace :rubocop do
|
11
|
-
desc 'Generate a configuration file acting as a TODO list.'
|
12
|
-
task :auto_gen_config do
|
13
|
-
exec 'bundle exec rubocop --auto-gen-config'
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
rescue LoadError
|
18
|
-
end
|
data/spec/fixtures/errors.yml
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
RSpec.describe Dry::Validation, 'with custom messages' do
|
2
|
-
subject(:validation) { schema.new }
|
3
|
-
|
4
|
-
describe 'defining schema' do
|
5
|
-
let(:schema) do
|
6
|
-
Class.new(Dry::Validation::Schema) do
|
7
|
-
configure do |config|
|
8
|
-
config.messages_file = SPEC_ROOT.join('fixtures/errors.yml')
|
9
|
-
config.namespace = :user
|
10
|
-
end
|
11
|
-
|
12
|
-
key(:email) { |email| email.filled? }
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
let(:attrs) do
|
17
|
-
{
|
18
|
-
email: 'jane@doe.org',
|
19
|
-
age: 19,
|
20
|
-
address: { city: 'NYC', street: 'Street 1/2', country: { code: 'US', name: 'USA' } },
|
21
|
-
phone_numbers: [
|
22
|
-
'123456', '234567'
|
23
|
-
]
|
24
|
-
}.freeze
|
25
|
-
end
|
26
|
-
|
27
|
-
describe '#messages' do
|
28
|
-
it 'returns compiled error messages' do
|
29
|
-
expect(validation.messages(attrs.merge(email: ''))).to eql([
|
30
|
-
[:email, ["email can't be blank"]]
|
31
|
-
])
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
RSpec.describe Dry::Validation do
|
2
|
-
subject(:validation) { schema.new }
|
3
|
-
|
4
|
-
shared_context 'uses custom predicates' do
|
5
|
-
it 'uses provided custom predicates' do
|
6
|
-
expect(validation.(email: 'jane@doe')).to be_empty
|
7
|
-
|
8
|
-
expect(validation.(email: nil)).to match_array([
|
9
|
-
[:error, [:input, [:email, nil, [[:val, [:email, [:predicate, [:filled?, []]]]]]]]]
|
10
|
-
])
|
11
|
-
|
12
|
-
expect(validation.(email: 'jane')).to match_array([
|
13
|
-
[:error, [:input, [:email, 'jane', [[:val, [:email, [:predicate, [:email?, []]]]]]]]]
|
14
|
-
])
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
describe 'defining schema with custom predicates container' do
|
19
|
-
let(:schema) do
|
20
|
-
Class.new(Dry::Validation::Schema) do
|
21
|
-
configure do |config|
|
22
|
-
config.predicates = Test::Predicates
|
23
|
-
end
|
24
|
-
|
25
|
-
key(:email) { |value| value.filled? & value.email? }
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
before do
|
30
|
-
module Test
|
31
|
-
module Predicates
|
32
|
-
include Dry::Validation::Predicates
|
33
|
-
|
34
|
-
predicate(:email?) do |input|
|
35
|
-
input.include?('@') # for the lols
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
include_context 'uses custom predicates'
|
42
|
-
end
|
43
|
-
|
44
|
-
describe 'defining schema with custom predicate methods' do
|
45
|
-
let(:schema) do
|
46
|
-
Class.new(Dry::Validation::Schema) do
|
47
|
-
key(:email) { |value| value.filled? & value.email? }
|
48
|
-
|
49
|
-
def email?(value)
|
50
|
-
value.include?('@')
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
include_context 'uses custom predicates'
|
56
|
-
end
|
57
|
-
end
|