dry-validation 0.13.3 → 1.7.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 (207) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +506 -95
  3. data/LICENSE +1 -1
  4. data/README.md +16 -12
  5. data/config/errors.yml +3 -88
  6. data/dry-validation.gemspec +37 -24
  7. data/lib/dry/validation/config.rb +24 -0
  8. data/lib/dry/validation/constants.rb +43 -0
  9. data/lib/dry/validation/contract/class_interface.rb +230 -0
  10. data/lib/dry/validation/contract.rb +171 -0
  11. data/lib/dry/validation/evaluator.rb +224 -0
  12. data/lib/dry/validation/extensions/hints.rb +67 -0
  13. data/lib/dry/validation/extensions/monads.rb +24 -8
  14. data/lib/dry/validation/extensions/predicates_as_macros.rb +75 -0
  15. data/lib/dry/validation/failures.rb +70 -0
  16. data/lib/dry/validation/function.rb +44 -0
  17. data/lib/dry/validation/macro.rb +38 -0
  18. data/lib/dry/validation/macros.rb +104 -0
  19. data/lib/dry/validation/message.rb +80 -80
  20. data/lib/dry/validation/message_set.rb +80 -105
  21. data/lib/dry/validation/messages/resolver.rb +131 -0
  22. data/lib/dry/validation/result.rb +183 -41
  23. data/lib/dry/validation/rule.rb +135 -0
  24. data/lib/dry/validation/schema_ext.rb +19 -0
  25. data/lib/dry/validation/values.rb +104 -0
  26. data/lib/dry/validation/version.rb +3 -1
  27. data/lib/dry/validation.rb +45 -28
  28. data/lib/dry-validation.rb +3 -1
  29. metadata +46 -344
  30. data/.codeclimate.yml +0 -17
  31. data/.gitignore +0 -9
  32. data/.rspec +0 -3
  33. data/.travis.yml +0 -29
  34. data/CONTRIBUTING.md +0 -31
  35. data/Gemfile +0 -25
  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/struct.rb +0 -32
  56. data/lib/dry/validation/extensions.rb +0 -7
  57. data/lib/dry/validation/input_processor_compiler/json.rb +0 -45
  58. data/lib/dry/validation/input_processor_compiler/params.rb +0 -49
  59. data/lib/dry/validation/input_processor_compiler/sanitizer.rb +0 -47
  60. data/lib/dry/validation/input_processor_compiler.rb +0 -137
  61. data/lib/dry/validation/message_compiler/visitor_opts.rb +0 -37
  62. data/lib/dry/validation/message_compiler.rb +0 -188
  63. data/lib/dry/validation/messages/abstract.rb +0 -119
  64. data/lib/dry/validation/messages/i18n.rb +0 -47
  65. data/lib/dry/validation/messages/namespaced.rb +0 -39
  66. data/lib/dry/validation/messages/yaml.rb +0 -61
  67. data/lib/dry/validation/messages.rb +0 -14
  68. data/lib/dry/validation/predicate_registry.rb +0 -115
  69. data/lib/dry/validation/predicates.rb +0 -19
  70. data/lib/dry/validation/schema/check.rb +0 -37
  71. data/lib/dry/validation/schema/class_interface.rb +0 -190
  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.rb +0 -126
  81. data/lib/dry/validation/schema_compiler.rb +0 -81
  82. data/lib/dry/validation/template.rb +0 -66
  83. data/lib/dry/validation/type_specs.rb +0 -70
  84. data/log/.gitkeep +0 -0
  85. data/spec/extensions/monads/result_spec.rb +0 -40
  86. data/spec/extensions/struct/schema_spec.rb +0 -32
  87. data/spec/fixtures/locales/en.yml +0 -8
  88. data/spec/fixtures/locales/pl.yml +0 -22
  89. data/spec/integration/custom_error_messages_spec.rb +0 -54
  90. data/spec/integration/custom_predicates_spec.rb +0 -228
  91. data/spec/integration/hints_spec.rb +0 -170
  92. data/spec/integration/injecting_rules_spec.rb +0 -30
  93. data/spec/integration/json/defining_base_schema_spec.rb +0 -41
  94. data/spec/integration/localized_error_messages_spec.rb +0 -72
  95. data/spec/integration/message_compiler_spec.rb +0 -405
  96. data/spec/integration/messages/i18n_spec.rb +0 -104
  97. data/spec/integration/optional_keys_spec.rb +0 -28
  98. data/spec/integration/params/predicates/array_spec.rb +0 -287
  99. data/spec/integration/params/predicates/empty_spec.rb +0 -263
  100. data/spec/integration/params/predicates/eql_spec.rb +0 -327
  101. data/spec/integration/params/predicates/even_spec.rb +0 -455
  102. data/spec/integration/params/predicates/excluded_from_spec.rb +0 -455
  103. data/spec/integration/params/predicates/excludes_spec.rb +0 -391
  104. data/spec/integration/params/predicates/false_spec.rb +0 -455
  105. data/spec/integration/params/predicates/filled_spec.rb +0 -467
  106. data/spec/integration/params/predicates/format_spec.rb +0 -454
  107. data/spec/integration/params/predicates/gt_spec.rb +0 -519
  108. data/spec/integration/params/predicates/gteq_spec.rb +0 -519
  109. data/spec/integration/params/predicates/included_in_spec.rb +0 -455
  110. data/spec/integration/params/predicates/includes_spec.rb +0 -391
  111. data/spec/integration/params/predicates/key_spec.rb +0 -67
  112. data/spec/integration/params/predicates/lt_spec.rb +0 -519
  113. data/spec/integration/params/predicates/lteq_spec.rb +0 -519
  114. data/spec/integration/params/predicates/max_size_spec.rb +0 -391
  115. data/spec/integration/params/predicates/min_size_spec.rb +0 -391
  116. data/spec/integration/params/predicates/none_spec.rb +0 -265
  117. data/spec/integration/params/predicates/not_eql_spec.rb +0 -327
  118. data/spec/integration/params/predicates/odd_spec.rb +0 -455
  119. data/spec/integration/params/predicates/size/fixed_spec.rb +0 -393
  120. data/spec/integration/params/predicates/size/range_spec.rb +0 -396
  121. data/spec/integration/params/predicates/true_spec.rb +0 -455
  122. data/spec/integration/params/predicates/type_spec.rb +0 -391
  123. data/spec/integration/result_spec.rb +0 -81
  124. data/spec/integration/schema/array_schema_spec.rb +0 -59
  125. data/spec/integration/schema/check_rules_spec.rb +0 -119
  126. data/spec/integration/schema/check_with_nested_el_spec.rb +0 -37
  127. data/spec/integration/schema/check_with_nth_el_spec.rb +0 -25
  128. data/spec/integration/schema/default_settings_spec.rb +0 -11
  129. data/spec/integration/schema/defining_base_schema_spec.rb +0 -41
  130. data/spec/integration/schema/dynamic_predicate_args_spec.rb +0 -43
  131. data/spec/integration/schema/each_with_set_spec.rb +0 -70
  132. data/spec/integration/schema/extending_dsl_spec.rb +0 -27
  133. data/spec/integration/schema/form_spec.rb +0 -236
  134. data/spec/integration/schema/hash_schema_spec.rb +0 -47
  135. data/spec/integration/schema/inheriting_schema_spec.rb +0 -31
  136. data/spec/integration/schema/input_processor_spec.rb +0 -46
  137. data/spec/integration/schema/json/explicit_types_spec.rb +0 -157
  138. data/spec/integration/schema/json_spec.rb +0 -163
  139. data/spec/integration/schema/macros/confirmation_spec.rb +0 -35
  140. data/spec/integration/schema/macros/each_spec.rb +0 -268
  141. data/spec/integration/schema/macros/filled_spec.rb +0 -87
  142. data/spec/integration/schema/macros/input_spec.rb +0 -139
  143. data/spec/integration/schema/macros/maybe_spec.rb +0 -99
  144. data/spec/integration/schema/macros/rule_spec.rb +0 -75
  145. data/spec/integration/schema/macros/value_spec.rb +0 -119
  146. data/spec/integration/schema/macros/when_spec.rb +0 -62
  147. data/spec/integration/schema/nested_schemas_spec.rb +0 -236
  148. data/spec/integration/schema/nested_values_spec.rb +0 -46
  149. data/spec/integration/schema/not_spec.rb +0 -34
  150. data/spec/integration/schema/numbers_spec.rb +0 -19
  151. data/spec/integration/schema/option_with_default_spec.rb +0 -64
  152. data/spec/integration/schema/or_spec.rb +0 -87
  153. data/spec/integration/schema/params/defining_base_schema_spec.rb +0 -41
  154. data/spec/integration/schema/params/explicit_types_spec.rb +0 -195
  155. data/spec/integration/schema/params_spec.rb +0 -234
  156. data/spec/integration/schema/predicate_verification_spec.rb +0 -9
  157. data/spec/integration/schema/predicates/array_spec.rb +0 -295
  158. data/spec/integration/schema/predicates/custom_spec.rb +0 -103
  159. data/spec/integration/schema/predicates/empty_spec.rb +0 -263
  160. data/spec/integration/schema/predicates/eql_spec.rb +0 -327
  161. data/spec/integration/schema/predicates/even_spec.rb +0 -455
  162. data/spec/integration/schema/predicates/excluded_from/array_spec.rb +0 -459
  163. data/spec/integration/schema/predicates/excluded_from/range_spec.rb +0 -459
  164. data/spec/integration/schema/predicates/excludes_spec.rb +0 -391
  165. data/spec/integration/schema/predicates/filled_spec.rb +0 -467
  166. data/spec/integration/schema/predicates/format_spec.rb +0 -455
  167. data/spec/integration/schema/predicates/gt_spec.rb +0 -519
  168. data/spec/integration/schema/predicates/gteq_spec.rb +0 -519
  169. data/spec/integration/schema/predicates/hash_spec.rb +0 -69
  170. data/spec/integration/schema/predicates/included_in/array_spec.rb +0 -459
  171. data/spec/integration/schema/predicates/included_in/range_spec.rb +0 -459
  172. data/spec/integration/schema/predicates/includes_spec.rb +0 -391
  173. data/spec/integration/schema/predicates/key_spec.rb +0 -88
  174. data/spec/integration/schema/predicates/lt_spec.rb +0 -520
  175. data/spec/integration/schema/predicates/lteq_spec.rb +0 -519
  176. data/spec/integration/schema/predicates/max_size_spec.rb +0 -391
  177. data/spec/integration/schema/predicates/min_size_spec.rb +0 -391
  178. data/spec/integration/schema/predicates/none_spec.rb +0 -265
  179. data/spec/integration/schema/predicates/not_eql_spec.rb +0 -391
  180. data/spec/integration/schema/predicates/odd_spec.rb +0 -455
  181. data/spec/integration/schema/predicates/size/fixed_spec.rb +0 -398
  182. data/spec/integration/schema/predicates/size/range_spec.rb +0 -395
  183. data/spec/integration/schema/predicates/type_spec.rb +0 -413
  184. data/spec/integration/schema/reusing_schema_spec.rb +0 -33
  185. data/spec/integration/schema/using_types_spec.rb +0 -135
  186. data/spec/integration/schema/validate_spec.rb +0 -120
  187. data/spec/integration/schema/xor_spec.rb +0 -35
  188. data/spec/integration/schema_builders_spec.rb +0 -17
  189. data/spec/integration/schema_spec.rb +0 -173
  190. data/spec/shared/message_compiler.rb +0 -11
  191. data/spec/shared/predicate_helper.rb +0 -15
  192. data/spec/shared/rule_compiler.rb +0 -8
  193. data/spec/spec_helper.rb +0 -62
  194. data/spec/support/define_struct.rb +0 -25
  195. data/spec/support/matchers.rb +0 -38
  196. data/spec/support/mutant.rb +0 -9
  197. data/spec/support/predicates_integration.rb +0 -7
  198. data/spec/unit/input_processor_compiler/json_spec.rb +0 -283
  199. data/spec/unit/input_processor_compiler/params_spec.rb +0 -328
  200. data/spec/unit/message_compiler/visit_failure_spec.rb +0 -38
  201. data/spec/unit/message_compiler/visit_spec.rb +0 -16
  202. data/spec/unit/message_compiler_spec.rb +0 -7
  203. data/spec/unit/predicate_registry_spec.rb +0 -34
  204. data/spec/unit/schema/key_spec.rb +0 -38
  205. data/spec/unit/schema/rule_spec.rb +0 -42
  206. data/spec/unit/schema/value_spec.rb +0 -131
  207. data/spec/unit/schema_spec.rb +0 -35
@@ -1,11 +0,0 @@
1
- RSpec.describe Dry::Validation::Schema, 'default settings' do
2
- subject(:schema) do
3
- Dry::Validation.Schema(build: false) do
4
- required(:name).filled
5
- end
6
- end
7
-
8
- it 'uses :yaml messages by default' do
9
- expect(schema.config.messages).to be(:yaml)
10
- end
11
- end
@@ -1,41 +0,0 @@
1
- require 'dry/validation/messages/i18n'
2
- require 'i18n'
3
-
4
- RSpec.describe 'Defining base schema class' do
5
- subject(:schema) do
6
- Dry::Validation.Schema(BaseSchema) do
7
- required(:email).filled(:email?)
8
- end
9
- end
10
-
11
- before do
12
- class BaseSchema < Dry::Validation::Schema
13
- configure do |config|
14
- config.messages_file = SPEC_ROOT.join('fixtures/locales/en.yml')
15
- config.messages = :i18n
16
- end
17
-
18
- def email?(value)
19
- true
20
- end
21
-
22
- define! do
23
- required(:name).filled
24
- end
25
- end
26
- end
27
-
28
- after do
29
- Object.send(:remove_const, :BaseSchema)
30
- end
31
-
32
- it 'inherits predicates' do
33
- expect(schema).to respond_to(:email?)
34
- end
35
-
36
- it 'inherits rules' do
37
- expect(schema.(name: nil).messages).to eql(
38
- name: ['must be filled'], email: ['is missing', 'must be an email']
39
- )
40
- end
41
- end
@@ -1,43 +0,0 @@
1
- RSpec.describe Dry::Validation::Schema, 'dynamic predicate args' do
2
- context 'with base rules' do
3
- subject(:schema) do
4
- Dry::Validation.Schema do
5
- configure do
6
- def data
7
- %w(a b c)
8
- end
9
- end
10
-
11
- required(:letter).filled(included_in?: data)
12
- end
13
- end
14
-
15
- it 'evaluates predicate arguments' do
16
- expect(schema.(letter: 'a')).to be_success
17
- expect(schema.(letter: 'f')).to be_failure
18
- end
19
- end
20
-
21
- context 'with high-level rules' do
22
- subject(:schema) do
23
- Dry::Validation.Schema do
24
- configure do
25
- def data
26
- %w(a b c)
27
- end
28
- end
29
-
30
- required(:letter).filled(:str?)
31
-
32
- rule(valid_letter: [:letter]) do |letter|
33
- letter.included_in?(data)
34
- end
35
- end
36
- end
37
-
38
- it 'evaluates predicate arguments' do
39
- expect(schema.(letter: 'a')).to be_success
40
- expect(schema.(letter: 'f')).to be_failure
41
- end
42
- end
43
- end
@@ -1,70 +0,0 @@
1
- RSpec.describe 'Schema with each and set rules' do
2
- subject(:schema) do
3
- Dry::Validation.Schema do
4
- required(:payments).each do
5
- required(:method).filled(:str?)
6
- required(:amount).filled(:float?)
7
- end
8
- end
9
- end
10
-
11
- describe '#messages' do
12
- it 'validates using all rules' do
13
- expect(schema.(payments: [{}]).messages).to eql(
14
- { payments: {
15
- 0 => { method: ['is missing'], amount: ['is missing'] }
16
- }}
17
- )
18
- end
19
-
20
- it 'validates each payment against its set of rules' do
21
- input = {
22
- payments: [
23
- { method: 'cc', amount: 1.23 },
24
- { method: 'wire', amount: 4.56 }
25
- ]
26
- }
27
-
28
- expect(schema.(input).messages).to eql({})
29
- end
30
-
31
- it 'validates presence of the method key for each payment' do
32
- input = {
33
- payments: [
34
- { method: 'cc', amount: 1.23 },
35
- { amount: 4.56 }
36
- ]
37
- }
38
-
39
- expect(schema.(input).messages).to eql(
40
- payments: { 1 => { method: ['is missing'] } }
41
- )
42
- end
43
-
44
- it 'validates type of the method value for each payment' do
45
- input = {
46
- payments: [
47
- { method: 'cc', amount: 1.23 },
48
- { method: 12, amount: 4.56 }
49
- ]
50
- }
51
-
52
- expect(schema.(input).messages).to eql(
53
- payments: { 1 => { method: ['must be a string'] } }
54
- )
55
- end
56
-
57
- it 'validates type of the amount value for each payment' do
58
- input = {
59
- payments: [
60
- { method: 'cc', amount: 1.23 },
61
- { method: 'wire', amount: '4.56' }
62
- ]
63
- }
64
-
65
- expect(schema.(input).messages).to eql(
66
- payments: { 1 => { amount: ['must be a float'] } }
67
- )
68
- end
69
- end
70
- end
@@ -1,27 +0,0 @@
1
- RSpec.describe 'Extending DSL' do
2
- it 'allows configuring custom DSL methods' do
3
- dsl_ext = Module.new do
4
- def maybe_int(name, *predicates, &block)
5
- required(name, [:nil, :integer]).maybe(:int?, *predicates, &block)
6
- end
7
- end
8
-
9
- Dry::Validation::Schema.configure do |config|
10
- config.dsl_extensions = dsl_ext
11
- end
12
-
13
- schema = Dry::Validation.Schema do
14
- configure do
15
- config.input_processor = :params
16
- config.type_specs = true
17
- end
18
-
19
- maybe_int(:age)
20
- end
21
-
22
- expect(schema.(age: nil)).to be_success
23
- expect(schema.(age: 1)).to be_success
24
- expect(schema.(age: '1')).to be_success
25
- expect(schema.(age: 'foo').messages).to eql(age: ['must be an integer'])
26
- end
27
- end
@@ -1,236 +0,0 @@
1
- RSpec.describe 'Dry::Validation::Schema::Form', 'defining a schema' do
2
- before(:all) { require 'dry/validation/compat/form' }
3
-
4
- subject(:schema) do
5
- Dry::Validation.Form do
6
- configure do
7
- def email?(value)
8
- true
9
- end
10
- end
11
-
12
- required(:email).filled
13
-
14
- required(:age).maybe(:int?, gt?: 18)
15
-
16
- required(:address).schema do
17
- required(:city).filled
18
- required(:street).filled
19
-
20
- required(:loc).schema do
21
- required(:lat).filled(:float?)
22
- required(:lng).filled(:float?)
23
- end
24
- end
25
-
26
- optional(:password).maybe.confirmation
27
-
28
- optional(:phone_number).maybe(:int?, gt?: 0)
29
-
30
- rule(:email_valid) { value(:email).email? }
31
- end
32
- end
33
-
34
- describe '#messages' do
35
- it 'returns compiled error messages' do
36
- result = schema.('email' => '', 'age' => '19')
37
-
38
- expect(result.messages).to eql(
39
- email: ['must be filled'],
40
- address: ['is missing']
41
- )
42
-
43
- expect(result.output).to eql(email: '', age: 19)
44
- end
45
-
46
- it 'returns hints for nested data' do
47
- result = schema.(
48
- 'email' => 'jane@doe.org',
49
- 'age' => '19',
50
- 'address' => {
51
- 'city' => '',
52
- 'street' => 'Street 1/2',
53
- 'loc' => { 'lat' => '123.456', 'lng' => '' }
54
- }
55
- )
56
-
57
- expect(result.messages).to eql(
58
- address: {
59
- loc: { lng: ['must be filled'] },
60
- city: ['must be filled']
61
- }
62
- )
63
- end
64
- end
65
-
66
- describe '#call' do
67
- it 'passes when attributes are valid' do
68
- result = schema.(
69
- 'email' => 'jane@doe.org',
70
- 'age' => '19',
71
- 'address' => {
72
- 'city' => 'NYC',
73
- 'street' => 'Street 1/2',
74
- 'loc' => { 'lat' => '123.456', 'lng' => '456.123' }
75
- }
76
- )
77
-
78
- expect(result).to be_success
79
-
80
- expect(result.output).to eql(
81
- email: 'jane@doe.org', age: 19,
82
- address: {
83
- city: 'NYC', street: 'Street 1/2',
84
- loc: { lat: 123.456, lng: 456.123 }
85
- }
86
- )
87
- end
88
-
89
- it 'validates presence of an email and min age value' do
90
- result = schema.('email' => '', 'age' => '18')
91
-
92
- expect(result.messages).to eql(
93
- address: ['is missing'],
94
- age: ['must be greater than 18'],
95
- email: ['must be filled']
96
- )
97
- end
98
-
99
- it 'handles optionals' do
100
- result = schema.(
101
- 'email' => 'jane@doe.org',
102
- 'age' => '19',
103
- 'phone_number' => '12',
104
- 'address' => {
105
- 'city' => 'NYC',
106
- 'street' => 'Street 1/2',
107
- 'loc' => { 'lat' => '123.456', 'lng' => '456.123' }
108
- }
109
- )
110
-
111
- expect(result).to be_success
112
-
113
- expect(result.output).to eql(
114
- email: 'jane@doe.org', age: 19, phone_number: 12,
115
- address: {
116
- city: 'NYC', street: 'Street 1/2',
117
- loc: { lat: 123.456, lng: 456.123 }
118
- }
119
- )
120
- end
121
- end
122
-
123
- describe 'with an each and nested schema' do
124
- subject(:schema) do
125
- Dry::Validation.Form do
126
- required(:items).each do
127
- schema do
128
- required(:title).filled(:str?)
129
- end
130
- end
131
- end
132
- end
133
-
134
- it 'passes when each element passes schema check' do
135
- expect(schema.(items: [{ title: 'Foo' }])).to be_success
136
- end
137
-
138
- it 'fails when one or more elements did not pass schema check' do
139
- expect(schema.(items: [{ title: 'Foo' }, { title: :Foo }]).messages).to eql(
140
- items: { 1 => { title: ['must be a string'] } }
141
- )
142
- end
143
- end
144
-
145
- describe 'symbolizing keys when coercion fails' do
146
- subject(:schema) do
147
- Dry::Validation.Form do
148
- required(:email).value(size?: 8..60)
149
- required(:birthdate).value(:date?)
150
- required(:age).value(:int?, gt?: 23)
151
- required(:tags).maybe(max_size?: 3)
152
- end
153
- end
154
-
155
- let(:tags) { %(al b c) }
156
-
157
- it 'symbolizes keys and coerces values' do
158
- result = schema.(
159
- 'email' => 'jane@doe.org',
160
- 'birthdate' => '2001-02-03',
161
- 'age' => '24',
162
- 'tags' => tags
163
- ).to_h
164
-
165
- expect(result.to_h).to eql(
166
- email: 'jane@doe.org',
167
- birthdate: Date.new(2001, 2, 3),
168
- age: 24,
169
- tags: tags
170
- )
171
- end
172
-
173
- it 'symbolizes keys even when coercion fails' do
174
- result = schema.(
175
- 'email' => 'jane@doe.org',
176
- 'birthdate' => '2001-sutin-03',
177
- 'age' => ['oops'],
178
- 'tags' => nil
179
- )
180
-
181
- expect(result.to_h).to eql(
182
- email: 'jane@doe.org',
183
- birthdate: '2001-sutin-03',
184
- age: ['oops'],
185
- tags: nil
186
- )
187
-
188
- expect(result.messages).to eql(
189
- birthdate: ['must be a date'],
190
- age: ['must be an integer', 'must be greater than 23']
191
- )
192
- end
193
- end
194
-
195
- describe 'with nested schema in a high-level rule' do
196
- subject(:schema) do
197
- Dry::Validation.Form do
198
- required(:address).maybe(:hash?)
199
-
200
- required(:delivery).filled(:bool?)
201
-
202
- rule(address: [:delivery, :address]) do |delivery, address|
203
- delivery.true?.then(address.schema(AddressSchema))
204
- end
205
- end
206
- end
207
-
208
- before do
209
- AddressSchema = Dry::Validation.Form do
210
- required(:city).filled
211
- required(:zipcode).filled(:int?)
212
- end
213
- end
214
-
215
- after do
216
- Object.send(:remove_const, :AddressSchema)
217
- end
218
-
219
- it 'succeeds when nested form schema succeeds' do
220
- result = schema.(delivery: '1', address: { city: 'NYC', zipcode: '123' })
221
- expect(result).to be_success
222
- end
223
-
224
- it 'does not apply schema when there is no match' do
225
- result = schema.(delivery: '0', address: nil)
226
- expect(result).to be_success
227
- end
228
-
229
- it 'fails when nested schema fails' do
230
- result = schema.(delivery: '1', address: { city: 'NYC', zipcode: 'foo' })
231
- expect(result.messages).to eql(
232
- address: { zipcode: ['must be an integer'] }
233
- )
234
- end
235
- end
236
- end
@@ -1,47 +0,0 @@
1
- RSpec.describe Dry::Validation::Schema, 'for a hash' do
2
- context 'without type specs' do
3
- subject(:schema) do
4
- Dry::Validation.Schema do
5
- hash? do
6
- required(:prefix).filled
7
- required(:value).filled
8
- end
9
- end
10
- end
11
-
12
- it 'applies its rules to array input' do
13
- result = schema.(prefix: 1, value: 123)
14
-
15
- expect(result).to be_success
16
-
17
- result = schema.(prefix: 1, value: nil)
18
-
19
- expect(result.messages).to eql(value: ["must be filled"])
20
- end
21
- end
22
-
23
- context 'with type specs' do
24
- subject(:schema) do
25
- Dry::Validation.Params do
26
- configure { config.type_specs = true }
27
-
28
- hash? do
29
- required(:prefix, :integer).filled
30
- required(:value, :integer).filled
31
- end
32
- end
33
- end
34
-
35
- it 'applies its rules to coerced array input' do
36
- result = schema.(prefix: 1, value: '123')
37
-
38
- expect(result).to be_success
39
-
40
- expect(result.output).to eql(prefix: 1, value: 123)
41
-
42
- result = schema.(prefix: 1, value: nil)
43
-
44
- expect(result.messages).to eql(value: ["must be filled"])
45
- end
46
- end
47
- end
@@ -1,31 +0,0 @@
1
- RSpec.describe 'Inheriting schema' do
2
- subject(:schema) do
3
- Dry::Validation.Schema(base_schema) do
4
- required(:location).schema do
5
- required(:lat).filled(:float?)
6
- required(:lng).filled(:float?)
7
- end
8
- end
9
- end
10
-
11
- let(:base_schema) do
12
- Dry::Validation.Schema do
13
- required(:city).filled
14
- end
15
- end
16
-
17
- it 'inherits rules from parent schema' do
18
- expect(schema.(city: 'NYC', location: { lat: 1.23, lng: 45.6 })).to be_success
19
-
20
- expect(schema.(city: '', location: { lat: 1.23, lng: 45.6 }).messages).to eql(
21
- city: ['must be filled']
22
- )
23
-
24
- expect(schema.(city: 'NYC', location: { lat: nil, lng: '45.6' }).messages).to eql(
25
- location: {
26
- lat: ['must be filled'],
27
- lng: ['must be a float']
28
- }
29
- )
30
- end
31
- end
@@ -1,46 +0,0 @@
1
- RSpec.describe Dry::Validation::Schema, 'setting input processor in schema' do
2
- subject(:schema) do
3
- Dry::Validation.Schema do
4
- configure do
5
- config.input_processor = :sanitizer
6
- end
7
-
8
- required(:email).filled
9
-
10
- required(:age).maybe(:int?, gt?: 18)
11
-
12
- required(:address).schema do
13
- required(:city).filled
14
- required(:street).filled
15
- end
16
-
17
- required(:phone_numbers).each do
18
- required(:prefix).filled
19
- required(:value).filled
20
- end
21
- end
22
- end
23
-
24
- it 'rejects unspecified keys' do
25
- result = schema.(
26
- email: 'jane@doe',
27
- age: 19,
28
- such: 'key',
29
- address: { city: 'NYC', street: 'Street', wow: 'bad' },
30
- phone_numbers: [
31
- { prefix: '48', value: '123' },
32
- { lol: '!!', prefix: '1', value: '312' }
33
- ]
34
- )
35
-
36
- expect(result.output).to eql(
37
- email: 'jane@doe',
38
- age: 19,
39
- address: { city: 'NYC', street: 'Street' },
40
- phone_numbers: [
41
- { prefix: '48', value: '123' },
42
- { prefix: '1', value: '312' }
43
- ]
44
- )
45
- end
46
- end