dry-validation 0.7.4 → 0.8.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 (143) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +9 -6
  4. data/CHANGELOG.md +58 -0
  5. data/Gemfile +3 -3
  6. data/benchmarks/benchmark_form_invalid.rb +64 -0
  7. data/benchmarks/benchmark_form_valid.rb +64 -0
  8. data/benchmarks/profile_schema_call_invalid.rb +20 -0
  9. data/benchmarks/profile_schema_call_valid.rb +20 -0
  10. data/benchmarks/profile_schema_definition.rb +14 -0
  11. data/benchmarks/profile_schema_messages_invalid.rb +20 -0
  12. data/benchmarks/suite.rb +5 -0
  13. data/config/errors.yml +12 -5
  14. data/dry-validation.gemspec +2 -2
  15. data/examples/basic.rb +2 -2
  16. data/examples/form.rb +2 -2
  17. data/examples/json.rb +2 -2
  18. data/examples/nested.rb +6 -6
  19. data/lib/dry/validation.rb +22 -3
  20. data/lib/dry/validation/deprecations.rb +23 -0
  21. data/lib/dry/validation/error_compiler.rb +31 -11
  22. data/lib/dry/validation/error_compiler/input.rb +44 -57
  23. data/lib/dry/validation/hint_compiler.rb +15 -7
  24. data/lib/dry/validation/input_processor_compiler.rb +13 -6
  25. data/lib/dry/validation/input_processor_compiler/form.rb +2 -0
  26. data/lib/dry/validation/input_processor_compiler/sanitizer.rb +1 -1
  27. data/lib/dry/validation/messages/abstract.rb +9 -1
  28. data/lib/dry/validation/predicate_registry.rb +101 -0
  29. data/lib/dry/validation/result.rb +8 -1
  30. data/lib/dry/validation/schema.rb +110 -44
  31. data/lib/dry/validation/schema/check.rb +4 -2
  32. data/lib/dry/validation/schema/deprecated.rb +31 -0
  33. data/lib/dry/validation/schema/dsl.rb +18 -11
  34. data/lib/dry/validation/schema/form.rb +1 -0
  35. data/lib/dry/validation/schema/json.rb +1 -0
  36. data/lib/dry/validation/schema/key.rb +23 -10
  37. data/lib/dry/validation/schema/rule.rb +81 -20
  38. data/lib/dry/validation/schema/value.rb +110 -25
  39. data/lib/dry/validation/version.rb +1 -1
  40. data/spec/fixtures/locales/en.yml +1 -0
  41. data/spec/fixtures/locales/pl.yml +1 -1
  42. data/spec/integration/custom_error_messages_spec.rb +2 -2
  43. data/spec/integration/custom_predicates_spec.rb +98 -15
  44. data/spec/integration/error_compiler_spec.rb +111 -96
  45. data/spec/integration/form/predicates/array_spec.rb +243 -0
  46. data/spec/integration/form/predicates/empty_spec.rb +263 -0
  47. data/spec/integration/form/predicates/eql_spec.rb +327 -0
  48. data/spec/integration/form/predicates/even_spec.rb +455 -0
  49. data/spec/integration/form/predicates/excluded_from_spec.rb +455 -0
  50. data/spec/integration/form/predicates/excludes_spec.rb +391 -0
  51. data/spec/integration/form/predicates/false_spec.rb +455 -0
  52. data/spec/integration/form/predicates/filled_spec.rb +467 -0
  53. data/spec/integration/form/predicates/format_spec.rb +454 -0
  54. data/spec/integration/form/predicates/gt_spec.rb +519 -0
  55. data/spec/integration/form/predicates/gteq_spec.rb +519 -0
  56. data/spec/integration/form/predicates/included_in_spec.rb +455 -0
  57. data/spec/integration/form/predicates/includes_spec.rb +391 -0
  58. data/spec/integration/form/predicates/key_spec.rb +75 -0
  59. data/spec/integration/form/predicates/lt_spec.rb +519 -0
  60. data/spec/integration/form/predicates/lteq_spec.rb +519 -0
  61. data/spec/integration/form/predicates/max_size_spec.rb +391 -0
  62. data/spec/integration/form/predicates/min_size_spec.rb +391 -0
  63. data/spec/integration/form/predicates/none_spec.rb +265 -0
  64. data/spec/integration/form/predicates/not_eql_spec.rb +327 -0
  65. data/spec/integration/form/predicates/odd_spec.rb +455 -0
  66. data/spec/integration/form/predicates/size/fixed_spec.rb +399 -0
  67. data/spec/integration/form/predicates/size/range_spec.rb +398 -0
  68. data/spec/integration/form/predicates/true_spec.rb +455 -0
  69. data/spec/integration/form/predicates/type_spec.rb +391 -0
  70. data/spec/integration/hints_spec.rb +90 -4
  71. data/spec/integration/injecting_rules_spec.rb +2 -2
  72. data/spec/integration/localized_error_messages_spec.rb +2 -2
  73. data/spec/integration/messages/i18n_spec.rb +3 -3
  74. data/spec/integration/optional_keys_spec.rb +3 -3
  75. data/spec/integration/schema/array_schema_spec.rb +49 -13
  76. data/spec/integration/schema/check_rules_spec.rb +6 -6
  77. data/spec/integration/schema/check_with_nested_el_spec.rb +3 -3
  78. data/spec/integration/schema/check_with_nth_el_spec.rb +1 -1
  79. data/spec/integration/schema/each_with_set_spec.rb +3 -3
  80. data/spec/integration/schema/extending_dsl_spec.rb +27 -0
  81. data/spec/integration/schema/form/explicit_types_spec.rb +182 -0
  82. data/spec/integration/schema/form_spec.rb +90 -18
  83. data/spec/integration/schema/hash_schema_spec.rb +47 -0
  84. data/spec/integration/schema/inheriting_schema_spec.rb +4 -4
  85. data/spec/integration/schema/input_processor_spec.rb +8 -8
  86. data/spec/integration/schema/json/explicit_types_spec.rb +157 -0
  87. data/spec/integration/schema/json_spec.rb +18 -18
  88. data/spec/integration/schema/macros/confirmation_spec.rb +1 -1
  89. data/spec/integration/schema/macros/each_spec.rb +177 -43
  90. data/spec/integration/schema/macros/{required_spec.rb → filled_spec.rb} +34 -6
  91. data/spec/integration/schema/macros/input_spec.rb +21 -0
  92. data/spec/integration/schema/macros/maybe_spec.rb +39 -2
  93. data/spec/integration/schema/macros/value_spec.rb +105 -0
  94. data/spec/integration/schema/macros/when_spec.rb +28 -8
  95. data/spec/integration/schema/nested_values_spec.rb +11 -8
  96. data/spec/integration/schema/not_spec.rb +2 -2
  97. data/spec/integration/schema/numbers_spec.rb +1 -1
  98. data/spec/integration/schema/option_with_default_spec.rb +1 -1
  99. data/spec/integration/schema/predicate_verification_spec.rb +9 -0
  100. data/spec/integration/schema/predicates/array_spec.rb +295 -0
  101. data/spec/integration/schema/predicates/custom_spec.rb +103 -0
  102. data/spec/integration/schema/predicates/empty_spec.rb +263 -0
  103. data/spec/integration/schema/predicates/eql_spec.rb +327 -0
  104. data/spec/integration/schema/predicates/even_spec.rb +455 -0
  105. data/spec/integration/schema/predicates/excluded_from_spec.rb +455 -0
  106. data/spec/integration/schema/predicates/excludes_spec.rb +391 -0
  107. data/spec/integration/schema/predicates/filled_spec.rb +467 -0
  108. data/spec/integration/schema/predicates/format_spec.rb +455 -0
  109. data/spec/integration/schema/predicates/gt_spec.rb +519 -0
  110. data/spec/integration/schema/predicates/gteq_spec.rb +519 -0
  111. data/spec/integration/schema/predicates/hash_spec.rb +69 -0
  112. data/spec/integration/schema/predicates/included_in_spec.rb +455 -0
  113. data/spec/integration/schema/predicates/includes_spec.rb +391 -0
  114. data/spec/integration/schema/predicates/key_spec.rb +88 -0
  115. data/spec/integration/schema/predicates/lt_spec.rb +520 -0
  116. data/spec/integration/schema/predicates/lteq_spec.rb +519 -0
  117. data/spec/integration/schema/predicates/max_size_spec.rb +391 -0
  118. data/spec/integration/schema/predicates/min_size_spec.rb +391 -0
  119. data/spec/integration/schema/predicates/none_spec.rb +265 -0
  120. data/spec/integration/schema/predicates/not_eql_spec.rb +391 -0
  121. data/spec/integration/schema/predicates/odd_spec.rb +455 -0
  122. data/spec/integration/schema/predicates/size/fixed_spec.rb +401 -0
  123. data/spec/integration/schema/predicates/size/range_spec.rb +399 -0
  124. data/spec/integration/schema/predicates/type_spec.rb +391 -0
  125. data/spec/integration/schema/reusing_schema_spec.rb +4 -4
  126. data/spec/integration/schema/using_types_spec.rb +24 -6
  127. data/spec/integration/schema/xor_spec.rb +2 -2
  128. data/spec/integration/schema_builders_spec.rb +15 -0
  129. data/spec/integration/schema_spec.rb +37 -12
  130. data/spec/shared/predicate_helper.rb +13 -0
  131. data/spec/spec_helper.rb +10 -0
  132. data/spec/support/matchers.rb +38 -0
  133. data/spec/support/predicates_integration.rb +7 -0
  134. data/spec/unit/hint_compiler_spec.rb +10 -8
  135. data/spec/unit/input_processor_compiler/form_spec.rb +45 -43
  136. data/spec/unit/input_processor_compiler/json_spec.rb +37 -35
  137. data/spec/unit/predicate_registry_spec.rb +34 -0
  138. data/spec/unit/schema/key_spec.rb +12 -14
  139. data/spec/unit/schema/rule_spec.rb +4 -2
  140. data/spec/unit/schema/value_spec.rb +38 -121
  141. metadata +150 -16
  142. data/lib/dry/validation/schema/attr.rb +0 -15
  143. data/spec/integration/attr_spec.rb +0 -122
@@ -0,0 +1,519 @@
1
+ RSpec.describe 'Predicates: Gt' do
2
+ context 'with required' do
3
+ subject(:schema) do
4
+ Dry::Validation.Schema do
5
+ required(:foo) { gt?(23) }
6
+ end
7
+ end
8
+
9
+ context 'with valid input' do
10
+ let(:input) { { foo: 33 } }
11
+
12
+ it 'is successful' do
13
+ expect(result).to be_successful
14
+ end
15
+ end
16
+
17
+ context 'with missing input' do
18
+ let(:input) { {} }
19
+
20
+ it 'is not successful' do
21
+ expect(result).to be_failing ['is missing', 'must be greater than 23']
22
+ end
23
+ end
24
+
25
+ context 'with nil input' do
26
+ let(:input) { { foo: nil } }
27
+
28
+ it 'is raises error' do
29
+ expect { result }.to raise_error(NoMethodError)
30
+ end
31
+ end
32
+
33
+ context 'with blank input' do
34
+ let(:input) { { foo: '' } }
35
+
36
+ it 'is raises error' do
37
+ expect { result }.to raise_error(ArgumentError, 'comparison of String with 23 failed')
38
+ end
39
+ end
40
+
41
+ context 'with invalid input type' do
42
+ let(:input) { { foo: [] } }
43
+
44
+ it 'is raises error' do
45
+ expect { result }.to raise_error(NoMethodError)
46
+ end
47
+ end
48
+
49
+ context 'with equal input' do
50
+ let(:input) { { foo: 23 } }
51
+
52
+ it 'is not successful' do
53
+ expect(result).to be_failing ['must be greater than 23']
54
+ end
55
+ end
56
+
57
+ context 'with less than input' do
58
+ let(:input) { { foo: 0 } }
59
+
60
+ it 'is not successful' do
61
+ expect(result).to be_failing ['must be greater than 23']
62
+ end
63
+ end
64
+ end
65
+
66
+ context 'with optional' do
67
+ subject(:schema) do
68
+ Dry::Validation.Schema do
69
+ optional(:foo) { gt?(23) }
70
+ end
71
+ end
72
+
73
+ context 'with valid input' do
74
+ let(:input) { { foo: 33 } }
75
+
76
+ it 'is successful' do
77
+ expect(result).to be_successful
78
+ end
79
+ end
80
+
81
+ context 'with missing input' do
82
+ let(:input) { {} }
83
+
84
+ it 'is successful' do
85
+ expect(result).to be_successful
86
+ end
87
+ end
88
+
89
+ context 'with nil input' do
90
+ let(:input) { { foo: nil } }
91
+
92
+ it 'is raises error' do
93
+ expect { result }.to raise_error(NoMethodError)
94
+ end
95
+ end
96
+
97
+ context 'with blank input' do
98
+ let(:input) { { foo: '' } }
99
+
100
+ it 'is raises error' do
101
+ expect { result }.to raise_error(ArgumentError, 'comparison of String with 23 failed')
102
+ end
103
+ end
104
+
105
+ context 'with invalid input type' do
106
+ let(:input) { { foo: [] } }
107
+
108
+ it 'is raises error' do
109
+ expect { result }.to raise_error(NoMethodError)
110
+ end
111
+ end
112
+
113
+ context 'with equal input' do
114
+ let(:input) { { foo: 23 } }
115
+
116
+ it 'is not successful' do
117
+ expect(result).to be_failing ['must be greater than 23']
118
+ end
119
+ end
120
+
121
+ context 'with less than input' do
122
+ let(:input) { { foo: 0 } }
123
+
124
+ it 'is not successful' do
125
+ expect(result).to be_failing ['must be greater than 23']
126
+ end
127
+ end
128
+ end
129
+
130
+ context 'as macro' do
131
+ context 'with required' do
132
+ context 'with value' do
133
+ subject(:schema) do
134
+ Dry::Validation.Schema do
135
+ required(:foo).value(gt?: 23)
136
+ end
137
+ end
138
+
139
+ context 'with valid input' do
140
+ let(:input) { { foo: 33 } }
141
+
142
+ it 'is successful' do
143
+ expect(result).to be_successful
144
+ end
145
+ end
146
+
147
+ context 'with missing input' do
148
+ let(:input) { {} }
149
+
150
+ it 'is not successful' do
151
+ expect(result).to be_failing ['is missing', 'must be greater than 23']
152
+ end
153
+ end
154
+
155
+ context 'with nil input' do
156
+ let(:input) { { foo: nil } }
157
+
158
+ it 'is raises error' do
159
+ expect { result }.to raise_error(NoMethodError)
160
+ end
161
+ end
162
+
163
+ context 'with blank input' do
164
+ let(:input) { { foo: '' } }
165
+
166
+ it 'is raises error' do
167
+ expect { result }.to raise_error(ArgumentError, 'comparison of String with 23 failed')
168
+ end
169
+ end
170
+
171
+ context 'with invalid input type' do
172
+ let(:input) { { foo: [] } }
173
+
174
+ it 'is raises error' do
175
+ expect { result }.to raise_error(NoMethodError)
176
+ end
177
+ end
178
+
179
+ context 'with equal input' do
180
+ let(:input) { { foo: 23 } }
181
+
182
+ it 'is not successful' do
183
+ expect(result).to be_failing ['must be greater than 23']
184
+ end
185
+ end
186
+
187
+ context 'with less than input' do
188
+ let(:input) { { foo: 0 } }
189
+
190
+ it 'is not successful' do
191
+ expect(result).to be_failing ['must be greater than 23']
192
+ end
193
+ end
194
+ end
195
+
196
+ context 'with filled' do
197
+ subject(:schema) do
198
+ Dry::Validation.Schema do
199
+ required(:foo).filled(gt?: 23)
200
+ end
201
+ end
202
+
203
+ context 'with valid input' do
204
+ let(:input) { { foo: 33 } }
205
+
206
+ it 'is successful' do
207
+ expect(result).to be_successful
208
+ end
209
+ end
210
+
211
+ context 'with missing input' do
212
+ let(:input) { {} }
213
+
214
+ it 'is not successful' do
215
+ expect(result).to be_failing ['is missing', 'must be greater than 23']
216
+ end
217
+ end
218
+
219
+ context 'with nil input' do
220
+ let(:input) { { foo: nil } }
221
+
222
+ it 'is not successful' do
223
+ expect(result).to be_failing ['must be filled', 'must be greater than 23']
224
+ end
225
+ end
226
+
227
+ context 'with blank input' do
228
+ let(:input) { { foo: '' } }
229
+
230
+ it 'is not successful' do
231
+ expect(result).to be_failing ['must be filled', 'must be greater than 23']
232
+ end
233
+ end
234
+
235
+ context 'with invalid input type' do
236
+ let(:input) { { foo: [] } }
237
+
238
+ it 'is not successful' do
239
+ expect(result).to be_failing ['must be filled', 'must be greater than 23']
240
+ end
241
+ end
242
+
243
+ context 'with equal input' do
244
+ let(:input) { { foo: 23 } }
245
+
246
+ it 'is not successful' do
247
+ expect(result).to be_failing ['must be greater than 23']
248
+ end
249
+ end
250
+
251
+ context 'with less than input' do
252
+ let(:input) { { foo: 0 } }
253
+
254
+ it 'is not successful' do
255
+ expect(result).to be_failing ['must be greater than 23']
256
+ end
257
+ end
258
+ end
259
+
260
+ context 'with maybe' do
261
+ subject(:schema) do
262
+ Dry::Validation.Schema do
263
+ required(:foo).maybe(gt?: 23)
264
+ end
265
+ end
266
+
267
+ context 'with valid input' do
268
+ let(:input) { { foo: 33 } }
269
+
270
+ it 'is successful' do
271
+ expect(result).to be_successful
272
+ end
273
+ end
274
+
275
+ context 'with missing input' do
276
+ let(:input) { {} }
277
+
278
+ it 'is not successful' do
279
+ expect(result).to be_failing ['is missing', 'must be greater than 23']
280
+ end
281
+ end
282
+
283
+ context 'with nil input' do
284
+ let(:input) { { foo: nil } }
285
+
286
+ it 'is successful' do
287
+ expect(result).to be_successful
288
+ end
289
+ end
290
+
291
+ context 'with blank input' do
292
+ let(:input) { { foo: '' } }
293
+
294
+ it 'is raises error' do
295
+ expect { result }.to raise_error(ArgumentError, 'comparison of String with 23 failed')
296
+ end
297
+ end
298
+
299
+ context 'with invalid input type' do
300
+ let(:input) { { foo: [] } }
301
+
302
+ it 'is raises error' do
303
+ expect { result }.to raise_error(NoMethodError)
304
+ end
305
+ end
306
+
307
+ context 'with equal input' do
308
+ let(:input) { { foo: 23 } }
309
+
310
+ it 'is not successful' do
311
+ expect(result).to be_failing ['must be greater than 23']
312
+ end
313
+ end
314
+
315
+ context 'with less than input' do
316
+ let(:input) { { foo: 0 } }
317
+
318
+ it 'is not successful' do
319
+ expect(result).to be_failing ['must be greater than 23']
320
+ end
321
+ end
322
+ end
323
+ end
324
+
325
+ context 'with optional' do
326
+ context 'with value' do
327
+ subject(:schema) do
328
+ Dry::Validation.Schema do
329
+ optional(:foo).value(gt?: 23)
330
+ end
331
+ end
332
+
333
+ context 'with valid input' do
334
+ let(:input) { { foo: 33 } }
335
+
336
+ it 'is successful' do
337
+ expect(result).to be_successful
338
+ end
339
+ end
340
+
341
+ context 'with missing input' do
342
+ let(:input) { {} }
343
+
344
+ it 'is successful' do
345
+ expect(result).to be_successful
346
+ end
347
+ end
348
+
349
+ context 'with nil input' do
350
+ let(:input) { { foo: nil } }
351
+
352
+ it 'is raises error' do
353
+ expect { result }.to raise_error(NoMethodError)
354
+ end
355
+ end
356
+
357
+ context 'with blank input' do
358
+ let(:input) { { foo: '' } }
359
+
360
+ it 'is raises error' do
361
+ expect { result }.to raise_error(ArgumentError, 'comparison of String with 23 failed')
362
+ end
363
+ end
364
+
365
+ context 'with invalid input type' do
366
+ let(:input) { { foo: [] } }
367
+
368
+ it 'is raises error' do
369
+ expect { result }.to raise_error(NoMethodError)
370
+ end
371
+ end
372
+
373
+ context 'with equal input' do
374
+ let(:input) { { foo: 23 } }
375
+
376
+ it 'is not successful' do
377
+ expect(result).to be_failing ['must be greater than 23']
378
+ end
379
+ end
380
+
381
+ context 'with less than input' do
382
+ let(:input) { { foo: 0 } }
383
+
384
+ it 'is not successful' do
385
+ expect(result).to be_failing ['must be greater than 23']
386
+ end
387
+ end
388
+ end
389
+
390
+ context 'with filled' do
391
+ subject(:schema) do
392
+ Dry::Validation.Schema do
393
+ optional(:foo).filled(gt?: 23)
394
+ end
395
+ end
396
+
397
+ context 'with valid input' do
398
+ let(:input) { { foo: 33 } }
399
+
400
+ it 'is successful' do
401
+ expect(result).to be_successful
402
+ end
403
+ end
404
+
405
+ context 'with missing input' do
406
+ let(:input) { {} }
407
+
408
+ it 'is successful' do
409
+ expect(result).to be_successful
410
+ end
411
+ end
412
+
413
+ context 'with nil input' do
414
+ let(:input) { { foo: nil } }
415
+
416
+ it 'is not successful' do
417
+ expect(result).to be_failing ['must be filled', 'must be greater than 23']
418
+ end
419
+ end
420
+
421
+ context 'with blank input' do
422
+ let(:input) { { foo: '' } }
423
+
424
+ it 'is not successful' do
425
+ expect(result).to be_failing ['must be filled', 'must be greater than 23']
426
+ end
427
+ end
428
+
429
+ context 'with invalid input type' do
430
+ let(:input) { { foo: [] } }
431
+
432
+ it 'is not successful' do
433
+ expect(result).to be_failing ['must be filled', 'must be greater than 23']
434
+ end
435
+ end
436
+
437
+ context 'with equal input' do
438
+ let(:input) { { foo: 23 } }
439
+
440
+ it 'is not successful' do
441
+ expect(result).to be_failing ['must be greater than 23']
442
+ end
443
+ end
444
+
445
+ context 'with less than input' do
446
+ let(:input) { { foo: 0 } }
447
+
448
+ it 'is not successful' do
449
+ expect(result).to be_failing ['must be greater than 23']
450
+ end
451
+ end
452
+ end
453
+
454
+ context 'with maybe' do
455
+ subject(:schema) do
456
+ Dry::Validation.Schema do
457
+ optional(:foo).maybe(gt?: 23)
458
+ end
459
+ end
460
+
461
+ context 'with valid input' do
462
+ let(:input) { { foo: 33 } }
463
+
464
+ it 'is successful' do
465
+ expect(result).to be_successful
466
+ end
467
+ end
468
+
469
+ context 'with missing input' do
470
+ let(:input) { {} }
471
+
472
+ it 'is successful' do
473
+ expect(result).to be_successful
474
+ end
475
+ end
476
+
477
+ context 'with nil input' do
478
+ let(:input) { { foo: nil } }
479
+
480
+ it 'is successful' do
481
+ expect(result).to be_successful
482
+ end
483
+ end
484
+
485
+ context 'with blank input' do
486
+ let(:input) { { foo: '' } }
487
+
488
+ it 'is raises error' do
489
+ expect { result }.to raise_error(ArgumentError, 'comparison of String with 23 failed')
490
+ end
491
+ end
492
+
493
+ context 'with invalid input type' do
494
+ let(:input) { { foo: [] } }
495
+
496
+ it 'is raises error' do
497
+ expect { result }.to raise_error(NoMethodError)
498
+ end
499
+ end
500
+
501
+ context 'with equal input' do
502
+ let(:input) { { foo: 23 } }
503
+
504
+ it 'is not successful' do
505
+ expect(result).to be_failing ['must be greater than 23']
506
+ end
507
+ end
508
+
509
+ context 'with less than input' do
510
+ let(:input) { { foo: 0 } }
511
+
512
+ it 'is not successful' do
513
+ expect(result).to be_failing ['must be greater than 23']
514
+ end
515
+ end
516
+ end
517
+ end
518
+ end
519
+ end