dry-validation 1.0.0 → 1.1.1

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: 7acb8c840fe5a4c12564c86985078e25cff1bea877b9e2dc4f29b39bc892b6a5
4
- data.tar.gz: ae09dc37911b0e4031918f22efabd53035501119a71da60ce08b4e0a00a3e0b6
3
+ metadata.gz: 3821e92d2dced61bb892e20a5e5d69b596128fcdbd05596e41fff8716767b08c
4
+ data.tar.gz: f797d5e46604e777966cb3d9a7a4032265227684164224a8ff109fc8ba51d1c1
5
5
  SHA512:
6
- metadata.gz: 9430d9ca1660c3d280dd5c32f1787bce32c06c38ecd22987f53ccce8b581debce2679b95dc3b2eb9a96598d16c2dc0d99f5b65aa26de14fe0f2a03c5bb822a87
7
- data.tar.gz: a07ad85054ae898cd155db7874219332e58956f57904c1dde445d27d34aa81aa2b7d1a431e6218f6aa320bfdb0e0fffd20fd619a98991929b12c1f643326c77a
6
+ metadata.gz: 7504498b77c794b9fe37e0384fba50a8fb6c99e3fecd3423e66fe018006288b3ba1a5a7a2232fb53dede256ba0a13630313748a0214b4a0d9865fc22c0b9edae
7
+ data.tar.gz: 654233d365e7844985f465e16335a234a2d5c2c240b97a485d286a52e6229e3ee80d8719e76d3ec95fe393d75f480617452b7813cb36b4b033021f9b98958461
@@ -1,3 +1,25 @@
1
+ # v1.1.1 2019-06-24
2
+
3
+ ### Fixed
4
+
5
+ * `Rule#each` works with array values from nested hashes (@mustardnoise)
6
+
7
+ [Compare v1.1.0...v1.1.1](https://github.com/dry-rb/dry-validation/compare/v1.1.0...v1.1.1)
8
+
9
+ # v1.1.0 2019-06-14
10
+
11
+ ### Added
12
+
13
+ * `key?` method available within rules, that can be used to check if there's a value under the rule's default key (refs #540) (@solnic)
14
+ * `value` supports hash-based path specifications now (refs #547) (@solnic)
15
+ * `value` can read multiple values when the key points to them, ie in case of `rule(geo: [:lat, :lon])` it would return an array with `lat` and `lon` (@solnic)
16
+
17
+ ### Fixed
18
+
19
+ * Passing multiple macro names to `validate` or `each` works correctly (fixed #538 #541) (@jandudulski)
20
+
21
+ [Compare v1.0.0...v1.1.0](https://github.com/dry-rb/dry-validation/compare/v1.0.0...v1.1.0)
22
+
1
23
  # v1.0.0 2019-06-10
2
24
 
3
25
  This release is a complete rewrite on top of `dry-schema` that uses contract classes to define schema and validation rules. It's **not backward-compatible**. This release addressed over 150 known issues, including bugs and missing features.
@@ -12,7 +34,7 @@ See [the list of all addressed issues](https://github.com/dry-rb/dry-validation/
12
34
  - Support for macros that encapsulate common rule logic
13
35
  - Built-in `:acceptance` macro
14
36
 
15
- [Compare v0.13.3...v1.0.0](https://github.com/dry-rb/dry-validation/compare/v1.13.3...v1.0.0)
37
+ [Compare v0.13.3...v1.0.0](https://github.com/dry-rb/dry-validation/compare/v0.13.3...v1.0.0)
16
38
 
17
39
  # v1.0.0 2019-06-10 (compared to 1.0.0.rc3)
18
40
 
@@ -41,9 +41,12 @@ module Dry
41
41
  # @return [Contract]
42
42
  #
43
43
  # @api public
44
+ #
45
+ # rubocop:disable Naming/MethodName
44
46
  def self.Contract(options = EMPTY_HASH, &block)
45
47
  Contract.build(options, &block)
46
48
  end
49
+ # rubocop:enable Naming/MethodName
47
50
 
48
51
  # This is needed by Macros::Registrar
49
52
  #
@@ -11,6 +11,12 @@ module Dry
11
11
  # Root path is used for base errors in hash representation of error messages
12
12
  ROOT_PATH = [nil].freeze
13
13
 
14
+ # Path to the default errors locale file
15
+ DEFAULT_ERRORS_NAMESPACE = 'dry_validation'
16
+
17
+ # Path to the default errors locale file
18
+ DEFAULT_ERRORS_PATH = Pathname(__FILE__).join('../../../../config/errors.yml').realpath.freeze
19
+
14
20
  # Mapping for block kwarg options used by block_options
15
21
  #
16
22
  # @see Rule#block_options
@@ -54,8 +54,8 @@ module Dry
54
54
  extend Dry::Initializer
55
55
  extend ClassInterface
56
56
 
57
- config.messages.top_namespace = 'dry_validation'
58
- config.messages.load_paths << Pathname(__FILE__).join('../../../../config/errors.yml').realpath
57
+ config.messages.top_namespace = DEFAULT_ERRORS_NAMESPACE
58
+ config.messages.load_paths << DEFAULT_ERRORS_PATH
59
59
 
60
60
  # @!attribute [r] config
61
61
  # @return [Config] Contract's configuration object
@@ -118,7 +118,9 @@ module Dry
118
118
  # @api private
119
119
  def error?(result, key)
120
120
  path = Schema::Path[key]
121
- result.error?(path) || path.map.with_index { |_k, i| result.error?(path.keys[0..i - 2]) }.any?
121
+
122
+ result.error?(path) ||
123
+ path.map.with_index { |_k, i| result.error?(path.keys[0..i - 2]) }.any?
122
124
  end
123
125
 
124
126
  # Get a registered macro
@@ -147,6 +147,22 @@ module Dry
147
147
  values[key_name]
148
148
  end
149
149
 
150
+ # Return if the value under the default key is available
151
+ #
152
+ # This is useful when dealing with rules for optional keys
153
+ #
154
+ # @example
155
+ # rule(:age) do
156
+ # key.failure(:invalid) if key? && value < 18
157
+ # end
158
+ #
159
+ # @return [Boolean]
160
+ #
161
+ # @api public
162
+ def key?
163
+ values.key?(key_name)
164
+ end
165
+
150
166
  # Check if there are any errors under the provided path
151
167
  #
152
168
  # @param [Symbol, String, Array] A Path-compatible spec
@@ -49,6 +49,8 @@ module Dry
49
49
  # @return [String]
50
50
  #
51
51
  # @api public
52
+ #
53
+ # rubocop:disable Metrics/AbcSize
52
54
  def message(rule, tokens: EMPTY_HASH, locale: nil, full: false, path:)
53
55
  keys = path.to_a.compact
54
56
  msg_opts = tokens.merge(path: keys, locale: locale || messages.default_locale)
@@ -70,6 +72,7 @@ module Dry
70
72
 
71
73
  [full ? "#{messages.rule(keys.last, msg_opts)} #{text}" : text, meta]
72
74
  end
75
+ # rubocop:enable Metrics/AbcSize
73
76
  end
74
77
  end
75
78
  end
@@ -148,9 +148,9 @@ module Dry
148
148
  # @api public
149
149
  def inspect
150
150
  if context.empty?
151
- "#<#{self.class}#{to_h.inspect} errors=#{errors.to_h.inspect}>"
151
+ "#<#{self.class}#{to_h} errors=#{errors.to_h}>"
152
152
  else
153
- "#<#{self.class}#{to_h.inspect} errors=#{errors.to_h.inspect} context=#{context.each.to_h.inspect}>"
153
+ "#<#{self.class}#{to_h} errors=#{errors.to_h} context=#{context.each.to_h}>"
154
154
  end
155
155
  end
156
156
 
@@ -54,7 +54,7 @@ module Dry
54
54
  #
55
55
  # @api public
56
56
  def validate(*macros, &block)
57
- @macros = macros.map { |spec| Array(spec) }.map(&:flatten)
57
+ @macros = parse_macros(*macros)
58
58
  @block = block if block
59
59
  self
60
60
  end
@@ -68,17 +68,22 @@ module Dry
68
68
  # rule(:nums).each do
69
69
  # key.failure("must be greater than 0") if value < 0
70
70
  # end
71
+ # rule(:nums).each(min: 3)
72
+ # rule(address: :city) do
73
+ # key.failure("oops") if value != 'Munich'
74
+ # end
71
75
  #
72
76
  # @return [Rule]
73
77
  #
74
78
  # @api public
75
79
  def each(*macros, &block)
76
- root = keys
80
+ root = keys[0]
81
+ macros = parse_macros(*macros)
77
82
  @keys = []
78
83
 
79
84
  @block = proc do
80
- values[root].each_with_index do |_, idx|
81
- path = [*root, idx]
85
+ (values[root] || []).each_with_index do |_, idx|
86
+ path = [*Schema::Path[root].to_a, idx]
82
87
 
83
88
  next if result.error?(path)
84
89
 
@@ -99,6 +104,22 @@ module Dry
99
104
  def inspect
100
105
  %(#<#{self.class} keys=#{keys.inspect}>)
101
106
  end
107
+
108
+ # Parse function arguments into macros structure
109
+ #
110
+ # @return [Array]
111
+ #
112
+ # @api private
113
+ def parse_macros(*args)
114
+ args.each_with_object([]) do |spec, macros|
115
+ case spec
116
+ when Hash
117
+ spec.each { |k, v| macros << [k, Array(v)] }
118
+ else
119
+ macros << Array(spec)
120
+ end
121
+ end
122
+ end
102
123
  end
103
124
  end
104
125
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'dry/equalizer'
4
+ require 'dry/schema/path'
4
5
  require 'dry/validation/constants'
5
6
 
6
7
  module Dry
@@ -40,17 +41,39 @@ module Dry
40
41
  #
41
42
  # @api public
42
43
  def [](*args)
43
- if args.size.equal?(1)
44
- case (key = args[0])
45
- when Symbol then data[key]
46
- when String then self[*key.split(DOT).map(&:to_sym)]
47
- when Array then self[*key]
44
+ return data.dig(*args) if args.size > 1
45
+
46
+ case (key = args[0])
47
+ when Symbol, String, Array, Hash
48
+ path = Schema::Path[key]
49
+ keys = path.to_a
50
+
51
+ return data.dig(*keys) unless keys.last.is_a?(Array)
52
+
53
+ last = keys.pop
54
+ vals = self.class.new(data.dig(*keys))
55
+
56
+ last.map { |name| vals[name] }
57
+ else
58
+ raise ArgumentError, '+key+ must be a valid path specification'
59
+ end
60
+ end
61
+
62
+ # @api public
63
+ def key?(key, hash = data)
64
+ return hash.key?(key) if key.is_a?(Symbol)
65
+
66
+ Schema::Path[key].reduce(hash) do |a, e|
67
+ if e.is_a?(Array)
68
+ result = e.all? { |k| key?(k, a) }
69
+ return result
48
70
  else
49
- raise ArgumentError, '+key+ must be a symbol, string, array, or a list of keys for dig'
71
+ return false unless a.is_a?(Array) ? (e >= 0 && e < a.size) : a.key?(e)
50
72
  end
51
- else
52
- data.dig(*args)
73
+ a[e]
53
74
  end
75
+
76
+ true
54
77
  end
55
78
 
56
79
  # @api private
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module Validation
5
- VERSION = '1.0.0'
5
+ VERSION = '1.1.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.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-10 00:00:00.000000000 Z
11
+ date: 2019-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby