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,157 +0,0 @@
1
- RSpec.describe Dry::Validation::Schema::JSON, 'explicit types' do
2
- context 'single type spec without rules' do
3
- subject(:schema) do
4
- Dry::Validation.JSON do
5
- configure { config.type_specs = true }
6
- required(:bdate, :date)
7
- end
8
- end
9
-
10
- it 'uses json coercion' do
11
- expect(schema.('bdate' => '2010-09-08').to_h).to eql(bdate: Date.new(2010, 9, 8))
12
- end
13
- end
14
-
15
- context 'single type spec with rules' do
16
- subject(:schema) do
17
- Dry::Validation.JSON do
18
- configure { config.type_specs = true }
19
- required(:bdate, :date).value(:date?, gt?: Date.new(2009))
20
- end
21
- end
22
-
23
- it 'applies rules to coerced value' do
24
- expect(schema.(bdate: "2010-09-07").messages).to be_empty
25
- expect(schema.(bdate: "2008-01-01").messages).to eql(bdate: ['must be greater than 2009-01-01'])
26
- end
27
- end
28
-
29
- context 'sum type spec without rules' do
30
- subject(:schema) do
31
- Dry::Validation.JSON do
32
- configure { config.type_specs = true }
33
- required(:bdate, [:nil, :date])
34
- end
35
- end
36
-
37
- it 'uses form coercion' do
38
- expect(schema.('bdate' => '2010-09-08').to_h).to eql(bdate: Date.new(2010, 9, 8))
39
- expect(schema.('bdate' => '').to_h).to eql(bdate: nil)
40
- end
41
- end
42
-
43
- context 'sum type spec with rules' do
44
- subject(:schema) do
45
- Dry::Validation.JSON do
46
- configure { config.type_specs = true }
47
- required(:bdate, [:nil, :date]).maybe(:date?, gt?: Date.new(2008))
48
- end
49
- end
50
-
51
- it 'applies rules to coerced value' do
52
- expect(schema.(bdate: nil).messages).to be_empty
53
- expect(schema.(bdate: "2010-09-07").messages).to be_empty
54
- expect(schema.(bdate: "2008-01-01").messages).to eql(bdate: ['must be greater than 2008-01-01'])
55
- end
56
- end
57
-
58
- context 'using a type object' do
59
- subject(:schema) do
60
- Dry::Validation.JSON do
61
- configure { config.type_specs = true }
62
- required(:bdate, Types::JSON::Nil | Types::JSON::Date)
63
- end
64
- end
65
-
66
- it 'uses form coercion' do
67
- expect(schema.('bdate' => '').to_h).to eql(bdate: nil)
68
- expect(schema.('bdate' => '2010-09-08').to_h).to eql(bdate: Date.new(2010, 9, 8))
69
- end
70
- end
71
-
72
- context 'nested schema' do
73
- subject(:schema) do
74
- Dry::Validation.JSON do
75
- configure { config.type_specs = true }
76
-
77
- required(:user).schema do
78
- required(:email, :string)
79
- required(:bdate, :date)
80
-
81
- required(:address).schema do
82
- required(:street, :string)
83
- required(:city, :string)
84
- required(:zipcode, :string)
85
-
86
- required(:location).schema do
87
- required(:lat, :float)
88
- required(:lng, :float)
89
- end
90
- end
91
- end
92
- end
93
- end
94
-
95
- it 'uses form coercion for nested input' do
96
- input = {
97
- 'user' => {
98
- 'email' => 'jane@doe.org',
99
- 'bdate' => '2010-09-08',
100
- 'address' => {
101
- 'street' => 'Street 1',
102
- 'city' => 'NYC',
103
- 'zipcode' => '1234',
104
- 'location' => { 'lat' => 1.23, 'lng' => 4.56 }
105
- }
106
- }
107
- }
108
-
109
- expect(schema.(input).to_h).to eql(
110
- user: {
111
- email: 'jane@doe.org',
112
- bdate: Date.new(2010, 9, 8),
113
- address: {
114
- street: 'Street 1',
115
- city: 'NYC',
116
- zipcode: '1234',
117
- location: { lat: 1.23, lng: 4.56 }
118
- }
119
- }
120
- )
121
- end
122
- end
123
-
124
- context 'nested schema with arrays' do
125
- subject(:schema) do
126
- Dry::Validation.JSON do
127
- configure { config.type_specs = true }
128
-
129
- required(:song).schema do
130
- required(:title, :string)
131
-
132
- required(:tags).each do
133
- schema do
134
- required(:name, :string)
135
- end
136
- end
137
- end
138
- end
139
- end
140
-
141
- it 'uses form coercion for nested input' do
142
- input = {
143
- 'song' => {
144
- 'title' => 'dry-rb is awesome lala',
145
- 'tags' => [{ 'name' => 'red' }, { 'name' => 'blue' }]
146
- }
147
- }
148
-
149
- expect(schema.(input).to_h).to eql(
150
- song: {
151
- title: 'dry-rb is awesome lala',
152
- tags: [{ name: 'red' }, { name: 'blue' }]
153
- }
154
- )
155
- end
156
- end
157
- end
@@ -1,163 +0,0 @@
1
- RSpec.describe Dry::Validation::Schema::JSON, 'defining a schema' do
2
- subject(:schema) do
3
- Dry::Validation.JSON do
4
- configure do
5
- def email?(value)
6
- true
7
- end
8
- end
9
-
10
- required(:email).filled
11
-
12
- required(:age).maybe(:int?, gt?: 18)
13
-
14
- required(:address).schema do
15
- required(:city).filled
16
- required(:street).filled
17
-
18
- required(:loc).schema do
19
- required(:lat).filled(:float?)
20
- required(:lng).filled(:float?)
21
- end
22
- end
23
-
24
- optional(:password).maybe.confirmation
25
-
26
- optional(:phone_number).maybe(:int?, gt?: 0)
27
-
28
- rule(:email_valid) { value(:email).email? }
29
- end
30
- end
31
-
32
- describe '#messages' do
33
- it 'returns compiled error messages' do
34
- result = schema.('email' => '', 'age' => 19)
35
-
36
- expect(result.messages).to eql(
37
- email: ['must be filled'],
38
- address: ['is missing'],
39
- )
40
-
41
- expect(result.output).to eql(email: '', age: 19)
42
- end
43
-
44
- it 'returns hints for nested data' do
45
- result = schema.(
46
- 'email' => 'jane@doe.org',
47
- 'age' => 19,
48
- 'address' => {
49
- 'city' => '',
50
- 'street' => 'Street 1/2',
51
- 'loc' => { 'lat' => '123.456', 'lng' => '' }
52
- }
53
- )
54
-
55
- expect(result.messages).to eql(
56
- address: {
57
- loc: { lat: ['must be a float'], lng: ['must be filled'] },
58
- city: ['must be filled']
59
- }
60
- )
61
- end
62
- end
63
-
64
- describe '#call' do
65
- it 'passes when attributes are valid' do
66
- result = schema.(
67
- 'email' => 'jane@doe.org',
68
- 'age' => 19,
69
- 'address' => {
70
- 'city' => 'NYC',
71
- 'street' => 'Street 1/2',
72
- 'loc' => { 'lat' => 123.456, 'lng' => 456.123 }
73
- }
74
- )
75
-
76
- expect(result).to be_success
77
-
78
- expect(result.output).to eql(
79
- email: 'jane@doe.org', age: 19,
80
- address: {
81
- city: 'NYC', street: 'Street 1/2',
82
- loc: { lat: 123.456, lng: 456.123 }
83
- }
84
- )
85
- end
86
-
87
- it 'validates presence of an email and min age value' do
88
- result = schema.('email' => '', 'age' => 18)
89
-
90
- expect(result.messages).to eql(
91
- address: ['is missing'],
92
- age: ['must be greater than 18'],
93
- email: ['must be filled']
94
- )
95
- end
96
-
97
- it 'handles optionals' do
98
- result = schema.(
99
- 'email' => 'jane@doe.org',
100
- 'age' => 19,
101
- 'phone_number' => 12,
102
- 'address' => {
103
- 'city' => 'NYC',
104
- 'street' => 'Street 1/2',
105
- 'loc' => { 'lat' => 123.456, 'lng' => 456.123 }
106
- }
107
- )
108
-
109
- expect(result).to be_success
110
-
111
- expect(result.output).to eql(
112
- email: 'jane@doe.org', age: 19, phone_number: 12,
113
- address: {
114
- city: 'NYC', street: 'Street 1/2',
115
- loc: { lat: 123.456, lng: 456.123 }
116
- }
117
- )
118
- end
119
- end
120
-
121
- describe 'with nested schema in a high-level rule' do
122
- subject(:schema) do
123
- Dry::Validation.JSON do
124
- required(:address).maybe(:hash?)
125
-
126
- required(:delivery).filled(:bool?)
127
-
128
- rule(address: [:delivery, :address]) do |delivery, address|
129
- delivery.true?.then(address.schema(AddressSchema))
130
- end
131
- end
132
- end
133
-
134
- before do
135
- AddressSchema = Dry::Validation.JSON do
136
- required(:city).filled
137
- required(:zipcode).filled(:int?)
138
- end
139
- end
140
-
141
- after do
142
- Object.send(:remove_const, :AddressSchema)
143
- end
144
-
145
- it 'succeeds when nested form schema succeeds' do
146
- result = schema.(delivery: true, address: { city: 'NYC', zipcode: 123 })
147
- expect(result).to be_success
148
- end
149
-
150
- it 'does not apply schema when there is no match' do
151
- result = schema.(delivery: false, address: nil)
152
- expect(result).to be_success
153
- end
154
-
155
- it 'fails when nested schema fails' do
156
- result = schema.(delivery: true, address: { city: 'NYC', zipcode: 'foo' })
157
-
158
- expect(result.messages).to eql(
159
- address: { zipcode: ['must be an integer'] }
160
- )
161
- end
162
- end
163
- end
@@ -1,35 +0,0 @@
1
- RSpec.describe 'Macros #confirmation' do
2
- describe 'with a maybe password with min-size specified' do
3
- subject(:schema) do
4
- Dry::Validation.Schema do
5
- configure do
6
- config.input_processor = :sanitizer
7
-
8
- def self.messages
9
- Messages.default.merge(
10
- en: { errors: { password_confirmation: 'does not match' } }
11
- )
12
- end
13
- end
14
-
15
- required(:password).maybe(min_size?: 3).confirmation
16
- end
17
- end
18
-
19
- it 'passes when values are equal' do
20
- expect(schema.(password: 'foo', password_confirmation: 'foo')).to be_success
21
- end
22
-
23
- it 'fails when source value is invalid' do
24
- expect(schema.(password: 'fo', password_confirmation: nil).messages).to eql(
25
- password: ['size cannot be less than 3']
26
- )
27
- end
28
-
29
- it 'fails when values are not equal' do
30
- expect(schema.(password: 'foo', password_confirmation: 'fo').messages).to eql(
31
- password_confirmation: ['does not match']
32
- )
33
- end
34
- end
35
- end
@@ -1,268 +0,0 @@
1
- RSpec.describe 'Macros #each' do
2
- context "predicate without options" do
3
- subject(:schema) do
4
- Dry::Validation.Schema do
5
- required(:foo).each(:filled?, :str?)
6
- end
7
- end
8
-
9
- context 'with valid input' do
10
- let(:input) { { foo: %w(a b c) } }
11
-
12
- it 'is successful' do
13
- expect(result).to be_successful
14
- end
15
- end
16
-
17
- context 'with invalid input' do
18
- let(:input) { { foo: [[1, 2], "", "foo"] } }
19
-
20
- it 'is not successful' do
21
- expect(result).to be_failing(0 => ["must be a string"], 1 => ["must be filled"])
22
- end
23
- end
24
-
25
- context 'with invalid input type' do
26
- let(:input) { { foo: nil } }
27
-
28
- it 'is not successful' do
29
- expect(result).to be_failing ["must be an array"]
30
- end
31
- end
32
- end
33
-
34
- context "predicate with options" do
35
- subject(:schema) do
36
- Dry::Validation.Schema do
37
- required(:foo).each(size?: 3)
38
- end
39
- end
40
-
41
- context 'with valid input' do
42
- let(:input) { { foo: [[1,2,3], "foo"] } }
43
-
44
- it 'is successful' do
45
- expect(result).to be_successful
46
- end
47
- end
48
-
49
- context 'with invalid input' do
50
- let(:input) { { foo: [[1,2], "foo"] } }
51
-
52
- it 'is not successful' do
53
- expect(result).to be_failing(0 => ["size must be 3"])
54
- end
55
- end
56
-
57
- context 'with invalid input type' do
58
- let(:input) { { foo: nil } }
59
-
60
- it 'is not successful' do
61
- expect(result).to be_failing ["must be an array"]
62
- end
63
- end
64
- end
65
-
66
- context 'with filled macro' do
67
- subject(:schema) do
68
- Dry::Validation.Schema do
69
- required(:foo).filled(size?: 2) { each(:str?) }
70
- end
71
- end
72
-
73
- context 'with valid input' do
74
- let(:input) { { foo: %w(a b) } }
75
-
76
- it 'is successful' do
77
- expect(result).to be_successful
78
- end
79
- end
80
-
81
- context 'when value is not valid' do
82
- let(:input) { { foo: ["foo"] } }
83
-
84
- it 'is not successful' do
85
- expect(result).to be_failing(["size must be 2"])
86
- end
87
- end
88
-
89
- context 'when value has invalid elements' do
90
- let(:input) { { foo: [:foo, "foo"] } }
91
-
92
- it 'is not successful' do
93
- expect(result).to be_failing(0 => ["must be a string"])
94
- end
95
- end
96
- end
97
-
98
- context 'with maybe macro' do
99
- subject(:schema) do
100
- Dry::Validation.Schema do
101
- required(:foo).maybe { each(:str?) }
102
- end
103
- end
104
-
105
- context 'with nil input' do
106
- let(:input) { { foo: nil } }
107
-
108
- it 'is successful' do
109
- expect(result).to be_successful
110
- end
111
- end
112
-
113
- context 'with valid input' do
114
- let(:input) { { foo: %w(a b c) } }
115
-
116
- it 'is successful' do
117
- expect(result).to be_successful
118
- end
119
- end
120
-
121
- context 'with invalid input' do
122
- let(:input) { { foo: [:foo, "foo"] } }
123
-
124
- it 'is not successful' do
125
- expect(result).to be_failing(0 => ["must be a string"])
126
- end
127
- end
128
- end
129
-
130
- context 'with external schema macro' do
131
- subject(:schema) do
132
- Dry::Validation.Schema do
133
- required(:foo).each(FooSchema)
134
- end
135
- end
136
-
137
- before do
138
- FooSchema = Dry::Validation.Schema do
139
- required(:bar).filled(:str?)
140
- end
141
- end
142
-
143
- after do
144
- Object.send(:remove_const, :FooSchema)
145
- end
146
-
147
- context 'with valid input' do
148
- let(:input) { { foo: [{ bar: "baz" }] } }
149
-
150
- it 'is successful' do
151
- expect(result).to be_successful
152
- end
153
- end
154
-
155
- context 'when value is not valid' do
156
- let(:input) { { foo: [{ bar: 1 }] } }
157
-
158
- it 'is not successful' do
159
- # FIXME: our be_failing didn't work with such nested wow hash
160
- expect(result.messages).to eql(foo: { 0 => { bar: ["must be a string"] } })
161
- end
162
- end
163
- end
164
-
165
- context 'with a block' do
166
- context 'with a nested schema' do
167
- subject(:schema) do
168
- Dry::Validation.Schema do
169
- required(:songs).each do
170
- schema do
171
- required(:title).filled
172
- required(:author).filled
173
- end
174
- end
175
- end
176
- end
177
-
178
- it 'passes when all elements are valid' do
179
- songs = [
180
- { title: 'Hello', author: 'Jane' },
181
- { title: 'World', author: 'Joe' }
182
- ]
183
-
184
- expect(schema.(songs: songs)).to be_success
185
- end
186
-
187
- it 'fails when value is not an array' do
188
- expect(schema.(songs: 'oops').messages).to eql(songs: ['must be an array'])
189
- end
190
-
191
- it 'fails when not all elements are valid' do
192
- songs = [
193
- { title: 'Hello', author: 'Jane' },
194
- { title: nil, author: 'Joe' },
195
- { title: 'World', author: nil },
196
- { title: nil, author: nil }
197
- ]
198
-
199
- expect(schema.(songs: songs).messages).to eql(
200
- songs: {
201
- 1 => { title: ['must be filled'] },
202
- 2 => { author: ['must be filled'] },
203
- 3 => { title: ['must be filled'], author: ['must be filled'] }
204
- }
205
- )
206
- end
207
- end
208
- end
209
-
210
- context 'with inferred predicates and a form schema' do
211
- context "predicate w/o options" do
212
- subject(:schema) do
213
- Dry::Validation.Params do
214
- required(:songs).each(:str?)
215
- end
216
- end
217
-
218
- it 'passes when all elements are valid' do
219
- songs = %w(hello world)
220
-
221
- expect(schema.(songs: songs)).to be_success
222
- end
223
-
224
- it 'fails when value is not an array' do
225
- expect(schema.(songs: 'oops').messages).to eql(songs: ['must be an array'])
226
- end
227
-
228
- it 'fails when not all elements are valid' do
229
- songs = ['hello', nil, 2]
230
-
231
- expect(schema.(songs: songs).messages).to eql(
232
- songs: {
233
- 1 => ['must be a string'],
234
- 2 => ['must be a string']
235
- }
236
- )
237
- end
238
- end
239
- end
240
-
241
- context 'with a custom predicate' do
242
- subject(:schema) do
243
- Dry::Validation.Schema do
244
- configure do
245
- def self.messages
246
- super.merge(en: { errors: { valid_content?: 'must have type key' }})
247
- end
248
-
249
- def valid_content?(content)
250
- content.key?(:type)
251
- end
252
- end
253
-
254
- required(:contents).each(:valid_content?)
255
- end
256
- end
257
-
258
- it 'passes when all elements are valid' do
259
- expect(schema.(contents: [{ type: 'foo' }, { type: 'bar' }]))
260
- end
261
-
262
- it 'fails when some elements are not valid' do
263
- expect(schema.(contents: [{ type: 'foo' }, { oops: 'bar' }]).errors).to eql(
264
- contents: { 1 => ['must have type key']}
265
- )
266
- end
267
- end
268
- end
@@ -1,87 +0,0 @@
1
- RSpec.describe 'Macros #filled' do
2
- describe 'with no args' do
3
- subject(:schema) do
4
- Dry::Validation.Schema do
5
- required(:email).filled
6
- end
7
- end
8
-
9
- it 'generates filled? rule' do
10
- expect(schema.(email: '').messages).to eql(
11
- email: ['must be filled']
12
- )
13
- end
14
- end
15
-
16
- describe 'with a type specification' do
17
- subject(:schema) do
18
- Dry::Validation.Schema do
19
- required(:age).filled(:int?)
20
- end
21
- end
22
-
23
- it 'generates filled? & int? rule' do
24
- expect(schema.(age: nil).messages).to eql(
25
- age: ['must be filled']
26
- )
27
- end
28
- end
29
-
30
- describe 'with a predicate with args' do
31
- context 'with a flat arg' do
32
- subject(:schema) do
33
- Dry::Validation.Schema do
34
- required(:age).filled(:int?, gt?: 18)
35
- end
36
- end
37
-
38
- it 'generates filled? & int? & gt? rule' do
39
- expect(schema.(age: nil).messages).to eql(
40
- age: ['must be filled', 'must be greater than 18']
41
- )
42
- end
43
- end
44
-
45
- context 'with a range arg' do
46
- subject(:schema) do
47
- Dry::Validation.Schema do
48
- required(:age).filled(:int?, size?: 18..24)
49
- end
50
- end
51
-
52
- it 'generates filled? & int? & size? rule' do
53
- expect(schema.(age: nil).messages).to eql(
54
- age: ['must be filled', 'size must be within 18 - 24']
55
- )
56
- end
57
- end
58
-
59
- context 'with a block' do
60
- subject(:schema) do
61
- Dry::Validation.Schema do
62
- required(:age).filled { int? & size?(18..24) }
63
- end
64
- end
65
-
66
- it 'generates filled? & int? & size? rule' do
67
- expect(schema.(age: nil).messages).to eql(
68
- age: ['must be filled', 'size must be within 18 - 24']
69
- )
70
- end
71
- end
72
-
73
- context 'with a predicate and a block' do
74
- subject(:schema) do
75
- Dry::Validation.Schema do
76
- required(:age).filled(:int?) { size?(18..24) }
77
- end
78
- end
79
-
80
- it 'generates filled? & int? & size? rule' do
81
- expect(schema.(age: nil).messages).to eql(
82
- age: ['must be filled', 'size must be within 18 - 24']
83
- )
84
- end
85
- end
86
- end
87
- end