dry-validation 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -2
- data/Gemfile +4 -0
- data/README.md +131 -42
- data/config/errors.yml +36 -27
- data/examples/basic.rb +2 -4
- data/examples/each.rb +2 -2
- data/examples/form.rb +1 -2
- data/examples/nested.rb +2 -4
- data/examples/rule_ast.rb +0 -8
- data/lib/dry/validation.rb +0 -5
- data/lib/dry/validation/error.rb +2 -6
- data/lib/dry/validation/error_compiler.rb +19 -5
- data/lib/dry/validation/input_type_compiler.rb +2 -1
- data/lib/dry/validation/messages.rb +7 -58
- data/lib/dry/validation/messages/abstract.rb +75 -0
- data/lib/dry/validation/messages/i18n.rb +24 -0
- data/lib/dry/validation/messages/namespaced.rb +27 -0
- data/lib/dry/validation/messages/yaml.rb +50 -0
- data/lib/dry/validation/result.rb +19 -49
- data/lib/dry/validation/rule.rb +2 -2
- data/lib/dry/validation/rule/group.rb +21 -0
- data/lib/dry/validation/rule/result.rb +73 -0
- data/lib/dry/validation/rule_compiler.rb +5 -0
- data/lib/dry/validation/schema.rb +33 -14
- data/lib/dry/validation/schema/definition.rb +16 -0
- data/lib/dry/validation/schema/result.rb +21 -3
- data/lib/dry/validation/schema/rule.rb +1 -1
- data/lib/dry/validation/schema/value.rb +2 -1
- data/lib/dry/validation/version.rb +1 -1
- data/spec/fixtures/locales/en.yml +5 -0
- data/spec/fixtures/locales/pl.yml +14 -0
- data/spec/integration/custom_error_messages_spec.rb +4 -16
- data/spec/{unit → integration}/error_compiler_spec.rb +81 -39
- data/spec/integration/localized_error_messages_spec.rb +52 -0
- data/spec/integration/messages/i18n_spec.rb +71 -0
- data/spec/integration/rule_groups_spec.rb +35 -0
- data/spec/integration/schema_form_spec.rb +9 -9
- data/spec/integration/schema_spec.rb +2 -2
- data/spec/shared/predicates.rb +2 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/rule/group_spec.rb +12 -0
- data/spec/unit/schema_spec.rb +35 -0
- metadata +24 -6
- data/spec/fixtures/errors.yml +0 -4
data/lib/dry/validation/rule.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'dry/validation/result'
|
2
|
-
|
3
1
|
module Dry
|
4
2
|
module Validation
|
5
3
|
class Rule
|
@@ -44,3 +42,5 @@ require 'dry/validation/rule/value'
|
|
44
42
|
require 'dry/validation/rule/each'
|
45
43
|
require 'dry/validation/rule/set'
|
46
44
|
require 'dry/validation/rule/composite'
|
45
|
+
require 'dry/validation/rule/group'
|
46
|
+
require 'dry/validation/rule/result'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Dry
|
2
|
+
module Validation
|
3
|
+
class Rule::Group < Rule
|
4
|
+
attr_reader :rules
|
5
|
+
|
6
|
+
def initialize(identifier, predicate)
|
7
|
+
name, rules = identifier.to_a.first
|
8
|
+
@rules = rules
|
9
|
+
super(name, predicate)
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(*input)
|
13
|
+
Validation.Result(input, predicate.(*input), self)
|
14
|
+
end
|
15
|
+
|
16
|
+
def type
|
17
|
+
:group
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Dry
|
2
|
+
module Validation
|
3
|
+
def self.Result(input, value, rule)
|
4
|
+
case value
|
5
|
+
when Array then Rule::Result::Set.new(input, value, rule)
|
6
|
+
else Rule::Result::Value.new(input, value, rule)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Rule::Result
|
11
|
+
include Dry::Equalizer(:success?, :input, :rule)
|
12
|
+
|
13
|
+
attr_reader :input, :value, :rule, :name
|
14
|
+
|
15
|
+
class Rule::Result::Set < Rule::Result
|
16
|
+
def success?
|
17
|
+
value.all?(&:success?)
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_ary
|
21
|
+
indices = value.map { |v| v.failure? ? value.index(v) : nil }.compact
|
22
|
+
[:input, [rule.name, input, value.values_at(*indices).map(&:to_ary)]]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Rule::Result::Value < Rule::Result
|
27
|
+
def to_ary
|
28
|
+
[:input, [rule.name, input, [rule.to_ary]]]
|
29
|
+
end
|
30
|
+
alias_method :to_a, :to_ary
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(input, value, rule)
|
34
|
+
@input = input
|
35
|
+
@value = value
|
36
|
+
@rule = rule
|
37
|
+
@name = rule.name
|
38
|
+
end
|
39
|
+
|
40
|
+
def >(other)
|
41
|
+
if success?
|
42
|
+
other.(input)
|
43
|
+
else
|
44
|
+
Validation.Result(input, true, rule)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def and(other)
|
49
|
+
if success?
|
50
|
+
other.(input)
|
51
|
+
else
|
52
|
+
self
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def or(other)
|
57
|
+
if success?
|
58
|
+
self
|
59
|
+
else
|
60
|
+
other.(input)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def success?
|
65
|
+
@value
|
66
|
+
end
|
67
|
+
|
68
|
+
def failure?
|
69
|
+
! success?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -4,6 +4,7 @@ require 'dry/validation/error'
|
|
4
4
|
require 'dry/validation/rule_compiler'
|
5
5
|
require 'dry/validation/messages'
|
6
6
|
require 'dry/validation/error_compiler'
|
7
|
+
require 'dry/validation/result'
|
7
8
|
require 'dry/validation/schema/result'
|
8
9
|
|
9
10
|
module Dry
|
@@ -13,7 +14,7 @@ module Dry
|
|
13
14
|
extend Definition
|
14
15
|
|
15
16
|
setting :predicates, Predicates
|
16
|
-
setting :messages,
|
17
|
+
setting :messages, :yaml
|
17
18
|
setting :messages_file
|
18
19
|
setting :namespace
|
19
20
|
|
@@ -26,7 +27,13 @@ module Dry
|
|
26
27
|
end
|
27
28
|
|
28
29
|
def self.messages
|
29
|
-
default =
|
30
|
+
default =
|
31
|
+
case config.messages
|
32
|
+
when :yaml then Messages.default
|
33
|
+
when :i18n then Messages::I18n.new
|
34
|
+
else
|
35
|
+
raise RuntimeError, "+#{config.messages}+ is not a valid messages identifier"
|
36
|
+
end
|
30
37
|
|
31
38
|
if config.messages_file && config.namespace
|
32
39
|
default.merge(config.messages_file).namespaced(config.namespace)
|
@@ -43,36 +50,48 @@ module Dry
|
|
43
50
|
@__rules__ ||= []
|
44
51
|
end
|
45
52
|
|
46
|
-
|
53
|
+
def self.groups
|
54
|
+
@__groups__ ||= []
|
55
|
+
end
|
56
|
+
|
57
|
+
attr_reader :rules, :groups
|
47
58
|
|
48
59
|
attr_reader :error_compiler
|
49
60
|
|
50
61
|
def initialize(error_compiler = self.class.error_compiler)
|
51
|
-
|
62
|
+
compiler = RuleCompiler.new(self)
|
63
|
+
@rules = compiler.(self.class.rules.map(&:to_ary))
|
64
|
+
@groups = compiler.(self.class.groups.map(&:to_ary))
|
52
65
|
@error_compiler = error_compiler
|
53
66
|
end
|
54
67
|
|
55
68
|
def call(input)
|
56
|
-
|
57
|
-
|
58
|
-
|
69
|
+
result = Validation::Result.new(rules.map { |rule| rule.(input) })
|
70
|
+
|
71
|
+
groups.each do |group|
|
72
|
+
result.with_values(group.rules) do |values|
|
73
|
+
result << group.(*values)
|
74
|
+
end
|
59
75
|
end
|
60
76
|
|
61
|
-
|
62
|
-
end
|
77
|
+
errors = Error::Set.new(result.failures.map { |failure| Error.new(failure) })
|
63
78
|
|
64
|
-
|
65
|
-
result = call(input)
|
66
|
-
Result.new(result.params, error_compiler.(result.to_ary))
|
79
|
+
Schema::Result.new(input, result, errors, error_compiler)
|
67
80
|
end
|
68
81
|
|
69
82
|
def [](name)
|
70
|
-
if
|
83
|
+
if predicates.key?(name)
|
84
|
+
predicates[name]
|
85
|
+
elsif respond_to?(name)
|
71
86
|
Predicate.new(name, &method(name))
|
72
87
|
else
|
73
|
-
|
88
|
+
raise ArgumentError, "+#{name}+ is not a valid predicate name"
|
74
89
|
end
|
75
90
|
end
|
91
|
+
|
92
|
+
def predicates
|
93
|
+
self.class.predicates
|
94
|
+
end
|
76
95
|
end
|
77
96
|
end
|
78
97
|
end
|
@@ -9,6 +9,22 @@ module Dry
|
|
9
9
|
def optional(name, &block)
|
10
10
|
Key.new(name, rules).optional(&block)
|
11
11
|
end
|
12
|
+
|
13
|
+
def rule(name, **options)
|
14
|
+
predicate, rules = options.to_a.first
|
15
|
+
identifier = { name => rules }
|
16
|
+
|
17
|
+
groups << [:group, [identifier, [:predicate, predicate]]]
|
18
|
+
end
|
19
|
+
|
20
|
+
def confirmation(name)
|
21
|
+
identifier = :"#{name}_confirmation"
|
22
|
+
|
23
|
+
key(name, &:filled?)
|
24
|
+
key(identifier, &:filled?)
|
25
|
+
|
26
|
+
rule(identifier, eql?: [name, identifier])
|
27
|
+
end
|
12
28
|
end
|
13
29
|
end
|
14
30
|
end
|
@@ -1,20 +1,26 @@
|
|
1
1
|
module Dry
|
2
2
|
module Validation
|
3
3
|
class Schema::Result
|
4
|
-
include Dry::Equalizer(:params, :
|
4
|
+
include Dry::Equalizer(:params, :messages)
|
5
5
|
include Enumerable
|
6
6
|
|
7
7
|
attr_reader :params
|
8
8
|
|
9
|
+
attr_reader :result
|
10
|
+
|
9
11
|
attr_reader :errors
|
10
12
|
|
11
|
-
|
13
|
+
attr_reader :error_compiler
|
14
|
+
|
15
|
+
def initialize(params, result, errors, error_compiler)
|
12
16
|
@params = params
|
17
|
+
@result = result
|
13
18
|
@errors = errors
|
19
|
+
@error_compiler = error_compiler
|
14
20
|
end
|
15
21
|
|
16
22
|
def each(&block)
|
17
|
-
|
23
|
+
failures.each(&block)
|
18
24
|
end
|
19
25
|
|
20
26
|
def empty?
|
@@ -24,6 +30,18 @@ module Dry
|
|
24
30
|
def to_ary
|
25
31
|
errors.map(&:to_ary)
|
26
32
|
end
|
33
|
+
|
34
|
+
def messages(options = {})
|
35
|
+
@messages ||= error_compiler.with(options).(errors.map(&:to_ary))
|
36
|
+
end
|
37
|
+
|
38
|
+
def successes
|
39
|
+
result.successes
|
40
|
+
end
|
41
|
+
|
42
|
+
def failures
|
43
|
+
result.failures
|
44
|
+
end
|
27
45
|
end
|
28
46
|
end
|
29
47
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
pl:
|
2
|
+
errors:
|
3
|
+
filled?: "%{name} nie może być pusty"
|
4
|
+
size?:
|
5
|
+
arg:
|
6
|
+
default: "wielkość musi być równa %{num}"
|
7
|
+
range: "wielkość musi być między %{left} a %{right}"
|
8
|
+
rules:
|
9
|
+
email:
|
10
|
+
filled?: "Proszę podać adres email"
|
11
|
+
user:
|
12
|
+
rules:
|
13
|
+
email:
|
14
|
+
filled?: "Hej user! Dawaj ten email no!"
|
@@ -5,29 +5,17 @@ RSpec.describe Dry::Validation, 'with custom messages' do
|
|
5
5
|
let(:schema) do
|
6
6
|
Class.new(Dry::Validation::Schema) do
|
7
7
|
configure do |config|
|
8
|
-
config.messages_file = SPEC_ROOT.join('fixtures/
|
9
|
-
config.namespace = :user
|
8
|
+
config.messages_file = SPEC_ROOT.join('fixtures/locales/en.yml')
|
10
9
|
end
|
11
10
|
|
12
|
-
key(:email
|
11
|
+
key(:email, &:filled?)
|
13
12
|
end
|
14
13
|
end
|
15
14
|
|
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
15
|
describe '#messages' do
|
28
16
|
it 'returns compiled error messages' do
|
29
|
-
expect(validation.
|
30
|
-
[:email, [
|
17
|
+
expect(validation.(email: '').messages).to match_array([
|
18
|
+
[:email, [['Please provide your email', '']]]
|
31
19
|
])
|
32
20
|
end
|
33
21
|
end
|
@@ -6,10 +6,14 @@ RSpec.describe Dry::Validation::ErrorCompiler do
|
|
6
6
|
|
7
7
|
let(:messages) do
|
8
8
|
Messages.default.merge(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
en: {
|
10
|
+
errors: {
|
11
|
+
key?: '+%{name}+ key is missing in the hash',
|
12
|
+
rules: {
|
13
|
+
address: {
|
14
|
+
filled?: 'Please provide your address'
|
15
|
+
}
|
16
|
+
}
|
13
17
|
}
|
14
18
|
}
|
15
19
|
)
|
@@ -26,202 +30,240 @@ RSpec.describe Dry::Validation::ErrorCompiler do
|
|
26
30
|
end
|
27
31
|
|
28
32
|
it 'converts error ast into another format' do
|
29
|
-
expect(error_compiler.(ast)).to eql(
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
expect(error_compiler.(ast)).to eql(
|
34
|
+
name: [["+name+ key is missing in the hash", nil]],
|
35
|
+
age: [["age must be greater than 18", 18]],
|
36
|
+
email: [["email must be filled", '']],
|
37
|
+
address: [["Please provide your address", '']]
|
38
|
+
)
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
38
42
|
describe '#visit_predicate' do
|
39
43
|
describe ':empty?' do
|
40
44
|
it 'returns valid message' do
|
41
|
-
msg = error_compiler.visit_predicate([:empty?, []], [], :tags)
|
45
|
+
msg, val = error_compiler.visit_predicate([:empty?, []], [], :tags)
|
42
46
|
|
47
|
+
expect(val).to eql([])
|
43
48
|
expect(msg).to eql('tags cannot be empty')
|
44
49
|
end
|
45
50
|
end
|
46
51
|
|
47
52
|
describe ':exclusion?' do
|
48
53
|
it 'returns valid message' do
|
49
|
-
msg = error_compiler.visit_predicate([:exclusion?, [[1, 2, 3]]], 2, :num)
|
54
|
+
msg, val = error_compiler.visit_predicate([:exclusion?, [[1, 2, 3]]], 2, :num)
|
50
55
|
|
56
|
+
expect(val).to be(2)
|
51
57
|
expect(msg).to eql('num must not be one of: 1, 2, 3')
|
52
58
|
end
|
53
59
|
end
|
54
60
|
|
55
61
|
describe ':inclusion?' do
|
56
62
|
it 'returns valid message' do
|
57
|
-
msg = error_compiler.visit_predicate([:inclusion?, [[1, 2, 3]]], 2, :num)
|
63
|
+
msg, val = error_compiler.visit_predicate([:inclusion?, [[1, 2, 3]]], 2, :num)
|
58
64
|
|
65
|
+
expect(val).to be(2)
|
59
66
|
expect(msg).to eql('num must be one of: 1, 2, 3')
|
60
67
|
end
|
61
68
|
end
|
62
69
|
|
63
70
|
describe ':gt?' do
|
64
71
|
it 'returns valid message' do
|
65
|
-
msg = error_compiler.visit_predicate([:gt?, [3]], 2, :num)
|
72
|
+
msg, val = error_compiler.visit_predicate([:gt?, [3]], 2, :num)
|
66
73
|
|
67
|
-
expect(
|
74
|
+
expect(val).to be(2)
|
75
|
+
expect(msg).to eql('num must be greater than 3')
|
68
76
|
end
|
69
77
|
end
|
70
78
|
|
71
79
|
describe ':gteq?' do
|
72
80
|
it 'returns valid message' do
|
73
|
-
msg = error_compiler.visit_predicate([:gteq?, [3]], 2, :num)
|
81
|
+
msg, val = error_compiler.visit_predicate([:gteq?, [3]], 2, :num)
|
74
82
|
|
83
|
+
expect(val).to be(2)
|
75
84
|
expect(msg).to eql('num must be greater than or equal to 3')
|
76
85
|
end
|
77
86
|
end
|
78
87
|
|
79
88
|
describe ':lt?' do
|
80
89
|
it 'returns valid message' do
|
81
|
-
msg = error_compiler.visit_predicate([:lt?, [3]], 2, :num)
|
90
|
+
msg, val = error_compiler.visit_predicate([:lt?, [3]], 2, :num)
|
82
91
|
|
92
|
+
expect(val).to be(2)
|
83
93
|
expect(msg).to eql('num must be less than 3 (2 was given)')
|
84
94
|
end
|
85
95
|
end
|
86
96
|
|
87
97
|
describe ':lteq?' do
|
88
98
|
it 'returns valid message' do
|
89
|
-
msg = error_compiler.visit_predicate([:lteq?, [3]], 2, :num)
|
99
|
+
msg, val = error_compiler.visit_predicate([:lteq?, [3]], 2, :num)
|
90
100
|
|
101
|
+
expect(val).to be(2)
|
91
102
|
expect(msg).to eql('num must be less than or equal to 3')
|
92
103
|
end
|
93
104
|
end
|
94
105
|
|
95
106
|
describe ':hash?' do
|
96
107
|
it 'returns valid message' do
|
97
|
-
msg = error_compiler.visit_predicate([:hash?, []], '', :address)
|
108
|
+
msg, val = error_compiler.visit_predicate([:hash?, []], '', :address)
|
98
109
|
|
110
|
+
expect(val).to eql('')
|
99
111
|
expect(msg).to eql('address must be a hash')
|
100
112
|
end
|
101
113
|
end
|
102
114
|
|
103
115
|
describe ':array?' do
|
104
116
|
it 'returns valid message' do
|
105
|
-
msg = error_compiler.visit_predicate([:array?, []], '', :phone_numbers)
|
117
|
+
msg, val = error_compiler.visit_predicate([:array?, []], '', :phone_numbers)
|
106
118
|
|
119
|
+
expect(val).to eql('')
|
107
120
|
expect(msg).to eql('phone_numbers must be an array')
|
108
121
|
end
|
109
122
|
end
|
110
123
|
|
111
124
|
describe ':int?' do
|
112
125
|
it 'returns valid message' do
|
113
|
-
msg = error_compiler.visit_predicate([:int?, []], '2', :num)
|
126
|
+
msg, val = error_compiler.visit_predicate([:int?, []], '2', :num)
|
114
127
|
|
128
|
+
expect(val).to eql('2')
|
115
129
|
expect(msg).to eql('num must be an integer')
|
116
130
|
end
|
117
131
|
end
|
118
132
|
|
119
133
|
describe ':float?' do
|
120
134
|
it 'returns valid message' do
|
121
|
-
msg = error_compiler.visit_predicate([:float?, []], '2', :num)
|
135
|
+
msg, val = error_compiler.visit_predicate([:float?, []], '2', :num)
|
122
136
|
|
137
|
+
expect(val).to eql('2')
|
123
138
|
expect(msg).to eql('num must be a float')
|
124
139
|
end
|
125
140
|
end
|
126
141
|
|
127
142
|
describe ':decimal?' do
|
128
143
|
it 'returns valid message' do
|
129
|
-
msg = error_compiler.visit_predicate([:decimal?, []], '2', :num)
|
144
|
+
msg, val = error_compiler.visit_predicate([:decimal?, []], '2', :num)
|
130
145
|
|
146
|
+
expect(val).to eql('2')
|
131
147
|
expect(msg).to eql('num must be a decimal')
|
132
148
|
end
|
133
149
|
end
|
134
150
|
|
135
151
|
describe ':date?' do
|
136
152
|
it 'returns valid message' do
|
137
|
-
msg = error_compiler.visit_predicate([:date?, []], '2', :num)
|
153
|
+
msg, val = error_compiler.visit_predicate([:date?, []], '2', :num)
|
138
154
|
|
155
|
+
expect(val).to eql('2')
|
139
156
|
expect(msg).to eql('num must be a date')
|
140
157
|
end
|
141
158
|
end
|
142
159
|
|
143
160
|
describe ':date_time?' do
|
144
161
|
it 'returns valid message' do
|
145
|
-
msg = error_compiler.visit_predicate([:date_time?, []], '2', :num)
|
162
|
+
msg, val = error_compiler.visit_predicate([:date_time?, []], '2', :num)
|
146
163
|
|
164
|
+
expect(val).to eql('2')
|
147
165
|
expect(msg).to eql('num must be a date time')
|
148
166
|
end
|
149
167
|
end
|
150
168
|
|
151
169
|
describe ':time?' do
|
152
170
|
it 'returns valid message' do
|
153
|
-
msg = error_compiler.visit_predicate([:time?, []], '2', :num)
|
171
|
+
msg, val = error_compiler.visit_predicate([:time?, []], '2', :num)
|
154
172
|
|
173
|
+
expect(val).to eql('2')
|
155
174
|
expect(msg).to eql('num must be a time')
|
156
175
|
end
|
157
176
|
end
|
158
177
|
|
159
178
|
describe ':max_size?' do
|
160
179
|
it 'returns valid message' do
|
161
|
-
msg = error_compiler.visit_predicate([:max_size?, [3]], 'abcd', :num)
|
180
|
+
msg, val = error_compiler.visit_predicate([:max_size?, [3]], 'abcd', :num)
|
162
181
|
|
182
|
+
expect(val).to eql('abcd')
|
163
183
|
expect(msg).to eql('num size cannot be greater than 3')
|
164
184
|
end
|
165
185
|
end
|
166
186
|
|
167
187
|
describe ':min_size?' do
|
168
188
|
it 'returns valid message' do
|
169
|
-
msg = error_compiler.visit_predicate([:min_size?, [3]], 'ab', :num)
|
189
|
+
msg, val = error_compiler.visit_predicate([:min_size?, [3]], 'ab', :num)
|
170
190
|
|
191
|
+
expect(val).to eql('ab')
|
171
192
|
expect(msg).to eql('num size cannot be less than 3')
|
172
193
|
end
|
173
194
|
end
|
174
195
|
|
175
|
-
describe ':
|
196
|
+
describe ':none?' do
|
176
197
|
it 'returns valid message' do
|
177
|
-
msg = error_compiler.visit_predicate([:
|
198
|
+
msg, val = error_compiler.visit_predicate([:none?, []], nil, :num)
|
178
199
|
|
179
|
-
expect(
|
200
|
+
expect(val).to be(nil)
|
201
|
+
expect(msg).to eql('num cannot be defined')
|
180
202
|
end
|
181
203
|
end
|
182
204
|
|
183
205
|
describe ':size?' do
|
206
|
+
it 'returns valid message when val is array and arg is int' do
|
207
|
+
msg, val = error_compiler.visit_predicate([:size?, [3]], [1], :numbers)
|
208
|
+
|
209
|
+
expect(val).to eql([1])
|
210
|
+
expect(msg).to eql('numbers size must be 3')
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'returns valid message when val is array and arg is range' do
|
214
|
+
msg, val = error_compiler.visit_predicate([:size?, [3..4]], [1], :numbers)
|
215
|
+
|
216
|
+
expect(val).to eql([1])
|
217
|
+
expect(msg).to eql('numbers size must be within 3 - 4')
|
218
|
+
end
|
219
|
+
|
184
220
|
it 'returns valid message when arg is int' do
|
185
|
-
msg = error_compiler.visit_predicate([:size?, [3]], 'ab', :num)
|
221
|
+
msg, val = error_compiler.visit_predicate([:size?, [3]], 'ab', :num)
|
186
222
|
|
187
|
-
expect(
|
223
|
+
expect(val).to eql('ab')
|
224
|
+
expect(msg).to eql('num length must be 3')
|
188
225
|
end
|
189
226
|
|
190
227
|
it 'returns valid message when arg is range' do
|
191
|
-
msg = error_compiler.visit_predicate([:size?, [3..4]], 'ab', :num)
|
228
|
+
msg, val = error_compiler.visit_predicate([:size?, [3..4]], 'ab', :num)
|
192
229
|
|
193
|
-
expect(
|
230
|
+
expect(val).to eql('ab')
|
231
|
+
expect(msg).to eql('num length must be within 3 - 4')
|
194
232
|
end
|
195
233
|
end
|
196
234
|
|
197
235
|
describe ':str?' do
|
198
236
|
it 'returns valid message' do
|
199
|
-
msg = error_compiler.visit_predicate([:str?, []], 3, :num)
|
237
|
+
msg, val = error_compiler.visit_predicate([:str?, []], 3, :num)
|
200
238
|
|
239
|
+
expect(val).to be(3)
|
201
240
|
expect(msg).to eql('num must be a string')
|
202
241
|
end
|
203
242
|
end
|
204
243
|
|
205
244
|
describe ':bool?' do
|
206
245
|
it 'returns valid message' do
|
207
|
-
msg = error_compiler.visit_predicate([:bool?, []], 3, :num)
|
246
|
+
msg, val = error_compiler.visit_predicate([:bool?, []], 3, :num)
|
208
247
|
|
248
|
+
expect(val).to be(3)
|
209
249
|
expect(msg).to eql('num must be boolean')
|
210
250
|
end
|
211
251
|
end
|
212
252
|
|
213
253
|
describe ':format?' do
|
214
254
|
it 'returns valid message' do
|
215
|
-
msg = error_compiler.visit_predicate([:format?, [/^F/]], 'Bar', :str)
|
255
|
+
msg, val = error_compiler.visit_predicate([:format?, [/^F/]], 'Bar', :str)
|
216
256
|
|
257
|
+
expect(val).to eql('Bar')
|
217
258
|
expect(msg).to eql('str is in invalid format')
|
218
259
|
end
|
219
260
|
end
|
220
261
|
|
221
262
|
describe ':eql?' do
|
222
263
|
it 'returns valid message' do
|
223
|
-
msg = error_compiler.visit_predicate([:eql?, ['Bar']], 'Foo', :str)
|
264
|
+
msg, val = error_compiler.visit_predicate([:eql?, ['Bar']], 'Foo', :str)
|
224
265
|
|
266
|
+
expect(val).to eql('Foo')
|
225
267
|
expect(msg).to eql('str must be equal to Bar')
|
226
268
|
end
|
227
269
|
end
|