dry-validation 0.13.3 → 1.3.1

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 (206) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +233 -12
  3. data/LICENSE +1 -1
  4. data/README.md +13 -9
  5. data/config/errors.yml +3 -88
  6. data/lib/dry-validation.rb +2 -0
  7. data/lib/dry/validation.rb +47 -28
  8. data/lib/dry/validation/config.rb +24 -0
  9. data/lib/dry/validation/constants.rb +43 -0
  10. data/lib/dry/validation/contract.rb +160 -0
  11. data/lib/dry/validation/contract/class_interface.rb +223 -0
  12. data/lib/dry/validation/evaluator.rb +197 -0
  13. data/lib/dry/validation/extensions/hints.rb +69 -0
  14. data/lib/dry/validation/extensions/monads.rb +23 -7
  15. data/lib/dry/validation/extensions/predicates_as_macros.rb +75 -0
  16. data/lib/dry/validation/failures.rb +58 -0
  17. data/lib/dry/validation/function.rb +44 -0
  18. data/lib/dry/validation/macro.rb +38 -0
  19. data/lib/dry/validation/macros.rb +104 -0
  20. data/lib/dry/validation/message.rb +79 -79
  21. data/lib/dry/validation/message_set.rb +108 -88
  22. data/lib/dry/validation/messages/resolver.rb +79 -0
  23. data/lib/dry/validation/result.rb +154 -42
  24. data/lib/dry/validation/rule.rb +129 -0
  25. data/lib/dry/validation/schema_ext.rb +46 -0
  26. data/lib/dry/validation/values.rb +94 -0
  27. data/lib/dry/validation/version.rb +3 -1
  28. metadata +41 -336
  29. data/.codeclimate.yml +0 -17
  30. data/.gitignore +0 -9
  31. data/.rspec +0 -3
  32. data/.travis.yml +0 -29
  33. data/CONTRIBUTING.md +0 -31
  34. data/Gemfile +0 -25
  35. data/Rakefile +0 -22
  36. data/benchmarks/benchmark_form_invalid.rb +0 -64
  37. data/benchmarks/benchmark_form_valid.rb +0 -64
  38. data/benchmarks/benchmark_schema_invalid_huge.rb +0 -52
  39. data/benchmarks/profile_schema_call_invalid.rb +0 -20
  40. data/benchmarks/profile_schema_call_valid.rb +0 -20
  41. data/benchmarks/profile_schema_definition.rb +0 -14
  42. data/benchmarks/profile_schema_huge_invalid.rb +0 -30
  43. data/benchmarks/profile_schema_messages_invalid.rb +0 -20
  44. data/benchmarks/suite.rb +0 -5
  45. data/dry-validation.gemspec +0 -28
  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 -137
  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 -188
  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 -119
  65. data/lib/dry/validation/messages/i18n.rb +0 -47
  66. data/lib/dry/validation/messages/namespaced.rb +0 -39
  67. data/lib/dry/validation/messages/yaml.rb +0 -61
  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.rb +0 -126
  71. data/lib/dry/validation/schema/check.rb +0 -37
  72. data/lib/dry/validation/schema/class_interface.rb +0 -190
  73. data/lib/dry/validation/schema/deprecated.rb +0 -30
  74. data/lib/dry/validation/schema/dsl.rb +0 -118
  75. data/lib/dry/validation/schema/form.rb +0 -9
  76. data/lib/dry/validation/schema/json.rb +0 -21
  77. data/lib/dry/validation/schema/key.rb +0 -71
  78. data/lib/dry/validation/schema/params.rb +0 -22
  79. data/lib/dry/validation/schema/rule.rb +0 -202
  80. data/lib/dry/validation/schema/value.rb +0 -211
  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/spec/extensions/monads/result_spec.rb +0 -40
  85. data/spec/extensions/struct/schema_spec.rb +0 -32
  86. data/spec/fixtures/locales/en.yml +0 -8
  87. data/spec/fixtures/locales/pl.yml +0 -22
  88. data/spec/integration/custom_error_messages_spec.rb +0 -54
  89. data/spec/integration/custom_predicates_spec.rb +0 -228
  90. data/spec/integration/hints_spec.rb +0 -170
  91. data/spec/integration/injecting_rules_spec.rb +0 -30
  92. data/spec/integration/json/defining_base_schema_spec.rb +0 -41
  93. data/spec/integration/localized_error_messages_spec.rb +0 -72
  94. data/spec/integration/message_compiler_spec.rb +0 -405
  95. data/spec/integration/messages/i18n_spec.rb +0 -104
  96. data/spec/integration/optional_keys_spec.rb +0 -28
  97. data/spec/integration/params/predicates/array_spec.rb +0 -287
  98. data/spec/integration/params/predicates/empty_spec.rb +0 -263
  99. data/spec/integration/params/predicates/eql_spec.rb +0 -327
  100. data/spec/integration/params/predicates/even_spec.rb +0 -455
  101. data/spec/integration/params/predicates/excluded_from_spec.rb +0 -455
  102. data/spec/integration/params/predicates/excludes_spec.rb +0 -391
  103. data/spec/integration/params/predicates/false_spec.rb +0 -455
  104. data/spec/integration/params/predicates/filled_spec.rb +0 -467
  105. data/spec/integration/params/predicates/format_spec.rb +0 -454
  106. data/spec/integration/params/predicates/gt_spec.rb +0 -519
  107. data/spec/integration/params/predicates/gteq_spec.rb +0 -519
  108. data/spec/integration/params/predicates/included_in_spec.rb +0 -455
  109. data/spec/integration/params/predicates/includes_spec.rb +0 -391
  110. data/spec/integration/params/predicates/key_spec.rb +0 -67
  111. data/spec/integration/params/predicates/lt_spec.rb +0 -519
  112. data/spec/integration/params/predicates/lteq_spec.rb +0 -519
  113. data/spec/integration/params/predicates/max_size_spec.rb +0 -391
  114. data/spec/integration/params/predicates/min_size_spec.rb +0 -391
  115. data/spec/integration/params/predicates/none_spec.rb +0 -265
  116. data/spec/integration/params/predicates/not_eql_spec.rb +0 -327
  117. data/spec/integration/params/predicates/odd_spec.rb +0 -455
  118. data/spec/integration/params/predicates/size/fixed_spec.rb +0 -393
  119. data/spec/integration/params/predicates/size/range_spec.rb +0 -396
  120. data/spec/integration/params/predicates/true_spec.rb +0 -455
  121. data/spec/integration/params/predicates/type_spec.rb +0 -391
  122. data/spec/integration/result_spec.rb +0 -81
  123. data/spec/integration/schema/array_schema_spec.rb +0 -59
  124. data/spec/integration/schema/check_rules_spec.rb +0 -119
  125. data/spec/integration/schema/check_with_nested_el_spec.rb +0 -37
  126. data/spec/integration/schema/check_with_nth_el_spec.rb +0 -25
  127. data/spec/integration/schema/default_settings_spec.rb +0 -11
  128. data/spec/integration/schema/defining_base_schema_spec.rb +0 -41
  129. data/spec/integration/schema/dynamic_predicate_args_spec.rb +0 -43
  130. data/spec/integration/schema/each_with_set_spec.rb +0 -70
  131. data/spec/integration/schema/extending_dsl_spec.rb +0 -27
  132. data/spec/integration/schema/form_spec.rb +0 -236
  133. data/spec/integration/schema/hash_schema_spec.rb +0 -47
  134. data/spec/integration/schema/inheriting_schema_spec.rb +0 -31
  135. data/spec/integration/schema/input_processor_spec.rb +0 -46
  136. data/spec/integration/schema/json/explicit_types_spec.rb +0 -157
  137. data/spec/integration/schema/json_spec.rb +0 -163
  138. data/spec/integration/schema/macros/confirmation_spec.rb +0 -35
  139. data/spec/integration/schema/macros/each_spec.rb +0 -268
  140. data/spec/integration/schema/macros/filled_spec.rb +0 -87
  141. data/spec/integration/schema/macros/input_spec.rb +0 -139
  142. data/spec/integration/schema/macros/maybe_spec.rb +0 -99
  143. data/spec/integration/schema/macros/rule_spec.rb +0 -75
  144. data/spec/integration/schema/macros/value_spec.rb +0 -119
  145. data/spec/integration/schema/macros/when_spec.rb +0 -62
  146. data/spec/integration/schema/nested_schemas_spec.rb +0 -236
  147. data/spec/integration/schema/nested_values_spec.rb +0 -46
  148. data/spec/integration/schema/not_spec.rb +0 -34
  149. data/spec/integration/schema/numbers_spec.rb +0 -19
  150. data/spec/integration/schema/option_with_default_spec.rb +0 -64
  151. data/spec/integration/schema/or_spec.rb +0 -87
  152. data/spec/integration/schema/params/defining_base_schema_spec.rb +0 -41
  153. data/spec/integration/schema/params/explicit_types_spec.rb +0 -195
  154. data/spec/integration/schema/params_spec.rb +0 -234
  155. data/spec/integration/schema/predicate_verification_spec.rb +0 -9
  156. data/spec/integration/schema/predicates/array_spec.rb +0 -295
  157. data/spec/integration/schema/predicates/custom_spec.rb +0 -103
  158. data/spec/integration/schema/predicates/empty_spec.rb +0 -263
  159. data/spec/integration/schema/predicates/eql_spec.rb +0 -327
  160. data/spec/integration/schema/predicates/even_spec.rb +0 -455
  161. data/spec/integration/schema/predicates/excluded_from/array_spec.rb +0 -459
  162. data/spec/integration/schema/predicates/excluded_from/range_spec.rb +0 -459
  163. data/spec/integration/schema/predicates/excludes_spec.rb +0 -391
  164. data/spec/integration/schema/predicates/filled_spec.rb +0 -467
  165. data/spec/integration/schema/predicates/format_spec.rb +0 -455
  166. data/spec/integration/schema/predicates/gt_spec.rb +0 -519
  167. data/spec/integration/schema/predicates/gteq_spec.rb +0 -519
  168. data/spec/integration/schema/predicates/hash_spec.rb +0 -69
  169. data/spec/integration/schema/predicates/included_in/array_spec.rb +0 -459
  170. data/spec/integration/schema/predicates/included_in/range_spec.rb +0 -459
  171. data/spec/integration/schema/predicates/includes_spec.rb +0 -391
  172. data/spec/integration/schema/predicates/key_spec.rb +0 -88
  173. data/spec/integration/schema/predicates/lt_spec.rb +0 -520
  174. data/spec/integration/schema/predicates/lteq_spec.rb +0 -519
  175. data/spec/integration/schema/predicates/max_size_spec.rb +0 -391
  176. data/spec/integration/schema/predicates/min_size_spec.rb +0 -391
  177. data/spec/integration/schema/predicates/none_spec.rb +0 -265
  178. data/spec/integration/schema/predicates/not_eql_spec.rb +0 -391
  179. data/spec/integration/schema/predicates/odd_spec.rb +0 -455
  180. data/spec/integration/schema/predicates/size/fixed_spec.rb +0 -398
  181. data/spec/integration/schema/predicates/size/range_spec.rb +0 -395
  182. data/spec/integration/schema/predicates/type_spec.rb +0 -413
  183. data/spec/integration/schema/reusing_schema_spec.rb +0 -33
  184. data/spec/integration/schema/using_types_spec.rb +0 -135
  185. data/spec/integration/schema/validate_spec.rb +0 -120
  186. data/spec/integration/schema/xor_spec.rb +0 -35
  187. data/spec/integration/schema_builders_spec.rb +0 -17
  188. data/spec/integration/schema_spec.rb +0 -173
  189. data/spec/shared/message_compiler.rb +0 -11
  190. data/spec/shared/predicate_helper.rb +0 -15
  191. data/spec/shared/rule_compiler.rb +0 -8
  192. data/spec/spec_helper.rb +0 -62
  193. data/spec/support/define_struct.rb +0 -25
  194. data/spec/support/matchers.rb +0 -38
  195. data/spec/support/mutant.rb +0 -9
  196. data/spec/support/predicates_integration.rb +0 -7
  197. data/spec/unit/input_processor_compiler/json_spec.rb +0 -283
  198. data/spec/unit/input_processor_compiler/params_spec.rb +0 -328
  199. data/spec/unit/message_compiler/visit_failure_spec.rb +0 -38
  200. data/spec/unit/message_compiler/visit_spec.rb +0 -16
  201. data/spec/unit/message_compiler_spec.rb +0 -7
  202. data/spec/unit/predicate_registry_spec.rb +0 -34
  203. data/spec/unit/schema/key_spec.rb +0 -38
  204. data/spec/unit/schema/rule_spec.rb +0 -42
  205. data/spec/unit/schema/value_spec.rb +0 -131
  206. data/spec/unit/schema_spec.rb +0 -35
@@ -1,99 +0,0 @@
1
- RSpec.describe 'Macros #maybe' do
2
- describe 'with no args' do
3
- subject(:schema) do
4
- Dry::Validation.Schema do
5
- required(:email).maybe
6
- end
7
- end
8
-
9
- it 'generates none? | filled? rule' do
10
- expect(schema.(email: nil).messages).to be_empty
11
- expect(schema.(email: 'jane@doe').messages).to be_empty
12
- end
13
- end
14
-
15
- describe 'with a predicate with args' do
16
- subject(:schema) do
17
- Dry::Validation.Schema do
18
- required(:name).maybe(min_size?: 3)
19
- end
20
- end
21
-
22
- it 'generates none? | (filled? & min_size?) rule' do
23
- expect(schema.(name: nil).messages).to be_empty
24
-
25
- expect(schema.(name: 'jane').messages).to be_empty
26
-
27
- expect(schema.(name: 'xy').messages).to eql(
28
- name: ['size cannot be less than 3']
29
- )
30
- end
31
- end
32
-
33
- describe 'with a block' do
34
- subject(:schema) do
35
- Dry::Validation.Schema do
36
- required(:name).maybe { str? & min_size?(3) }
37
- end
38
- end
39
-
40
- it 'generates none? | (str? & min_size?) rule' do
41
- expect(schema.(name: nil).messages).to be_empty
42
-
43
- expect(schema.(name: 'jane').messages).to be_empty
44
-
45
- expect(schema.(name: 'xy').messages).to eql(
46
- name: ['size cannot be less than 3']
47
- )
48
- end
49
- end
50
-
51
- describe 'with an optional key and a block with schema' do
52
- subject(:schema) do
53
- Dry::Validation.Schema do
54
- optional(:employee).maybe do
55
- schema do
56
- required(:id).filled(:str?)
57
- end
58
- end
59
- end
60
- end
61
-
62
- it 'passes when input is valid' do
63
- expect(schema.(employee: { id: '1' })).to be_success
64
- end
65
-
66
- it 'passes when key is missing' do
67
- expect(schema.({})).to be_success
68
- end
69
-
70
- it 'passes when value is nil' do
71
- expect(schema.(employee: nil)).to be_success
72
- end
73
-
74
- it 'fails when value for nested schema is invalid' do
75
- expect(schema.(employee: { id: 1 }).messages).to eql(
76
- employee: { id: ['must be a string'] }
77
- )
78
- end
79
- end
80
-
81
- describe 'with a predicate and a block' do
82
- subject(:schema) do
83
- Dry::Validation.Schema do
84
- required(:name).maybe(:str?) { min_size?(3) }
85
- end
86
- end
87
-
88
- it 'generates none? | (str? & min_size?) rule' do
89
- expect(schema.(name: nil).messages).to be_empty
90
-
91
- expect(schema.(name: 'jane').messages).to be_empty
92
-
93
- expect(schema.(name: 'xy').messages).to eql(
94
- name: ['size cannot be less than 3']
95
- )
96
- end
97
- end
98
- end
99
-
@@ -1,75 +0,0 @@
1
- RSpec.describe 'Macros / rule' do
2
- shared_context 'password confirmation high-level rule' do
3
- subject(:schema) { schema_class.new }
4
-
5
- let(:schema_class) do
6
- Dry::Validation.Schema(build: false) do
7
- required(:user).schema do
8
- required(:password).filled
9
- required(:password_confirmation).filled
10
-
11
- rule(password_confirmation: %i[password_confirmation password]) do |pc, p|
12
- pc.eql?(p)
13
- end
14
- end
15
- end
16
- end
17
-
18
- it 'passes when input is valid' do
19
- expect(schema.(user: { password: 'foo', password_confirmation: 'foo' })).to be_successful
20
- end
21
-
22
- it 'fails when the rule failed' do
23
- expect(schema.(user: { password: 'foo', password_confirmation: 'bar' }).messages).to eql(
24
- user: { password_confirmation: [error_message] }
25
- )
26
- end
27
- end
28
-
29
- context 'with the default message' do
30
- let(:error_message) { 'must be equal to foo' }
31
-
32
- include_context 'password confirmation high-level rule'
33
- end
34
-
35
- context 'with a custom message' do
36
- let(:error_message) { 'does not match' }
37
-
38
- before do
39
- schema_class.class_eval do
40
- def self.messages
41
- default_messages.merge(en: { errors: { password_confirmation: 'does not match' } })
42
- end
43
- end
44
- end
45
-
46
- include_context 'password confirmation high-level rule'
47
- end
48
-
49
- context 'with two rules relying on the same value' do
50
- subject(:schema) do
51
- Dry::Validation.Schema do
52
- required(:x).filled(:int?)
53
-
54
- rule(a: [:x]) do |x|
55
- x.gt?(3)
56
- end
57
-
58
- rule(b: [:x]) do |x|
59
- x.gt?(5)
60
- end
61
- end
62
- end
63
-
64
- it 'passes when input is valid' do
65
- expect(schema.(x: 6)).to be_successful
66
- end
67
-
68
- it 'fails when rules failed' do
69
- expect(schema.(x: 2).messages).to eql(
70
- a: ['must be greater than 3'],
71
- b: ['must be greater than 5']
72
- )
73
- end
74
- end
75
- end
@@ -1,119 +0,0 @@
1
- RSpec.describe 'Macros #value' do
2
- describe 'with no args' do
3
- it 'raises an exception' do
4
- expect { Dry::Validation.Schema { required(:email).value } }.to raise_error(
5
- ArgumentError, "wrong number of arguments (given 0, expected at least 1)"
6
- )
7
- end
8
- end
9
-
10
- describe 'with a type specification' do
11
- subject(:schema) do
12
- Dry::Validation.Schema do
13
- required(:age).value(:int?)
14
- end
15
- end
16
-
17
- it 'generates int? rule' do
18
- expect(schema.(age: nil).messages).to eql(
19
- age: ['must be an integer']
20
- )
21
- end
22
- end
23
-
24
- describe 'with a predicate with args' do
25
- context 'with a flat arg' do
26
- subject(:schema) do
27
- Dry::Validation.Schema do
28
- required(:age).value(:int?, gt?: 18)
29
- end
30
- end
31
-
32
- it 'generates int? & gt? rule' do
33
- expect(schema.(age: nil).messages).to eql(
34
- age: ['must be an integer', 'must be greater than 18']
35
- )
36
- end
37
- end
38
-
39
- context 'with a second predicate with args' do
40
- subject(:schema) do
41
- Dry::Validation.Schema do
42
- required(:name).value(:str?, min_size?: 3, max_size?: 6)
43
- end
44
- end
45
-
46
- it 'generates str? & min_size? & max_size?' do
47
- expect(schema.(name: 'fo').messages).to eql(
48
- name: ['size cannot be less than 3', 'size cannot be greater than 6']
49
- )
50
- end
51
- end
52
-
53
- context 'with a range arg' do
54
- subject(:schema) do
55
- Dry::Validation.Schema do
56
- required(:age).value(:int?, size?: 18..24)
57
- end
58
- end
59
-
60
- it 'generates int? & gt? rule' do
61
- expect(schema.(age: nil).messages).to eql(
62
- age: ['must be an integer', 'size must be within 18 - 24']
63
- )
64
- end
65
- end
66
-
67
- context 'with a block' do
68
- subject(:schema) do
69
- Dry::Validation.Schema do
70
- required(:age).value { int? & size?(18..24) }
71
- end
72
- end
73
-
74
- it 'generates int? & gt? rule' do
75
- expect(schema.(age: nil).messages).to eql(
76
- age: ['must be an integer', 'size must be within 18 - 24']
77
- )
78
- end
79
- end
80
-
81
- context 'with a predicate and a block' do
82
- subject(:schema) do
83
- Dry::Validation.Schema do
84
- required(:age).value(:int?) { size?(18..24) }
85
- end
86
- end
87
-
88
- it 'generates int? & gt? rule' do
89
- expect(schema.(age: nil).messages).to eql(
90
- age: ['must be an integer', 'size must be within 18 - 24']
91
- )
92
- end
93
- end
94
-
95
- context 'with a schema' do
96
- subject(:schema) do
97
- Dry::Validation.Schema do
98
- required(:data).value(DataSchema)
99
- end
100
- end
101
-
102
- before do
103
- DataSchema = Dry::Validation.Schema do
104
- required(:foo).filled(size?: 2..10)
105
- end
106
- end
107
-
108
- after do
109
- Object.send(:remove_const, :DataSchema)
110
- end
111
-
112
- it 'uses the schema' do
113
- expect(schema.(data: { foo: '' }).messages).to eql(
114
- data: { foo: ['must be filled', 'length must be within 2 - 10'] }
115
- )
116
- end
117
- end
118
- end
119
- end
@@ -1,62 +0,0 @@
1
- RSpec.describe 'Macros #when' do
2
- context 'with a result rule returned from the block' do
3
- subject(:schema) do
4
- Dry::Validation.Schema do
5
- required(:email).maybe
6
-
7
- required(:login).filled.when(:true?) do
8
- value(:email).filled?
9
- end
10
- end
11
- end
12
-
13
- it 'generates check rule' do
14
- expect(schema.(login: true, email: nil).messages).to eql(
15
- email: ['must be filled']
16
- )
17
-
18
- expect(schema.(login: false, email: nil).messages).to be_empty
19
- end
20
- end
21
-
22
- describe 'with a result rule depending on another result' do
23
- subject(:schema) do
24
- Dry::Validation.Schema do
25
- required(:left).maybe(:int?)
26
- required(:right).maybe(:int?)
27
-
28
- required(:compare).maybe(:bool?).when(:true?) do
29
- value(:left).gt?(value(:right))
30
- end
31
- end
32
- end
33
-
34
- it 'generates check rule' do
35
- expect(schema.(compare: false, left: nil, right: nil)).to be_success
36
-
37
- expect(schema.(compare: true, left: 1, right: 2).messages).to eql(
38
- left: ['must be greater than 2']
39
- )
40
- end
41
- end
42
-
43
- context 'predicate with options' do
44
- subject(:schema) do
45
- Dry::Validation.Schema do
46
- required(:bar).maybe
47
-
48
- required(:foo).filled.when(size?: 3) do
49
- value(:bar).filled?
50
- end
51
- end
52
- end
53
-
54
- it 'generates check rule' do
55
- expect(schema.(foo: [1,2,3], bar: nil).messages).to eql(
56
- bar: ['must be filled']
57
- )
58
-
59
- expect(schema.(foo: [1,2], bar: nil).messages).to be_empty
60
- end
61
- end
62
- end
@@ -1,236 +0,0 @@
1
- RSpec.describe Schema, 'nested schemas' do
2
- context 'with multiple nested schemas' do
3
- subject(:schema) do
4
- Dry::Validation.Schema do
5
- required(:content).schema do
6
- required(:meta).schema do
7
- required(:version).filled
8
- end
9
-
10
- required(:data).schema do
11
- required(:city).filled
12
- end
13
- end
14
- end
15
- end
16
-
17
- it 'passes when input is valid' do
18
- input = {content: {meta: {version: "1.0"}, data: {city: "Canberra"}}}
19
- expect(schema.(input)).to be_success
20
- end
21
-
22
- it 'fails when one sub-key is missing' do
23
- input = {content: {data: {city: "Canberra"}}}
24
- expect(schema.(input).messages).to eql(content: {meta: ['is missing']})
25
- end
26
-
27
- it 'fails when both sub-keys are missing' do
28
- input = {content: {}}
29
- expect(schema.(input).messages).to eql(content: {meta: ['is missing'], data: ['is missing']})
30
- end
31
-
32
- it 'fails when the deeply nested keys are invalid' do
33
- input = {content: {meta: {version: ""}, data: {city: ""}}}
34
- expect(schema.(input).messages).to eql(content: {meta: {version: ["must be filled"]}, data: {city: ["must be filled"]}})
35
- end
36
- end
37
-
38
- context 'with a 2-level deep schema' do
39
- subject(:schema) do
40
- Dry::Validation.Schema do
41
- required(:meta).schema do
42
- required(:info).schema do
43
- required(:details).filled
44
- required(:meta).filled
45
- end
46
- end
47
- end
48
- end
49
-
50
- it 'passes when input is valid' do
51
- expect(schema.(meta: { info: { details: 'Krakow', meta: 'foo' }})).to be_success
52
- end
53
-
54
- it 'fails when root key is missing' do
55
- expect(schema.({}).messages).to eql(meta: ['is missing'])
56
- end
57
-
58
- it 'fails when 1-level key is missing' do
59
- expect(schema.(meta: {}).messages).to eql(
60
- meta: { info: ['is missing'] }
61
- )
62
- end
63
-
64
- it 'fails when 2-level key is missing' do
65
- expect(schema.(meta: { info: {} }).messages).to eql(
66
- meta: { info: { details: ['is missing'], meta: ['is missing'] } }
67
- )
68
- end
69
-
70
- it 'fails when 1-level key has invalid value' do
71
- expect(schema.(meta: { info: nil, meta: 'foo' }).messages).to eql(
72
- meta: { info: ['must be a hash'] }
73
- )
74
- end
75
-
76
- it 'fails when 2-level key has invalid value' do
77
- expect(schema.(meta: { info: { details: nil, meta: 'foo' } }).messages).to eql(
78
- meta: { info: { details: ['must be filled'] } }
79
- )
80
- end
81
- end
82
-
83
- context 'when duplicated key names are used in 2 subsequent levels' do
84
- subject(:schema) do
85
- Dry::Validation.Schema do
86
- required(:meta).schema do
87
- required(:meta).filled
88
- end
89
- end
90
- end
91
-
92
- it 'passes when input is valid' do
93
- expect(schema.(meta: { meta: 'data' })).to be_success
94
- end
95
-
96
- it 'fails when root key is missing' do
97
- expect(schema.({}).messages).to eql(meta: ['is missing'])
98
- end
99
-
100
- it 'fails when 1-level key is missing' do
101
- expect(schema.(meta: {}).messages).to eql(meta: { meta: ['is missing'] })
102
- end
103
-
104
- it 'fails when 1-level key value is invalid' do
105
- expect(schema.(meta: { meta: '' }).messages).to eql(
106
- meta: { meta: ['must be filled'] }
107
- )
108
- end
109
- end
110
-
111
- context 'when duplicated key names are used in 2 subsequent levels as schemas' do
112
- subject(:schema) do
113
- Dry::Validation.Schema do
114
- required(:meta).schema do
115
- required(:meta).schema do
116
- required(:data).filled
117
- end
118
- end
119
- end
120
- end
121
-
122
- it 'passes when input is valid' do
123
- expect(schema.(meta: { meta: { data: 'this is fine' } })).to be_success
124
- end
125
-
126
- it 'fails when root key is missing' do
127
- expect(schema.({}).messages).to eql(meta: ['is missing'])
128
- end
129
-
130
- it 'fails when 1-level key is missing' do
131
- expect(schema.(meta: {}).messages).to eql(meta: { meta: ['is missing'] })
132
- end
133
-
134
- it 'fails when 1-level key value is invalid' do
135
- expect(schema.(meta: { meta: '' }).messages).to eql(
136
- meta: { meta: ['must be a hash'] }
137
- )
138
- end
139
-
140
- it 'fails when 2-level key is missing' do
141
- expect(schema.(meta: { meta: {} }).messages).to eql(
142
- meta: { meta: { data: ['is missing'] } }
143
- )
144
- end
145
-
146
- it 'fails when 2-level key value is invalid' do
147
- expect(schema.(meta: { meta: { data: '' } }).messages).to eql(
148
- meta: { meta: { data: ['must be filled'] } }
149
- )
150
- end
151
- end
152
-
153
- context 'with `each` + schema inside another schema' do
154
- subject(:schema) do
155
- Dry::Validation.Schema do
156
- required(:meta).schema do
157
- required(:data).each do
158
- schema do
159
- required(:info).schema do
160
- required(:name).filled
161
- end
162
- end
163
- end
164
- end
165
- end
166
- end
167
-
168
- it 'passes when data is valid' do
169
- expect(schema.(meta: { data: [{ info: { name: 'oh hai' } }] })).to be_success
170
- end
171
-
172
- it 'fails when root key is missing' do
173
- expect(schema.({}).messages).to eql(meta: ['is missing'])
174
- end
175
-
176
- it 'fails when root key value is invalid' do
177
- expect(schema.(meta: '').messages).to eql(meta: ['must be a hash'])
178
- end
179
-
180
- it 'fails when 1-level key is missing' do
181
- expect(schema.(meta: {}).messages).to eql(meta: { data: ['is missing'] })
182
- end
183
-
184
- it 'fails when 1-level key has invalid value' do
185
- expect(schema.(meta: { data: '' }).messages).to eql(meta: { data: ['must be an array'] })
186
- end
187
-
188
- it 'fails when 1-level key has value with a missing key' do
189
- expect(schema.(meta: { data: [{}] }).messages).to eql(
190
- meta: { data: { 0 => { info: ['is missing'] } } }
191
- )
192
- end
193
-
194
- it 'fails when 1-level key has value with an incorrect type' do
195
- expect(schema.(meta: { data: [{ info: ''}] }).messages).to eql(
196
- meta: { data: { 0 => { info: ['must be a hash'] } } }
197
- )
198
- end
199
-
200
- it 'fails when 1-level key has value with a key with an invalid value' do
201
- expect(schema.(meta: { data: [{ info: { name: '' } }] }).messages).to eql(
202
- meta: { data: { 0 => { info: { name: ['must be filled'] } } } }
203
- )
204
- end
205
- end
206
-
207
- context 'with 2-level `each` + schema' do
208
- subject(:schema) do
209
- Dry::Validation.Schema do
210
- required(:data).each do
211
- schema do
212
- required(:tags).each do
213
- required(:name).filled
214
- end
215
- end
216
- end
217
- end
218
- end
219
-
220
- it 'passes when input is valid' do
221
- expect(schema.(data: [{ tags: [{ name: 'red' }, { name: 'blue' }] }])).to be_success
222
- end
223
-
224
- it 'fails when 1-level element is not valid' do
225
- expect(schema.(data: [{}]).messages).to eql(
226
- data: { 0 => { tags: ['is missing'] } }
227
- )
228
- end
229
-
230
- it 'fails when 2-level element is not valid' do
231
- expect(schema.(data: [{ tags: [{ name: 'red' }, { name: '' }] }]).messages).to eql(
232
- data: { 0 => { tags: { 1 => { name: ['must be filled'] } } } }
233
- )
234
- end
235
- end
236
- end