dry-validation 1.5.0 → 1.5.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c4b57593ac3fd38a26ef3eb26a31b34503bfa75a6fc118358745aa9fb772be1
4
- data.tar.gz: 534dc4c9e0a8e83faec7077a78e4b3fd7e7fa5b55b6aa277479999332920bcb5
3
+ metadata.gz: ab7416252f8c05238652ca9116ec461448e2024c8d68f7c588e3ef401f7a2ed6
4
+ data.tar.gz: 4137cfee57067480713402f0dd571cb06fde1ef6cafa6feb717596939cbfac1d
5
5
  SHA512:
6
- metadata.gz: 8268526e70a23bd00ff7825accd0b7f4ca682342a2fefab22051e756e574a8b2834d527e1c1e2cce0a7084308eb9d721dafce92b1500c793588ba9d219499e82
7
- data.tar.gz: d1ca0f28f775093521f74330dc4a09142a99c83c693aefcab1571f32343692a72c5f3669bd51baf10865fc9de93074ab3893ddfbb6412edf540bf3f2ac37b47c
6
+ metadata.gz: 01cae726d99151eed0bb1ef1514e8db05f9d10c8d341ffdb8ef7329de9456b63511f5eb390b25113c4da06241dfb1070ca1110ae24a5e050b6c6d5e03e2100a5
7
+ data.tar.gz: 849817760314b9a9e4cc120bc618fc42a302cc08150dcc23eb20c726b1a9b79481b19ca0013674f544608600d7d573d5cf1d1436e826bbcf7d25cf9bd3bad3e6
@@ -1,4 +1,69 @@
1
- ## unreleased
1
+ ## 1.5.5
2
+
3
+ 2020-09-03
4
+
5
+ ### Fixed
6
+
7
+ - Dependency on dry-schema was bumped to >= 1.5.2 (see #666 for more info) (@artofhuman)
8
+
9
+
10
+ [Compare v1.5.4...master](https://github.com/dry-rb/dry-validation/compare/v1.5.4...master)
11
+
12
+ ## 1.5.4 2020-08-21
13
+
14
+
15
+ ### Added
16
+
17
+ - You can now pass any key or a path to the rule's `key?` helper (see #664 for more info) (@alassek)
18
+
19
+ ### Fixed
20
+
21
+ - Full messages work correctly with rule failures now (issue #661 fixed via #662) (@stind)
22
+ - Providing a custom message template for array errors works correctly (issue #663 fixed via #665) (@tadeusz-niemiec)
23
+
24
+
25
+ [Compare v1.5.3...v1.5.4](https://github.com/dry-rb/dry-validation/compare/v1.5.3...v1.5.4)
26
+
27
+ ## 1.5.3 2020-07-27
28
+
29
+
30
+ ### Added
31
+
32
+ - You can now access current value's index via `rule(:foo).each do |index:|` (issue #606 done via #657) (@mrbongiolo)
33
+
34
+ ### Fixed
35
+
36
+ - Using `.each(:foo)` works as expected when there are errors related to other keys (issue #659 fixed via #660) (@solnic)
37
+
38
+ ### Changed
39
+
40
+ - `Result#error?` is now a public API and it takes into consideration both schema and rule errors (issue #655 fixed via #656) (@PragTob)
41
+
42
+ [Compare v1.5.2...v1.5.3](https://github.com/dry-rb/dry-validation/compare/v1.5.2...v1.5.3)
43
+
44
+ ## 1.5.2 2020-07-14
45
+
46
+
47
+ ### Fixed
48
+
49
+ - `key?` predicate in rules no longer crashes when the rule path points to a non-existent array value (issue #653 fixed via #654) (@solnic)
50
+
51
+
52
+ [Compare v1.5.1...v1.5.2](https://github.com/dry-rb/dry-validation/compare/v1.5.1...v1.5.2)
53
+
54
+ ## 1.5.1 2020-06-18
55
+
56
+
57
+ ### Fixed
58
+
59
+ - dry-monads no longer required for the `:hints` extension (@schokomarie)
60
+ - Using `full: true` option works as expected with custom rule messages (issue #618 fixed via #651) (@sirfilip)
61
+ - Using `locale: ...` option works as expected with hints (issue #589 fixed via 652) (@sirfilip)
62
+
63
+
64
+ [Compare v1.5.0...v1.5.1](https://github.com/dry-rb/dry-validation/compare/v1.5.0...v1.5.1)
65
+
66
+ ## 1.5.0 2020-03-11
2
67
 
3
68
 
4
69
  ### Added
@@ -11,7 +76,7 @@
11
76
  - dry-schema dependency was bumped to `~> 1.5` (@solnic)
12
77
  - [internal] `KeyMap` patches have been removed since dry-schema now provides required functionality (@solnic)
13
78
 
14
- [Compare v1.4.2...master](https://github.com/dry-rb/dry-validation/compare/v1.4.2...master)
79
+ [Compare v1.4.2...v1.5.0](https://github.com/dry-rb/dry-validation/compare/v1.4.2...v1.5.0)
15
80
 
16
81
  ## 1.4.2 2020-01-18
17
82
 
@@ -123,14 +123,14 @@ module Dry
123
123
  return path.expand.any? { |nested_path| error?(result, nested_path) }
124
124
  end
125
125
 
126
- return true if result.error?(path)
126
+ return true if result.schema_error?(path)
127
127
 
128
128
  path
129
129
  .to_a[0..-2]
130
130
  .any? { |key|
131
131
  curr_path = Schema::Path[path.keys[0..path.keys.index(key)]]
132
132
 
133
- return false unless result.error?(curr_path)
133
+ return false unless result.schema_error?(curr_path)
134
134
 
135
135
  result.errors.any? { |err|
136
136
  (other = Schema::Path[err.path]).same_root?(curr_path) && other == curr_path
@@ -146,7 +146,7 @@ module Dry
146
146
  #
147
147
  # @return [Object]
148
148
  #
149
- # @public
149
+ # @api public
150
150
  def value
151
151
  values[key_name]
152
152
  end
@@ -155,27 +155,34 @@ 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
171
178
  #
172
- # @param [Symbol, String, Array] A Path-compatible spec
179
+ # @param path [Symbol, String, Array] A Path-compatible spec
173
180
  #
174
181
  # @return [Boolean]
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
@@ -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
@@ -25,7 +25,7 @@ module Dry
25
25
  # end
26
26
  #
27
27
  # @param [Symbol] name The name of the macro
28
- # @param [Array] *args Optional default arguments for the macro
28
+ # @param [Array] args Optional default positional arguments for the macro
29
29
  #
30
30
  # @return [self]
31
31
  #
@@ -85,7 +85,7 @@ module Dry
85
85
  # @api private
86
86
  def freeze
87
87
  source_messages.select { |err| err.respond_to?(:evaluate) }.each do |err|
88
- idx = source_messages.index(err)
88
+ idx = messages.index(err) || source_messages.index(err)
89
89
  msg = err.evaluate(locale: locale, full: options[:full])
90
90
  messages[idx] = msg
91
91
  end
@@ -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[message, 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|
@@ -69,6 +72,11 @@ module Dry
69
72
  template, meta = messages[rule, msg_opts.merge(path: keys.last)] unless template
70
73
  end
71
74
 
75
+ if !template && keys.size > 1
76
+ non_index_keys = keys.reject { |k| k.is_a?(Integer) }
77
+ template, meta = messages[rule, msg_opts.merge(path: non_index_keys.join(DOT))]
78
+ end
79
+
72
80
  unless template
73
81
  raise MissingMessageError, <<~STR
74
82
  Message template for #{rule.inspect} under #{keys.join(DOT).inspect} was not found
@@ -78,12 +86,29 @@ module Dry
78
86
  parsed_tokens = parse_tokens(tokens)
79
87
  text = template.(template.data(parsed_tokens))
80
88
 
81
- [full ? "#{messages.rule(keys.last, msg_opts)} #{text}" : text, meta]
89
+ [message_text(text, path: path, locale: locale, full: full), meta]
82
90
  end
83
91
  # rubocop:enable Metrics/AbcSize
84
92
 
85
93
  private
86
94
 
95
+ def message_text(text, path:, locale: nil, full: false)
96
+ return text unless full
97
+
98
+ key = key_text(path: path, locale: locale)
99
+
100
+ [key, text].compact.join(FULL_MESSAGE_WHITESPACE[locale])
101
+ end
102
+
103
+ def key_text(path:, locale: nil)
104
+ locale ||= messages.default_locale
105
+
106
+ keys = path.to_a.compact
107
+ msg_opts = {path: keys, locale: locale}
108
+
109
+ messages.rule(keys.last, msg_opts) || keys.last
110
+ end
111
+
87
112
  def parse_tokens(tokens)
88
113
  Hash[
89
114
  tokens.map do |key, token|
@@ -101,8 +101,15 @@ 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,7 +123,7 @@ module Dry
116
123
  key_path = Schema::Path[key]
117
124
  err_path = Schema::Path[error.path]
118
125
 
119
- return false unless key_path.same_root?(err_path)
126
+ next unless key_path.same_root?(err_path)
120
127
 
121
128
  key_path == err_path
122
129
  }
@@ -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
@@ -86,9 +86,9 @@ module Dry
86
86
  values[root].each_with_index do |_, idx|
87
87
  path = [*Schema::Path[root].to_a, idx]
88
88
 
89
- next if result.error?(path)
89
+ next if result.schema_error?(path)
90
90
 
91
- evaluator = with(macros: macros, keys: [path], &block)
91
+ evaluator = with(macros: macros, keys: [path], index: idx, &block)
92
92
 
93
93
  failures.concat(evaluator.failures)
94
94
  end
@@ -35,7 +35,10 @@ module Dry
35
35
  # key.failure('must be > 18') if values[:age] <= 18
36
36
  # end
37
37
  #
38
- # @param [Symbol] key
38
+ # @param args [Symbol, String, Hash, Array<Symbol>] If given as a single
39
+ # Symbol, String, Array or Hash, build a key array using
40
+ # {Dry::Schema::Path} digging for data. If given as positional
41
+ # arguments, use these with Hash#dig on the data directly.
39
42
  #
40
43
  # @return [Object]
41
44
  #
@@ -65,6 +68,8 @@ module Dry
65
68
  if e.is_a?(Array)
66
69
  result = e.all? { |k| key?(k, a) }
67
70
  return result
71
+ elsif e.is_a?(Symbol) && a.is_a?(Array)
72
+ return false
68
73
  else
69
74
  return false unless a.is_a?(Array) ? (e >= 0 && e < a.size) : a.key?(e)
70
75
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module Validation
5
- VERSION = "1.5.0"
5
+ VERSION = "1.5.5"
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.0
4
+ version: 1.5.5
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-03-11 00:00:00.000000000 Z
11
+ date: 2020-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby