dry-validation 1.4.0 → 1.5.2

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.
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2019 dry-rb team
3
+ Copyright (c) 2015-2020 dry-rb team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -1,29 +1,28 @@
1
1
  [gem]: https://rubygems.org/gems/dry-validation
2
- [ci]: https://github.com/dry-rb/dry-validation/actions?query=workflow%3Aci
3
- [codeclimate]: https://codeclimate.com/github/dry-rb/dry-validation
2
+ [actions]: https://github.com/dry-rb/dry-validation/actions
3
+ [codacy]: https://www.codacy.com/gh/dry-rb/dry-validation
4
4
  [chat]: https://dry-rb.zulipchat.com
5
5
  [inchpages]: http://inch-ci.org/github/dry-rb/dry-validation
6
6
 
7
7
  # dry-validation [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
8
8
 
9
9
  [![Gem Version](https://badge.fury.io/rb/dry-validation.svg)][gem]
10
- [![Build Status](https://github.com/dry-rb/dry-monads/workflows/ci/badge.svg)][ci]
11
- [![Code Climate](https://codeclimate.com/github/dry-rb/dry-validation/badges/gpa.svg)][codeclimate]
12
- [![Test Coverage](https://codeclimate.com/github/dry-rb/dry-validation/badges/coverage.svg)][codeclimate]
10
+ [![CI Status](https://github.com/dry-rb/dry-validation/workflows/ci/badge.svg)][actions]
11
+ [![Codacy Badge](https://api.codacy.com/project/badge/Grade/f30e3ff5ec304c55a73868cdbf055c67)][codacy]
12
+ [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/f30e3ff5ec304c55a73868cdbf055c67)][codacy]
13
13
  [![Inline docs](http://inch-ci.org/github/dry-rb/dry-validation.svg?branch=master)][inchpages]
14
14
 
15
15
  ## Links
16
16
 
17
- - [User documentation](https://dry-rb.org/gems/dry-validation)
18
- - [API documentation](http://rubydoc.info/gems/dry-validation)
19
- - [Guidelines for contributing](CONTRIBUTING.md)
17
+ * [User documentation](http://dry-rb.org/gems/dry-validation)
18
+ * [API documentation](http://rubydoc.info/gems/dry-validation)
20
19
 
21
20
  ## Supported Ruby versions
22
21
 
23
22
  This library officially supports the following Ruby versions:
24
23
 
25
- - MRI >= `2.4`
26
- - jruby >= `9.2`
24
+ * MRI >= `2.4`
25
+ * jruby >= `9.2`
27
26
 
28
27
  ## License
29
28
 
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ # this file is managed by dry-rb/devtools project
3
+
4
+ lib = File.expand_path('lib', __dir__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require 'dry/validation/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'dry-validation'
10
+ spec.authors = ["Piotr Solnica"]
11
+ spec.email = ["piotr.solnica@gmail.com"]
12
+ spec.license = 'MIT'
13
+ spec.version = Dry::Validation::VERSION.dup
14
+
15
+ spec.summary = "Validation library"
16
+ spec.description = spec.summary
17
+ spec.homepage = 'https://dry-rb.org/gems/dry-validation'
18
+ spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-validation.gemspec", "lib/**/*", "config/*.yml"]
19
+ spec.bindir = 'bin'
20
+ spec.executables = []
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
24
+ spec.metadata['changelog_uri'] = 'https://github.com/dry-rb/dry-validation/blob/master/CHANGELOG.md'
25
+ spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-validation'
26
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-validation/issues'
27
+
28
+ spec.required_ruby_version = ">= 2.4.0"
29
+
30
+ # to update dependencies edit project.yml
31
+ spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
32
+ spec.add_runtime_dependency "dry-container", "~> 0.7", ">= 0.7.1"
33
+ spec.add_runtime_dependency "dry-core", "~> 0.4"
34
+ spec.add_runtime_dependency "dry-equalizer", "~> 0.2"
35
+ spec.add_runtime_dependency "dry-initializer", "~> 3.0"
36
+ spec.add_runtime_dependency "dry-schema", "~> 1.5"
37
+
38
+ spec.add_development_dependency "bundler"
39
+ spec.add_development_dependency "rake"
40
+ spec.add_development_dependency "rspec"
41
+ end
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/validation'
3
+ require "dry/validation"
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/validation/constants'
4
- require 'dry/validation/contract'
5
- require 'dry/validation/macros'
3
+ require "dry/validation/constants"
4
+ require "dry/validation/contract"
5
+ require "dry/validation/macros"
6
6
 
7
7
  # Main namespace
8
8
  #
@@ -16,15 +16,15 @@ module Dry
16
16
  extend Macros::Registrar
17
17
 
18
18
  register_extension(:monads) do
19
- require 'dry/validation/extensions/monads'
19
+ require "dry/validation/extensions/monads"
20
20
  end
21
21
 
22
22
  register_extension(:hints) do
23
- require 'dry/validation/extensions/hints'
23
+ require "dry/validation/extensions/hints"
24
24
  end
25
25
 
26
26
  register_extension(:predicates_as_macros) do
27
- require 'dry/validation/extensions/predicates_as_macros'
27
+ require "dry/validation/extensions/predicates_as_macros"
28
28
  end
29
29
 
30
30
  # Define a contract and build its instance
@@ -46,11 +46,9 @@ module Dry
46
46
  #
47
47
  # @api public
48
48
  #
49
- # rubocop:disable Naming/MethodName
50
49
  def self.Contract(options = EMPTY_HASH, &block)
51
50
  Contract.build(options, &block)
52
51
  end
53
- # rubocop:enable Naming/MethodName
54
52
 
55
53
  # This is needed by Macros::Registrar
56
54
  #
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/schema/config'
4
- require 'dry/validation/macros'
3
+ require "dry/schema/config"
4
+ require "dry/validation/macros"
5
5
 
6
6
  module Dry
7
7
  module Validation
@@ -1,22 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pathname'
4
- require 'dry/core/constants'
3
+ require "pathname"
4
+ require "dry/core/constants"
5
5
 
6
6
  module Dry
7
7
  module Validation
8
8
  include Dry::Core::Constants
9
9
 
10
- DOT = '.'
10
+ DOT = "."
11
11
 
12
12
  # Root path is used for base errors in hash representation of error messages
13
13
  ROOT_PATH = [nil].freeze
14
14
 
15
15
  # Path to the default errors locale file
16
- DEFAULT_ERRORS_NAMESPACE = 'dry_validation'
16
+ DEFAULT_ERRORS_NAMESPACE = "dry_validation"
17
17
 
18
18
  # Path to the default errors locale file
19
- DEFAULT_ERRORS_PATH = Pathname(__FILE__).join('../../../../config/errors.yml').realpath.freeze
19
+ DEFAULT_ERRORS_PATH = Pathname(__FILE__).join("../../../../config/errors.yml").realpath.freeze
20
20
 
21
21
  # Mapping for block kwarg options used by block_options
22
22
  #
@@ -1,18 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'concurrent/map'
4
-
5
- require 'dry/equalizer'
6
- require 'dry/initializer'
7
- require 'dry/schema/path'
8
-
9
- require 'dry/validation/config'
10
- require 'dry/validation/constants'
11
- require 'dry/validation/rule'
12
- require 'dry/validation/evaluator'
13
- require 'dry/validation/messages/resolver'
14
- require 'dry/validation/result'
15
- require 'dry/validation/contract/class_interface'
3
+ require "concurrent/map"
4
+
5
+ require "dry/equalizer"
6
+ require "dry/initializer"
7
+ require "dry/schema/path"
8
+
9
+ require "dry/validation/config"
10
+ require "dry/validation/constants"
11
+ require "dry/validation/rule"
12
+ require "dry/validation/evaluator"
13
+ require "dry/validation/messages/resolver"
14
+ require "dry/validation/result"
15
+ require "dry/validation/contract/class_interface"
16
16
 
17
17
  module Dry
18
18
  module Validation
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/schema'
4
- require 'dry/schema/messages'
5
- require 'dry/schema/path'
6
- require 'dry/schema/key_map'
3
+ require "dry/schema"
4
+ require "dry/schema/messages"
5
+ require "dry/schema/path"
6
+ require "dry/schema/key_map"
7
7
 
8
- require 'dry/validation/constants'
9
- require 'dry/validation/macros'
10
- require 'dry/validation/schema_ext'
8
+ require "dry/validation/constants"
9
+ require "dry/validation/macros"
10
+ require "dry/validation/schema_ext"
11
11
 
12
12
  module Dry
13
13
  module Validation
@@ -23,7 +23,7 @@ module Dry
23
23
  # @api private
24
24
  def inherited(klass)
25
25
  super
26
- klass.instance_variable_set('@config', config.dup)
26
+ klass.instance_variable_set("@config", config.dup)
27
27
  end
28
28
 
29
29
  # Configuration
@@ -154,28 +154,15 @@ module Dry
154
154
  private
155
155
 
156
156
  # @api private
157
- # rubocop:disable Metrics/AbcSize
158
157
  def ensure_valid_keys(*keys)
159
- valid_paths = key_map.to_dot_notation.map { |value| Schema::Path[value] }
160
-
161
- invalid_keys = keys
162
- .map { |key|
163
- [key, Schema::Path[key]]
164
- }
165
- .flat_map { |(key, path)|
166
- if (last = path.last).is_a?(Array)
167
- last.map { |last_key|
168
- path_key = [*path.to_a[0..-2], last_key]
169
- [path_key, Schema::Path[path_key]]
170
- }
171
- else
172
- [[key, path]]
173
- end
174
- }
175
- .reject { |(_, path)|
176
- valid_paths.any? { |valid_path| valid_path.include?(path) }
177
- }
178
- .map(&:first)
158
+ valid_paths = key_map.to_dot_notation
159
+ key_paths = key_paths(keys)
160
+
161
+ invalid_keys = key_paths.map { |(key, path)|
162
+ unless valid_paths.any? { |vp| vp.include?(path) || vp.include?("#{path}[]") }
163
+ key
164
+ end
165
+ }.compact.uniq
179
166
 
180
167
  return if invalid_keys.empty?
181
168
 
@@ -183,7 +170,28 @@ module Dry
183
170
  #{name}.rule specifies keys that are not defined by the schema: #{invalid_keys.inspect}
184
171
  STR
185
172
  end
186
- # rubocop:enable Metrics/AbcSize
173
+
174
+ # @api private
175
+ def key_paths(keys)
176
+ keys.map { |key|
177
+ case key
178
+ when Hash
179
+ path = Schema::Path[key]
180
+ if path.multi_value?
181
+ *head, tail = Array(path)
182
+ [key].product(
183
+ tail.map { |el| [*head, *el] }.map { |parts| parts.join(DOT) }
184
+ )
185
+ else
186
+ [[key, path.to_a.join(DOT)]]
187
+ end
188
+ when Array
189
+ [[key, Schema::Path[key].to_a.join(DOT)]]
190
+ else
191
+ [[key, key.to_s]]
192
+ end
193
+ }.flatten(1)
194
+ end
187
195
 
188
196
  # @api private
189
197
  def key_map
@@ -192,7 +200,7 @@ module Dry
192
200
 
193
201
  # @api private
194
202
  def core_schema_opts
195
- { parent: superclass&.__schema__, config: config }
203
+ {parent: superclass&.__schema__, config: config}
196
204
  end
197
205
 
198
206
  # @api private
@@ -200,7 +208,7 @@ module Dry
200
208
  return __schema__ if external_schemas.empty? && block.nil?
201
209
 
202
210
  unless __schema__.nil?
203
- raise ::Dry::Validation::DuplicateSchemaError, 'Schema has already been defined'
211
+ raise ::Dry::Validation::DuplicateSchemaError, "Schema has already been defined"
204
212
  end
205
213
 
206
214
  schema_opts = core_schema_opts
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/initializer'
3
+ require "dry/initializer"
4
+ require "dry/core/deprecations"
4
5
 
5
- require 'dry/validation/constants'
6
- require 'dry/validation/failures'
6
+ require "dry/validation/constants"
7
+ require "dry/validation/failures"
7
8
 
8
9
  module Dry
9
10
  module Validation
@@ -16,6 +17,9 @@ module Dry
16
17
  # @api public
17
18
  class Evaluator
18
19
  extend Dry::Initializer
20
+ extend Dry::Core::Deprecations[:'dry-validation']
21
+
22
+ deprecate :error?, :schema_error?
19
23
 
20
24
  # @!attribute [r] _contract
21
25
  # @return [Contract]
@@ -142,7 +146,7 @@ module Dry
142
146
  #
143
147
  # @return [Object]
144
148
  #
145
- # @public
149
+ # @api public
146
150
  def value
147
151
  values[key_name]
148
152
  end
@@ -163,17 +167,26 @@ module Dry
163
167
  values.key?(key_name)
164
168
  end
165
169
 
166
- # Check if there are any errors under the provided path
170
+ # Check if there are any errors on the schema under the provided path
167
171
  #
168
- # @param [Symbol, String, Array] A Path-compatible spec
172
+ # @param path [Symbol, String, Array] A Path-compatible spec
169
173
  #
170
174
  # @return [Boolean]
171
175
  #
172
176
  # @api public
173
- def error?(path)
177
+ def schema_error?(path)
174
178
  result.error?(path)
175
179
  end
176
180
 
181
+ # Check if there are any errors on the current rule
182
+ #
183
+ # @return [Boolean]
184
+ #
185
+ # @api public
186
+ def rule_error?
187
+ !key(path).empty?
188
+ end
189
+
177
190
  # @api private
178
191
  def respond_to_missing?(meth, include_private = false)
179
192
  super || _contract.respond_to?(meth, true)
@@ -192,6 +205,7 @@ module Dry
192
205
  super
193
206
  end
194
207
  end
208
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
195
209
  end
196
210
  end
197
211
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/monads/result'
4
-
5
3
  module Dry
6
4
  module Validation
7
5
  # Hints extension
@@ -46,7 +44,7 @@ module Dry
46
44
  #
47
45
  # @api public
48
46
  def messages(new_options = EMPTY_HASH)
49
- errors.with(hints.to_a, options.merge(**new_options))
47
+ errors.with(hints(new_options).to_a, options.merge(**new_options))
50
48
  end
51
49
 
52
50
  # Return hint messages
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/monads/result'
3
+ require "dry/monads/result"
4
4
 
5
5
  module Dry
6
6
  module Validation
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/schema/predicate_registry'
4
- require 'dry/validation/contract'
3
+ require "dry/schema/predicate_registry"
4
+ require "dry/validation/contract"
5
5
 
6
6
  module Dry
7
7
  module Validation
@@ -12,7 +12,7 @@ module Dry
12
12
  #
13
13
  # @see Dry::Validation::Contract
14
14
  WHITELIST = %i[
15
- filled? gt? gteq? included_in? includes? inclusion? is? lt?
15
+ filled? format? gt? gteq? included_in? includes? inclusion? is? lt?
16
16
  lteq? max_size? min_size? not_eql? odd? respond_to? size? true?
17
17
  uuid_v4?
18
18
  ].freeze
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/schema/path'
4
- require 'dry/validation/constants'
3
+ require "dry/schema/path"
4
+ require "dry/validation/constants"
5
5
 
6
6
  module Dry
7
7
  module Validation
@@ -57,9 +57,14 @@ module Dry
57
57
  #
58
58
  # @api public
59
59
  def failure(message, tokens = EMPTY_HASH)
60
- opts << { message: message, tokens: tokens, path: path }
60
+ opts << {message: message, tokens: tokens, path: path}
61
61
  self
62
62
  end
63
+
64
+ # @api private
65
+ def empty?
66
+ opts.empty?
67
+ end
63
68
  end
64
69
  end
65
70
  end