dry-validation 1.3.0 → 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.
@@ -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
@@ -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
@@ -45,14 +45,26 @@ module Dry
45
45
  # @example
46
46
  # failure(:taken)
47
47
  #
48
+ # @overload failure(meta_hash)
49
+ # Use meta_hash[:text] as a message (either explicitely or as an identifier),
50
+ # setting the rest of the hash as error meta attribute
51
+ # @param meta [Hash] The hash containing the message as value for the :text key
52
+ # @example
53
+ # failure({text: :invalid, key: value})
54
+ #
48
55
  # @see Evaluator#key
49
56
  # @see Evaluator#base
50
57
  #
51
58
  # @api public
52
59
  def failure(message, tokens = EMPTY_HASH)
53
- opts << { message: message, tokens: tokens, path: path }
60
+ opts << {message: message, tokens: tokens, path: path}
54
61
  self
55
62
  end
63
+
64
+ # @api private
65
+ def empty?
66
+ opts.empty?
67
+ end
56
68
  end
57
69
  end
58
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
@@ -52,7 +52,7 @@ module Dry
52
52
  #
53
53
  # @api public
54
54
  def evaluate(**opts)
55
- evaluated_text, rest = text.(opts)
55
+ evaluated_text, rest = text.(**opts)
56
56
  Message.new(evaluated_text, path: path, meta: rest.merge(meta))
57
57
  end
58
58
  end
@@ -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
@@ -41,7 +41,7 @@ module Dry
41
41
  return self if new_options.empty? && other.eql?(messages)
42
42
 
43
43
  self.class.new(
44
- (other + select { |err| err.is_a?(Message) }).uniq,
44
+ other | select { |err| err.is_a?(Message) },
45
45
  options.merge(source: source_messages, **new_options)
46
46
  ).freeze
47
47
  end
@@ -54,9 +54,9 @@ module Dry
54
54
  #
55
55
  # @api private
56
56
  def add(message)
57
+ @empty = nil
57
58
  source_messages << message
58
59
  messages << message
59
- initialize_placeholders!
60
60
  self
61
61
  end
62
62
 
@@ -92,51 +92,6 @@ module Dry
92
92
  to_h
93
93
  self
94
94
  end
95
-
96
- private
97
-
98
- # @api private
99
- def unique_paths
100
- source_messages.uniq(&:path).map(&:path)
101
- end
102
-
103
- # @api private
104
- def messages_map
105
- @messages_map ||= reduce(placeholders) { |hash, msg|
106
- node = msg.path.reduce(hash) { |a, e| a.is_a?(Hash) ? a[e] : a.last[e] }
107
- (node[0].is_a?(::Array) ? node[0] : node) << msg.dump
108
- hash
109
- }
110
- end
111
-
112
- # @api private
113
- #
114
- # rubocop:disable Metrics/AbcSize
115
- # rubocop:disable Metrics/PerceivedComplexity
116
- def initialize_placeholders!
117
- @placeholders = unique_paths.each_with_object(EMPTY_HASH.dup) { |path, hash|
118
- curr_idx = 0
119
- last_idx = path.size - 1
120
- node = hash
121
-
122
- while curr_idx <= last_idx
123
- key = path[curr_idx]
124
-
125
- next_node =
126
- if node.is_a?(Array) && key.is_a?(Symbol)
127
- node_hash = (node << [] << {}).last
128
- node_hash[key] || (node_hash[key] = curr_idx < last_idx ? {} : [])
129
- else
130
- node[key] || (node[key] = curr_idx < last_idx ? {} : [])
131
- end
132
-
133
- node = next_node
134
- curr_idx += 1
135
- end
136
- }
137
- end
138
- # rubocop:enable Metrics/AbcSize
139
- # rubocop:enable Metrics/PerceivedComplexity
140
95
  end
141
96
  end
142
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
@@ -22,6 +22,8 @@ module Dry
22
22
  # Resolve Message object from provided args and path
23
23
  #
24
24
  # This is used internally by contracts when rules are applied
25
+ # If message argument is a Hash, then it MUST have a :text key,
26
+ # which value will be used as the message value
25
27
  #
26
28
  # @return [Message, Message::Localized]
27
29
  #
@@ -34,7 +36,12 @@ module Dry
34
36
  Message[message, path, meta]
35
37
  when Hash
36
38
  meta = message.dup
37
- text = meta.delete(:text)
39
+ text = meta.delete(:text) { |key|
40
+ raise ArgumentError, <<~STR
41
+ +message+ Hash must contain :#{key} key (#{message.inspect} given)
42
+ STR
43
+ }
44
+
38
45
  call(message: text, tokens: tokens, path: path, meta: meta)
39
46
  else
40
47
  raise ArgumentError, <<~STR
@@ -68,11 +75,31 @@ module Dry
68
75
  STR
69
76
  end
70
77
 
71
- text = template.(template.data(tokens))
78
+ parsed_tokens = parse_tokens(tokens)
79
+ text = template.(template.data(parsed_tokens))
72
80
 
73
81
  [full ? "#{messages.rule(keys.last, msg_opts)} #{text}" : text, meta]
74
82
  end
75
83
  # rubocop:enable Metrics/AbcSize
84
+
85
+ private
86
+
87
+ def parse_tokens(tokens)
88
+ Hash[
89
+ tokens.map do |key, token|
90
+ [key, parse_token(token)]
91
+ end
92
+ ]
93
+ end
94
+
95
+ def parse_token(token)
96
+ case token
97
+ when Array
98
+ token.join(", ")
99
+ else
100
+ token
101
+ end
102
+ end
76
103
  end
77
104
  end
78
105
  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,6 +179,22 @@ module Dry
179
179
  super
180
180
  end
181
181
 
182
+ if RUBY_VERSION >= "2.7"
183
+ # Pattern matching
184
+ #
185
+ # @api private
186
+ def deconstruct_keys(keys)
187
+ values.deconstruct_keys(keys)
188
+ end
189
+
190
+ # Pattern matching
191
+ #
192
+ # @api private
193
+ def deconstruct
194
+ [values, context.each.to_h]
195
+ end
196
+ end
197
+
182
198
  private
183
199
 
184
200
  # @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
@@ -118,12 +118,18 @@ module Dry
118
118
  args.each_with_object([]) do |spec, macros|
119
119
  case spec
120
120
  when Hash
121
- spec.each { |k, v| macros << [k, Array(v)] }
121
+ add_macro_from_hash(macros, spec)
122
122
  else
123
123
  macros << Array(spec)
124
124
  end
125
125
  end
126
126
  end
127
+
128
+ def add_macro_from_hash(macros, spec)
129
+ spec.each do |k, v|
130
+ macros << [k, v.is_a?(Array) ? v : [v]]
131
+ end
132
+ end
127
133
  end
128
134
  end
129
135
  end
@@ -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.map(&:to_dot_notation).flatten(1)).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
 
@@ -89,6 +89,7 @@ module Dry
89
89
  super
90
90
  end
91
91
  end
92
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
92
93
  end
93
94
  end
94
95
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module Validation
5
- VERSION = '1.3.0'
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.3.0
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: 2019-08-14 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
@@ -25,53 +25,53 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: dry-core
28
+ name: dry-container
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.4'
33
+ version: '0.7'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 0.7.1
34
37
  type: :runtime
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
41
  - - "~>"
39
42
  - !ruby/object:Gem::Version
40
- version: '0.4'
43
+ version: '0.7'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 0.7.1
41
47
  - !ruby/object:Gem::Dependency
42
- name: dry-equalizer
48
+ name: dry-core
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '0.2'
53
+ version: '0.4'
48
54
  type: :runtime
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: '0.2'
60
+ version: '0.4'
55
61
  - !ruby/object:Gem::Dependency
56
- name: dry-container
62
+ name: dry-equalizer
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
65
  - - "~>"
60
66
  - !ruby/object:Gem::Version
61
- version: '0.7'
62
- - - ">="
63
- - !ruby/object:Gem::Version
64
- version: 0.7.1
67
+ version: '0.2'
65
68
  type: :runtime
66
69
  prerelease: false
67
70
  version_requirements: !ruby/object:Gem::Requirement
68
71
  requirements:
69
72
  - - "~>"
70
73
  - !ruby/object:Gem::Version
71
- version: '0.7'
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: 0.7.1
74
+ version: '0.2'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: dry-initializer
77
77
  requirement: !ruby/object:Gem::Requirement
@@ -92,20 +92,14 @@ dependencies:
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '1.0'
96
- - - ">="
97
- - !ruby/object:Gem::Version
98
- version: 1.3.1
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.0'
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- version: 1.3.1
102
+ version: '1.5'
109
103
  - !ruby/object:Gem::Dependency
110
104
  name: bundler
111
105
  requirement: !ruby/object:Gem::Requirement
@@ -148,7 +142,7 @@ dependencies:
148
142
  - - ">="
149
143
  - !ruby/object:Gem::Version
150
144
  version: '0'
151
- description:
145
+ description: Validation library
152
146
  email:
153
147
  - piotr.solnica@gmail.com
154
148
  executables: []
@@ -159,6 +153,7 @@ files:
159
153
  - LICENSE
160
154
  - README.md
161
155
  - config/errors.yml
156
+ - dry-validation.gemspec
162
157
  - lib/dry-validation.rb
163
158
  - lib/dry/validation.rb
164
159
  - lib/dry/validation/config.rb
@@ -184,7 +179,11 @@ files:
184
179
  homepage: https://dry-rb.org/gems/dry-validation
185
180
  licenses:
186
181
  - MIT
187
- metadata: {}
182
+ metadata:
183
+ allowed_push_host: https://rubygems.org
184
+ changelog_uri: https://github.com/dry-rb/dry-validation/blob/master/CHANGELOG.md
185
+ source_code_uri: https://github.com/dry-rb/dry-validation
186
+ bug_tracker_uri: https://github.com/dry-rb/dry-validation/issues
188
187
  post_install_message:
189
188
  rdoc_options: []
190
189
  require_paths:
@@ -193,7 +192,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
193
192
  requirements:
194
193
  - - ">="
195
194
  - !ruby/object:Gem::Version
196
- version: '2.3'
195
+ version: 2.4.0
197
196
  required_rubygems_version: !ruby/object:Gem::Requirement
198
197
  requirements:
199
198
  - - ">="