dry-validation 1.3.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  - - ">="