dry-validation 1.0.0.beta1 → 1.0.0.beta2

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: f6a47d27d49e9894cf283af7e4809cea07f45e5f8f3f52a180dd20d8c849b315
4
- data.tar.gz: 83f1e9b5ff94c4db24769624dd1552f0876be541926ffd57d43c2490757ab662
3
+ metadata.gz: 705706b2bc77cae54a87647ce3d85d685aa2fe619e40950533e1d96a513d1ca0
4
+ data.tar.gz: a0ad40a08b44475bafa4510707870603517145602e5567bb10cd39f98a1895af
5
5
  SHA512:
6
- metadata.gz: 67ab872380ecdc45fbe1efeb8cec95a03dff692aae2e74ca498483ceb7104b6a2d5cd78bdc23884d69d89665f110f79c3fa67285b97a40cc2c3625f9744bc34f
7
- data.tar.gz: f306b9dc73085526c485a7b18f2e33c83d08dd72922f1640bbc9b3b6ea0164ad1fbda752da0bb9b5d1f55dbd47c6ca6aa9ebef297035fd7adb22bb18be879c4e
6
+ metadata.gz: 7f2a5347e9b057d76cf9d99c0c313c7437133c1884e750a6c54d095e00f66eb600d7d79a033c2ba561a32c92b783c3153cbd8d88e62c715cd75e9d238f2a034a
7
+ data.tar.gz: 0a6312efffe80b0156da48da466a9c4384e0b636ef34a93587097592e72a9a2d72f9503e8aa6e556399fc8ad9a18399cc1e5fea2ddb9e66b6268509fcb796d4a
@@ -1,3 +1,31 @@
1
+ # v1.0.0.beta2 2019-04-04
2
+
3
+ ### Added
4
+
5
+ * Support for arbitrary meta-data in failures, ie:
6
+
7
+ ```ruby
8
+ class NewUserContract < Dry::Validation::Contract
9
+ params do
10
+ required(:login).filled(:string)
11
+ end
12
+
13
+ rule(:login) do
14
+ key.failure(text: 'is taken', code: 123) unless db.unique?(values[:login])
15
+ end
16
+ end
17
+ ```
18
+
19
+ Now your error hash will include `{ login: [{ text: 'is taken', code: 123 }] }` (solnic + flash-gordon)
20
+
21
+ ### Changed
22
+
23
+ * [BREAKING] `Error` was renamed to `Message` as it is a more generic concept (solnic)
24
+ * [BREAKING] `ErrorSet` was renamed to `MessageSet` for consistency (solnic)
25
+ * [BREAKING] `:monads` extension wraps entire result objects in `Success` or `Failure` (flash-gordon)
26
+
27
+ [Compare v1.0.0.beta1...v1.0.0.beta2](https://github.com/dry-rb/dry-validation/compare/v1.0.0.beta1...v1.0.0.beta2)
28
+
1
29
  # v1.0.0.beta1 2019-03-26
2
30
 
3
31
  ### Added
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  [gem]: https://rubygems.org/gems/dry-validation
2
2
  [travis]: https://travis-ci.org/dry-rb/dry-validation
3
3
  [codeclimate]: https://codeclimate.com/github/dry-rb/dry-validation
4
- [coveralls]: https://coveralls.io/r/dry-rb/dry-validation
4
+ [chat]: https://dry-rb.zulipchat.com
5
5
  [inchpages]: http://inch-ci.org/github/dry-rb/dry-validation
6
6
 
7
- # dry-validation [![Join the chat at https://gitter.im/dry-rb/chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dry-rb/chat)
7
+ # dry-validation [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
8
8
 
9
9
  [![Gem Version](https://badge.fury.io/rb/dry-validation.svg)][gem]
10
10
  [![Build Status](https://travis-ci.org/dry-rb/dry-validation.svg?branch=master)][travis]
@@ -11,7 +11,6 @@ require 'dry/validation/rule'
11
11
  require 'dry/validation/evaluator'
12
12
  require 'dry/validation/messages/resolver'
13
13
  require 'dry/validation/result'
14
- require 'dry/validation/error'
15
14
  require 'dry/validation/contract/class_interface'
16
15
 
17
16
  module Dry
@@ -27,7 +27,7 @@ module Dry
27
27
  #
28
28
  # @api public
29
29
  def to_monad
30
- success? ? Success(to_h) : Failure(self)
30
+ success? ? Success(self) : Failure(self)
31
31
  end
32
32
  end
33
33
  end
@@ -1,15 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'dry/equalizer'
4
+
5
+ require 'dry/schema/constants'
4
6
  require 'dry/schema/message'
5
7
 
6
8
  module Dry
7
9
  module Validation
8
- # Error message
10
+ # Message message
9
11
  #
10
12
  # @api public
11
- class Error < Schema::Message
12
- include Dry::Equalizer(:text, :path)
13
+ class Message < Schema::Message
14
+ include Dry::Equalizer(:text, :path, :meta)
13
15
 
14
16
  # @!attribute [r] text
15
17
  # @return [String] text The error message text
@@ -19,29 +21,36 @@ module Dry
19
21
  # @return [Array<Symbol, Integer>] path The path to the value with the error
20
22
  attr_reader :path
21
23
 
24
+ # @!attribute [r] meta
25
+ # @return [Hash] meta Optional hash with meta-data
26
+ attr_reader :meta
27
+
22
28
  # @api public
23
- class Localized < Error
29
+ class Localized < Message
24
30
  # @api public
25
31
  def evaluate(**opts)
26
- Error.new(text.(opts), path: path)
32
+ evaluated_text, rest = text.(opts)
33
+ Message.new(evaluated_text, path: path, meta: rest.merge(meta))
27
34
  end
28
35
  end
29
36
 
30
37
  # Build an error
31
38
  #
32
- # @return [Error, Error::Localized]
39
+ # @return [Message, Message::Localized]
33
40
  #
34
41
  # @api public
35
- def self.[](text, path)
36
- text.respond_to?(:call) ? Localized.new(text, path: path) : Error.new(text, path: path)
42
+ def self.[](text, path, meta)
43
+ klass = text.respond_to?(:call) ? Localized : Message
44
+ klass.new(text, path: path, meta: meta)
37
45
  end
38
46
 
39
47
  # Initialize a new error object
40
48
  #
41
49
  # @api private
42
- def initialize(text, path:)
50
+ def initialize(text, path:, meta: EMPTY_HASH)
43
51
  @text = text
44
52
  @path = Array(path)
53
+ @meta = meta
45
54
  end
46
55
 
47
56
  # Check if this is a base error not associated with any key
@@ -3,17 +3,17 @@
3
3
  require 'dry/schema/message_set'
4
4
 
5
5
  require 'dry/validation/constants'
6
- require 'dry/validation/error'
6
+ require 'dry/validation/message'
7
7
 
8
8
  module Dry
9
9
  module Validation
10
- # ErrorSet is a specialized message set for handling validation errors
10
+ # MessageSet is a specialized message set for handling validation messages
11
11
  #
12
12
  # @api public
13
- class ErrorSet < Schema::MessageSet
13
+ class MessageSet < Schema::MessageSet
14
14
  # @!attribute [r] source
15
15
  # Return the source set of messages used to produce final evaluated messages
16
- # @return [Array<Error, Error::Localized, Schema::Message>]
16
+ # @return [Array<Message, Message::Localized, Schema::Message>]
17
17
  # @api private
18
18
  attr_reader :source_messages
19
19
 
@@ -29,54 +29,54 @@ module Dry
29
29
  super
30
30
  end
31
31
 
32
- # Return a new error set using updated options
32
+ # Return a new message set using updated options
33
33
  #
34
- # @return [ErrorSet]
34
+ # @return [MessageSet]
35
35
  #
36
36
  # @api private
37
37
  def with(other, new_options = EMPTY_HASH)
38
38
  return self if new_options.empty?
39
39
 
40
40
  self.class.new(
41
- other + select { |err| err.is_a?(Error) },
41
+ other + select { |err| err.is_a?(Message) },
42
42
  options.merge(source: source_messages, **new_options)
43
43
  ).freeze
44
44
  end
45
45
 
46
- # Add a new error
46
+ # Add a new message
47
47
  #
48
48
  # This is used when result is being prepared
49
49
  #
50
- # @return [ErrorSet]
50
+ # @return [MessageSet]
51
51
  #
52
52
  # @api private
53
- def add(error)
54
- source_messages << error
55
- messages << error
53
+ def add(message)
54
+ source_messages << message
55
+ messages << message
56
56
  initialize_placeholders!
57
57
  self
58
58
  end
59
59
 
60
- # Filter error set using provided predicates
60
+ # Filter message set using provided predicates
61
61
  #
62
- # This method is open to any predicate because errors can be anything that
62
+ # This method is open to any predicate because messages can be anything that
63
63
  # implements Message API, thus they can implement whatever predicates you
64
64
  # may need.
65
65
  #
66
- # @example get a list of base errors
67
- # error_set = contract.(input).error_set
68
- # error_set.filter(:base?)
66
+ # @example get a list of base messages
67
+ # message_set = contract.(input).message_set
68
+ # message_set.filter(:base?)
69
69
  #
70
70
  # @param [Array<Symbol>] *predicates
71
71
  #
72
- # @return [ErrorSet]
72
+ # @return [MessageSet]
73
73
  #
74
74
  # @api public
75
75
  def filter(*predicates)
76
- errors = select { |e|
77
- predicates.all? { |predicate| e.respond_to?(predicate) && e.public_send(predicate) }
76
+ messages = select { |msg|
77
+ predicates.all? { |predicate| msg.respond_to?(predicate) && msg.public_send(predicate) }
78
78
  }
79
- self.class.new(errors)
79
+ self.class.new(messages)
80
80
  end
81
81
 
82
82
  # @api private
@@ -101,7 +101,7 @@ module Dry
101
101
  def messages_map
102
102
  @messages_map ||= reduce(placeholders) { |hash, msg|
103
103
  node = msg.path.reduce(hash) { |a, e| a.is_a?(Hash) ? a[e] : a.last[e] }
104
- (node.size > 1 ? node[0] : node) << msg.to_s
104
+ (node.size > 1 ? node[0] : node) << msg.dump
105
105
  hash
106
106
  }
107
107
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'dry/validation/message'
4
+
3
5
  module Dry
4
6
  module Validation
5
7
  module Messages
@@ -23,19 +25,23 @@ module Dry
23
25
  @locale = locale
24
26
  end
25
27
 
26
- # Resolve Error object from provided args and path
28
+ # Resolve Message object from provided args and path
27
29
  #
28
30
  # This is used internally by contracts when rules are applied
29
31
  #
30
- # @return [Error, Error::Localized]
32
+ # @return [Message, Message::Localized]
31
33
  #
32
34
  # @api public
33
- def call(message:, tokens:, path:)
35
+ def call(message:, tokens:, path:, meta: EMPTY_HASH)
34
36
  case message
35
37
  when Symbol
36
- Error[->(**opts) { message(message, path: path, tokens: tokens, **opts) }, path]
38
+ Message[->(**opts) { message(message, path: path, tokens: tokens, **opts) }, path, meta]
37
39
  when String
38
- Error[message, path]
40
+ Message[message, path, meta]
41
+ when Hash
42
+ meta = message.dup
43
+ text = meta.delete(:text)
44
+ call(message: text, tokens: tokens, path: path, meta: meta)
39
45
  end
40
46
  end
41
47
  alias_method :[], :call
@@ -50,10 +56,10 @@ module Dry
50
56
  msg_opts = tokens.merge(path: keys, locale: locale)
51
57
 
52
58
  if keys.empty?
53
- template = messages["rules.#{rule}", msg_opts]
59
+ template, meta = messages["rules.#{rule}", msg_opts]
54
60
  else
55
- template = messages[rule, msg_opts.merge(path: keys.join(DOT))]
56
- template ||= messages[rule, msg_opts.merge(path: keys.last)]
61
+ template, meta = messages[rule, msg_opts.merge(path: keys.join(DOT))]
62
+ template, meta = messages[rule, msg_opts.merge(path: keys.last)] unless template
57
63
  end
58
64
 
59
65
  unless template
@@ -64,7 +70,7 @@ module Dry
64
70
 
65
71
  text = template.(template.data(tokens))
66
72
 
67
- full ? "#{messages.rule(keys.last, msg_opts)} #{text}" : text
73
+ [full ? "#{messages.rule(keys.last, msg_opts)} #{text}" : text, meta]
68
74
  end
69
75
  end
70
76
  end
@@ -3,7 +3,7 @@
3
3
  require 'dry/equalizer'
4
4
 
5
5
  require 'dry/validation/constants'
6
- require 'dry/validation/error_set'
6
+ require 'dry/validation/message_set'
7
7
 
8
8
  module Dry
9
9
  module Validation
@@ -45,7 +45,7 @@ module Dry
45
45
 
46
46
  # Get error set
47
47
  #
48
- # @return [ErrorSet]
48
+ # @return [MessageSet]
49
49
  #
50
50
  # @api public
51
51
  def errors(new_options = EMPTY_HASH)
@@ -134,7 +134,7 @@ module Dry
134
134
 
135
135
  # @api private
136
136
  def initialize_errors(options = self.options)
137
- ErrorSet.new(schema_errors(options), options)
137
+ MessageSet.new(schema_errors(options), options)
138
138
  end
139
139
 
140
140
  # @api private
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module Validation
5
- VERSION = '1.0.0.beta1'
5
+ VERSION = '1.0.0.beta2'
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.beta1
4
+ version: 1.0.0.beta2
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-03-26 00:00:00.000000000 Z
11
+ date: 2019-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -76,22 +76,22 @@ dependencies:
76
76
  name: dry-schema
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '0.3'
82
79
  - - ">="
83
80
  - !ruby/object:Gem::Version
84
- version: '0.4'
81
+ version: '0.5'
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: '0.5'
85
85
  type: :runtime
86
86
  prerelease: false
87
87
  version_requirements: !ruby/object:Gem::Requirement
88
88
  requirements:
89
- - - "~>"
90
- - !ruby/object:Gem::Version
91
- version: '0.3'
92
89
  - - ">="
93
90
  - !ruby/object:Gem::Version
94
- version: '0.4'
91
+ version: '0.5'
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '0.5'
95
95
  - !ruby/object:Gem::Dependency
96
96
  name: bundler
97
97
  requirement: !ruby/object:Gem::Requirement
@@ -150,10 +150,10 @@ files:
150
150
  - lib/dry/validation/constants.rb
151
151
  - lib/dry/validation/contract.rb
152
152
  - lib/dry/validation/contract/class_interface.rb
153
- - lib/dry/validation/error.rb
154
- - lib/dry/validation/error_set.rb
155
153
  - lib/dry/validation/evaluator.rb
156
154
  - lib/dry/validation/extensions/monads.rb
155
+ - lib/dry/validation/message.rb
156
+ - lib/dry/validation/message_set.rb
157
157
  - lib/dry/validation/messages/resolver.rb
158
158
  - lib/dry/validation/result.rb
159
159
  - lib/dry/validation/rule.rb