dry-validation 0.12.0 → 1.6.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.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +696 -239
  3. data/LICENSE +1 -1
  4. data/README.md +15 -12
  5. data/config/errors.yml +3 -88
  6. data/dry-validation.gemspec +31 -17
  7. data/lib/dry-validation.rb +3 -1
  8. data/lib/dry/validation.rb +45 -28
  9. data/lib/dry/validation/config.rb +24 -0
  10. data/lib/dry/validation/constants.rb +43 -0
  11. data/lib/dry/validation/contract.rb +171 -0
  12. data/lib/dry/validation/contract/class_interface.rb +230 -0
  13. data/lib/dry/validation/evaluator.rb +224 -0
  14. data/lib/dry/validation/extensions/hints.rb +67 -0
  15. data/lib/dry/validation/extensions/monads.rb +24 -8
  16. data/lib/dry/validation/extensions/predicates_as_macros.rb +75 -0
  17. data/lib/dry/validation/failures.rb +70 -0
  18. data/lib/dry/validation/function.rb +44 -0
  19. data/lib/dry/validation/macro.rb +38 -0
  20. data/lib/dry/validation/macros.rb +104 -0
  21. data/lib/dry/validation/message.rb +80 -80
  22. data/lib/dry/validation/message_set.rb +80 -105
  23. data/lib/dry/validation/messages/resolver.rb +131 -0
  24. data/lib/dry/validation/result.rb +183 -41
  25. data/lib/dry/validation/rule.rb +135 -0
  26. data/lib/dry/validation/schema_ext.rb +19 -0
  27. data/lib/dry/validation/values.rb +104 -0
  28. data/lib/dry/validation/version.rb +3 -1
  29. metadata +47 -336
  30. data/.codeclimate.yml +0 -17
  31. data/.gitignore +0 -9
  32. data/.rspec +0 -3
  33. data/.travis.yml +0 -26
  34. data/CONTRIBUTING.md +0 -31
  35. data/Gemfile +0 -33
  36. data/Rakefile +0 -22
  37. data/benchmarks/benchmark_form_invalid.rb +0 -64
  38. data/benchmarks/benchmark_form_valid.rb +0 -64
  39. data/benchmarks/benchmark_schema_invalid_huge.rb +0 -52
  40. data/benchmarks/profile_schema_call_invalid.rb +0 -20
  41. data/benchmarks/profile_schema_call_valid.rb +0 -20
  42. data/benchmarks/profile_schema_definition.rb +0 -14
  43. data/benchmarks/profile_schema_huge_invalid.rb +0 -30
  44. data/benchmarks/profile_schema_messages_invalid.rb +0 -20
  45. data/benchmarks/suite.rb +0 -5
  46. data/examples/basic.rb +0 -15
  47. data/examples/each.rb +0 -14
  48. data/examples/json.rb +0 -12
  49. data/examples/multiple.rb +0 -27
  50. data/examples/nested.rb +0 -22
  51. data/examples/params.rb +0 -11
  52. data/lib/dry/validation/compat/form.rb +0 -67
  53. data/lib/dry/validation/deprecations.rb +0 -24
  54. data/lib/dry/validation/executor.rb +0 -91
  55. data/lib/dry/validation/extensions.rb +0 -7
  56. data/lib/dry/validation/extensions/struct.rb +0 -32
  57. data/lib/dry/validation/input_processor_compiler.rb +0 -135
  58. data/lib/dry/validation/input_processor_compiler/json.rb +0 -45
  59. data/lib/dry/validation/input_processor_compiler/params.rb +0 -49
  60. data/lib/dry/validation/input_processor_compiler/sanitizer.rb +0 -47
  61. data/lib/dry/validation/message_compiler.rb +0 -192
  62. data/lib/dry/validation/message_compiler/visitor_opts.rb +0 -37
  63. data/lib/dry/validation/messages.rb +0 -14
  64. data/lib/dry/validation/messages/abstract.rb +0 -112
  65. data/lib/dry/validation/messages/i18n.rb +0 -35
  66. data/lib/dry/validation/messages/namespaced.rb +0 -32
  67. data/lib/dry/validation/messages/yaml.rb +0 -54
  68. data/lib/dry/validation/predicate_registry.rb +0 -115
  69. data/lib/dry/validation/schema.rb +0 -126
  70. data/lib/dry/validation/schema/check.rb +0 -37
  71. data/lib/dry/validation/schema/class_interface.rb +0 -189
  72. data/lib/dry/validation/schema/deprecated.rb +0 -30
  73. data/lib/dry/validation/schema/dsl.rb +0 -118
  74. data/lib/dry/validation/schema/form.rb +0 -9
  75. data/lib/dry/validation/schema/json.rb +0 -21
  76. data/lib/dry/validation/schema/key.rb +0 -71
  77. data/lib/dry/validation/schema/params.rb +0 -22
  78. data/lib/dry/validation/schema/rule.rb +0 -202
  79. data/lib/dry/validation/schema/value.rb +0 -211
  80. data/lib/dry/validation/schema_compiler.rb +0 -81
  81. data/lib/dry/validation/type_specs.rb +0 -70
  82. data/spec/extensions/monads/result_spec.rb +0 -40
  83. data/spec/extensions/struct/schema_spec.rb +0 -32
  84. data/spec/fixtures/locales/en.yml +0 -6
  85. data/spec/fixtures/locales/pl.yml +0 -18
  86. data/spec/integration/custom_error_messages_spec.rb +0 -48
  87. data/spec/integration/custom_predicates_spec.rb +0 -228
  88. data/spec/integration/hints_spec.rb +0 -170
  89. data/spec/integration/injecting_rules_spec.rb +0 -30
  90. data/spec/integration/json/defining_base_schema_spec.rb +0 -41
  91. data/spec/integration/localized_error_messages_spec.rb +0 -72
  92. data/spec/integration/message_compiler_spec.rb +0 -405
  93. data/spec/integration/messages/i18n_spec.rb +0 -94
  94. data/spec/integration/optional_keys_spec.rb +0 -28
  95. data/spec/integration/params/predicates/array_spec.rb +0 -287
  96. data/spec/integration/params/predicates/empty_spec.rb +0 -263
  97. data/spec/integration/params/predicates/eql_spec.rb +0 -327
  98. data/spec/integration/params/predicates/even_spec.rb +0 -455
  99. data/spec/integration/params/predicates/excluded_from_spec.rb +0 -455
  100. data/spec/integration/params/predicates/excludes_spec.rb +0 -391
  101. data/spec/integration/params/predicates/false_spec.rb +0 -455
  102. data/spec/integration/params/predicates/filled_spec.rb +0 -467
  103. data/spec/integration/params/predicates/format_spec.rb +0 -454
  104. data/spec/integration/params/predicates/gt_spec.rb +0 -519
  105. data/spec/integration/params/predicates/gteq_spec.rb +0 -519
  106. data/spec/integration/params/predicates/included_in_spec.rb +0 -455
  107. data/spec/integration/params/predicates/includes_spec.rb +0 -391
  108. data/spec/integration/params/predicates/key_spec.rb +0 -67
  109. data/spec/integration/params/predicates/lt_spec.rb +0 -519
  110. data/spec/integration/params/predicates/lteq_spec.rb +0 -519
  111. data/spec/integration/params/predicates/max_size_spec.rb +0 -391
  112. data/spec/integration/params/predicates/min_size_spec.rb +0 -391
  113. data/spec/integration/params/predicates/none_spec.rb +0 -265
  114. data/spec/integration/params/predicates/not_eql_spec.rb +0 -327
  115. data/spec/integration/params/predicates/odd_spec.rb +0 -455
  116. data/spec/integration/params/predicates/size/fixed_spec.rb +0 -393
  117. data/spec/integration/params/predicates/size/range_spec.rb +0 -396
  118. data/spec/integration/params/predicates/true_spec.rb +0 -455
  119. data/spec/integration/params/predicates/type_spec.rb +0 -391
  120. data/spec/integration/result_spec.rb +0 -81
  121. data/spec/integration/schema/array_schema_spec.rb +0 -59
  122. data/spec/integration/schema/check_rules_spec.rb +0 -119
  123. data/spec/integration/schema/check_with_nested_el_spec.rb +0 -37
  124. data/spec/integration/schema/check_with_nth_el_spec.rb +0 -25
  125. data/spec/integration/schema/default_settings_spec.rb +0 -11
  126. data/spec/integration/schema/defining_base_schema_spec.rb +0 -41
  127. data/spec/integration/schema/dynamic_predicate_args_spec.rb +0 -43
  128. data/spec/integration/schema/each_with_set_spec.rb +0 -70
  129. data/spec/integration/schema/extending_dsl_spec.rb +0 -27
  130. data/spec/integration/schema/form_spec.rb +0 -236
  131. data/spec/integration/schema/hash_schema_spec.rb +0 -47
  132. data/spec/integration/schema/inheriting_schema_spec.rb +0 -31
  133. data/spec/integration/schema/input_processor_spec.rb +0 -46
  134. data/spec/integration/schema/json/explicit_types_spec.rb +0 -157
  135. data/spec/integration/schema/json_spec.rb +0 -163
  136. data/spec/integration/schema/macros/confirmation_spec.rb +0 -35
  137. data/spec/integration/schema/macros/each_spec.rb +0 -268
  138. data/spec/integration/schema/macros/filled_spec.rb +0 -87
  139. data/spec/integration/schema/macros/input_spec.rb +0 -139
  140. data/spec/integration/schema/macros/maybe_spec.rb +0 -99
  141. data/spec/integration/schema/macros/rule_spec.rb +0 -75
  142. data/spec/integration/schema/macros/value_spec.rb +0 -119
  143. data/spec/integration/schema/macros/when_spec.rb +0 -62
  144. data/spec/integration/schema/nested_schemas_spec.rb +0 -236
  145. data/spec/integration/schema/nested_values_spec.rb +0 -46
  146. data/spec/integration/schema/not_spec.rb +0 -34
  147. data/spec/integration/schema/numbers_spec.rb +0 -19
  148. data/spec/integration/schema/option_with_default_spec.rb +0 -64
  149. data/spec/integration/schema/or_spec.rb +0 -87
  150. data/spec/integration/schema/params/defining_base_schema_spec.rb +0 -41
  151. data/spec/integration/schema/params/explicit_types_spec.rb +0 -195
  152. data/spec/integration/schema/params_spec.rb +0 -234
  153. data/spec/integration/schema/predicate_verification_spec.rb +0 -9
  154. data/spec/integration/schema/predicates/array_spec.rb +0 -295
  155. data/spec/integration/schema/predicates/custom_spec.rb +0 -103
  156. data/spec/integration/schema/predicates/empty_spec.rb +0 -263
  157. data/spec/integration/schema/predicates/eql_spec.rb +0 -327
  158. data/spec/integration/schema/predicates/even_spec.rb +0 -455
  159. data/spec/integration/schema/predicates/excluded_from/array_spec.rb +0 -459
  160. data/spec/integration/schema/predicates/excluded_from/range_spec.rb +0 -459
  161. data/spec/integration/schema/predicates/excludes_spec.rb +0 -391
  162. data/spec/integration/schema/predicates/filled_spec.rb +0 -467
  163. data/spec/integration/schema/predicates/format_spec.rb +0 -455
  164. data/spec/integration/schema/predicates/gt_spec.rb +0 -519
  165. data/spec/integration/schema/predicates/gteq_spec.rb +0 -519
  166. data/spec/integration/schema/predicates/hash_spec.rb +0 -69
  167. data/spec/integration/schema/predicates/included_in/array_spec.rb +0 -459
  168. data/spec/integration/schema/predicates/included_in/range_spec.rb +0 -459
  169. data/spec/integration/schema/predicates/includes_spec.rb +0 -391
  170. data/spec/integration/schema/predicates/key_spec.rb +0 -88
  171. data/spec/integration/schema/predicates/lt_spec.rb +0 -520
  172. data/spec/integration/schema/predicates/lteq_spec.rb +0 -519
  173. data/spec/integration/schema/predicates/max_size_spec.rb +0 -391
  174. data/spec/integration/schema/predicates/min_size_spec.rb +0 -391
  175. data/spec/integration/schema/predicates/none_spec.rb +0 -265
  176. data/spec/integration/schema/predicates/not_eql_spec.rb +0 -391
  177. data/spec/integration/schema/predicates/odd_spec.rb +0 -455
  178. data/spec/integration/schema/predicates/size/fixed_spec.rb +0 -398
  179. data/spec/integration/schema/predicates/size/range_spec.rb +0 -395
  180. data/spec/integration/schema/predicates/type_spec.rb +0 -413
  181. data/spec/integration/schema/reusing_schema_spec.rb +0 -33
  182. data/spec/integration/schema/using_types_spec.rb +0 -135
  183. data/spec/integration/schema/validate_spec.rb +0 -120
  184. data/spec/integration/schema/xor_spec.rb +0 -35
  185. data/spec/integration/schema_builders_spec.rb +0 -17
  186. data/spec/integration/schema_spec.rb +0 -173
  187. data/spec/shared/message_compiler.rb +0 -11
  188. data/spec/shared/predicate_helper.rb +0 -15
  189. data/spec/shared/rule_compiler.rb +0 -8
  190. data/spec/spec_helper.rb +0 -58
  191. data/spec/support/define_struct.rb +0 -25
  192. data/spec/support/matchers.rb +0 -38
  193. data/spec/support/mutant.rb +0 -9
  194. data/spec/support/predicates_integration.rb +0 -7
  195. data/spec/unit/input_processor_compiler/json_spec.rb +0 -283
  196. data/spec/unit/input_processor_compiler/params_spec.rb +0 -328
  197. data/spec/unit/message_compiler/visit_failure_spec.rb +0 -38
  198. data/spec/unit/message_compiler/visit_spec.rb +0 -16
  199. data/spec/unit/message_compiler_spec.rb +0 -7
  200. data/spec/unit/predicate_registry_spec.rb +0 -34
  201. data/spec/unit/schema/key_spec.rb +0 -38
  202. data/spec/unit/schema/rule_spec.rb +0 -42
  203. data/spec/unit/schema/value_spec.rb +0 -131
  204. data/spec/unit/schema_spec.rb +0 -35
@@ -1,18 +0,0 @@
1
- pl:
2
- errors:
3
- filled?: "nie może być pusty"
4
- size?:
5
- arg:
6
- default: "wielkość musi być równa %{size}"
7
- range: "wielkość musi być między %{size_left} a %{size_right}"
8
- value:
9
- string:
10
- arg:
11
- default: "wielkość musi być równa %{size}"
12
- rules:
13
- email:
14
- filled?: "Proszę podać adres email"
15
- user:
16
- rules:
17
- email:
18
- filled?: "Hej user! Dawaj ten email no!"
@@ -1,48 +0,0 @@
1
- require 'dry/validation/messages/i18n'
2
-
3
- RSpec.describe Dry::Validation do
4
- shared_context 'schema with customized messages' do
5
- describe '#messages' do
6
- it 'returns compiled error messages' do
7
- expect(schema.(email: '').messages).to eql(
8
- email: ['Please provide your email']
9
- )
10
- end
11
- end
12
- end
13
-
14
- context 'yaml' do
15
- subject(:schema) do
16
- Dry::Validation.Schema do
17
- configure do
18
- config.messages_file = SPEC_ROOT.join('fixtures/locales/en.yml')
19
- end
20
-
21
- required(:email, &:filled?)
22
- end
23
- end
24
-
25
- include_context 'schema with customized messages'
26
- end
27
-
28
- context 'i18n' do
29
- context 'with custom messages set globally' do
30
- before do
31
- I18n.load_path << SPEC_ROOT.join('fixtures/locales/en.yml')
32
- I18n.backend.load_translations
33
- end
34
-
35
- subject(:schema) do
36
- Dry::Validation.Schema do
37
- configure do
38
- config.messages = :i18n
39
- end
40
-
41
- required(:email, &:filled?)
42
- end
43
- end
44
-
45
- include_context 'schema with customized messages'
46
- end
47
- end
48
- end
@@ -1,228 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- RSpec.describe Dry::Validation do
3
- shared_context 'uses custom predicates' do
4
- it 'uses provided custom predicates' do
5
- expect(schema.(email: 'jane@doe')).to be_success
6
-
7
- expect(schema.(email: nil).messages).to eql(
8
- email: ['must be filled', 'must be a valid email']
9
- )
10
-
11
- expect(schema.(email: 'jane').messages).to eql(
12
- email: ['must be a valid email']
13
- )
14
- end
15
- end
16
-
17
- let(:base_class) do
18
- Class.new(Dry::Validation::Schema) do
19
- def self.messages
20
- Dry::Validation::Messages.default.merge(
21
- en: { errors: { email?: 'must be a valid email' } }
22
- )
23
- end
24
- end
25
- end
26
-
27
- describe 'defining schema with custom predicates container' do
28
- before do
29
- module Test
30
- module Predicates
31
- include Dry::Logic::Predicates
32
-
33
- def self.email?(input)
34
- input.include?('@') # for the lols
35
- end
36
- end
37
- end
38
- end
39
-
40
- context 'when configured globally' do
41
- subject(:schema) do
42
- Dry::Validation.Schema(base_class) do
43
- required(:email) { filled? & email? }
44
- end
45
- end
46
-
47
- before do
48
- Dry::Validation::Schema.predicates(Test::Predicates)
49
- end
50
-
51
- after do
52
- # HACK: reset global predicates configuration
53
- Dry::Validation::Schema.configure do |config|
54
- config.predicates = Dry::Logic::Predicates
55
- end
56
- end
57
-
58
- include_context 'uses custom predicates'
59
- end
60
-
61
- context 'when configured locally' do
62
- subject(:schema) do
63
- Dry::Validation.Schema(base_class) do
64
- configure do
65
- predicates(Test::Predicates)
66
- end
67
-
68
- required(:email) { filled? & email? }
69
- end
70
- end
71
-
72
- include_context 'uses custom predicates'
73
- end
74
- end
75
-
76
- describe 'defining schema with custom predicate methods' do
77
- subject(:schema) do
78
- Dry::Validation.Schema(base_class) do
79
- configure do
80
- def email?(value)
81
- value.include?('@')
82
- end
83
- end
84
-
85
- required(:email) { filled? & email? }
86
- end
87
- end
88
-
89
- include_context 'uses custom predicates'
90
- end
91
-
92
- describe 'custom predicate which requires an arbitrary dependency' do
93
- subject(:schema) do
94
- Dry::Validation.Schema(base_class) do
95
- configure do
96
- option :email_check
97
-
98
- def email?(value)
99
- email_check.(value)
100
- end
101
- end
102
-
103
- required(:email).filled(:email?)
104
- end
105
- end
106
-
107
- it 'uses injected dependency for the custom predicate' do
108
- email_check = -> input { input.include?('@') }
109
-
110
- expect(schema.with(email_check: email_check).(email: 'foo').messages).to eql(
111
- email: ['must be a valid email']
112
- )
113
- end
114
- end
115
-
116
- it 'raises an error when message is missing' do
117
- schema = Dry::Validation.Schema do
118
- configure do
119
- def email?(value)
120
- false
121
- end
122
- end
123
-
124
- required(:email).filled(:email?)
125
- end
126
-
127
- expect { schema.(email: 'foo').messages }.to raise_error(
128
- Dry::Validation::MissingMessageError, /email/
129
- )
130
- end
131
-
132
- it 'works with custom predicate args' do
133
- schema = Dry::Validation.Schema do
134
- configure do
135
- def self.messages
136
- Dry::Validation::Messages.default.merge(
137
- en: { errors: { fav_number?: 'must be %{expected}' } }
138
- )
139
- end
140
- def fav_number?(expected, current)
141
- current == expected
142
- end
143
- end
144
-
145
- required(:foo) { fav_number?(23) }
146
- end
147
-
148
- expect(schema.(foo: 20).messages).to eql(
149
- foo: ['must be 23']
150
- )
151
-
152
- end
153
-
154
- it 'works when no predicate args' do
155
- schema = Dry::Validation.Schema do
156
- configure do
157
- def self.messages
158
- Dry::Validation::Messages.default.merge(
159
- en: { errors: { with_no_args?: 'is always false' } }
160
- )
161
- end
162
-
163
- def with_no_args?
164
- false
165
- end
166
- end
167
-
168
- required(:email).filled(:with_no_args?)
169
- end
170
-
171
- expect(schema.(email: 'foo').messages).to eql(
172
- email: ['is always false']
173
- )
174
- end
175
-
176
- it 'works with nested schemas' do
177
- schema = Dry::Validation.Schema do
178
- configure do
179
- def ok?(_value)
180
- true
181
- end
182
- end
183
-
184
- required(:foo).schema do
185
- required(:bar).value(:ok?)
186
- end
187
- end
188
-
189
- expect(schema.(foo: { bar: "1" })).to be_success
190
- end
191
-
192
- it 'works with interpolation of messages' do
193
- schema = Dry::Validation.Schema do
194
- configure do
195
- option :categories, []
196
-
197
- def self.messages
198
- Dry::Validation::Messages.default.merge(
199
- en: {
200
- errors: {
201
- valid_category?: 'must be one of the categories: %{categories}'
202
- }
203
- },
204
- pl: {
205
- errors: {
206
- valid_category?: 'musi być jedną z: %{categories}'
207
- }
208
- }
209
- )
210
- end
211
-
212
- def valid_category?(categories, value)
213
- categories.include?(value)
214
- end
215
- end
216
-
217
- required(:category).filled(valid_category?: categories)
218
- end.with(categories: %w(foo bar))
219
-
220
- expect(schema.(category: 'baz').messages).to eql(
221
- category: ['must be one of the categories: foo, bar']
222
- )
223
-
224
- expect(schema.(category: 'baz').messages(locale: :pl)).to eql(
225
- category: ['musi być jedną z: foo, bar']
226
- )
227
- end
228
- end
@@ -1,170 +0,0 @@
1
- require 'dry/validation/messages/i18n'
2
-
3
- RSpec.describe 'Validation hints' do
4
- shared_context '#messages' do
5
- it 'provides hints for additional rules that were not checked' do
6
- expect(schema.(age: '17').messages).to eql(
7
- age: ['must be an integer', 'must be greater than 18']
8
- )
9
- end
10
-
11
- it 'skips type-check rules' do
12
- expect(schema.(age: 17).messages).to eql(
13
- age: ['must be greater than 18']
14
- )
15
- end
16
- end
17
-
18
- context 'with yaml messages' do
19
- subject(:schema) do
20
- Dry::Validation.Schema do
21
- required(:age).maybe(:int?, gt?: 18)
22
- end
23
- end
24
-
25
- include_context '#messages'
26
- end
27
-
28
- context 'with i18n messages' do
29
- subject(:schema) do
30
- Dry::Validation.Schema do
31
- configure { configure { |c| c.messages = :i18n } }
32
-
33
- required(:age).maybe(:int?, gt?: 18)
34
- end
35
- end
36
-
37
- include_context '#messages'
38
- end
39
-
40
- context 'when type expectation is specified' do
41
- subject(:schema) do
42
- Dry::Validation.Schema do
43
- required(:email).filled
44
- required(:name).filled(:str?, size?: 5..25)
45
- end
46
- end
47
-
48
- it 'infers message for specific type' do
49
- expect(schema.(email: 'jane@doe', name: 'HN').messages).to eql(
50
- name: ['length must be within 5 - 25']
51
- )
52
- end
53
- end
54
-
55
- context 'when predicate failed and there is a corresponding hint generated' do
56
- subject(:schema) do
57
- Dry::Validation.Schema do
58
- required(:age).value(lt?: 23)
59
- end
60
- end
61
-
62
- it 'provides only failure error message' do
63
- result = schema.call(age: 23)
64
- expect(result.messages).to eql(age: ['must be less than 23'])
65
- end
66
- end
67
-
68
- context 'with a nested schema with same rule names' do
69
- subject(:schema) do
70
- Dry::Validation.Schema do
71
- required(:code).filled(:str?, eql?: 'foo')
72
-
73
- required(:nested).schema do
74
- required(:code).filled(:str?, eql?: 'bar')
75
- end
76
- end
77
- end
78
-
79
- it 'provides error messages' do
80
- result = schema.call(code: 'x', nested: { code: 'y' })
81
-
82
- expect(result.messages).to eql(
83
- code: ['must be equal to foo'],
84
- nested: {
85
- code: ['must be equal to bar']
86
- }
87
- )
88
- end
89
-
90
- it 'provides hints' do
91
- result = schema.call(code: '', nested: { code: '' })
92
-
93
- expect(result.messages).to eql(
94
- code: ['must be filled', 'must be equal to foo'],
95
- nested: {
96
- code: ['must be filled', 'must be equal to bar']
97
- }
98
- )
99
- end
100
- end
101
-
102
- context 'with an each rule' do
103
- subject(:schema) do
104
- Dry::Validation.Schema do
105
- required(:nums).each(:int?, gt?: 0)
106
- end
107
- end
108
-
109
- it 'provides hints for each element' do
110
- expect(schema.(nums: [1, 'foo', 0]).messages).to eql(
111
- nums: {
112
- 1 => ['must be an integer', 'must be greater than 0'],
113
- 2 => ['must be greater than 0']
114
- }
115
- )
116
- end
117
- end
118
-
119
- context 'with a format? predicate' do
120
- subject(:schema) do
121
- Dry::Validation.Schema do
122
- required(:name).value(size?: 2, format?: /xy/)
123
- end
124
- end
125
-
126
- it 'skips hints' do
127
- expect(schema.(name: 'x').messages[:name]).to_not include('is in invalid format')
128
- expect(schema.(name: 'ab').messages[:name]).to include('is in invalid format')
129
- end
130
- end
131
-
132
- context 'when the message uses input value' do
133
- subject(:schema) do
134
- Dry::Validation.Schema do
135
- configure do
136
- def self.messages
137
- Messages.default.merge(
138
- en: {
139
- errors: {
140
- blue?: {
141
- failure: '%{value} is not equal to blue',
142
- hint: 'must be equal to blue'
143
- }
144
- }
145
- }
146
- )
147
- end
148
-
149
- def blue?(value)
150
- value == 'blue'
151
- end
152
- end
153
-
154
- required(:pill).filled(:blue?)
155
- end
156
- end
157
-
158
- it 'provides a correct failure message' do
159
- expect(schema.(pill: 'red').messages).to eql(
160
- pill: ['red is not equal to blue']
161
- )
162
- end
163
-
164
- it 'provides a correct hint' do
165
- expect(schema.(pill: nil).messages).to eql(
166
- pill: ['must be filled', 'must be equal to blue']
167
- )
168
- end
169
- end
170
- end