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,35 +0,0 @@
1
- RSpec.describe 'Schema with xor rules' do
2
- subject(:schema) do
3
- Dry::Validation.Schema do
4
- configure do
5
- def self.messages
6
- Messages.default.merge(
7
- en: { errors: { be_reasonable: 'you cannot eat cake and have cake!' } }
8
- )
9
- end
10
- end
11
-
12
- required(:eat_cake).filled
13
-
14
- required(:have_cake).filled
15
-
16
- rule(be_reasonable: %i[eat_cake have_cake]) do |ec, hc|
17
- ec.eql?('yes!') ^ hc.eql?('yes!')
18
- end
19
- end
20
- end
21
-
22
- describe '#messages' do
23
- it 'passes when only one option is selected' do
24
- messages = schema.(eat_cake: 'yes!', have_cake: 'no!').messages[:be_reasonable]
25
-
26
- expect(messages).to be(nil)
27
- end
28
-
29
- it 'fails when both options are selected' do
30
- expect(schema.(eat_cake: 'yes!', have_cake: 'yes!').messages).to eql(
31
- be_reasonable: ['you cannot eat cake and have cake!']
32
- )
33
- end
34
- end
35
- end
@@ -1,17 +0,0 @@
1
- RSpec.describe 'Building schemas' do
2
- describe 'Dry::Validation.Schema' do
3
- it 'builds a schema class with custom predicate set' do
4
- predicates = Module.new do
5
- include Dry::Logic::Predicates
6
-
7
- def zomg?(*)
8
- true
9
- end
10
- end
11
-
12
- schema = Dry::Validation.Schema(predicates: predicates, build: false)
13
-
14
- expect(schema.predicates[:key?]).to be_a(Method)
15
- end
16
- end
17
- end
@@ -1,173 +0,0 @@
1
- RSpec.describe Dry::Validation::Schema, 'defining key-based schema' do
2
- describe 'with a flat structure' do
3
- subject(:schema) do
4
- Dry::Validation.Schema do
5
- configure do
6
- config.input_processor = :params
7
- config.type_specs = true
8
- end
9
-
10
- required(:email, :string).filled
11
- required(:age, [:nil, :integer]) { none? | (int? & gt?(18)) }
12
- end
13
- end
14
-
15
- it 'passes when input is valid' do
16
- expect(schema.(email: 'jane@doe', age: 19)).to be_success
17
- expect(schema.(email: 'jane@doe', age: nil)).to be_success
18
- end
19
-
20
- it 'fails when input is not valid' do
21
- expect(schema.(email: 'jane@doe', age: 17)).to_not be_success
22
- end
23
-
24
- it 'returns result which quacks like hash' do
25
- input = { email: 'jane@doe', age: 19 }
26
- result = schema.(input)
27
-
28
- expect(result[:email]).to eql('jane@doe')
29
- expect(Hash[result]).to eql(input)
30
-
31
- expect(result.to_a).to eql([[:email, 'jane@doe'], [:age, 19]])
32
- end
33
-
34
- describe '#type_map' do
35
- it 'returns key=>type map' do
36
- expect(schema.type_map).to eql(
37
- email: Types::String, age: Types::Params::Nil | Types::Params::Integer
38
- )
39
- end
40
-
41
- it 'uses type_map for input processor when it is not empty' do
42
- expect(schema.(email: 'jane@doe.org', age: '18').to_h).to eql(
43
- email: 'jane@doe.org', age: 18
44
- )
45
- end
46
- end
47
- end
48
-
49
- describe 'with nested structures' do
50
- subject(:schema) do
51
- class Test::CountrySchema
52
- def self.schema
53
- Dry::Validation.Schema do
54
- required(:name).filled
55
- required(:code).filled
56
- end
57
- end
58
- end
59
-
60
- Dry::Validation.Schema do
61
- required(:email).filled
62
-
63
- required(:age).maybe(:int?, gt?: 18)
64
-
65
- required(:address).schema do
66
- required(:city).filled(min_size?: 3)
67
-
68
- required(:street).filled
69
-
70
- required(:country).schema(Test::CountrySchema)
71
- end
72
-
73
- required(:phone_numbers).each(:str?)
74
- end
75
- end
76
-
77
- let(:input) do
78
- {
79
- email: 'jane@doe.org',
80
- age: 19,
81
- address: { city: 'NYC', street: 'Street 1/2', country: { code: 'US', name: 'USA' } },
82
- phone_numbers: [
83
- '123456', '234567'
84
- ]
85
- }.freeze
86
- end
87
-
88
- describe '#messages' do
89
- it 'returns compiled error messages' do
90
- expect(schema.(input.merge(email: '')).messages).to eql(
91
- email: ['must be filled']
92
- )
93
- end
94
- end
95
-
96
- describe '#call' do
97
- it 'passes when attributes are valid' do
98
- expect(schema.(input)).to be_success
99
- end
100
-
101
- it 'validates presence of an email and min age value' do
102
- expect(schema.(input.merge(email: '', age: 18)).messages).to eql(
103
- email: ['must be filled'], age: ['must be greater than 18']
104
- )
105
- end
106
-
107
- it 'validates presence of the email key and type of age value' do
108
- attrs = {
109
- name: 'Jane',
110
- age: '18',
111
- address: input[:address], phone_numbers: input[:phone_numbers]
112
- }
113
-
114
- expect(schema.(attrs).messages).to eql(
115
- email: ['is missing'],
116
- age: ['must be an integer', 'must be greater than 18']
117
- )
118
- end
119
-
120
- it 'validates presence of the address and phone_number keys' do
121
- attrs = { email: 'jane@doe.org', age: 19 }
122
-
123
- expect(schema.(attrs).messages).to eql(
124
- address: ['is missing'], phone_numbers: ['is missing']
125
- )
126
- end
127
-
128
- it 'validates presence of keys under address and min size of the city value' do
129
- attrs = input.merge(address: { city: 'NY' })
130
-
131
- expect(schema.(attrs).messages).to eql(
132
- address: {
133
- street: ['is missing'],
134
- country: ['is missing'],
135
- city: ['size cannot be less than 3']
136
- }
137
- )
138
- end
139
-
140
- it 'validates address type' do
141
- expect(schema.(input.merge(address: 'totally not a hash')).messages).to eql(
142
- address: ['must be a hash']
143
- )
144
- end
145
-
146
- it 'validates address code and name values' do
147
- attrs = input.merge(
148
- address: input[:address].merge(country: { code: 'US', name: '' })
149
- )
150
-
151
- expect(schema.(attrs).messages).to eql(
152
- address: { country: { name: ['must be filled'] } }
153
- )
154
- end
155
-
156
- it 'validates each phone number' do
157
- attrs = input.merge(phone_numbers: ['123', 312])
158
-
159
- expect(schema.(attrs).messages).to eql(
160
- phone_numbers: { 1 => ['must be a string'] }
161
- )
162
- end
163
- end
164
- end
165
-
166
- context 'nested keys' do
167
- it 'raises error when defining nested keys without `schema` block`' do
168
- expect {
169
- Dry::Validation.Schema { required(:foo).value { required(:bar).value(:str?) } }
170
- }.to raise_error(ArgumentError, /required/)
171
- end
172
- end
173
- end
@@ -1,11 +0,0 @@
1
- RSpec.shared_context :message_compiler do
2
- subject(:compiler) { Dry::Validation::MessageCompiler.new(messages) }
3
-
4
- let(:messages) do
5
- Dry::Validation::Messages.default
6
- end
7
-
8
- let(:result) do
9
- compiler.public_send(visitor, node)
10
- end
11
- end
@@ -1,15 +0,0 @@
1
- RSpec.shared_context 'predicate helper' do
2
- def p(name, *args)
3
- Dry::Logic::Rule::Predicate.new(predicates[name], args: args).to_ast
4
- end
5
-
6
- let!(:predicates) do
7
- Module.new {
8
- include Dry::Logic::Predicates
9
-
10
- def self.email?(value)
11
- true
12
- end
13
- }
14
- end
15
- end
@@ -1,8 +0,0 @@
1
- require 'dry/logic/rule_compiler'
2
- require 'dry/logic/predicates'
3
-
4
- RSpec.shared_context 'rule compiler' do
5
- let(:rule_compiler) do
6
- Dry::Logic::RuleCompiler.new(Dry::Logic::Predicates)
7
- end
8
- end
data/spec/spec_helper.rb DELETED
@@ -1,62 +0,0 @@
1
- if ENV['COVERAGE'] == 'true' && RUBY_ENGINE == 'ruby' && RUBY_VERSION == '2.3.1'
2
- require "simplecov"
3
- SimpleCov.start do
4
- add_filter '/spec/'
5
- end
6
- end
7
-
8
- begin
9
- require 'pry'
10
- require 'pry-byebug'
11
- rescue LoadError
12
- end
13
-
14
- require 'dry-validation'
15
- require 'dry/core/constants'
16
- require 'ostruct'
17
-
18
- SPEC_ROOT = Pathname(__dir__)
19
-
20
- Dir[SPEC_ROOT.join('shared/**/*.rb')].each(&method(:require))
21
- Dir[SPEC_ROOT.join('support/**/*.rb')].each(&method(:require))
22
-
23
- include Dry::Validation
24
-
25
- module Types
26
- include Dry::Types.module
27
- end
28
-
29
- Dry::Validation::Deprecations.configure do |config|
30
- config.logger = Logger.new(SPEC_ROOT.join('../log/deprecations.log'))
31
- end
32
-
33
- RSpec.configure do |config|
34
- config.disable_monkey_patching!
35
- config.warnings = true
36
-
37
- config.after do
38
- if defined?(I18n)
39
- I18n.load_path = Dry::Validation.messages_paths.dup
40
- I18n.backend.reload!
41
- end
42
- end
43
-
44
- config.include PredicatesIntegration
45
-
46
- config.before do
47
- module Test
48
- def self.remove_constants
49
- constants.each { |const| remove_const(const) }
50
- self
51
- end
52
- end
53
-
54
- Dry::Validation::Messages::Abstract.instance_variable_set('@cache', nil)
55
- Dry::Validation::Messages::YAML.instance_variable_set('@cache', nil)
56
- Dry::Validation::Messages::I18n.instance_variable_set('@cache', nil) if defined?(I18n)
57
- end
58
-
59
- config.after do
60
- Object.send(:remove_const, Test.remove_constants.name)
61
- end
62
- end
@@ -1,25 +0,0 @@
1
- module DefineStruct
2
- def from_hash(hash = {})
3
- values = members.map do |attr|
4
- val = hash[attr]
5
- val.is_a?(Hash) ? define_struct(*val.keys).from_hash(val) : val
6
- end
7
- new(*values)
8
- end
9
-
10
- def define_struct(*attrs)
11
- Struct.new(*attrs) do
12
- extend DefineStruct
13
- end
14
- end
15
- end
16
-
17
- def def_struct(*attrs)
18
- Struct.new(*attrs) do
19
- extend DefineStruct
20
- end
21
- end
22
-
23
- def struct_from_hash(hash)
24
- def_struct(*hash.keys).from_hash(hash)
25
- end
@@ -1,38 +0,0 @@
1
- require 'rspec/expectations'
2
-
3
- RSpec::Matchers.define :be_successful do
4
- match do |actual|
5
- actual.success? &&
6
- actual.messages.empty?
7
- end
8
-
9
- failure_message do |actual|
10
- "expected that #{actual.inspect} would be successful"
11
- end
12
-
13
- failure_message_when_negated do |actual|
14
- "expected that #{actual.inspect} would NOT be successful"
15
- end
16
- end
17
-
18
- RSpec::Matchers.define :be_failing do |messages|
19
- match do |actual|
20
- messages = case messages
21
- when Hash
22
- messages
23
- else
24
- Array(messages)
25
- end
26
-
27
- !actual.success? &&
28
- actual.messages.fetch(:foo) == messages
29
- end
30
-
31
- failure_message do |actual|
32
- "expected that #{actual.inspect} would be failing (#{messages.inspect})"
33
- end
34
-
35
- failure_message_when_negated do |actual|
36
- "expected that #{actual.inspect} would NOT be failing"
37
- end
38
- end
@@ -1,9 +0,0 @@
1
- module Mutant
2
- class Selector
3
- class Expression < self
4
- def call(_subject)
5
- integration.all_tests
6
- end
7
- end
8
- end
9
- end
@@ -1,7 +0,0 @@
1
- module PredicatesIntegration
2
- private
3
-
4
- def result
5
- schema.(input)
6
- end
7
- end
@@ -1,283 +0,0 @@
1
- RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
2
- subject(:compiler) { Dry::Validation::InputProcessorCompiler::JSON.new }
3
-
4
- include_context 'predicate helper'
5
-
6
- it 'supports arbitrary types via type?(const) => "json.const"' do
7
- rule_ast = [
8
- [
9
- :and,
10
- [
11
- [:val, p(:key?, :age)],
12
- [:key, [:age, p(:type?, Integer)]]
13
- ]
14
- ]
15
- ]
16
-
17
- input_type = compiler.(rule_ast)
18
-
19
- expect(input_type['age' => 21]).to eql(age: 21)
20
- end
21
-
22
- it 'supports arbitrary types via type?(conts)' do
23
- rule_ast = [
24
- [
25
- :and,
26
- [
27
- [:val, p(:key?, :admin)],
28
- [:key, [:admin, p(:type?, 'Bool')]]
29
- ]
30
- ]
31
- ]
32
-
33
- input_type = compiler.(rule_ast)
34
-
35
- expect(input_type['admin' => false]).to eql(admin: false)
36
- end
37
-
38
- it 'supports str? => "string"' do
39
- rule_ast = [
40
- [
41
- :and,
42
- [
43
- [:val, p(:key?, :email)],
44
- [
45
- :and, [
46
- [:key, [:email, p(:str?, [])]],
47
- [:key, [:email, p(:filled?, [])]]
48
- ]
49
- ]
50
- ]
51
- ]
52
- ]
53
-
54
- input_type = compiler.(rule_ast)
55
-
56
- expect(input_type['email' => 'jane@doe.org']).to eql(email: 'jane@doe.org')
57
- end
58
-
59
- it 'supports int? => "int"' do
60
- rule_ast = [
61
- [
62
- :and,
63
- [
64
- [:val, p(:key?, :age)],
65
- [:key, [:age, p(:int?, [])]],
66
- ]
67
- ]
68
- ]
69
-
70
- input_type = compiler.(rule_ast)
71
-
72
- expect(input_type['age' => 21]).to eql(age: 21)
73
- end
74
-
75
- it 'supports bool? => "bool"' do
76
- rule_ast = [
77
- [
78
- :and,
79
- [
80
- [:val, p(:key?, :admin)],
81
- [:key, [:admin, p(:bool?, [])]],
82
- ]
83
- ]
84
- ]
85
-
86
- input_type = compiler.(rule_ast)
87
-
88
- expect(input_type['admin' => true]).to eql(admin: true)
89
- expect(input_type['admin' => false]).to eql(admin: false)
90
- end
91
-
92
- it 'supports none? => "int"' do
93
- rule_ast = [
94
- [
95
- :and,
96
- [
97
- [:val, p(:key?, :age)],
98
- [
99
- :or, [
100
- [:key, [:age, p(:none?, [])]],
101
- [:key, [:age, p(:int?, [])]],
102
- ]
103
- ]
104
- ]
105
- ]
106
- ]
107
-
108
- input_type = compiler.(rule_ast)
109
-
110
- expect(input_type['age' => '']).to eql(age: nil)
111
- expect(input_type['age' => 21]).to eql(age: 21)
112
- end
113
-
114
- it 'supports float? => "float"' do
115
- rule_ast = [
116
- [
117
- :and,
118
- [
119
- [:val, p(:key?, :lat)],
120
- [:key, [:lat, p(:float?, [])]],
121
- ]
122
- ]
123
- ]
124
-
125
- input_type = compiler.(rule_ast)
126
-
127
- expect(input_type['lat' => 21.12]).to eql(lat: 21.12)
128
- end
129
-
130
- it 'supports decimal? => "json.decimal"' do
131
- rule_ast = [
132
- [
133
- :and,
134
- [
135
- [:val, p(:key?, :lat)],
136
- [:key, [:lat, p(:decimal?, [])]],
137
- ]
138
- ]
139
- ]
140
-
141
- input_type = compiler.(rule_ast)
142
-
143
- expect(input_type['lat' => 21.12]).to eql(lat: 21.12.to_d)
144
- end
145
-
146
- it 'supports date? => "json.date"' do
147
- rule_ast = [
148
- [
149
- :and,
150
- [
151
- [:val, p(:key?, :bday)],
152
- [:key, [:bday, p(:date?, [])]],
153
- ]
154
- ]
155
- ]
156
-
157
- input_type = compiler.(rule_ast)
158
-
159
- expect(input_type['bday' => '2012-01-23']).to eql(bday: Date.new(2012, 1, 23))
160
- end
161
-
162
- it 'supports date_time? => "json.date_time"' do
163
- rule_ast = [
164
- [
165
- :and,
166
- [
167
- [:val, p(:key?, :bday)],
168
- [:key, [:bday, p(:date_time?, [])]],
169
- ]
170
- ]
171
- ]
172
-
173
- input_type = compiler.(rule_ast)
174
-
175
- expect(input_type['bday' => '2012-01-23 11:07']).to eql(bday: DateTime.new(2012, 1, 23, 11, 7))
176
- end
177
-
178
- it 'supports time? => "json.time"' do
179
- rule_ast = [
180
- [
181
- :and,
182
- [
183
- [:val, p(:key?, :bday)],
184
- [:key, [:bday, p(:time?, [])]],
185
- ]
186
- ]
187
- ]
188
-
189
- input_type = compiler.(rule_ast)
190
-
191
- expect(input_type['bday' => '2012-01-23 11:07']).to eql(bday: Time.new(2012, 1, 23, 11, 7))
192
- end
193
-
194
- it 'supports each rule' do
195
- rule_ast = [
196
- [
197
- :and, [
198
- [:val, p(:key?, :author)],
199
- [:set, [
200
- [:and, [
201
- [:val, p(:key?, :books)],
202
- [
203
- :each, [
204
- :set, [
205
- [
206
- :and, [
207
- [:val, p(:key?, :published)],
208
- [:key, [:published, p(:bool?, [])]]
209
- ]
210
- ]
211
- ]
212
- ]
213
- ]
214
- ]]
215
- ]]
216
- ]
217
- ]
218
- ]
219
-
220
- input_type = compiler.(rule_ast)
221
-
222
- expect(input_type['author' => { 'books' => [{ 'published' => true }] }]).to eql(
223
- author: { books: [published: true] }
224
- )
225
-
226
- expect(input_type['author' => { 'books' => [{ 'published' => false }] }]).to eql(
227
- author: { books: [published: false] }
228
- )
229
- end
230
-
231
- it 'supports array? with an each rule' do
232
- rule_ast = [
233
- [
234
- :and, [
235
- [:val, p(:key?, :ids)],
236
- [:and, [
237
- [:key, [:ids, p(:array?, [])]],
238
- [:each, [:val, p(:int?, [])]]
239
- ]]
240
- ]
241
- ]
242
- ]
243
-
244
- input_type = compiler.(rule_ast)
245
-
246
- expect(input_type.('ids' => 'oops')).to eql(ids: 'oops')
247
-
248
- expect(input_type.('ids' => [1, 2, 3])).to eql(ids: [1, 2, 3])
249
- end
250
-
251
- it 'supports hash? with a set rule' do
252
- rule_ast = [
253
- [
254
- :and, [
255
- [:val, p(:key?, :address)],
256
- [
257
- :and, [
258
- [:key, [:address, p(:hash?, [])]],
259
- [
260
- :set, [
261
- [
262
- :and, [
263
- [:val, p(:key?, :street)],
264
- [:key, [:street, p(:filled?, [])]]
265
- ]
266
- ]
267
- ]
268
- ]
269
- ]
270
- ]
271
- ]
272
- ]
273
- ]
274
-
275
- input_type = compiler.(rule_ast)
276
-
277
- expect(input_type.('address' => 'oops')).to eql(address: 'oops')
278
-
279
- expect(input_type.('address' => { 'street' => 'ok' })).to eql(
280
- address: { street: 'ok' }
281
- )
282
- end
283
- end