dry-validation 0.13.3 → 1.3.1
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 +233 -12
- data/LICENSE +1 -1
- data/README.md +13 -9
- data/config/errors.yml +3 -88
- data/lib/dry-validation.rb +2 -0
- data/lib/dry/validation.rb +47 -28
- data/lib/dry/validation/config.rb +24 -0
- data/lib/dry/validation/constants.rb +43 -0
- data/lib/dry/validation/contract.rb +160 -0
- data/lib/dry/validation/contract/class_interface.rb +223 -0
- data/lib/dry/validation/evaluator.rb +197 -0
- data/lib/dry/validation/extensions/hints.rb +69 -0
- data/lib/dry/validation/extensions/monads.rb +23 -7
- data/lib/dry/validation/extensions/predicates_as_macros.rb +75 -0
- data/lib/dry/validation/failures.rb +58 -0
- data/lib/dry/validation/function.rb +44 -0
- data/lib/dry/validation/macro.rb +38 -0
- data/lib/dry/validation/macros.rb +104 -0
- data/lib/dry/validation/message.rb +79 -79
- data/lib/dry/validation/message_set.rb +108 -88
- data/lib/dry/validation/messages/resolver.rb +79 -0
- data/lib/dry/validation/result.rb +154 -42
- data/lib/dry/validation/rule.rb +129 -0
- data/lib/dry/validation/schema_ext.rb +46 -0
- data/lib/dry/validation/values.rb +94 -0
- data/lib/dry/validation/version.rb +3 -1
- metadata +41 -336
- data/.codeclimate.yml +0 -17
- data/.gitignore +0 -9
- data/.rspec +0 -3
- data/.travis.yml +0 -29
- data/CONTRIBUTING.md +0 -31
- data/Gemfile +0 -25
- data/Rakefile +0 -22
- data/benchmarks/benchmark_form_invalid.rb +0 -64
- data/benchmarks/benchmark_form_valid.rb +0 -64
- data/benchmarks/benchmark_schema_invalid_huge.rb +0 -52
- data/benchmarks/profile_schema_call_invalid.rb +0 -20
- data/benchmarks/profile_schema_call_valid.rb +0 -20
- data/benchmarks/profile_schema_definition.rb +0 -14
- data/benchmarks/profile_schema_huge_invalid.rb +0 -30
- data/benchmarks/profile_schema_messages_invalid.rb +0 -20
- data/benchmarks/suite.rb +0 -5
- data/dry-validation.gemspec +0 -28
- data/examples/basic.rb +0 -15
- data/examples/each.rb +0 -14
- data/examples/json.rb +0 -12
- data/examples/multiple.rb +0 -27
- data/examples/nested.rb +0 -22
- data/examples/params.rb +0 -11
- data/lib/dry/validation/compat/form.rb +0 -67
- data/lib/dry/validation/deprecations.rb +0 -24
- data/lib/dry/validation/executor.rb +0 -91
- data/lib/dry/validation/extensions.rb +0 -7
- data/lib/dry/validation/extensions/struct.rb +0 -32
- data/lib/dry/validation/input_processor_compiler.rb +0 -137
- data/lib/dry/validation/input_processor_compiler/json.rb +0 -45
- data/lib/dry/validation/input_processor_compiler/params.rb +0 -49
- data/lib/dry/validation/input_processor_compiler/sanitizer.rb +0 -47
- data/lib/dry/validation/message_compiler.rb +0 -188
- data/lib/dry/validation/message_compiler/visitor_opts.rb +0 -37
- data/lib/dry/validation/messages.rb +0 -14
- data/lib/dry/validation/messages/abstract.rb +0 -119
- data/lib/dry/validation/messages/i18n.rb +0 -47
- data/lib/dry/validation/messages/namespaced.rb +0 -39
- data/lib/dry/validation/messages/yaml.rb +0 -61
- data/lib/dry/validation/predicate_registry.rb +0 -115
- data/lib/dry/validation/predicates.rb +0 -19
- data/lib/dry/validation/schema.rb +0 -126
- data/lib/dry/validation/schema/check.rb +0 -37
- data/lib/dry/validation/schema/class_interface.rb +0 -190
- data/lib/dry/validation/schema/deprecated.rb +0 -30
- data/lib/dry/validation/schema/dsl.rb +0 -118
- data/lib/dry/validation/schema/form.rb +0 -9
- data/lib/dry/validation/schema/json.rb +0 -21
- data/lib/dry/validation/schema/key.rb +0 -71
- data/lib/dry/validation/schema/params.rb +0 -22
- data/lib/dry/validation/schema/rule.rb +0 -202
- data/lib/dry/validation/schema/value.rb +0 -211
- data/lib/dry/validation/schema_compiler.rb +0 -81
- data/lib/dry/validation/template.rb +0 -66
- data/lib/dry/validation/type_specs.rb +0 -70
- data/spec/extensions/monads/result_spec.rb +0 -40
- data/spec/extensions/struct/schema_spec.rb +0 -32
- data/spec/fixtures/locales/en.yml +0 -8
- data/spec/fixtures/locales/pl.yml +0 -22
- data/spec/integration/custom_error_messages_spec.rb +0 -54
- data/spec/integration/custom_predicates_spec.rb +0 -228
- data/spec/integration/hints_spec.rb +0 -170
- data/spec/integration/injecting_rules_spec.rb +0 -30
- data/spec/integration/json/defining_base_schema_spec.rb +0 -41
- data/spec/integration/localized_error_messages_spec.rb +0 -72
- data/spec/integration/message_compiler_spec.rb +0 -405
- data/spec/integration/messages/i18n_spec.rb +0 -104
- data/spec/integration/optional_keys_spec.rb +0 -28
- data/spec/integration/params/predicates/array_spec.rb +0 -287
- data/spec/integration/params/predicates/empty_spec.rb +0 -263
- data/spec/integration/params/predicates/eql_spec.rb +0 -327
- data/spec/integration/params/predicates/even_spec.rb +0 -455
- data/spec/integration/params/predicates/excluded_from_spec.rb +0 -455
- data/spec/integration/params/predicates/excludes_spec.rb +0 -391
- data/spec/integration/params/predicates/false_spec.rb +0 -455
- data/spec/integration/params/predicates/filled_spec.rb +0 -467
- data/spec/integration/params/predicates/format_spec.rb +0 -454
- data/spec/integration/params/predicates/gt_spec.rb +0 -519
- data/spec/integration/params/predicates/gteq_spec.rb +0 -519
- data/spec/integration/params/predicates/included_in_spec.rb +0 -455
- data/spec/integration/params/predicates/includes_spec.rb +0 -391
- data/spec/integration/params/predicates/key_spec.rb +0 -67
- data/spec/integration/params/predicates/lt_spec.rb +0 -519
- data/spec/integration/params/predicates/lteq_spec.rb +0 -519
- data/spec/integration/params/predicates/max_size_spec.rb +0 -391
- data/spec/integration/params/predicates/min_size_spec.rb +0 -391
- data/spec/integration/params/predicates/none_spec.rb +0 -265
- data/spec/integration/params/predicates/not_eql_spec.rb +0 -327
- data/spec/integration/params/predicates/odd_spec.rb +0 -455
- data/spec/integration/params/predicates/size/fixed_spec.rb +0 -393
- data/spec/integration/params/predicates/size/range_spec.rb +0 -396
- data/spec/integration/params/predicates/true_spec.rb +0 -455
- data/spec/integration/params/predicates/type_spec.rb +0 -391
- data/spec/integration/result_spec.rb +0 -81
- data/spec/integration/schema/array_schema_spec.rb +0 -59
- data/spec/integration/schema/check_rules_spec.rb +0 -119
- data/spec/integration/schema/check_with_nested_el_spec.rb +0 -37
- data/spec/integration/schema/check_with_nth_el_spec.rb +0 -25
- data/spec/integration/schema/default_settings_spec.rb +0 -11
- data/spec/integration/schema/defining_base_schema_spec.rb +0 -41
- data/spec/integration/schema/dynamic_predicate_args_spec.rb +0 -43
- data/spec/integration/schema/each_with_set_spec.rb +0 -70
- data/spec/integration/schema/extending_dsl_spec.rb +0 -27
- data/spec/integration/schema/form_spec.rb +0 -236
- data/spec/integration/schema/hash_schema_spec.rb +0 -47
- data/spec/integration/schema/inheriting_schema_spec.rb +0 -31
- data/spec/integration/schema/input_processor_spec.rb +0 -46
- data/spec/integration/schema/json/explicit_types_spec.rb +0 -157
- data/spec/integration/schema/json_spec.rb +0 -163
- data/spec/integration/schema/macros/confirmation_spec.rb +0 -35
- data/spec/integration/schema/macros/each_spec.rb +0 -268
- data/spec/integration/schema/macros/filled_spec.rb +0 -87
- data/spec/integration/schema/macros/input_spec.rb +0 -139
- data/spec/integration/schema/macros/maybe_spec.rb +0 -99
- data/spec/integration/schema/macros/rule_spec.rb +0 -75
- data/spec/integration/schema/macros/value_spec.rb +0 -119
- data/spec/integration/schema/macros/when_spec.rb +0 -62
- data/spec/integration/schema/nested_schemas_spec.rb +0 -236
- data/spec/integration/schema/nested_values_spec.rb +0 -46
- data/spec/integration/schema/not_spec.rb +0 -34
- data/spec/integration/schema/numbers_spec.rb +0 -19
- data/spec/integration/schema/option_with_default_spec.rb +0 -64
- data/spec/integration/schema/or_spec.rb +0 -87
- data/spec/integration/schema/params/defining_base_schema_spec.rb +0 -41
- data/spec/integration/schema/params/explicit_types_spec.rb +0 -195
- data/spec/integration/schema/params_spec.rb +0 -234
- data/spec/integration/schema/predicate_verification_spec.rb +0 -9
- data/spec/integration/schema/predicates/array_spec.rb +0 -295
- data/spec/integration/schema/predicates/custom_spec.rb +0 -103
- data/spec/integration/schema/predicates/empty_spec.rb +0 -263
- data/spec/integration/schema/predicates/eql_spec.rb +0 -327
- data/spec/integration/schema/predicates/even_spec.rb +0 -455
- data/spec/integration/schema/predicates/excluded_from/array_spec.rb +0 -459
- data/spec/integration/schema/predicates/excluded_from/range_spec.rb +0 -459
- data/spec/integration/schema/predicates/excludes_spec.rb +0 -391
- data/spec/integration/schema/predicates/filled_spec.rb +0 -467
- data/spec/integration/schema/predicates/format_spec.rb +0 -455
- data/spec/integration/schema/predicates/gt_spec.rb +0 -519
- data/spec/integration/schema/predicates/gteq_spec.rb +0 -519
- data/spec/integration/schema/predicates/hash_spec.rb +0 -69
- data/spec/integration/schema/predicates/included_in/array_spec.rb +0 -459
- data/spec/integration/schema/predicates/included_in/range_spec.rb +0 -459
- data/spec/integration/schema/predicates/includes_spec.rb +0 -391
- data/spec/integration/schema/predicates/key_spec.rb +0 -88
- data/spec/integration/schema/predicates/lt_spec.rb +0 -520
- data/spec/integration/schema/predicates/lteq_spec.rb +0 -519
- data/spec/integration/schema/predicates/max_size_spec.rb +0 -391
- data/spec/integration/schema/predicates/min_size_spec.rb +0 -391
- data/spec/integration/schema/predicates/none_spec.rb +0 -265
- data/spec/integration/schema/predicates/not_eql_spec.rb +0 -391
- data/spec/integration/schema/predicates/odd_spec.rb +0 -455
- data/spec/integration/schema/predicates/size/fixed_spec.rb +0 -398
- data/spec/integration/schema/predicates/size/range_spec.rb +0 -395
- data/spec/integration/schema/predicates/type_spec.rb +0 -413
- data/spec/integration/schema/reusing_schema_spec.rb +0 -33
- data/spec/integration/schema/using_types_spec.rb +0 -135
- data/spec/integration/schema/validate_spec.rb +0 -120
- data/spec/integration/schema/xor_spec.rb +0 -35
- data/spec/integration/schema_builders_spec.rb +0 -17
- data/spec/integration/schema_spec.rb +0 -173
- data/spec/shared/message_compiler.rb +0 -11
- data/spec/shared/predicate_helper.rb +0 -15
- data/spec/shared/rule_compiler.rb +0 -8
- data/spec/spec_helper.rb +0 -62
- data/spec/support/define_struct.rb +0 -25
- data/spec/support/matchers.rb +0 -38
- data/spec/support/mutant.rb +0 -9
- data/spec/support/predicates_integration.rb +0 -7
- data/spec/unit/input_processor_compiler/json_spec.rb +0 -283
- data/spec/unit/input_processor_compiler/params_spec.rb +0 -328
- data/spec/unit/message_compiler/visit_failure_spec.rb +0 -38
- data/spec/unit/message_compiler/visit_spec.rb +0 -16
- data/spec/unit/message_compiler_spec.rb +0 -7
- data/spec/unit/predicate_registry_spec.rb +0 -34
- data/spec/unit/schema/key_spec.rb +0 -38
- data/spec/unit/schema/rule_spec.rb +0 -42
- data/spec/unit/schema/value_spec.rb +0 -131
- data/spec/unit/schema_spec.rb +0 -35
@@ -1,66 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'dry/equalizer'
|
4
|
-
|
5
|
-
module Dry
|
6
|
-
module Validation
|
7
|
-
module Messages
|
8
|
-
# Template wraps a string with interpolation tokens and defines evaluator function
|
9
|
-
# dynamically
|
10
|
-
#
|
11
|
-
# @api private
|
12
|
-
class Template
|
13
|
-
include Dry::Equalizer(:text)
|
14
|
-
|
15
|
-
TOKEN_REGEXP = /%{(\w*)}/
|
16
|
-
|
17
|
-
# !@attribute [r] text
|
18
|
-
# @return [String]
|
19
|
-
attr_reader :text
|
20
|
-
|
21
|
-
# !@attribute [r] tokens
|
22
|
-
# @return [Hash]
|
23
|
-
attr_reader :tokens
|
24
|
-
|
25
|
-
# !@attribute [r] evaluator
|
26
|
-
# @return [Proc]
|
27
|
-
attr_reader :evaluator
|
28
|
-
|
29
|
-
# @api private
|
30
|
-
def self.[](input)
|
31
|
-
new(*parse(input))
|
32
|
-
end
|
33
|
-
|
34
|
-
# @api private
|
35
|
-
def self.parse(input)
|
36
|
-
tokens = input.scan(TOKEN_REGEXP).flatten(1).map(&:to_sym)
|
37
|
-
text = input.gsub('%', '#')
|
38
|
-
|
39
|
-
evaluator = <<-RUBY.strip
|
40
|
-
-> (#{tokens.map { |token| "#{token}:" }.join(", ")}) { "#{text}" }
|
41
|
-
RUBY
|
42
|
-
|
43
|
-
[text, tokens, eval(evaluator, binding, __FILE__, __LINE__ - 3)]
|
44
|
-
end
|
45
|
-
|
46
|
-
# @api private
|
47
|
-
def initialize(text, tokens, evaluator)
|
48
|
-
@text = text
|
49
|
-
@tokens = tokens
|
50
|
-
@evaluator = evaluator
|
51
|
-
end
|
52
|
-
|
53
|
-
# @api private
|
54
|
-
def data(input)
|
55
|
-
tokens.each_with_object({}) { |k, h| h[k] = input[k] }
|
56
|
-
end
|
57
|
-
|
58
|
-
# @api private
|
59
|
-
def call(data = EMPTY_HASH)
|
60
|
-
data.empty? ? evaluator.() : evaluator.(data)
|
61
|
-
end
|
62
|
-
alias_method :[], :call
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,70 +0,0 @@
|
|
1
|
-
module Dry
|
2
|
-
module Validation
|
3
|
-
module TypeSpecs
|
4
|
-
def self.extended(klass)
|
5
|
-
super
|
6
|
-
klass.class_eval do
|
7
|
-
setting :input_processor, :noop
|
8
|
-
setting :hash_type, :weak
|
9
|
-
setting :type_map, {}
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def build_type_map(type_specs, category = config.input_processor)
|
14
|
-
if type_specs.is_a?(Array)
|
15
|
-
build_array_type(type_specs[0], category)
|
16
|
-
else
|
17
|
-
type_specs.reduce({}) { |res, (name, spec)|
|
18
|
-
res.update(name => resolve_spec(spec, category))
|
19
|
-
}
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def build_hash_type(spec = type_map)
|
24
|
-
lookup_type("hash", config.input_processor)
|
25
|
-
.public_send(config.hash_type, spec)
|
26
|
-
end
|
27
|
-
|
28
|
-
def build_array_type(spec, category)
|
29
|
-
member_schema = build_type_map(spec, category)
|
30
|
-
member_type = lookup_type("hash", category)
|
31
|
-
.public_send(config.hash_type, member_schema)
|
32
|
-
|
33
|
-
lookup_type("array", category).of(member_type)
|
34
|
-
end
|
35
|
-
|
36
|
-
def build_sum_type(spec, category)
|
37
|
-
spec
|
38
|
-
.map { |id| id.is_a?(Symbol) ? lookup_type(id, category) : id }
|
39
|
-
.reduce(:|)
|
40
|
-
end
|
41
|
-
|
42
|
-
def resolve_spec(spec, category)
|
43
|
-
case spec
|
44
|
-
when Symbol
|
45
|
-
lookup_type(spec, category)
|
46
|
-
when Hash
|
47
|
-
build_hash_type(spec)
|
48
|
-
when Array
|
49
|
-
if spec.size == 1
|
50
|
-
if spec[0].is_a?(Hash)
|
51
|
-
build_array_type(spec[0], category)
|
52
|
-
else
|
53
|
-
array_member = lookup_type(spec[0], category)
|
54
|
-
lookup_type("array", category).of(array_member)
|
55
|
-
end
|
56
|
-
else
|
57
|
-
build_sum_type(spec, category)
|
58
|
-
end
|
59
|
-
else
|
60
|
-
spec
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def lookup_type(name, category)
|
65
|
-
id = "#{category}.#{name}"
|
66
|
-
Types.type_keys.include?(id) ? Types[id] : Types[name.to_s]
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
RSpec.describe Dry::Validation::Result do
|
2
|
-
before { Dry::Validation.load_extensions(:monads) }
|
3
|
-
|
4
|
-
let(:schema) { Dry::Validation.Schema { required(:name).filled(:str?, size?: 2..4) } }
|
5
|
-
|
6
|
-
context 'with valid input' do
|
7
|
-
let(:input) { { name: 'Jane' } }
|
8
|
-
|
9
|
-
describe '#to_monad' do
|
10
|
-
it 'returns a Success value' do
|
11
|
-
monad = result.to_monad
|
12
|
-
|
13
|
-
expect(monad).to be_a Dry::Monads::Result
|
14
|
-
expect(monad).to be_a_success
|
15
|
-
expect(monad.value!).to eql(name: 'Jane')
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
context 'with invalid input' do
|
21
|
-
let(:input) { { name: '' } }
|
22
|
-
|
23
|
-
describe '#to_monad' do
|
24
|
-
it 'returns a Failure value' do
|
25
|
-
monad = result.to_monad
|
26
|
-
|
27
|
-
expect(monad).to be_a_failure
|
28
|
-
expect(monad.failure).to eql(name: ['must be filled', 'length must be within 2 - 4'])
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'returns full messages' do
|
32
|
-
monad = result.to_monad(full: true)
|
33
|
-
|
34
|
-
expect(monad).to be_a Dry::Monads::Result
|
35
|
-
expect(monad).to be_a_failure
|
36
|
-
expect(monad.failure).to eql(name: ['name must be filled', 'name length must be within 2 - 4'])
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
RSpec.describe Dry::Validation::Schema, 'defining schema using dry struct' do
|
2
|
-
before do
|
3
|
-
Dry::Validation.load_extensions(:struct)
|
4
|
-
end
|
5
|
-
|
6
|
-
subject(:schema) do
|
7
|
-
Dry::Validation.Schema do
|
8
|
-
required(:person).filled(Test::Person)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
before do
|
13
|
-
class Test::Name < Dry::Struct::Value
|
14
|
-
attribute :given_name, Dry::Types['strict.string']
|
15
|
-
attribute :family_name, Dry::Types['strict.string']
|
16
|
-
end
|
17
|
-
|
18
|
-
class Test::Person < Dry::Struct::Value
|
19
|
-
attribute :name, Test::Name
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'handles nested structs' do
|
24
|
-
expect(schema.call(person: { name: { given_name: 'Tim', family_name: 'Cooper' } })).to be_success
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'fails when input is not valid' do
|
28
|
-
expect(schema.call(person: { name: { given_name: 'Tim' } }).messages).to eq(
|
29
|
-
person: { name: { family_name: ['is missing', 'must be String'] } }
|
30
|
-
)
|
31
|
-
end
|
32
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
pl:
|
2
|
-
errors:
|
3
|
-
filled?: "nie może być pusty"
|
4
|
-
size?:
|
5
|
-
arg:
|
6
|
-
default: "wielkość musi być równa %{size}"
|
7
|
-
range: "wielkość musi być między %{size_left} a %{size_right}"
|
8
|
-
value:
|
9
|
-
string:
|
10
|
-
arg:
|
11
|
-
default: "wielkość musi być równa %{size}"
|
12
|
-
rules:
|
13
|
-
email:
|
14
|
-
filled?: "Proszę podać adres email"
|
15
|
-
user:
|
16
|
-
rules:
|
17
|
-
email:
|
18
|
-
filled?: "Hej user! Dawaj ten email no!"
|
19
|
-
|
20
|
-
rules:
|
21
|
-
email:
|
22
|
-
'Adres email'
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'dry/validation/messages/i18n'
|
2
|
-
|
3
|
-
RSpec.describe Dry::Validation do
|
4
|
-
shared_context 'schema with customized messages' do
|
5
|
-
describe '#messages' do
|
6
|
-
it 'returns compiled error messages' do
|
7
|
-
expect(schema.(email: '', age: 12).messages).to eql(
|
8
|
-
email: ['Please provide your email'], age: ['12 must be greater than 18']
|
9
|
-
)
|
10
|
-
|
11
|
-
expect(schema.(email: '', age: 14).messages).to eql(
|
12
|
-
email: ['Please provide your email'], age: ['14 must be greater than 18']
|
13
|
-
)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'yaml' do
|
19
|
-
subject(:schema) do
|
20
|
-
Dry::Validation.Schema do
|
21
|
-
configure do
|
22
|
-
config.messages_file = SPEC_ROOT.join('fixtures/locales/en.yml')
|
23
|
-
end
|
24
|
-
|
25
|
-
required(:email).filled
|
26
|
-
required(:age).value(gt?: 18)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
include_context 'schema with customized messages'
|
31
|
-
end
|
32
|
-
|
33
|
-
context 'i18n' do
|
34
|
-
context 'with custom messages set globally' do
|
35
|
-
before do
|
36
|
-
I18n.load_path << SPEC_ROOT.join('fixtures/locales/en.yml')
|
37
|
-
I18n.backend.load_translations
|
38
|
-
end
|
39
|
-
|
40
|
-
subject(:schema) do
|
41
|
-
Dry::Validation.Schema do
|
42
|
-
configure do
|
43
|
-
config.messages = :i18n
|
44
|
-
end
|
45
|
-
|
46
|
-
required(:email).filled
|
47
|
-
required(:age).value(gt?: 18)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
include_context 'schema with customized messages'
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,228 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
RSpec.describe Dry::Validation do
|
3
|
-
shared_context 'uses custom predicates' do
|
4
|
-
it 'uses provided custom predicates' do
|
5
|
-
expect(schema.(email: 'jane@doe')).to be_success
|
6
|
-
|
7
|
-
expect(schema.(email: nil).messages).to eql(
|
8
|
-
email: ['must be filled', 'must be a valid email']
|
9
|
-
)
|
10
|
-
|
11
|
-
expect(schema.(email: 'jane').messages).to eql(
|
12
|
-
email: ['must be a valid email']
|
13
|
-
)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
let(:base_class) do
|
18
|
-
Class.new(Dry::Validation::Schema) do
|
19
|
-
def self.messages
|
20
|
-
Dry::Validation::Messages.default.merge(
|
21
|
-
en: { errors: { email?: 'must be a valid email' } }
|
22
|
-
)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
describe 'defining schema with custom predicates container' do
|
28
|
-
before do
|
29
|
-
module Test
|
30
|
-
module Predicates
|
31
|
-
include Dry::Logic::Predicates
|
32
|
-
|
33
|
-
def self.email?(input)
|
34
|
-
input.include?('@') # for the lols
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
context 'when configured globally' do
|
41
|
-
subject(:schema) do
|
42
|
-
Dry::Validation.Schema(base_class) do
|
43
|
-
required(:email) { filled? & email? }
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
before do
|
48
|
-
Dry::Validation::Schema.predicates(Test::Predicates)
|
49
|
-
end
|
50
|
-
|
51
|
-
after do
|
52
|
-
# HACK: reset global predicates configuration
|
53
|
-
Dry::Validation::Schema.configure do |config|
|
54
|
-
config.predicates = Dry::Logic::Predicates
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
include_context 'uses custom predicates'
|
59
|
-
end
|
60
|
-
|
61
|
-
context 'when configured locally' do
|
62
|
-
subject(:schema) do
|
63
|
-
Dry::Validation.Schema(base_class) do
|
64
|
-
configure do
|
65
|
-
predicates(Test::Predicates)
|
66
|
-
end
|
67
|
-
|
68
|
-
required(:email) { filled? & email? }
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
include_context 'uses custom predicates'
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe 'defining schema with custom predicate methods' do
|
77
|
-
subject(:schema) do
|
78
|
-
Dry::Validation.Schema(base_class) do
|
79
|
-
configure do
|
80
|
-
def email?(value)
|
81
|
-
value.include?('@')
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
required(:email) { filled? & email? }
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
include_context 'uses custom predicates'
|
90
|
-
end
|
91
|
-
|
92
|
-
describe 'custom predicate which requires an arbitrary dependency' do
|
93
|
-
subject(:schema) do
|
94
|
-
Dry::Validation.Schema(base_class) do
|
95
|
-
configure do
|
96
|
-
option :email_check
|
97
|
-
|
98
|
-
def email?(value)
|
99
|
-
email_check.(value)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
required(:email).filled(:email?)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'uses injected dependency for the custom predicate' do
|
108
|
-
email_check = -> input { input.include?('@') }
|
109
|
-
|
110
|
-
expect(schema.with(email_check: email_check).(email: 'foo').messages).to eql(
|
111
|
-
email: ['must be a valid email']
|
112
|
-
)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
it 'raises an error when message is missing' do
|
117
|
-
schema = Dry::Validation.Schema do
|
118
|
-
configure do
|
119
|
-
def email?(value)
|
120
|
-
false
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
required(:email).filled(:email?)
|
125
|
-
end
|
126
|
-
|
127
|
-
expect { schema.(email: 'foo').messages }.to raise_error(
|
128
|
-
Dry::Validation::MissingMessageError, /email/
|
129
|
-
)
|
130
|
-
end
|
131
|
-
|
132
|
-
it 'works with custom predicate args' do
|
133
|
-
schema = Dry::Validation.Schema do
|
134
|
-
configure do
|
135
|
-
def self.messages
|
136
|
-
Dry::Validation::Messages.default.merge(
|
137
|
-
en: { errors: { fav_number?: 'must be %{expected}' } }
|
138
|
-
)
|
139
|
-
end
|
140
|
-
def fav_number?(expected, current)
|
141
|
-
current == expected
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
required(:foo) { fav_number?(23) }
|
146
|
-
end
|
147
|
-
|
148
|
-
expect(schema.(foo: 20).messages).to eql(
|
149
|
-
foo: ['must be 23']
|
150
|
-
)
|
151
|
-
|
152
|
-
end
|
153
|
-
|
154
|
-
it 'works when no predicate args' do
|
155
|
-
schema = Dry::Validation.Schema do
|
156
|
-
configure do
|
157
|
-
def self.messages
|
158
|
-
Dry::Validation::Messages.default.merge(
|
159
|
-
en: { errors: { with_no_args?: 'is always false' } }
|
160
|
-
)
|
161
|
-
end
|
162
|
-
|
163
|
-
def with_no_args?
|
164
|
-
false
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
required(:email).filled(:with_no_args?)
|
169
|
-
end
|
170
|
-
|
171
|
-
expect(schema.(email: 'foo').messages).to eql(
|
172
|
-
email: ['is always false']
|
173
|
-
)
|
174
|
-
end
|
175
|
-
|
176
|
-
it 'works with nested schemas' do
|
177
|
-
schema = Dry::Validation.Schema do
|
178
|
-
configure do
|
179
|
-
def ok?(_value)
|
180
|
-
true
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
required(:foo).schema do
|
185
|
-
required(:bar).value(:ok?)
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
expect(schema.(foo: { bar: "1" })).to be_success
|
190
|
-
end
|
191
|
-
|
192
|
-
it 'works with interpolation of messages' do
|
193
|
-
schema = Dry::Validation.Schema do
|
194
|
-
configure do
|
195
|
-
option :categories, []
|
196
|
-
|
197
|
-
def self.messages
|
198
|
-
Dry::Validation::Messages.default.merge(
|
199
|
-
en: {
|
200
|
-
errors: {
|
201
|
-
valid_category?: 'must be one of the categories: %{categories}'
|
202
|
-
}
|
203
|
-
},
|
204
|
-
pl: {
|
205
|
-
errors: {
|
206
|
-
valid_category?: 'musi być jedną z: %{categories}'
|
207
|
-
}
|
208
|
-
}
|
209
|
-
)
|
210
|
-
end
|
211
|
-
|
212
|
-
def valid_category?(categories, value)
|
213
|
-
categories.include?(value)
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
required(:category).filled(valid_category?: categories)
|
218
|
-
end.with(categories: %w(foo bar))
|
219
|
-
|
220
|
-
expect(schema.(category: 'baz').messages).to eql(
|
221
|
-
category: ['must be one of the categories: foo, bar']
|
222
|
-
)
|
223
|
-
|
224
|
-
expect(schema.(category: 'baz').messages(locale: :pl)).to eql(
|
225
|
-
category: ['musi być jedną z: foo, bar']
|
226
|
-
)
|
227
|
-
end
|
228
|
-
end
|