dry-validation 1.5.1 → 1.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2deba7f8bd2d4ad011e0f4be2aa20d4f20d219d85d0eeec23d3b3e0b12c0bcf4
4
- data.tar.gz: 12f9500062c0239d19f6bf32450db22065a9caa3062e4cb71d79a9370c3229ec
3
+ metadata.gz: 1cbb33c9bad218b481c727b04080736ad0d974f47b552ed305de4f50e5bd8d6d
4
+ data.tar.gz: e464d56a10afa52ab975d44d204a0879649007eeb98a1a15038e5c6d29b78b21
5
5
  SHA512:
6
- metadata.gz: be6cf6d5dfce8ebec88743b7661eaf4d3cc1294cea249b87e7c02fd00b36013a033fe5feab1ccdb3e6e6020873435fbfc5bf6ee41b5f76836358973f5074843e
7
- data.tar.gz: 77f87593b028dfa608f22835413a73fcbd7c2585e9a98c95f20a158df47fc5ca3f46a0357188f5bd1fc37140de7b57b833ae969aabe55bbdf71628f7db6f645e
6
+ metadata.gz: 94637a8714ffc4111c0279a7aeb52613fccf894abd33207600131e7af59803371b044691949c9a457c85bbdbb9d063c7c050aa58fc51966e7469b62f97156008
7
+ data.tar.gz: f15fbb334bd99fe79348a750bca344beff68156394c314f1845307a1b5b2462446117a80e47d0d3eb40108e3042de99744c205a7ffc99ef48bebd179a5fa0299
data/CHANGELOG.md CHANGED
@@ -1,14 +1,127 @@
1
- ## unreleased
1
+ <!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
2
+
3
+ ## 1.8.1 2022-05-28
4
+
5
+
6
+ ### Fixed
7
+
8
+ - Raise an InvalidKeyErrors on substring of valid keys (issue #705 fixed via #706) (@MatElGran)
9
+ - Using `rule(:arr).each { .. }` doesn't crash when `:arr` turns out to be `nil` (issue #708 fixed via #709) (@bautrey37)
10
+
11
+
12
+ [Compare v1.8.0...v1.8.1](https://github.com/dry-rb/dry-validation/compare/v1.8.0...v1.8.1)
13
+
14
+ ## 1.8.0 2022-02-17
15
+
16
+
17
+ ### Added
18
+
19
+ - New rule helper `base_rule_error?` which checks if there's any base error set (via #690) (@wuarmin)
20
+
21
+ ### Changed
22
+
23
+ - Dependency on dry-schema was bumped to 1.9.1 (@solnic)
24
+
25
+ [Compare v1.7.0...v1.8.0](https://github.com/dry-rb/dry-validation/compare/v1.7.0...v1.8.0)
26
+
27
+ ## 1.7.0 2021-09-12
28
+
29
+
30
+ ### Changed
31
+
32
+ - [internal] Upgraded to new `setting` API provided in dry-configurable 0.13.0 (@timriley in #686 and 3f8f7d8)
33
+ - Bumped dry-schema dependency to 1.8.0 (in part, to ensure dry-configurable 0.13.0 is available) (@timriley)
34
+
35
+ [Compare v1.6.0...v1.7.0](https://github.com/dry-rb/dry-validation/compare/v1.6.0...v1.7.0)
36
+
37
+ ## 1.6.0 2020-12-05
38
+
39
+
40
+ ### Added
41
+
42
+ - You can now pass a key name or path to `rule_error?` predicate (issue #658 closed via #673) (@moofkit)
43
+ - You can now pass initial context object to `Contract#call` (issue #674 via #675) (@pyromaniac)
44
+
45
+ ### Fixed
46
+
47
+ - Checking `key?` within a rule no longer crashes when value is `nil` or an empty string (issue #670 fixed via #672) (@alexxty7)
48
+
49
+
50
+ [Compare v1.5.6...v1.6.0](https://github.com/dry-rb/dry-validation/compare/v1.5.6...v1.6.0)
51
+
52
+ ## 1.5.6 2020-09-04
53
+
54
+
55
+ ### Fixed
56
+
57
+ - Dependency on dry-schema was bumped to >= 1.5.1. This time for real (@solnic)
58
+
59
+
60
+ [Compare v1.5.5...v1.5.6](https://github.com/dry-rb/dry-validation/compare/v1.5.5...v1.5.6)
61
+
62
+ ## 1.5.5 2020-09-03
63
+
64
+
65
+ ### Fixed
66
+
67
+ - Dependency on dry-schema was bumped to >= 1.5.2 (see #666 for more info) (@artofhuman)
68
+
69
+
70
+ [Compare v1.5.4...v1.5.5](https://github.com/dry-rb/dry-validation/compare/v1.5.4...v1.5.5)
71
+
72
+ ## 1.5.4 2020-08-21
73
+
74
+
75
+ ### Added
76
+
77
+ - You can now pass any key or a path to the rule's `key?` helper (see #664 for more info) (@alassek)
78
+
79
+ ### Fixed
80
+
81
+ - Full messages work correctly with rule failures now (issue #661 fixed via #662) (@stind)
82
+ - Providing a custom message template for array errors works correctly (issue #663 fixed via #665) (@tadeusz-niemiec)
83
+
84
+
85
+ [Compare v1.5.3...v1.5.4](https://github.com/dry-rb/dry-validation/compare/v1.5.3...v1.5.4)
86
+
87
+ ## 1.5.3 2020-07-27
88
+
89
+
90
+ ### Added
91
+
92
+ - You can now access current value's index via `rule(:foo).each do |index:|` (issue #606 done via #657) (@mrbongiolo)
93
+
94
+ ### Fixed
95
+
96
+ - Using `.each(:foo)` works as expected when there are errors related to other keys (issue #659 fixed via #660) (@solnic)
97
+
98
+ ### Changed
99
+
100
+ - `Result#error?` is now a public API and it takes into consideration both schema and rule errors (issue #655 fixed via #656) (@PragTob)
101
+
102
+ [Compare v1.5.2...v1.5.3](https://github.com/dry-rb/dry-validation/compare/v1.5.2...v1.5.3)
103
+
104
+ ## 1.5.2 2020-07-14
105
+
106
+
107
+ ### Fixed
108
+
109
+ - `key?` predicate in rules no longer crashes when the rule path points to a non-existent array value (issue #653 fixed via #654) (@solnic)
110
+
111
+
112
+ [Compare v1.5.1...v1.5.2](https://github.com/dry-rb/dry-validation/compare/v1.5.1...v1.5.2)
113
+
114
+ ## 1.5.1 2020-06-18
2
115
 
3
116
 
4
117
  ### Fixed
5
118
 
6
119
  - dry-monads no longer required for the `:hints` extension (@schokomarie)
7
120
  - Using `full: true` option works as expected with custom rule messages (issue #618 fixed via #651) (@sirfilip)
8
- - Using `locale: ...` option works as expected with hints (issue #589 fixed via #652) (@sirfilip)
121
+ - Using `locale: ...` option works as expected with hints (issue #589 fixed via 652) (@sirfilip)
9
122
 
10
123
 
11
- [Compare v1.5.0...master](https://github.com/dry-rb/dry-validation/compare/v1.5.0...master)
124
+ [Compare v1.5.0...v1.5.1](https://github.com/dry-rb/dry-validation/compare/v1.5.0...v1.5.1)
12
125
 
13
126
  ## 1.5.0 2020-03-11
14
127
 
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2020 dry-rb team
3
+ Copyright (c) 2015-2021 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,3 +1,4 @@
1
+ <!--- this file is synced from dry-rb/template-gem project -->
1
2
  [gem]: https://rubygems.org/gems/dry-validation
2
3
  [actions]: https://github.com/dry-rb/dry-validation/actions
3
4
  [codacy]: https://www.codacy.com/gh/dry-rb/dry-validation
@@ -10,19 +11,19 @@
10
11
  [![CI Status](https://github.com/dry-rb/dry-validation/workflows/ci/badge.svg)][actions]
11
12
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/f30e3ff5ec304c55a73868cdbf055c67)][codacy]
12
13
  [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/f30e3ff5ec304c55a73868cdbf055c67)][codacy]
13
- [![Inline docs](http://inch-ci.org/github/dry-rb/dry-validation.svg?branch=master)][inchpages]
14
+ [![Inline docs](http://inch-ci.org/github/dry-rb/dry-validation.svg?branch=main)][inchpages]
14
15
 
15
16
  ## Links
16
17
 
17
- * [User documentation](http://dry-rb.org/gems/dry-validation)
18
+ * [User documentation](https://dry-rb.org/gems/dry-validation)
18
19
  * [API documentation](http://rubydoc.info/gems/dry-validation)
19
20
 
20
21
  ## Supported Ruby versions
21
22
 
22
23
  This library officially supports the following Ruby versions:
23
24
 
24
- * MRI >= `2.4`
25
- * jruby >= `9.2`
25
+ * MRI `>= 2.7.0`
26
+ * jruby `>= 9.3` (postponed until 2.7 is supported)
26
27
 
27
28
  ## License
28
29
 
@@ -1,39 +1,39 @@
1
1
  # frozen_string_literal: true
2
- # this file is managed by dry-rb/devtools project
3
2
 
4
- lib = File.expand_path('lib', __dir__)
3
+ # this file is synced from dry-rb/template-gem project
4
+
5
+ lib = File.expand_path("lib", __dir__)
5
6
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
- require 'dry/validation/version'
7
+ require "dry/validation/version"
7
8
 
8
9
  Gem::Specification.new do |spec|
9
- spec.name = 'dry-validation'
10
+ spec.name = "dry-validation"
10
11
  spec.authors = ["Piotr Solnica"]
11
12
  spec.email = ["piotr.solnica@gmail.com"]
12
- spec.license = 'MIT'
13
+ spec.license = "MIT"
13
14
  spec.version = Dry::Validation::VERSION.dup
14
15
 
15
16
  spec.summary = "Validation library"
16
17
  spec.description = spec.summary
17
- spec.homepage = 'https://dry-rb.org/gems/dry-validation'
18
+ spec.homepage = "https://dry-rb.org/gems/dry-validation"
18
19
  spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-validation.gemspec", "lib/**/*", "config/*.yml"]
19
- spec.bindir = 'bin'
20
+ spec.bindir = "bin"
20
21
  spec.executables = []
21
- spec.require_paths = ['lib']
22
+ spec.require_paths = ["lib"]
22
23
 
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'
24
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
25
+ spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-validation/blob/main/CHANGELOG.md"
26
+ spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-validation"
27
+ spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-validation/issues"
27
28
 
28
- spec.required_ruby_version = ">= 2.4.0"
29
+ spec.required_ruby_version = ">= 2.7.0"
29
30
 
30
31
  # to update dependencies edit project.yml
31
32
  spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
32
33
  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"
34
+ spec.add_runtime_dependency "dry-core", "~> 0.5", ">= 0.5"
35
35
  spec.add_runtime_dependency "dry-initializer", "~> 3.0"
36
- spec.add_runtime_dependency "dry-schema", "~> 1.5"
36
+ spec.add_runtime_dependency "dry-schema", "~> 1.8", ">= 1.8.0"
37
37
 
38
38
  spec.add_development_dependency "bundler"
39
39
  spec.add_development_dependency "rake"
@@ -11,7 +11,7 @@ module Dry
11
11
  #
12
12
  # @api public
13
13
  class Config < Schema::Config
14
- setting :macros, Macros::Container.new, &:dup
14
+ setting :macros, default: Macros::Container.new, constructor: :dup.to_proc
15
15
 
16
16
  # @api private
17
17
  def dup
@@ -158,11 +158,13 @@ module Dry
158
158
  valid_paths = key_map.to_dot_notation
159
159
  key_paths = key_paths(keys)
160
160
 
161
- invalid_keys = key_paths.map { |(key, path)|
162
- unless valid_paths.any? { |vp| vp.include?(path) || vp.include?("#{path}[]") }
161
+ invalid_keys = key_paths.filter_map { |(key, path)|
162
+ if valid_paths.none? { |vp|
163
+ vp == path || vp.start_with?("#{path}.", "#{path}[]")
164
+ }
163
165
  key
164
166
  end
165
- }.compact.uniq
167
+ }.uniq
166
168
 
167
169
  return if invalid_keys.empty?
168
170
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "concurrent/map"
4
4
 
5
- require "dry/equalizer"
5
+ require "dry/core/equalizer"
6
6
  require "dry/initializer"
7
7
  require "dry/schema/path"
8
8
 
@@ -68,6 +68,11 @@ module Dry
68
68
  # @api public
69
69
  option :macros, default: -> { config.macros }
70
70
 
71
+ # @!attribute [r] default_context
72
+ # @return [Hash] Default context for rules
73
+ # @api public
74
+ option :default_context, default: -> { EMPTY_HASH }
75
+
71
76
  # @!attribute [r] schema
72
77
  # @return [Dry::Schema::Params, Dry::Schema::JSON, Dry::Schema::Processor]
73
78
  # @api private
@@ -86,12 +91,19 @@ module Dry
86
91
  # Apply the contract to an input
87
92
  #
88
93
  # @param [Hash] input The input to validate
94
+ # @param [Hash] context Initial context for rules
89
95
  #
90
96
  # @return [Result]
91
97
  #
92
98
  # @api public
93
- def call(input)
94
- Result.new(schema.(input), Concurrent::Map.new) do |result|
99
+ # rubocop: disable Metrics/AbcSize
100
+ def call(input, context = EMPTY_HASH)
101
+ context_map = Concurrent::Map.new.tap do |map|
102
+ default_context.each { |key, value| map[key] = value }
103
+ context.each { |key, value| map[key] = value }
104
+ end
105
+
106
+ Result.new(schema.(input), context_map) do |result|
95
107
  rules.each do |rule|
96
108
  next if rule.keys.any? { |key| error?(result, key) }
97
109
 
@@ -103,6 +115,7 @@ module Dry
103
115
  end
104
116
  end
105
117
  end
118
+ # rubocop: enable Metrics/AbcSize
106
119
 
107
120
  # Return a nice string representation
108
121
  #
@@ -123,14 +136,14 @@ module Dry
123
136
  return path.expand.any? { |nested_path| error?(result, nested_path) }
124
137
  end
125
138
 
126
- return true if result.error?(path)
139
+ return true if result.schema_error?(path)
127
140
 
128
141
  path
129
142
  .to_a[0..-2]
130
143
  .any? { |key|
131
144
  curr_path = Schema::Path[path.keys[0..path.keys.index(key)]]
132
145
 
133
- return false unless result.error?(curr_path)
146
+ return false unless result.schema_error?(curr_path)
134
147
 
135
148
  result.errors.any? { |err|
136
149
  (other = Schema::Path[err.path]).same_root?(curr_path) && other == curr_path
@@ -17,7 +17,7 @@ module Dry
17
17
  # @api public
18
18
  class Evaluator
19
19
  extend Dry::Initializer
20
- extend Dry::Core::Deprecations[:'dry-validation']
20
+ extend Dry::Core::Deprecations[:"dry-validation"]
21
21
 
22
22
  deprecate :error?, :schema_error?
23
23
 
@@ -73,7 +73,7 @@ module Dry
73
73
  @_options = options
74
74
 
75
75
  if block
76
- exec_opts = block_options.map { |key, value| [key, _options[value]] }.to_h
76
+ exec_opts = block_options.transform_values { _options[_1] }
77
77
  instance_exec(**exec_opts, &block)
78
78
  end
79
79
 
@@ -155,16 +155,23 @@ module Dry
155
155
  #
156
156
  # This is useful when dealing with rules for optional keys
157
157
  #
158
- # @example
158
+ # @example use the default key name
159
159
  # rule(:age) do
160
160
  # key.failure(:invalid) if key? && value < 18
161
161
  # end
162
162
  #
163
+ # @example specify the key name
164
+ # rule(:start_date, :end_date) do
165
+ # if key?(:start_date) && !key?(:end_date)
166
+ # key(:end_date).failure("must provide an end_date with start_date")
167
+ # end
168
+ # end
169
+ #
163
170
  # @return [Boolean]
164
171
  #
165
172
  # @api public
166
- def key?
167
- values.key?(key_name)
173
+ def key?(name = key_name)
174
+ values.key?(name)
168
175
  end
169
176
 
170
177
  # Check if there are any errors on the schema under the provided path
@@ -175,16 +182,31 @@ module Dry
175
182
  #
176
183
  # @api public
177
184
  def schema_error?(path)
178
- result.error?(path)
185
+ result.schema_error?(path)
179
186
  end
180
187
 
181
188
  # Check if there are any errors on the current rule
182
189
  #
190
+ # @param path [Symbol, String, Array] A Path-compatible spec
191
+ #
192
+ # @return [Boolean]
193
+ #
194
+ # @api public
195
+ def rule_error?(path = nil)
196
+ if path.nil?
197
+ !key(self.path).empty?
198
+ else
199
+ result.rule_error?(path)
200
+ end
201
+ end
202
+
203
+ # Check if there are any base rule errors
204
+ #
183
205
  # @return [Boolean]
184
206
  #
185
207
  # @api public
186
- def rule_error?
187
- !key(path).empty?
208
+ def base_rule_error?
209
+ !base.empty? || result.base_rule_error?
188
210
  end
189
211
 
190
212
  # @api private
@@ -36,8 +36,7 @@ module Dry
36
36
  block
37
37
  .parameters
38
38
  .select { |arg,| arg.equal?(:keyreq) }
39
- .map { |_, name| [name, BLOCK_OPTIONS_MAPPINGS[name]] }
40
- .to_h
39
+ .to_h { [_2, BLOCK_OPTIONS_MAPPINGS[_2]] }
41
40
  end
42
41
  end
43
42
  end
@@ -31,7 +31,7 @@ module Dry
31
31
 
32
32
  # @api private
33
33
  def extract_block_options(options)
34
- block_options.map { |key, value| [key, options[value]] }.to_h
34
+ block_options.transform_values { options[_1] }
35
35
  end
36
36
  end
37
37
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/equalizer"
3
+ require "dry/core/equalizer"
4
4
 
5
5
  require "dry/schema/constants"
6
6
  require "dry/schema/message"
@@ -70,11 +70,13 @@ module Dry
70
70
  # Initialize a new error object
71
71
  #
72
72
  # @api private
73
+ # rubocop: disable Lint/MissingSuper
73
74
  def initialize(text, path:, meta: EMPTY_HASH)
74
75
  @text = text
75
76
  @path = Array(path)
76
77
  @meta = meta
77
78
  end
79
+ # rubocop: enable Lint/MissingSuper
78
80
 
79
81
  # Check if this is a base error not associated with any key
80
82
  #
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "dry/validation/message"
4
+ require "dry/schema/message_compiler"
4
5
 
5
6
  module Dry
6
7
  module Validation
7
8
  module Messages
9
+ FULL_MESSAGE_WHITESPACE = Dry::Schema::MessageCompiler::FULL_MESSAGE_WHITESPACE
10
+
8
11
  # Resolve translated messages from failure arguments
9
12
  #
10
13
  # @api public
@@ -33,7 +36,7 @@ module Dry
33
36
  when Symbol
34
37
  Message[->(**opts) { message(message, path: path, tokens: tokens, **opts) }, path, meta]
35
38
  when String
36
- Message[->(**opts) { [message_text(message, path, **opts), meta] }, path, meta]
39
+ Message[->(**opts) { [message_text(message, path: path, **opts), meta] }, path, meta]
37
40
  when Hash
38
41
  meta = message.dup
39
42
  text = meta.delete(:text) { |key|
@@ -51,18 +54,6 @@ module Dry
51
54
  end
52
55
  alias_method :[], :call
53
56
 
54
- # Resolve a message
55
- #
56
- # @return String
57
- #
58
- # @api public
59
- def message_text(message, path, locale: nil, full: false, **opts)
60
- keys = path.to_a.compact
61
- msg_opts = EMPTY_HASH.merge(path: keys, locale: locale || messages.default_locale)
62
-
63
- full ? "#{messages.rule(keys.last, msg_opts) || keys.last} #{message}" : message
64
- end
65
-
66
57
  # Resolve a message
67
58
  #
68
59
  # @return [String]
@@ -70,7 +61,8 @@ module Dry
70
61
  # @api public
71
62
  #
72
63
  # rubocop:disable Metrics/AbcSize
73
- def message(rule, tokens: EMPTY_HASH, locale: nil, full: false, path:)
64
+ # rubocop:disable Metrics/PerceivedComplexity
65
+ def message(rule, path:, tokens: EMPTY_HASH, locale: nil, full: false)
74
66
  keys = path.to_a.compact
75
67
  msg_opts = tokens.merge(path: keys, locale: locale || messages.default_locale)
76
68
 
@@ -81,6 +73,11 @@ module Dry
81
73
  template, meta = messages[rule, msg_opts.merge(path: keys.last)] unless template
82
74
  end
83
75
 
76
+ if !template && keys.size > 1
77
+ non_index_keys = keys.reject { |k| k.is_a?(Integer) }
78
+ template, meta = messages[rule, msg_opts.merge(path: non_index_keys.join(DOT))]
79
+ end
80
+
84
81
  unless template
85
82
  raise MissingMessageError, <<~STR
86
83
  Message template for #{rule.inspect} under #{keys.join(DOT).inspect} was not found
@@ -90,18 +87,32 @@ module Dry
90
87
  parsed_tokens = parse_tokens(tokens)
91
88
  text = template.(template.data(parsed_tokens))
92
89
 
93
- [full ? "#{messages.rule(keys.last, msg_opts)} #{text}" : text, meta]
90
+ [message_text(text, path: path, locale: locale, full: full), meta]
94
91
  end
92
+ # rubocop:enable Metrics/PerceivedComplexity
95
93
  # rubocop:enable Metrics/AbcSize
96
94
 
97
95
  private
98
96
 
97
+ def message_text(text, path:, locale: nil, full: false)
98
+ return text unless full
99
+
100
+ key = key_text(path: path, locale: locale)
101
+
102
+ [key, text].compact.join(FULL_MESSAGE_WHITESPACE[locale])
103
+ end
104
+
105
+ def key_text(path:, locale: nil)
106
+ locale ||= messages.default_locale
107
+
108
+ keys = path.to_a.compact
109
+ msg_opts = {path: keys, locale: locale}
110
+
111
+ messages.rule(keys.last, msg_opts) || keys.last
112
+ end
113
+
99
114
  def parse_tokens(tokens)
100
- Hash[
101
- tokens.map do |key, token|
102
- [key, parse_token(token)]
103
- end
104
- ]
115
+ tokens.transform_values { parse_token(_1) }
105
116
  end
106
117
 
107
118
  def parse_token(token)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "concurrent/map"
4
- require "dry/equalizer"
4
+ require "dry/core/equalizer"
5
5
 
6
6
  require "dry/validation/constants"
7
7
  require "dry/validation/message_set"
@@ -101,11 +101,32 @@ module Dry
101
101
 
102
102
  # Check if values include an error for the provided key
103
103
  #
104
- # @api private
104
+ # @api public
105
105
  def error?(key)
106
+ errors.any? { |msg| Schema::Path[msg.path].include?(Schema::Path[key]) }
107
+ end
108
+
109
+ # Check if the base schema (without rules) includes an error for the provided key
110
+ #
111
+ # @api private
112
+ def schema_error?(key)
106
113
  schema_result.error?(key)
107
114
  end
108
115
 
116
+ # Check if the rules includes an error for the provided key
117
+ #
118
+ # @api private
119
+ def rule_error?(key)
120
+ !schema_error?(key) && error?(key)
121
+ end
122
+
123
+ # Check if the result contains any base rule errors
124
+ #
125
+ # @api private
126
+ def base_rule_error?
127
+ !errors.filter(:base?).empty?
128
+ end
129
+
109
130
  # Check if there's any error for the provided key
110
131
  #
111
132
  # This does not consider errors from the nested values
@@ -116,7 +137,7 @@ module Dry
116
137
  key_path = Schema::Path[key]
117
138
  err_path = Schema::Path[error.path]
118
139
 
119
- return false unless key_path.same_root?(err_path)
140
+ next unless key_path.same_root?(err_path)
120
141
 
121
142
  key_path == err_path
122
143
  }
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/equalizer"
3
+ require "dry/core/equalizer"
4
4
 
5
5
  require "dry/validation/constants"
6
6
  require "dry/validation/function"
@@ -65,8 +65,8 @@ module Dry
65
65
  # for a given array item.
66
66
  #
67
67
  # @example
68
- # rule(:nums).each do
69
- # key.failure("must be greater than 0") if value < 0
68
+ # rule(:nums).each do |index:|
69
+ # key([:number, index]).failure("must be greater than 0") if value < 0
70
70
  # end
71
71
  # rule(:nums).each(min: 3)
72
72
  # rule(address: :city) do
@@ -76,19 +76,21 @@ module Dry
76
76
  # @return [Rule]
77
77
  #
78
78
  # @api public
79
+ #
80
+ # rubocop:disable Metrics/AbcSize
79
81
  def each(*macros, &block)
80
82
  root = keys[0]
81
83
  macros = parse_macros(*macros)
82
84
  @keys = []
83
85
 
84
86
  @block = proc do
85
- unless result.base_error?(root) || !values.key?(root)
87
+ unless result.base_error?(root) || !values.key?(root) || values[root].nil?
86
88
  values[root].each_with_index do |_, idx|
87
89
  path = [*Schema::Path[root].to_a, idx]
88
90
 
89
- next if result.error?(path)
91
+ next if result.schema_error?(path)
90
92
 
91
- evaluator = with(macros: macros, keys: [path], &block)
93
+ evaluator = with(macros: macros, keys: [path], index: idx, &block)
92
94
 
93
95
  failures.concat(evaluator.failures)
94
96
  end
@@ -99,6 +101,7 @@ module Dry
99
101
 
100
102
  self
101
103
  end
104
+ # rubocop:enable Metrics/AbcSize
102
105
 
103
106
  # Return a nice string representation
104
107
  #
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/equalizer"
3
+ require "dry/core/equalizer"
4
4
  require "dry/schema/path"
5
5
  require "dry/validation/constants"
6
6
 
@@ -61,6 +61,7 @@ module Dry
61
61
  end
62
62
 
63
63
  # @api public
64
+ # rubocop: disable Metrics/PerceivedComplexity
64
65
  def key?(key, hash = data)
65
66
  return hash.key?(key) if key.is_a?(Symbol)
66
67
 
@@ -68,14 +69,20 @@ module Dry
68
69
  if e.is_a?(Array)
69
70
  result = e.all? { |k| key?(k, a) }
70
71
  return result
72
+ elsif e.is_a?(Symbol) && a.is_a?(Array)
73
+ return false
74
+ elsif a.nil?
75
+ return false
76
+ elsif a.is_a?(String)
77
+ return false
71
78
  else
72
79
  return false unless a.is_a?(Array) ? (e >= 0 && e < a.size) : a.key?(e)
73
80
  end
74
81
  a[e]
75
82
  end
76
-
77
83
  true
78
84
  end
85
+ # rubocop: enable Metrics/PerceivedComplexity
79
86
 
80
87
  # @api private
81
88
  def respond_to_missing?(meth, include_private = false)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module Validation
5
- VERSION = "1.5.1"
5
+ VERSION = "1.8.1"
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.5.1
4
+ version: 1.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-18 00:00:00.000000000 Z
11
+ date: 2022-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -50,28 +50,20 @@ dependencies:
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '0.4'
54
- type: :runtime
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '0.4'
61
- - !ruby/object:Gem::Dependency
62
- name: dry-equalizer
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
53
+ version: '0.5'
54
+ - - ">="
66
55
  - !ruby/object:Gem::Version
67
- version: '0.2'
56
+ version: '0.5'
68
57
  type: :runtime
69
58
  prerelease: false
70
59
  version_requirements: !ruby/object:Gem::Requirement
71
60
  requirements:
72
61
  - - "~>"
73
62
  - !ruby/object:Gem::Version
74
- version: '0.2'
63
+ version: '0.5'
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0.5'
75
67
  - !ruby/object:Gem::Dependency
76
68
  name: dry-initializer
77
69
  requirement: !ruby/object:Gem::Requirement
@@ -92,14 +84,20 @@ dependencies:
92
84
  requirements:
93
85
  - - "~>"
94
86
  - !ruby/object:Gem::Version
95
- version: '1.5'
87
+ version: '1.8'
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 1.8.0
96
91
  type: :runtime
97
92
  prerelease: false
98
93
  version_requirements: !ruby/object:Gem::Requirement
99
94
  requirements:
100
95
  - - "~>"
101
96
  - !ruby/object:Gem::Version
102
- version: '1.5'
97
+ version: '1.8'
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: 1.8.0
103
101
  - !ruby/object:Gem::Dependency
104
102
  name: bundler
105
103
  requirement: !ruby/object:Gem::Requirement
@@ -181,10 +179,10 @@ licenses:
181
179
  - MIT
182
180
  metadata:
183
181
  allowed_push_host: https://rubygems.org
184
- changelog_uri: https://github.com/dry-rb/dry-validation/blob/master/CHANGELOG.md
182
+ changelog_uri: https://github.com/dry-rb/dry-validation/blob/main/CHANGELOG.md
185
183
  source_code_uri: https://github.com/dry-rb/dry-validation
186
184
  bug_tracker_uri: https://github.com/dry-rb/dry-validation/issues
187
- post_install_message:
185
+ post_install_message:
188
186
  rdoc_options: []
189
187
  require_paths:
190
188
  - lib
@@ -192,15 +190,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
192
190
  requirements:
193
191
  - - ">="
194
192
  - !ruby/object:Gem::Version
195
- version: 2.4.0
193
+ version: 2.7.0
196
194
  required_rubygems_version: !ruby/object:Gem::Requirement
197
195
  requirements:
198
196
  - - ">="
199
197
  - !ruby/object:Gem::Version
200
198
  version: '0'
201
199
  requirements: []
202
- rubygems_version: 3.0.3
203
- signing_key:
200
+ rubygems_version: 3.2.32
201
+ signing_key:
204
202
  specification_version: 4
205
203
  summary: Validation library
206
204
  test_files: []