dry-validation 1.3.1 → 1.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f61fe3205cc418d53bd0f2217bdd49a0e49119a69cae87ecf24e76a89567f845
4
- data.tar.gz: 4ca306db1fd196c3253a78a6376fe0d4c197c5c8d625636bc37038b9caa3278b
3
+ metadata.gz: 63194a473d9c41ac3d26a861eeb4b83bee43196864439646cdb62fca01c6ac68
4
+ data.tar.gz: da3ec5f48cc07869828c9c692259e36fe199801a4c7573abaee67a3340928347
5
5
  SHA512:
6
- metadata.gz: d0c6a082c4a7077bd428e1bbe2f8ec4677950ea0f073d15cb955568307e2924b75e9d4bfb0f023b65739df7d061569e1aa8a3941968c263d68f4fd3fe12a61d5
7
- data.tar.gz: 50fa2999ebe80ce40fe244b10bac6cf3644f4dd7e7825913726e8cc2587a901f0d2d164d1c29e17b55f613bd7258dc13d672a5787334f90afc4059d0480312b9
6
+ metadata.gz: 5f523435436ea0c17789d40a2dba7fef627cab4dfcd2f1f2955c2a0b8f2a9a98d144e0ea3e821d07830bd100857fb20d18d9e6c6225e361193e4b0d6579613de
7
+ data.tar.gz: 93a13f949010dc5bbd47e1608ba43dcb6d18cea091c3ec8b5706e5d80bae4b6beecfc57312db83ec1dd1f3a8a9f26fa3c8b290307e7ba331f09c5d555d66c78d
@@ -1,8 +1,28 @@
1
+ # v1.4.0 2019-12-12
2
+
3
+ ### Added
4
+
5
+ - Support for multi-schema inheritance (@ianwhite)
6
+
7
+ ### Fixed
8
+
9
+ - Keyword warnings reported by Ruby 2.7 (@flash-gordon)
10
+ - Fixed an issue where `MessageSet` would be marked as empty too early (@ianwhite)
11
+ - Messages are correctly generated when there are errors for both an array and one or more of its elements (see #599) (@Bugagazavr)
12
+
13
+ ### Changed
14
+
15
+ - A meaningful exception is raised when failure options are not valid (@MatElGran)
16
+ - [internal] improved performance in `Contract.ensure_valid_keys` (@grzegorz-jakubiak)
17
+ - [internal] fixed keyword warnings on MRI 2.7.0 (@flash-gordon)
18
+
19
+ [Compare v1.3.1...master](https://github.com/dry-rb/dry-validation/compare/v1.3.1...master)
20
+
1
21
  # v1.3.1 2019-08-16
2
22
 
3
23
  ### Changed
4
24
 
5
- * You can now set an external schema without providing a block (alassek)
25
+ - You can now set an external schema without providing a block (@alassek)
6
26
 
7
27
  [Compare v1.3.0...v1.3.1](https://github.com/dry-rb/dry-validation/compare/v1.3.0...v1.3.1)
8
28
 
@@ -10,15 +30,15 @@
10
30
 
11
31
  ### Added
12
32
 
13
- * Support for setting an external schema (that can be extended too) (fixed #574) (@solnic)
33
+ - Support for setting an external schema (that can be extended too) (fixed #574) (@solnic)
14
34
 
15
35
  ### Fixed
16
36
 
17
- * Using a hash spec to define rule keys with more than one value is properly handled by rule guard now (fixed #576) (@solnic)
37
+ - Using a hash spec to define rule keys with more than one value is properly handled by rule guard now (fixed #576) (@solnic)
18
38
 
19
39
  ### Changed
20
40
 
21
- * `values` within rules uses `Hash#fetch_values` internally now, which improves performance (@esparta)
41
+ - `values` within rules uses `Hash#fetch_values` internally now, which improves performance (@esparta)
22
42
 
23
43
  [Compare v1.2.1...v1.3.0](https://github.com/dry-rb/dry-validation/compare/v1.2.1...v1.3.0)
24
44
 
@@ -26,10 +46,10 @@
26
46
 
27
47
  ### Fixed
28
48
 
29
- * Defining an abstract contract class that has no schema no longer crashes (issue #565) (@solnic)
30
- * Fixed an issue where `Rule#each` would crash when the value is not an array (issue #567) (@solnic)
31
- * Fixed an issue where guarding a rule would crash when keys are missing in the input (issue #569) (@solnic)
32
- * Added missing "pathname" require (issue #570) (@solnic)
49
+ - Defining an abstract contract class that has no schema no longer crashes (issue #565) (@solnic)
50
+ - Fixed an issue where `Rule#each` would crash when the value is not an array (issue #567) (@solnic)
51
+ - Fixed an issue where guarding a rule would crash when keys are missing in the input (issue #569) (@solnic)
52
+ - Added missing "pathname" require (issue #570) (@solnic)
33
53
 
34
54
  [Compare v1.2.0...v1.2.1](https://github.com/dry-rb/dry-validation/compare/v1.2.0...v1.2.1)
35
55
 
@@ -37,15 +57,15 @@
37
57
 
38
58
  ### Added
39
59
 
40
- * New extension `:predicates_as_macros` (@waiting-for-dev)
60
+ - New extension `:predicates_as_macros` (@waiting-for-dev)
41
61
 
42
62
  ### Fixed
43
63
 
44
- * Guarding rules for nested keys works correctly (issue #560) (@solnic)
64
+ - Guarding rules for nested keys works correctly (issue #560) (@solnic)
45
65
 
46
66
  ### Changed
47
67
 
48
- * `dry-schema` dependency was bumped to `>= 1.3.1` (@solnic)
68
+ - `dry-schema` dependency was bumped to `>= 1.3.1` (@solnic)
49
69
 
50
70
  [Compare v1.1.1...v1.2.0](https://github.com/dry-rb/dry-validation/compare/v1.1.1...v1.2.0)
51
71
 
@@ -53,7 +73,7 @@
53
73
 
54
74
  ### Fixed
55
75
 
56
- * `Rule#each` works with array values from nested hashes (@mustardnoise)
76
+ - `Rule#each` works with array values from nested hashes (@mustardnoise)
57
77
 
58
78
  [Compare v1.1.0...v1.1.1](https://github.com/dry-rb/dry-validation/compare/v1.1.0...v1.1.1)
59
79
 
@@ -61,13 +81,13 @@
61
81
 
62
82
  ### Added
63
83
 
64
- * `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)
65
- * `value` supports hash-based path specifications now (refs #547) (@solnic)
66
- * `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)
84
+ - `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)
85
+ - `value` supports hash-based path specifications now (refs #547) (@solnic)
86
+ - `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)
67
87
 
68
88
  ### Fixed
69
89
 
70
- * Passing multiple macro names to `validate` or `each` works correctly (fixed #538 #541) (@jandudulski)
90
+ - Passing multiple macro names to `validate` or `each` works correctly (fixed #538 #541) (@jandudulski)
71
91
 
72
92
  [Compare v1.0.0...v1.1.0](https://github.com/dry-rb/dry-validation/compare/v1.0.0...v1.1.0)
73
93
 
@@ -114,14 +134,14 @@ See [the list of all addressed issues](https://github.com/dry-rb/dry-validation/
114
134
 
115
135
  ### Added
116
136
 
117
- * [EXPERIMENTAL] `Validation.register_macro` for registering global macros (solnic)
118
- * [EXPERIMENTAL] `Contract.register_macro` for registering macros available to specific contract classes (solnic)
119
- * `Dry::Validation.Contract` shortcut for quickly defining a contract and getting its instance back (solnic)
120
- * New configuration option `config.locale` for setting the default locale (solnic)
137
+ - [EXPERIMENTAL] `Validation.register_macro` for registering global macros (solnic)
138
+ - [EXPERIMENTAL] `Contract.register_macro` for registering macros available to specific contract classes (solnic)
139
+ - `Dry::Validation.Contract` shortcut for quickly defining a contract and getting its instance back (solnic)
140
+ - New configuration option `config.locale` for setting the default locale (solnic)
121
141
 
122
142
  ### Fixed
123
143
 
124
- * `config/errors.yml` are now bundled with the gem, **`rc2` was broken because of this** (solnic)
144
+ - `config/errors.yml` are now bundled with the gem, **`rc2` was broken because of this** (solnic)
125
145
 
126
146
  [Compare v1.0.0.rc2...v1.0.0.rc3](https://github.com/dry-rb/dry-validation/compare/v1.0.0.rc2...v1.0.0.rc3)
127
147
 
@@ -131,17 +151,17 @@ This was **yanked** on rubygems.org because the bundled gem was missing `config`
131
151
 
132
152
  ### Added
133
153
 
134
- * [EXPERIMENTAL] support for registering macros via `Dry::Validation::Macros.register(:your_macro, &block)` (solnic)
135
- * [EXPERIMENTAL] `:acceptance` as the first built-in macro (issue #157) (solnic)
154
+ - [EXPERIMENTAL] support for registering macros via `Dry::Validation::Macros.register(:your_macro, &block)` (solnic)
155
+ - [EXPERIMENTAL] `:acceptance` as the first built-in macro (issue #157) (solnic)
136
156
 
137
157
  ### Fixed
138
158
 
139
- * Passing invalid argument to `failure` will raise a meaningful error instead of crashing (solnic)
159
+ - Passing invalid argument to `failure` will raise a meaningful error instead of crashing (solnic)
140
160
 
141
161
  ### Changed
142
162
 
143
- * In rule validation blocks, `values` is now an instance of a hash-like `Dry::Validation::Values` class, rather than `Dry::Schema::Result`. This gives more convenient access to data within rules (solnic)
144
- * Dependency on `dry-schema` was updated to `~> 1.0` (solnic)
163
+ - In rule validation blocks, `values` is now an instance of a hash-like `Dry::Validation::Values` class, rather than `Dry::Schema::Result`. This gives more convenient access to data within rules (solnic)
164
+ - Dependency on `dry-schema` was updated to `~> 1.0` (solnic)
145
165
 
146
166
  [Compare v1.0.0.rc1...v1.0.0.rc2](https://github.com/dry-rb/dry-validation/compare/v1.0.0.rc1...v1.0.0.rc2)
147
167
 
@@ -149,18 +169,18 @@ This was **yanked** on rubygems.org because the bundled gem was missing `config`
149
169
 
150
170
  ### Added
151
171
 
152
- * `:hints` extension is back (solnic)
153
- * `Result` objects have access to the context object which is shared between rules (flash-gordon)
172
+ - `:hints` extension is back (solnic)
173
+ - `Result` objects have access to the context object which is shared between rules (flash-gordon)
154
174
 
155
175
  ### Fixed
156
176
 
157
- * Multiple hint messages no longer crash message set (flash-gordon)
158
- * `Contract#inspect` no longer crashes (solnic)
177
+ - Multiple hint messages no longer crash message set (flash-gordon)
178
+ - `Contract#inspect` no longer crashes (solnic)
159
179
 
160
180
  ### Changed
161
181
 
162
- * Dependency on `dry-schema` was bumped to `~> 0.6` - this pulls in `dry-types 1.0.0` and `dry-logic 1.0.0` (solnic)
163
- * Dependency on `dry-initializer` was bumped to `~> 3.0` (solnic)
182
+ - Dependency on `dry-schema` was bumped to `~> 0.6` - this pulls in `dry-types 1.0.0` and `dry-logic 1.0.0` (solnic)
183
+ - Dependency on `dry-initializer` was bumped to `~> 3.0` (solnic)
164
184
 
165
185
  [Compare v1.0.0.beta2...v1.0.0.rc1](https://github.com/dry-rb/dry-validation/compare/v1.0.0.beta2...v1.0.0.rc1)
166
186
 
@@ -168,7 +188,7 @@ This was **yanked** on rubygems.org because the bundled gem was missing `config`
168
188
 
169
189
  ### Added
170
190
 
171
- * Support for arbitrary meta-data in failures, ie:
191
+ - Support for arbitrary meta-data in failures, ie:
172
192
 
173
193
  ```ruby
174
194
  class NewUserContract < Dry::Validation::Contract
@@ -186,9 +206,9 @@ This was **yanked** on rubygems.org because the bundled gem was missing `config`
186
206
 
187
207
  ### Changed
188
208
 
189
- * [BREAKING] `Error` was renamed to `Message` as it is a more generic concept (solnic)
190
- * [BREAKING] `ErrorSet` was renamed to `MessageSet` for consistency (solnic)
191
- * [BREAKING] `:monads` extension wraps entire result objects in `Success` or `Failure` (flash-gordon)
209
+ - [BREAKING] `Error` was renamed to `Message` as it is a more generic concept (solnic)
210
+ - [BREAKING] `ErrorSet` was renamed to `MessageSet` for consistency (solnic)
211
+ - [BREAKING] `:monads` extension wraps entire result objects in `Success` or `Failure` (flash-gordon)
192
212
 
193
213
  [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)
194
214
 
@@ -196,20 +216,20 @@ This was **yanked** on rubygems.org because the bundled gem was missing `config`
196
216
 
197
217
  ### Added
198
218
 
199
- * New API for setting failures `base.failure` for base errors and `key.failure` for key errors (solnic)
200
- * Support for `base` errors associated with a key even when child keys have errors too (solnic)
201
- * Support for `base` errors not associated with any key (solnic)
202
- * Result objects use `ErrorSet` object now for managing messages (solnic)
203
- * Nested keys are properly handled when generating messages hash (issue #489) (flash-gordon + solnic)
204
- * Result objects support `locale` and `full` options now (solnic)
205
- * Ability to configure `top_namespace` for messages, which will be used for both schema and rule localization (solnic)
206
- * Rule blocks receive a context object that you can use to share data between rules (solnic)
219
+ - New API for setting failures `base.failure` for base errors and `key.failure` for key errors (solnic)
220
+ - Support for `base` errors associated with a key even when child keys have errors too (solnic)
221
+ - Support for `base` errors not associated with any key (solnic)
222
+ - Result objects use `ErrorSet` object now for managing messages (solnic)
223
+ - Nested keys are properly handled when generating messages hash (issue #489) (flash-gordon + solnic)
224
+ - Result objects support `locale` and `full` options now (solnic)
225
+ - Ability to configure `top_namespace` for messages, which will be used for both schema and rule localization (solnic)
226
+ - Rule blocks receive a context object that you can use to share data between rules (solnic)
207
227
 
208
228
  ### Changed
209
229
 
210
- * [BREAKING] `Result#errors` returns an instance of `ErrorSet` now, it's an enumerable, coerible to a hash (solnic)
211
- * [BREAKING] `failure` was removed in favor of `key.failure` or `key(:foo).failure` (solnic)
212
- * [BREAKING] `Result#to_hash` was removed (flash-gordon)
230
+ - [BREAKING] `Result#errors` returns an instance of `ErrorSet` now, it's an enumerable, coerible to a hash (solnic)
231
+ - [BREAKING] `failure` was removed in favor of `key.failure` or `key(:foo).failure` (solnic)
232
+ - [BREAKING] `Result#to_hash` was removed (flash-gordon)
213
233
 
214
234
  [Compare v1.0.0.alpha2...v1.0.0.beta1](https://github.com/dry-rb/dry-validation/compare/v1.0.0.alpha2...v1.0.0.beta1)
215
235
 
@@ -219,13 +239,13 @@ First round of bug fixes. Thanks for testing <3!
219
239
 
220
240
  ### Fixed
221
241
 
222
- * Errors with nested messages are correctly built (flash-gordon)
223
- * Messages for nested keys are correctly resolved (solnic)
224
- * A message for a nested key is resolved when it's defined under `errors.rule.%{key}` too, but a message under nested key will override it (solnic)
242
+ - Errors with nested messages are correctly built (flash-gordon)
243
+ - Messages for nested keys are correctly resolved (solnic)
244
+ - A message for a nested key is resolved when it's defined under `errors.rule.%{key}` too, but a message under nested key will override it (solnic)
225
245
 
226
246
  ### Changed
227
247
 
228
- * When a message template is not found a more meaningful error is raised that includes both rule identifier and key path (solnic)
248
+ - When a message template is not found a more meaningful error is raised that includes both rule identifier and key path (solnic)
229
249
 
230
250
  [Compare v1.0.0.alpha1...v1.0.0.alpha2](https://github.com/dry-rb/dry-validation/compare/v1.0.0.alpha1...v1.0.0.alpha2)
231
251
 
@@ -235,8 +255,8 @@ Complete rewrite on top of `dry-schema`.
235
255
 
236
256
  ### Added
237
257
 
238
- * [BREAKING] `Dry::Validation::Contract` as a replacement for validation schemas (solnic)
239
- * [BREAKING] New `rule` DSL with an improved API for setting error messages (solnic)
258
+ - [BREAKING] `Dry::Validation::Contract` as a replacement for validation schemas (solnic)
259
+ - [BREAKING] New `rule` DSL with an improved API for setting error messages (solnic)
240
260
 
241
261
  [Compare v0.13.0...v1.0.0.alpha1](https://github.com/dry-rb/dry-validation/compare/v0.13.0...v1.0.0.alpha1)
242
262
 
@@ -257,7 +277,7 @@ Complete rewrite on top of `dry-schema`.
257
277
 
258
278
  ### Changed
259
279
 
260
- * [internal] dry-logic was pinned to `~> 0.4.2` (flash-gordon)
280
+ - [internal] dry-logic was pinned to `~> 0.4.2` (flash-gordon)
261
281
 
262
282
  [Compare v0.12.2...v0.12.3](https://github.com/dry-rb/dry-validation/compare/v0.12.2...v0.12.3)
263
283
 
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  [gem]: https://rubygems.org/gems/dry-validation
2
- [travis]: https://travis-ci.com/dry-rb/dry-validation
2
+ [ci]: https://github.com/dry-rb/dry-validation/actions?query=workflow%3Aci
3
3
  [codeclimate]: https://codeclimate.com/github/dry-rb/dry-validation
4
4
  [chat]: https://dry-rb.zulipchat.com
5
5
  [inchpages]: http://inch-ci.org/github/dry-rb/dry-validation
@@ -7,23 +7,23 @@
7
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
- [![Build Status](https://travis-ci.com/dry-rb/dry-validation.svg?branch=master)][travis]
10
+ [![Build Status](https://github.com/dry-rb/dry-monads/workflows/ci/badge.svg)][ci]
11
11
  [![Code Climate](https://codeclimate.com/github/dry-rb/dry-validation/badges/gpa.svg)][codeclimate]
12
12
  [![Test Coverage](https://codeclimate.com/github/dry-rb/dry-validation/badges/coverage.svg)][codeclimate]
13
13
  [![Inline docs](http://inch-ci.org/github/dry-rb/dry-validation.svg?branch=master)][inchpages]
14
14
 
15
15
  ## Links
16
16
 
17
- * [User documentation](https://dry-rb.org/gems/dry-validation)
18
- * [API documentation](http://rubydoc.info/gems/dry-validation)
19
- * [Guidelines for contributing](CONTRIBUTING.md)
17
+ - [User documentation](https://dry-rb.org/gems/dry-validation)
18
+ - [API documentation](http://rubydoc.info/gems/dry-validation)
19
+ - [Guidelines for contributing](CONTRIBUTING.md)
20
20
 
21
21
  ## Supported Ruby versions
22
22
 
23
- This library officially supports following Ruby versions:
23
+ This library officially supports the following Ruby versions:
24
24
 
25
- * MRI >= `2.4`
26
- * jruby >= `9.2`
25
+ - MRI >= `2.4`
26
+ - jruby >= `9.2`
27
27
 
28
28
  ## License
29
29
 
@@ -98,7 +98,7 @@ module Dry
98
98
  rule_result = rule.(self, result)
99
99
 
100
100
  rule_result.failures.each do |failure|
101
- result.add_error(message_resolver[failure])
101
+ result.add_error(message_resolver.(**failure))
102
102
  end
103
103
  end
104
104
  end
@@ -57,8 +57,8 @@ module Dry
57
57
  # @see https://dry-rb.org/gems/dry-schema/params/
58
58
  #
59
59
  # @api public
60
- def params(external_schema = nil, &block)
61
- define(:Params, external_schema, &block)
60
+ def params(*external_schemas, &block)
61
+ define(:Params, external_schemas, &block)
62
62
  end
63
63
 
64
64
  # Define a JSON schema for your contract
@@ -69,8 +69,8 @@ module Dry
69
69
  # @see https://dry-rb.org/gems/dry-schema/json/
70
70
  #
71
71
  # @api public
72
- def json(external_schema = nil, &block)
73
- define(:JSON, external_schema, &block)
72
+ def json(*external_schemas, &block)
73
+ define(:JSON, external_schemas, &block)
74
74
  end
75
75
 
76
76
  # Define a plain schema for your contract
@@ -81,8 +81,8 @@ module Dry
81
81
  # @see https://dry-rb.org/gems/dry-schema/
82
82
  #
83
83
  # @api public
84
- def schema(external_schema = nil, &block)
85
- define(:schema, external_schema, &block)
84
+ def schema(*external_schemas, &block)
85
+ define(:schema, external_schemas, &block)
86
86
  end
87
87
 
88
88
  # Define a rule for your contract
@@ -123,7 +123,7 @@ module Dry
123
123
  #
124
124
  # @api public
125
125
  def build(options = EMPTY_HASH, &block)
126
- Class.new(self, &block).new(options)
126
+ Class.new(self, &block).new(**options)
127
127
  end
128
128
 
129
129
  # @api private
@@ -162,7 +162,7 @@ module Dry
162
162
  .map { |key|
163
163
  [key, Schema::Path[key]]
164
164
  }
165
- .map { |(key, path)|
165
+ .flat_map { |(key, path)|
166
166
  if (last = path.last).is_a?(Array)
167
167
  last.map { |last_key|
168
168
  path_key = [*path.to_a[0..-2], last_key]
@@ -172,7 +172,6 @@ module Dry
172
172
  [[key, path]]
173
173
  end
174
174
  }
175
- .flatten(1)
176
175
  .reject { |(_, path)|
177
176
  valid_paths.any? { |valid_path| valid_path.include?(path) }
178
177
  }
@@ -197,8 +196,8 @@ module Dry
197
196
  end
198
197
 
199
198
  # @api private
200
- def define(method_name, external_schema, &block)
201
- return __schema__ if external_schema.nil? && block.nil?
199
+ def define(method_name, external_schemas, &block)
200
+ return __schema__ if external_schemas.empty? && block.nil?
202
201
 
203
202
  unless __schema__.nil?
204
203
  raise ::Dry::Validation::DuplicateSchemaError, 'Schema has already been defined'
@@ -206,15 +205,15 @@ module Dry
206
205
 
207
206
  schema_opts = core_schema_opts
208
207
 
209
- schema_opts.update(parent: external_schema) if external_schema
208
+ schema_opts.update(parent: external_schemas) if external_schemas.any?
210
209
 
211
210
  case method_name
212
211
  when :schema
213
- @__schema__ = Schema.define(schema_opts, &block)
212
+ @__schema__ = Schema.define(**schema_opts, &block)
214
213
  when :Params
215
- @__schema__ = Schema.Params(schema_opts, &block)
214
+ @__schema__ = Schema.Params(**schema_opts, &block)
216
215
  when :JSON
217
- @__schema__ = Schema.JSON(schema_opts, &block)
216
+ @__schema__ = Schema.JSON(**schema_opts, &block)
218
217
  end
219
218
  end
220
219
  end
@@ -63,19 +63,19 @@ module Dry
63
63
  # Initialize a new evaluator
64
64
  #
65
65
  # @api private
66
- def initialize(contract, options, &block)
67
- super(contract, options)
66
+ def initialize(contract, **options, &block)
67
+ super(contract, **options)
68
68
 
69
69
  @_options = options
70
70
 
71
71
  if block
72
72
  exec_opts = block_options.map { |key, value| [key, _options[value]] }.to_h
73
- instance_exec(exec_opts, &block)
73
+ instance_exec(**exec_opts, &block)
74
74
  end
75
75
 
76
76
  macros.each do |args|
77
77
  macro = macro(*args.flatten(1))
78
- instance_exec(macro.extract_block_options(_options.merge(macro: macro)), &macro.block)
78
+ instance_exec(**macro.extract_block_options(_options.merge(macro: macro)), &macro.block)
79
79
  end
80
80
  end
81
81
 
@@ -117,7 +117,7 @@ module Dry
117
117
 
118
118
  # @api private
119
119
  def with(new_opts, &block)
120
- self.class.new(_contract, _options.merge(new_opts), &block)
120
+ self.class.new(_contract, **_options, **new_opts, &block)
121
121
  end
122
122
 
123
123
  # Return default (first) key name
@@ -45,6 +45,13 @@ 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
  #
@@ -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
@@ -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,6 +54,7 @@ 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
60
  initialize_placeholders!
@@ -114,7 +115,7 @@ module Dry
114
115
  # rubocop:disable Metrics/AbcSize
115
116
  # rubocop:disable Metrics/PerceivedComplexity
116
117
  def initialize_placeholders!
117
- @placeholders = unique_paths.each_with_object(EMPTY_HASH.dup) { |path, hash|
118
+ @placeholders = unique_paths.sort_by(&:size).each_with_object(EMPTY_HASH.dup) { |path, hash|
118
119
  curr_idx = 0
119
120
  last_idx = path.size - 1
120
121
  node = hash
@@ -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
@@ -30,7 +30,7 @@ module Dry
30
30
  class Hash < Key
31
31
  # @api private
32
32
  def to_dot_notation
33
- [name].product(members.map(&:to_dot_notation).flatten(1)).map { |e| e.join(DOT) }
33
+ [name].product(members.flat_map(&:to_dot_notation)).map { |e| e.join(DOT) }
34
34
  end
35
35
  end
36
36
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module Validation
5
- VERSION = '1.3.1'
5
+ VERSION = '1.4.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.1
4
+ version: 1.4.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-16 00:00:00.000000000 Z
11
+ date: 2019-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby