dry-validation 1.4.2 → 1.5.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ea571eab29d2c8f50457cd8472a8f0d66da98bfda7f7fd1b697776532193b12d
4
- data.tar.gz: 0e45ff77064b269b25e4c9dbc84219dcc78e07390bb14e75dd2fa0ab24593096
3
+ metadata.gz: 5c4b57593ac3fd38a26ef3eb26a31b34503bfa75a6fc118358745aa9fb772be1
4
+ data.tar.gz: 534dc4c9e0a8e83faec7077a78e4b3fd7e7fa5b55b6aa277479999332920bcb5
5
5
  SHA512:
6
- metadata.gz: ddc760c72d530ceada83071591ebb7d214ed1c1fe7ec56486120170cd8b32a50916468dc086018820d3505a1eb14df1cbfe07a80b212da7c5f67c262dc47847b
7
- data.tar.gz: d06df105ce8e8a9ef8720dd6df9748585c9621a39bca8a73067e337ad153edbdbd052581be687a6df9bc0c62e16b1ad9fb8866014a0d4ba9a2c411c31d892610
6
+ metadata.gz: 8268526e70a23bd00ff7825accd0b7f4ca682342a2fefab22051e756e574a8b2834d527e1c1e2cce0a7084308eb9d721dafce92b1500c793588ba9d219499e82
7
+ data.tar.gz: d1ca0f28f775093521f74330dc4a09142a99c83c693aefcab1571f32343692a72c5f3669bd51baf10865fc9de93074ab3893ddfbb6412edf540bf3f2ac37b47c
@@ -1,3 +1,18 @@
1
+ ## unreleased
2
+
3
+
4
+ ### Added
5
+
6
+ - `schema_error?` rule helper (@waiting-for-dev)
7
+ - `rule_error?` rule helper (@waiting-for-dev)
8
+
9
+ ### Changed
10
+
11
+ - dry-schema dependency was bumped to `~> 1.5` (@solnic)
12
+ - [internal] `KeyMap` patches have been removed since dry-schema now provides required functionality (@solnic)
13
+
14
+ [Compare v1.4.2...master](https://github.com/dry-rb/dry-validation/compare/v1.4.2...master)
15
+
1
16
  ## 1.4.2 2020-01-18
2
17
 
3
18
 
@@ -16,6 +16,8 @@ Gem::Specification.new do |spec|
16
16
  spec.description = spec.summary
17
17
  spec.homepage = 'https://dry-rb.org/gems/dry-validation'
18
18
  spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-validation.gemspec", "lib/**/*", "config/*.yml"]
19
+ spec.bindir = 'bin'
20
+ spec.executables = []
19
21
  spec.require_paths = ['lib']
20
22
 
21
23
  spec.metadata['allowed_push_host'] = 'https://rubygems.org'
@@ -23,7 +25,7 @@ Gem::Specification.new do |spec|
23
25
  spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-validation'
24
26
  spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-validation/issues'
25
27
 
26
- spec.required_ruby_version = '>= 2.4.0'
28
+ spec.required_ruby_version = ">= 2.4.0"
27
29
 
28
30
  # to update dependencies edit project.yml
29
31
  spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
@@ -31,7 +33,7 @@ Gem::Specification.new do |spec|
31
33
  spec.add_runtime_dependency "dry-core", "~> 0.4"
32
34
  spec.add_runtime_dependency "dry-equalizer", "~> 0.2"
33
35
  spec.add_runtime_dependency "dry-initializer", "~> 3.0"
34
- spec.add_runtime_dependency "dry-schema", "~> 1.4", ">= 1.4.3"
36
+ spec.add_runtime_dependency "dry-schema", "~> 1.5"
35
37
 
36
38
  spec.add_development_dependency "bundler"
37
39
  spec.add_development_dependency "rake"
@@ -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]
@@ -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
172
  # @param [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)
@@ -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,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
@@ -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
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/initializer'
4
- require 'dry/validation/constants'
3
+ require "dry/initializer"
4
+ require "dry/validation/constants"
5
5
 
6
6
  module Dry
7
7
  module Validation
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/validation/constants'
4
- require 'dry/validation/function'
3
+ require "dry/validation/constants"
4
+ require "dry/validation/function"
5
5
 
6
6
  module Dry
7
7
  module Validation
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/container'
4
- require 'dry/validation/macro'
3
+ require "dry/container"
4
+ require "dry/validation/macro"
5
5
 
6
6
  module Dry
7
7
  module Validation
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/equalizer'
3
+ require "dry/equalizer"
4
4
 
5
- require 'dry/schema/constants'
6
- require 'dry/schema/message'
5
+ require "dry/schema/constants"
6
+ require "dry/schema/message"
7
7
 
8
8
  module Dry
9
9
  module Validation
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/schema/message_set'
3
+ require "dry/schema/message_set"
4
4
 
5
- require 'dry/validation/constants'
6
- require 'dry/validation/message'
5
+ require "dry/validation/constants"
6
+ require "dry/validation/message"
7
7
 
8
8
  module Dry
9
9
  module Validation
@@ -57,7 +57,6 @@ module Dry
57
57
  @empty = nil
58
58
  source_messages << message
59
59
  messages << message
60
- initialize_placeholders!
61
60
  self
62
61
  end
63
62
 
@@ -93,51 +92,6 @@ module Dry
93
92
  to_h
94
93
  self
95
94
  end
96
-
97
- private
98
-
99
- # @api private
100
- def unique_paths
101
- source_messages.uniq(&:path).map(&:path)
102
- end
103
-
104
- # @api private
105
- def messages_map
106
- @messages_map ||= reduce(placeholders) { |hash, msg|
107
- node = msg.path.reduce(hash) { |a, e| a.is_a?(Hash) ? a[e] : a.last[e] }
108
- (node[0].is_a?(::Array) ? node[0] : node) << msg.dump
109
- hash
110
- }
111
- end
112
-
113
- # @api private
114
- #
115
- # rubocop:disable Metrics/AbcSize
116
- # rubocop:disable Metrics/PerceivedComplexity
117
- def initialize_placeholders!
118
- @placeholders = unique_paths.sort_by(&:size).each_with_object(EMPTY_HASH.dup) { |path, hash|
119
- curr_idx = 0
120
- last_idx = path.size - 1
121
- node = hash
122
-
123
- while curr_idx <= last_idx
124
- key = path[curr_idx]
125
-
126
- next_node =
127
- if node.is_a?(Array) && key.is_a?(Symbol)
128
- node_hash = (node << [] << {}).last
129
- node_hash[key] || (node_hash[key] = curr_idx < last_idx ? {} : [])
130
- else
131
- node[key] || (node[key] = curr_idx < last_idx ? {} : [])
132
- end
133
-
134
- node = next_node
135
- curr_idx += 1
136
- end
137
- }
138
- end
139
- # rubocop:enable Metrics/AbcSize
140
- # rubocop:enable Metrics/PerceivedComplexity
141
95
  end
142
96
  end
143
97
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/validation/message'
3
+ require "dry/validation/message"
4
4
 
5
5
  module Dry
6
6
  module Validation
@@ -95,7 +95,7 @@ module Dry
95
95
  def parse_token(token)
96
96
  case token
97
97
  when Array
98
- token.join(', ')
98
+ token.join(", ")
99
99
  else
100
100
  token
101
101
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'concurrent/map'
4
- require 'dry/equalizer'
3
+ require "concurrent/map"
4
+ require "dry/equalizer"
5
5
 
6
- require 'dry/validation/constants'
7
- require 'dry/validation/message_set'
8
- require 'dry/validation/values'
6
+ require "dry/validation/constants"
7
+ require "dry/validation/message_set"
8
+ require "dry/validation/values"
9
9
 
10
10
  module Dry
11
11
  module Validation
@@ -179,7 +179,7 @@ module Dry
179
179
  super
180
180
  end
181
181
 
182
- if RUBY_VERSION >= '2.7'
182
+ if RUBY_VERSION >= "2.7"
183
183
  # Pattern matching
184
184
  #
185
185
  # @api private
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/equalizer'
3
+ require "dry/equalizer"
4
4
 
5
- require 'dry/validation/constants'
6
- require 'dry/validation/function'
5
+ require "dry/validation/constants"
6
+ require "dry/validation/function"
7
7
 
8
8
  module Dry
9
9
  module Validation
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/schema/key'
4
- require 'dry/schema/key_map'
3
+ require "dry/schema/path"
5
4
 
6
5
  module Dry
7
6
  module Schema
@@ -16,31 +15,5 @@ module Dry
16
15
  to_a[0..-2].product(last).map { |spec| self.class[spec] }
17
16
  end
18
17
  end
19
-
20
- # @api private
21
- #
22
- # TODO: this should be moved to dry-schema at some point
23
- class Key
24
- # @api private
25
- def to_dot_notation
26
- [name.to_s]
27
- end
28
-
29
- # @api private
30
- class Hash < Key
31
- # @api private
32
- def to_dot_notation
33
- [name].product(members.flat_map(&:to_dot_notation)).map { |e| e.join(DOT) }
34
- end
35
- end
36
- end
37
-
38
- # @api private
39
- class KeyMap
40
- # @api private
41
- def to_dot_notation
42
- @to_dot_notation ||= map(&:to_dot_notation).flatten
43
- end
44
- end
45
18
  end
46
19
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/equalizer'
4
- require 'dry/schema/path'
5
- require 'dry/validation/constants'
3
+ require "dry/equalizer"
4
+ require "dry/schema/path"
5
+ require "dry/validation/constants"
6
6
 
7
7
  module Dry
8
8
  module Validation
@@ -53,7 +53,7 @@ module Dry
53
53
  vals = self.class.new(data.dig(*keys))
54
54
  vals.fetch_values(*last) { nil }
55
55
  else
56
- raise ArgumentError, '+key+ must be a valid path specification'
56
+ raise ArgumentError, "+key+ must be a valid path specification"
57
57
  end
58
58
  end
59
59
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module Validation
5
- VERSION = '1.4.2'
5
+ VERSION = "1.5.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-validation
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.2
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-18 00:00:00.000000000 Z
11
+ date: 2020-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -92,20 +92,14 @@ dependencies:
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '1.4'
96
- - - ">="
97
- - !ruby/object:Gem::Version
98
- version: 1.4.3
95
+ version: '1.5'
99
96
  type: :runtime
100
97
  prerelease: false
101
98
  version_requirements: !ruby/object:Gem::Requirement
102
99
  requirements:
103
100
  - - "~>"
104
101
  - !ruby/object:Gem::Version
105
- version: '1.4'
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- version: 1.4.3
102
+ version: '1.5'
109
103
  - !ruby/object:Gem::Dependency
110
104
  name: bundler
111
105
  requirement: !ruby/object:Gem::Requirement