spec/integration/error_compiler_spec.rb in dry-validation-0.7.4 vs spec/integration/error_compiler_spec.rb in dry-validation-0.8.0
- old
+ new
@@ -2,15 +2,24 @@
require 'dry/validation/error_compiler'
RSpec.describe Dry::Validation::ErrorCompiler do
subject(:error_compiler) { ErrorCompiler.new(messages) }
+ include_context 'predicate helper'
+
let(:messages) do
Messages.default.merge(
en: {
errors: {
- key?: '+%{name}+ key is missing in the hash',
+ key?: {
+ arg: {
+ default: '+%{name}+ key is missing in the hash',
+ },
+ value: {
+ gender: 'Please provide your gender'
+ }
+ },
rules: {
address: {
filled?: 'Please provide your address'
}
}
@@ -28,20 +37,22 @@
end
describe '#call with flat inputs' do
let(:ast) do
[
- [:error, [:name, [:input, [:name, [:result, [nil, [:val, [:predicate, [:key?, [:name]]]]]]]]]],
- [:error, [:age, [:input, [:age, [:result, [18, [:val, [:predicate, [:gt?, [18]]]]]]]]]],
- [:error, [:email, [:input, [:email, [:result, ["", [:val, [:predicate, [:filled?, []]]]]]]]]],
- [:error, [:address, [:input, [:address, [:result, ["", [:val, [:predicate, [:filled?, []]]]]]]]]]
+ [:error, [:name, [:input, [:name, [:result, [nil, [:val, p(:key?, :name)]]]]]]],
+ [:error, [:gender, [:input, [:gender, [:result, [nil, [:val, p(:key?, :gender)]]]]]]],
+ [:error, [:age, [:input, [:age, [:result, [18, [:val, p(:gt?, 18)]]]]]]],
+ [:error, [:email, [:input, [:email, [:result, ["", [:val, p(:filled?)]]]]]]],
+ [:error, [:address, [:input, [:address, [:result, ["", [:val, p(:filled?)]]]]]]]
]
end
it 'converts error ast into another format' do
expect(error_compiler.(ast)).to eql(
name: ["+name+ key is missing in the hash"],
+ gender: ["Please provide your gender"],
age: ["must be greater than 18"],
email: ["must be filled"],
address: ["Please provide your address"]
)
end
@@ -55,12 +66,12 @@
[true, true],
[
:check, [
:newsletter,
[:implication, [
- [:key, [[:settings, :offers], [:predicate, [:true?, []]]]],
- [:key, [[:settings, :newsletter], [:predicate, [:false?, []]]]]]
+ [:key, [[:settings, :offers], p(:true?)]],
+ [:key, [[:settings, :newsletter], p(:false?)]]]
]
]
]
]
]
@@ -81,11 +92,11 @@
[:input, [
:payments, [:result, [
[{ method: "cc", amount: 1.23 }, { amount: 4.56 }], [:each, [
[:el, [
1, [
- :result, [{ amount: 4.56 }, [:val, [:predicate, [:key?, [:method]]]]]
+ :result, [{ amount: 4.56 }, [:val, p(:key?, :method)]]
]
]]
]]]
]]]
]]]
@@ -100,340 +111,344 @@
describe '#visit with an :input node' do
context 'full message' do
it 'returns full message including rule name' do
msg = error_compiler.with(full: true).visit(
- [:input, [:num, [
- :result, ['2', [:val, [:predicate, [:int?, []]]]]]
- ]]
+ [:input, [:num, [:result, ['2', [:val, p(:int?)]]]]]
)
expect(msg).to eql(num: ['num must be an integer'])
end
end
context 'rule name translations' do
it 'translates rule name and its message' do
msg = error_compiler.with(locale: :pl, full: true).visit(
- [:input, [:email, [
- :result, ['oops', [:val, [:predicate, [:email?, []]]]]]
- ]]
+ [:input, [:email, [:result, ['oops', [:val, p(:email?)]]]]]
)
expect(msg).to eql(email: ['adres email nie jest poprawny'])
end
end
describe ':empty?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:tags, [:result, [nil, [:val, [:predicate, [:empty?, []]]]]]]]
+ [:input, [:tags, [:result, [nil, [:val, p(:empty?)]]]]]
)
expect(msg).to eql(tags: ['must be empty'])
end
end
- describe ':exclusion?' do
+ describe ':excluded_from?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, [2, [:val, [:predicate, [:exclusion?, [[1, 2, 3]]]]]]]
- ]]
+ [:input, [:num, [:result, [2, [:val, p(:excluded_from?, [1, 2, 3])]]]]]
)
expect(msg).to eql(num: ['must not be one of: 1, 2, 3'])
end
end
- describe ':inclusion?' do
+ describe ':excludes?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, [2, [:val, [:predicate, [:inclusion?, [[1, 2, 3]]]]]]]
- ]]
+ [:input, [:array, [:result, [[1, 2, 3], [:val, p(:excludes?, 2)]]]]]
)
+ expect(msg).to eql(array: ['must not include 2'])
+ end
+ end
+
+ describe ':included_in?' do
+ it 'returns valid message' do
+ msg = error_compiler.visit(
+ [:input, [:num, [:result, [2, [:val, p(:included_in?, [1, 2, 3])]]]]]
+ )
+
expect(msg).to eql(num: ['must be one of: 1, 2, 3'])
end
end
+ describe ':includes?' do
+ it 'returns valid message' do
+ msg = error_compiler.visit(
+ [:input, [:num, [:result, [[1, 2, 3], [:val, p(:includes?, 2)]]]]]
+ )
+
+ expect(msg).to eql(num: ['must include 2'])
+ end
+ end
+
describe ':gt?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, [2, [:val, [:predicate, [:gt?, [3]]]]]]
- ]]
+ [:input, [:num, [:result, [2, [:val, p(:gt?, 3)]]]]]
)
expect(msg).to eql(num: ['must be greater than 3'])
end
end
describe ':gteq?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, [2, [:val, [:predicate, [:gteq?, [3]]]]]]
- ]]
+ [:input, [:num, [:result, [2, [:val, p(:gteq?, 3)]]]]]
)
expect(msg).to eql(num: ['must be greater than or equal to 3'])
end
end
describe ':lt?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, [2, [:val, [:predicate, [:lt?, [3]]]]]]
- ]]
+ [:input, [:num, [:result, [2, [:val, p(:lt?, 3)]]]]]
)
- expect(msg).to eql(num: ['must be less than 3 (2 was given)'])
+ expect(msg).to eql(num: ['must be less than 3'])
end
end
describe ':lteq?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, [2, [:val, [:predicate, [:lteq?, [3]]]]]]
- ]]
+ [:input, [:num, [:result, [2, [:val, p(:lteq?, 3)]]]]]
)
expect(msg).to eql(num: ['must be less than or equal to 3'])
end
end
describe ':hash?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:address, [
- :result, ['', [:val, [:predicate, [:hash?, []]]]]]
- ]]
+ [:input, [:address, [:result, ['', [:val, p(:hash?, [])]]]]]
)
expect(msg).to eql(address: ['must be a hash'])
end
end
describe ':array?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:phone_numbers, [
- :result, ['', [:val, [:predicate, [:array?, []]]]]]
- ]]
+ [:input, [:phone_numbers, [:result, ['', [:val, p(:array?)]]]]]
)
expect(msg).to eql(phone_numbers: ['must be an array'])
end
end
describe ':int?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, ['2', [:val, [:predicate, [:int?, []]]]]]
- ]]
+ [:input, [:num, [:result, ['2', [:val, p(:int?)]]]]]
)
expect(msg).to eql(num: ['must be an integer'])
end
end
describe ':float?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, ['2', [:val, [:predicate, [:float?, []]]]]]
- ]]
+ [:input, [:num, [:result, ['2', [:val, p(:float?)]]]]]
)
expect(msg).to eql(num: ['must be a float'])
end
end
describe ':decimal?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, ['2', [:val, [:predicate, [:decimal?, []]]]]]
- ]]
+ [:input, [:num, [:result, ['2', [:val, p(:decimal?)]]]]]
)
expect(msg).to eql(num: ['must be a decimal'])
end
end
describe ':date?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, ['2', [:val, [:predicate, [:date?, []]]]]]
- ]]
+ [:input, [:num, [:result, ['2', [:val, p(:date?)]]]]]
)
expect(msg).to eql(num: ['must be a date'])
end
end
describe ':date_time?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, ['2', [:val, [:predicate, [:date_time?, []]]]]]
- ]]
+ [:input, [:num, [:result, ['2', [:val, p(:date_time?)]]]]]
)
expect(msg).to eql(num: ['must be a date time'])
end
end
describe ':time?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, ['2', [:val, [:predicate, [:time?, []]]]]]
- ]]
+ [:input, [:num, [:result, ['2', [:val, p(:time?)]]]]]
)
expect(msg).to eql(num: ['must be a time'])
end
end
describe ':max_size?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, ['abcd', [:val, [:predicate, [:max_size?, [3]]]]]]
- ]]
+ [:input, [:num, [:result, ['abcd', [:val, p(:max_size?, 3)]]]]]
)
expect(msg).to eql(num: ['size cannot be greater than 3'])
end
end
describe ':min_size?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, ['ab', [:val, [:predicate, [:min_size?, [3]]]]]]
- ]]
+ [:input, [:num, [:result, ['ab', [:val, p(:min_size?, 3)]]]]]
)
expect(msg).to eql(num: ['size cannot be less than 3'])
end
end
describe ':none?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, [nil, [:val, [:predicate, [:none?, []]]]]]
- ]]
+ [:input, [:num, [:result, [nil, [:val, p(:none?)]]]]]
)
expect(msg).to eql(num: ['cannot be defined'])
end
end
describe ':size?' do
it 'returns valid message when val is array and arg is int' do
msg = error_compiler.visit(
- [:input, [:numbers, [
- :result, [[1], [:val, [:predicate, [:size?, [3]]]]]]
- ]]
+ [:input, [:numbers, [:result, [[1], [:val, p(:size?, 3)]]]]]
)
expect(msg).to eql(numbers: ['size must be 3'])
end
it 'returns valid message when val is array and arg is range' do
msg = error_compiler.visit(
- [:input, [:numbers, [
- :result, [[1], [:val, [:predicate, [:size?, [3..4]]]]]]
- ]]
+ [:input, [:numbers, [:result, [[1], [:val, p(:size?, 3..4)]]]]]
)
expect(msg).to eql(numbers: ['size must be within 3 - 4'])
end
it 'returns valid message when arg is int' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, ['ab', [:val, [:predicate, [:size?, [3]]]]]]
- ]]
+ [:input, [:num, [:result, ['ab', [:val, p(:size?, 3)]]]]]
)
expect(msg).to eql(num: ['length must be 3'])
end
it 'returns valid message when arg is range' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, ['ab', [:val, [:predicate, [:size?, [3..4]]]]]]
- ]]
+ [:input, [:num, [:result, ['ab', [:val, p(:size?, 3..4)]]]]]
)
expect(msg).to eql(num: ['length must be within 3 - 4'])
end
end
describe ':str?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, [3, [:val, [:predicate, [:str?, []]]]]]
- ]]
+ [:input, [:num, [:result, [3, [:val, p(:str?)]]]]]
)
expect(msg).to eql(num: ['must be a string'])
end
end
describe ':bool?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:num, [
- :result, [3, [:val, [:predicate, [:bool?, []]]]]]
- ]]
+ [:input, [:num, [:result, [3, [:val, p(:bool?)]]]]]
)
expect(msg).to eql(num: ['must be boolean'])
end
end
describe ':format?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:str, [
- :result, ['Bar', [:val, [:predicate, [:format?, [/^F/]]]]]]
- ]]
+ [:input, [:str, [:result, ['Bar', [:val, p(:format?, /^F/)]]]]]
)
expect(msg).to eql(str: ['is in invalid format'])
end
end
+ describe ':number?' do
+ it 'returns valid message' do
+ msg = error_compiler.visit(
+ [:input, [:str, [:result, ["not a number", [:val, p(:number?)]]]]]
+ )
+
+ expect(msg).to eql(str: ['must be a number'])
+ end
+ end
+
+ describe ':odd?' do
+ it 'returns valid message' do
+ msg = error_compiler.visit(
+ [:input, [:str, [:result, [1, [:val, p(:odd?)]]]]]
+ )
+
+ expect(msg).to eql(str: ['must be odd'])
+ end
+ end
+
+ describe ':even?' do
+ it 'returns valid message' do
+ msg = error_compiler.visit(
+ [:input, [:str, [:result, [2, [:val, p(:even?)]]]]]
+ )
+
+ expect(msg).to eql(str: ['must be even'])
+ end
+ end
+
describe ':eql?' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:str, [
- :result, ['Foo', [:val, [:predicate, [:eql?, ['Bar']]]]]]
- ]]
+ [:input, [:str, [:result, ['Foo', [:val, p(:eql?, 'Bar')]]]]]
)
expect(msg).to eql(str: ['must be equal to Bar'])
end
end
+ describe ':not_eql?' do
+ it 'returns valid message' do
+ msg = error_compiler.visit(
+ [:input, [:str, [:result, ['Foo', [:val, p(:not_eql?, 'Foo')]]]]]
+ )
+
+ expect(msg).to eql(str: ['must not be equal to Foo'])
+ end
+ end
+
describe ':type??' do
it 'returns valid message' do
msg = error_compiler.visit(
- [:input, [:age, [
- :result, ['1', [:val, [:predicate, [:type?, [Integer]]]]]]
- ]]
+ [:input, [:age, [:result, ['1', [:val, p(:type?, Integer)]]]]]
)
expect(msg).to eql(age: ['must be Integer'])
end
end