dry-validation 0.7.4 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +9 -6
  4. data/CHANGELOG.md +58 -0
  5. data/Gemfile +3 -3
  6. data/benchmarks/benchmark_form_invalid.rb +64 -0
  7. data/benchmarks/benchmark_form_valid.rb +64 -0
  8. data/benchmarks/profile_schema_call_invalid.rb +20 -0
  9. data/benchmarks/profile_schema_call_valid.rb +20 -0
  10. data/benchmarks/profile_schema_definition.rb +14 -0
  11. data/benchmarks/profile_schema_messages_invalid.rb +20 -0
  12. data/benchmarks/suite.rb +5 -0
  13. data/config/errors.yml +12 -5
  14. data/dry-validation.gemspec +2 -2
  15. data/examples/basic.rb +2 -2
  16. data/examples/form.rb +2 -2
  17. data/examples/json.rb +2 -2
  18. data/examples/nested.rb +6 -6
  19. data/lib/dry/validation.rb +22 -3
  20. data/lib/dry/validation/deprecations.rb +23 -0
  21. data/lib/dry/validation/error_compiler.rb +31 -11
  22. data/lib/dry/validation/error_compiler/input.rb +44 -57
  23. data/lib/dry/validation/hint_compiler.rb +15 -7
  24. data/lib/dry/validation/input_processor_compiler.rb +13 -6
  25. data/lib/dry/validation/input_processor_compiler/form.rb +2 -0
  26. data/lib/dry/validation/input_processor_compiler/sanitizer.rb +1 -1
  27. data/lib/dry/validation/messages/abstract.rb +9 -1
  28. data/lib/dry/validation/predicate_registry.rb +101 -0
  29. data/lib/dry/validation/result.rb +8 -1
  30. data/lib/dry/validation/schema.rb +110 -44
  31. data/lib/dry/validation/schema/check.rb +4 -2
  32. data/lib/dry/validation/schema/deprecated.rb +31 -0
  33. data/lib/dry/validation/schema/dsl.rb +18 -11
  34. data/lib/dry/validation/schema/form.rb +1 -0
  35. data/lib/dry/validation/schema/json.rb +1 -0
  36. data/lib/dry/validation/schema/key.rb +23 -10
  37. data/lib/dry/validation/schema/rule.rb +81 -20
  38. data/lib/dry/validation/schema/value.rb +110 -25
  39. data/lib/dry/validation/version.rb +1 -1
  40. data/spec/fixtures/locales/en.yml +1 -0
  41. data/spec/fixtures/locales/pl.yml +1 -1
  42. data/spec/integration/custom_error_messages_spec.rb +2 -2
  43. data/spec/integration/custom_predicates_spec.rb +98 -15
  44. data/spec/integration/error_compiler_spec.rb +111 -96
  45. data/spec/integration/form/predicates/array_spec.rb +243 -0
  46. data/spec/integration/form/predicates/empty_spec.rb +263 -0
  47. data/spec/integration/form/predicates/eql_spec.rb +327 -0
  48. data/spec/integration/form/predicates/even_spec.rb +455 -0
  49. data/spec/integration/form/predicates/excluded_from_spec.rb +455 -0
  50. data/spec/integration/form/predicates/excludes_spec.rb +391 -0
  51. data/spec/integration/form/predicates/false_spec.rb +455 -0
  52. data/spec/integration/form/predicates/filled_spec.rb +467 -0
  53. data/spec/integration/form/predicates/format_spec.rb +454 -0
  54. data/spec/integration/form/predicates/gt_spec.rb +519 -0
  55. data/spec/integration/form/predicates/gteq_spec.rb +519 -0
  56. data/spec/integration/form/predicates/included_in_spec.rb +455 -0
  57. data/spec/integration/form/predicates/includes_spec.rb +391 -0
  58. data/spec/integration/form/predicates/key_spec.rb +75 -0
  59. data/spec/integration/form/predicates/lt_spec.rb +519 -0
  60. data/spec/integration/form/predicates/lteq_spec.rb +519 -0
  61. data/spec/integration/form/predicates/max_size_spec.rb +391 -0
  62. data/spec/integration/form/predicates/min_size_spec.rb +391 -0
  63. data/spec/integration/form/predicates/none_spec.rb +265 -0
  64. data/spec/integration/form/predicates/not_eql_spec.rb +327 -0
  65. data/spec/integration/form/predicates/odd_spec.rb +455 -0
  66. data/spec/integration/form/predicates/size/fixed_spec.rb +399 -0
  67. data/spec/integration/form/predicates/size/range_spec.rb +398 -0
  68. data/spec/integration/form/predicates/true_spec.rb +455 -0
  69. data/spec/integration/form/predicates/type_spec.rb +391 -0
  70. data/spec/integration/hints_spec.rb +90 -4
  71. data/spec/integration/injecting_rules_spec.rb +2 -2
  72. data/spec/integration/localized_error_messages_spec.rb +2 -2
  73. data/spec/integration/messages/i18n_spec.rb +3 -3
  74. data/spec/integration/optional_keys_spec.rb +3 -3
  75. data/spec/integration/schema/array_schema_spec.rb +49 -13
  76. data/spec/integration/schema/check_rules_spec.rb +6 -6
  77. data/spec/integration/schema/check_with_nested_el_spec.rb +3 -3
  78. data/spec/integration/schema/check_with_nth_el_spec.rb +1 -1
  79. data/spec/integration/schema/each_with_set_spec.rb +3 -3
  80. data/spec/integration/schema/extending_dsl_spec.rb +27 -0
  81. data/spec/integration/schema/form/explicit_types_spec.rb +182 -0
  82. data/spec/integration/schema/form_spec.rb +90 -18
  83. data/spec/integration/schema/hash_schema_spec.rb +47 -0
  84. data/spec/integration/schema/inheriting_schema_spec.rb +4 -4
  85. data/spec/integration/schema/input_processor_spec.rb +8 -8
  86. data/spec/integration/schema/json/explicit_types_spec.rb +157 -0
  87. data/spec/integration/schema/json_spec.rb +18 -18
  88. data/spec/integration/schema/macros/confirmation_spec.rb +1 -1
  89. data/spec/integration/schema/macros/each_spec.rb +177 -43
  90. data/spec/integration/schema/macros/{required_spec.rb → filled_spec.rb} +34 -6
  91. data/spec/integration/schema/macros/input_spec.rb +21 -0
  92. data/spec/integration/schema/macros/maybe_spec.rb +39 -2
  93. data/spec/integration/schema/macros/value_spec.rb +105 -0
  94. data/spec/integration/schema/macros/when_spec.rb +28 -8
  95. data/spec/integration/schema/nested_values_spec.rb +11 -8
  96. data/spec/integration/schema/not_spec.rb +2 -2
  97. data/spec/integration/schema/numbers_spec.rb +1 -1
  98. data/spec/integration/schema/option_with_default_spec.rb +1 -1
  99. data/spec/integration/schema/predicate_verification_spec.rb +9 -0
  100. data/spec/integration/schema/predicates/array_spec.rb +295 -0
  101. data/spec/integration/schema/predicates/custom_spec.rb +103 -0
  102. data/spec/integration/schema/predicates/empty_spec.rb +263 -0
  103. data/spec/integration/schema/predicates/eql_spec.rb +327 -0
  104. data/spec/integration/schema/predicates/even_spec.rb +455 -0
  105. data/spec/integration/schema/predicates/excluded_from_spec.rb +455 -0
  106. data/spec/integration/schema/predicates/excludes_spec.rb +391 -0
  107. data/spec/integration/schema/predicates/filled_spec.rb +467 -0
  108. data/spec/integration/schema/predicates/format_spec.rb +455 -0
  109. data/spec/integration/schema/predicates/gt_spec.rb +519 -0
  110. data/spec/integration/schema/predicates/gteq_spec.rb +519 -0
  111. data/spec/integration/schema/predicates/hash_spec.rb +69 -0
  112. data/spec/integration/schema/predicates/included_in_spec.rb +455 -0
  113. data/spec/integration/schema/predicates/includes_spec.rb +391 -0
  114. data/spec/integration/schema/predicates/key_spec.rb +88 -0
  115. data/spec/integration/schema/predicates/lt_spec.rb +520 -0
  116. data/spec/integration/schema/predicates/lteq_spec.rb +519 -0
  117. data/spec/integration/schema/predicates/max_size_spec.rb +391 -0
  118. data/spec/integration/schema/predicates/min_size_spec.rb +391 -0
  119. data/spec/integration/schema/predicates/none_spec.rb +265 -0
  120. data/spec/integration/schema/predicates/not_eql_spec.rb +391 -0
  121. data/spec/integration/schema/predicates/odd_spec.rb +455 -0
  122. data/spec/integration/schema/predicates/size/fixed_spec.rb +401 -0
  123. data/spec/integration/schema/predicates/size/range_spec.rb +399 -0
  124. data/spec/integration/schema/predicates/type_spec.rb +391 -0
  125. data/spec/integration/schema/reusing_schema_spec.rb +4 -4
  126. data/spec/integration/schema/using_types_spec.rb +24 -6
  127. data/spec/integration/schema/xor_spec.rb +2 -2
  128. data/spec/integration/schema_builders_spec.rb +15 -0
  129. data/spec/integration/schema_spec.rb +37 -12
  130. data/spec/shared/predicate_helper.rb +13 -0
  131. data/spec/spec_helper.rb +10 -0
  132. data/spec/support/matchers.rb +38 -0
  133. data/spec/support/predicates_integration.rb +7 -0
  134. data/spec/unit/hint_compiler_spec.rb +10 -8
  135. data/spec/unit/input_processor_compiler/form_spec.rb +45 -43
  136. data/spec/unit/input_processor_compiler/json_spec.rb +37 -35
  137. data/spec/unit/predicate_registry_spec.rb +34 -0
  138. data/spec/unit/schema/key_spec.rb +12 -14
  139. data/spec/unit/schema/rule_spec.rb +4 -2
  140. data/spec/unit/schema/value_spec.rb +38 -121
  141. metadata +150 -16
  142. data/lib/dry/validation/schema/attr.rb +0 -15
  143. data/spec/integration/attr_spec.rb +0 -122
@@ -1,13 +1,15 @@
1
1
  RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
2
2
  subject(:compiler) { Dry::Validation::InputProcessorCompiler::JSON.new }
3
3
 
4
+ include_context 'predicate helper'
5
+
4
6
  it 'supports arbitrary types via type?(const) => "json.const"' do
5
7
  rule_ast = [
6
8
  [
7
9
  :and,
8
10
  [
9
- [:val, [:predicate, [:key?, [:age]]]],
10
- [:key, [:age, [:predicate, [:type?, [Fixnum]]]]]
11
+ [:val, p(:key?, :age)],
12
+ [:key, [:age, p(:type?, Fixnum)]]
11
13
  ]
12
14
  ]
13
15
  ]
@@ -22,8 +24,8 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
22
24
  [
23
25
  :and,
24
26
  [
25
- [:val, [:predicate, [:key?, [:admin]]]],
26
- [:key, [:admin, [:predicate, [:type?, ['Bool']]]]]
27
+ [:val, p(:key?, :admin)],
28
+ [:key, [:admin, p(:type?, 'Bool')]]
27
29
  ]
28
30
  ]
29
31
  ]
@@ -38,11 +40,11 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
38
40
  [
39
41
  :and,
40
42
  [
41
- [:val, [:predicate, [:key?, [:email]]]],
43
+ [:val, p(:key?, :email)],
42
44
  [
43
45
  :and, [
44
- [:key, [:email, [:predicate, [:str?, []]]]],
45
- [:key, [:email, [:predicate, [:filled?, []]]]]
46
+ [:key, [:email, p(:str?, [])]],
47
+ [:key, [:email, p(:filled?, [])]]
46
48
  ]
47
49
  ]
48
50
  ]
@@ -59,8 +61,8 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
59
61
  [
60
62
  :and,
61
63
  [
62
- [:val, [:predicate, [:key?, [:age]]]],
63
- [:key, [:age, [:predicate, [:int?, []]]]],
64
+ [:val, p(:key?, :age)],
65
+ [:key, [:age, p(:int?, [])]],
64
66
  ]
65
67
  ]
66
68
  ]
@@ -75,8 +77,8 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
75
77
  [
76
78
  :and,
77
79
  [
78
- [:val, [:predicate, [:key?, [:admin]]]],
79
- [:key, [:admin, [:predicate, [:bool?, []]]]],
80
+ [:val, p(:key?, :admin)],
81
+ [:key, [:admin, p(:bool?, [])]],
80
82
  ]
81
83
  ]
82
84
  ]
@@ -92,11 +94,11 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
92
94
  [
93
95
  :and,
94
96
  [
95
- [:val, [:predicate, [:key?, [:age]]]],
97
+ [:val, p(:key?, :age)],
96
98
  [
97
99
  :or, [
98
- [:key, [:age, [:predicate, [:none?, []]]]],
99
- [:key, [:age, [:predicate, [:int?, []]]]],
100
+ [:key, [:age, p(:none?, [])]],
101
+ [:key, [:age, p(:int?, [])]],
100
102
  ]
101
103
  ]
102
104
  ]
@@ -114,8 +116,8 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
114
116
  [
115
117
  :and,
116
118
  [
117
- [:val, [:predicate, [:key?, [:lat]]]],
118
- [:key, [:lat, [:predicate, [:float?, []]]]],
119
+ [:val, p(:key?, :lat)],
120
+ [:key, [:lat, p(:float?, [])]],
119
121
  ]
120
122
  ]
121
123
  ]
@@ -130,8 +132,8 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
130
132
  [
131
133
  :and,
132
134
  [
133
- [:val, [:predicate, [:key?, [:lat]]]],
134
- [:key, [:lat, [:predicate, [:decimal?, []]]]],
135
+ [:val, p(:key?, :lat)],
136
+ [:key, [:lat, p(:decimal?, [])]],
135
137
  ]
136
138
  ]
137
139
  ]
@@ -146,8 +148,8 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
146
148
  [
147
149
  :and,
148
150
  [
149
- [:val, [:predicate, [:key?, [:bday]]]],
150
- [:key, [:bday, [:predicate, [:date?, []]]]],
151
+ [:val, p(:key?, :bday)],
152
+ [:key, [:bday, p(:date?, [])]],
151
153
  ]
152
154
  ]
153
155
  ]
@@ -162,8 +164,8 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
162
164
  [
163
165
  :and,
164
166
  [
165
- [:val, [:predicate, [:key?, [:bday]]]],
166
- [:key, [:bday, [:predicate, [:date_time?, []]]]],
167
+ [:val, p(:key?, :bday)],
168
+ [:key, [:bday, p(:date_time?, [])]],
167
169
  ]
168
170
  ]
169
171
  ]
@@ -178,8 +180,8 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
178
180
  [
179
181
  :and,
180
182
  [
181
- [:val, [:predicate, [:key?, [:bday]]]],
182
- [:key, [:bday, [:predicate, [:time?, []]]]],
183
+ [:val, p(:key?, :bday)],
184
+ [:key, [:bday, p(:time?, [])]],
183
185
  ]
184
186
  ]
185
187
  ]
@@ -193,17 +195,17 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
193
195
  rule_ast = [
194
196
  [
195
197
  :and, [
196
- [:val, [:predicate, [:key?, [:author]]]],
198
+ [:val, p(:key?, :author)],
197
199
  [:set, [
198
200
  [:and, [
199
- [:val, [:predicate, [:key?, [:books]]]],
201
+ [:val, p(:key?, :books)],
200
202
  [
201
203
  :each, [
202
204
  :set, [
203
205
  [
204
206
  :and, [
205
- [:val, [:predicate, [:key?, [:published]]]],
206
- [:key, [:published, [:predicate, [:bool?, []]]]]
207
+ [:val, p(:key?, :published)],
208
+ [:key, [:published, p(:bool?, [])]]
207
209
  ]
208
210
  ]
209
211
  ]
@@ -230,10 +232,10 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
230
232
  rule_ast = [
231
233
  [
232
234
  :and, [
233
- [:val, [:predicate, [:key?, [:ids]]]],
235
+ [:val, p(:key?, :ids)],
234
236
  [:and, [
235
- [:key, [:ids, [:predicate, [:array?, []]]]],
236
- [:each, [:val, [:predicate, [:int?, []]]]]
237
+ [:key, [:ids, p(:array?, [])]],
238
+ [:each, [:val, p(:int?, [])]]
237
239
  ]]
238
240
  ]
239
241
  ]
@@ -250,16 +252,16 @@ RSpec.describe Dry::Validation::InputProcessorCompiler::JSON, '#call' do
250
252
  rule_ast = [
251
253
  [
252
254
  :and, [
253
- [:val, [:predicate, [:key?, [:address]]]],
255
+ [:val, p(:key?, :address)],
254
256
  [
255
257
  :and, [
256
- [:key, [:address, [:predicate, [:hash?, []]]]],
258
+ [:key, [:address, p(:hash?, [])]],
257
259
  [
258
260
  :set, [
259
261
  [
260
262
  :and, [
261
- [:val, [:predicate, [:key?, [:street]]]],
262
- [:key, [:street, [:predicate, [:filled?, []]]]]
263
+ [:val, p(:key?, :street)],
264
+ [:key, [:street, p(:filled?, [])]]
263
265
  ]
264
266
  ]
265
267
  ]
@@ -0,0 +1,34 @@
1
+ require 'dry/validation/predicate_registry'
2
+
3
+ RSpec.describe PredicateRegistry do
4
+ subject!(:predicate_registry) { schema_class.registry }
5
+
6
+ let(:schema_class) { Class.new(Schema) }
7
+ let(:schema) { schema_class.new }
8
+
9
+ before do
10
+ schema_class.class_eval { def dis_ok?; true; end }
11
+ end
12
+
13
+ describe '.[]' do
14
+ it 'returns a registry which collects predicate methods' do
15
+ expect(predicate_registry[:dis_ok?]).to be_instance_of(Dry::Logic::Predicate)
16
+ end
17
+ end
18
+
19
+ describe '#[]' do
20
+ it 'gives access to built-in predicates' do
21
+ expect(predicate_registry[:filled?].("sutin")).to be(true)
22
+ end
23
+ end
24
+
25
+ describe '#bind' do
26
+ it 'binds unbound predicates and return finalized registry' do
27
+ registry = predicate_registry.bind(schema)
28
+
29
+ expect(registry).to be_frozen
30
+ expect(registry[:dis_ok?]).to be_instance_of(Dry::Logic::Predicate)
31
+ expect(registry[:dis_ok?].()).to be(true)
32
+ end
33
+ end
34
+ end
@@ -1,29 +1,27 @@
1
1
  RSpec.describe Schema::Key do
2
- describe '#key?' do
3
- subject(:user) { Schema::Key[:user] }
2
+ include_context 'predicate helper'
4
3
 
5
- it 'returns a key rule' do
6
- rule = user.key?(:address)
4
+ let(:registry) { PredicateRegistry.new(predicates) }
5
+
6
+ describe '#str?' do
7
+ subject(:user) { Schema::Key[:user, registry: registry] }
7
8
 
8
- expect(rule.to_ast).to eql([:key, [:user, [:predicate, [:key?, [:address]]]]])
9
+ it 'returns a key rule' do
10
+ expect(user.str?.to_ast).to eql([:key, [:user, p(:str?)]])
9
11
  end
10
12
 
11
13
  it 'returns a key rule & disjunction rule created within the block' do
12
14
  user.hash? do
13
- key(:email) { none? | filled? }
15
+ required(:email) { none? | filled? }
14
16
  end
15
17
 
16
18
  expect(user.to_ast).to eql([
17
19
  :key, [:user, [
18
20
  :and, [
19
- [:val, [:predicate, [:hash?, []]]],
20
- [:key, [:user, [:set, [
21
- [:and, [
22
- [:val, [:predicate, [:key?, [:email]]]],
23
- [:or, [
24
- [:key, [:email, [:predicate, [:none?, []]]]],
25
- [:key, [:email, [:predicate, [:filled?, []]]]]]
26
- ]]
21
+ [:val, p(:hash?)],
22
+ [:key, [:user, [:and, [
23
+ [:val, p(:key?, :email)],
24
+ [:or, [[:key, [:email, p(:none?)]], [:key, [:email, p(:filled?)]]]
27
25
  ]]]]]
28
26
  ]
29
27
  ]]
@@ -1,6 +1,8 @@
1
1
  RSpec.describe Schema::Rule do
2
- let(:filled) { [:val, [:email, [:predicate, [:filled?, []]]]] }
3
- let(:format) { [:val, [:email, [:predicate, [:format?, [/regex/]]]]] }
2
+ include_context 'predicate helper'
3
+
4
+ let(:filled) { [:val, [:email, p(:filled?)]] }
5
+ let(:format) { [:val, [:email, p(:format?, /regex/)]] }
4
6
 
5
7
  let(:left) { Schema::Rule.new(filled, name: :email, target: target) }
6
8
  let(:right) { Schema::Rule.new(format, name: :email, target: target) }
@@ -1,147 +1,64 @@
1
1
  RSpec.describe Schema::Value do
2
2
  include_context 'rule compiler'
3
+ include_context 'predicate helper'
3
4
 
4
- describe '#key' do
5
- subject(:value) { Schema::Value.new }
5
+ let(:registry) { PredicateRegistry.new(predicates) }
6
+
7
+ describe '#required' do
8
+ subject(:value) { Schema::Value.new(registry: registry) }
6
9
 
7
10
  let(:expected_ast) do
8
11
  [:and, [
9
- [:val, [:predicate, [:key?, [:address]]]],
10
- [:key, [:address, [:predicate, [:filled?, []]]]]
12
+ [:val, p(:key?, :address)],
13
+ [:key, [:address, p(:filled?)]]
11
14
  ]]
12
15
  end
13
16
 
14
17
  it 'creates a rule for a specified key using a block' do
15
- rule = value.key(:address, &:filled?)
18
+ rule = value.required(:address, &:filled?)
16
19
 
17
20
  expect(rule.to_ast).to eql(expected_ast)
18
21
  end
19
22
 
20
23
  it 'creates a rule for a specified key using a macro' do
21
- rule = value.key(:address).required
22
-
23
- expect(rule.to_ast).to eql(expected_ast)
24
- end
25
- end
26
-
27
- describe '#key deeply nested' do
28
- subject(:value) { Schema::Value.new }
29
-
30
- let(:expected_ast) do
31
- [:and, [
32
- [:val, [:predicate, [:key?, [:address]]]],
33
- [:key, [:address,
34
- [:and, [
35
- [:val, [:predicate, [:key?, [:location]]]],
36
- [:key, [:location,
37
- [:set, [
38
- [:and, [
39
- [:val, [:predicate, [:key?, [:lat]]]],
40
- [:key, [:lat, [:predicate, [:filled?, []]]]]]
41
- ],
42
- [:and, [
43
- [:val, [:predicate, [:key?, [:lng]]]],
44
- [:key, [:lng, [:predicate, [:filled?, []]]]]
45
- ]]
46
- ]]
47
- ]]]
48
- ]]]
49
- ]]
50
- end
51
-
52
- it 'creates a rule for specified keys using blocks' do
53
- rule = value.key(:address) do
54
- key(:location) do
55
- key(:lat) { filled? }
56
- key(:lng) { filled? }
57
- end
58
- end
59
-
60
- expect(rule.to_ast).to eql(expected_ast)
61
- end
62
-
63
- it 'creates a rule for specified keys using macros' do
64
- rule = value.key(:address) do
65
- key(:location) do
66
- key(:lat).required
67
- key(:lng).required
68
- end
69
- end
70
-
71
- expect(rule.to_ast).to eql(expected_ast)
72
- end
73
- end
74
-
75
- describe '#key with multiple inner-keys' do
76
- subject(:value) { Schema::Value.new }
77
-
78
- let(:expected_ast) do
79
- [:and, [
80
- [:val, [:predicate, [:key?, [:address]]]],
81
- [:key, [:address, [:set, [
82
- [:and, [
83
- [:val, [:predicate, [:key?, [:city]]]],
84
- [:key, [:city, [:predicate, [:filled?, []]]]]]
85
- ],
86
- [:and, [
87
- [:val, [:predicate, [:key?, [:zipcode]]]],
88
- [:key, [:zipcode, [:predicate, [:filled?, []]]]]
89
- ]]
90
- ]]]]
91
- ]]
92
- end
93
-
94
- it 'creates a rule for specified keys using blocks' do
95
- rule = value.key(:address) do
96
- key(:city) { filled? }
97
- key(:zipcode) { filled? }
98
- end
99
-
100
- expect(rule.to_ast).to eql(expected_ast)
101
- end
102
-
103
- it 'creates a rule for specified keys using macros' do
104
- rule = value.key(:address) do
105
- key(:city).required
106
- key(:zipcode).required
107
- end
24
+ rule = value.required(:address).filled
108
25
 
109
26
  expect(rule.to_ast).to eql(expected_ast)
110
27
  end
111
28
  end
112
29
 
113
30
  describe '#each' do
114
- subject(:value) { Schema::Value.new }
31
+ subject(:value) { Schema::Value.new(registry: registry) }
115
32
 
116
33
  it 'creates an each rule with another rule returned from the block' do
117
34
  rule = value.each { key?(:method) }
118
35
 
119
36
  expect(rule.to_ast).to eql(
120
37
  [:and, [
121
- [:val, [:predicate, [:array?, []]]],
122
- [:each, [:set, [[:val, [:predicate, [:key?, [:method]]]]]]]
38
+ [:val, p(:array?)],
39
+ [:each, [:val, p(:key?, :method)]]
123
40
  ]]
124
41
  )
125
42
  end
126
43
 
127
44
  it 'creates an each rule with other rules returned from the block' do
128
45
  rule = value.each do
129
- key(:method) { str? }
130
- key(:amount) { float? }
46
+ required(:method) { str? }
47
+ required(:amount) { float? }
131
48
  end
132
49
 
133
50
  expect(rule.to_ast).to eql(
134
51
  [:and, [
135
- [:val, [:predicate, [:array?, []]]],
52
+ [:val, p(:array?)],
136
53
  [:each,
137
54
  [:set, [
138
55
  [:and, [
139
- [:val, [:predicate, [:key?, [:method]]]],
140
- [:key, [:method, [:predicate, [:str?, []]]]]
56
+ [:val, p(:key?, :method)],
57
+ [:key, [:method, p(:str?)]]
141
58
  ]],
142
59
  [:and, [
143
- [:val, [:predicate, [:key?, [:amount]]]],
144
- [:key, [:amount, [:predicate, [:float?, []]]]]
60
+ [:val, p(:key?, :amount)],
61
+ [:key, [:amount, p(:float?)]]
145
62
  ]]
146
63
  ]]]
147
64
  ]]
@@ -150,17 +67,17 @@ RSpec.describe Schema::Value do
150
67
  end
151
68
 
152
69
  describe '#hash? with block' do
153
- subject(:user) { Schema::Value.new }
70
+ subject(:user) { Schema::Value.new(registry: registry) }
154
71
 
155
72
  it 'builds hash? & rule created within the block' do
156
- rule = user.hash? { key(:email).required }
73
+ rule = user.hash? { required(:email).filled }
157
74
 
158
75
  expect(rule.to_ast).to eql([
159
76
  :and, [
160
- [:val, [:predicate, [:hash?, []]]],
77
+ [:val, p(:hash?)],
161
78
  [:and, [
162
- [:val, [:predicate, [:key?, [:email]]]],
163
- [:key, [:email, [:predicate, [:filled?, []]]]]
79
+ [:val, p(:key?, :email)],
80
+ [:key, [:email, p(:filled?)]]
164
81
  ]]
165
82
  ]
166
83
  ])
@@ -168,29 +85,29 @@ RSpec.describe Schema::Value do
168
85
 
169
86
  it 'builds hash? & rule created within the block with deep nesting' do
170
87
  rule = user.hash? do
171
- key(:address) do
88
+ required(:address) do
172
89
  hash? do
173
- key(:city).required
174
- key(:zipcode).required
90
+ required(:city).filled
91
+ required(:zipcode).filled
175
92
  end
176
93
  end
177
94
  end
178
95
 
179
96
  expect(rule.to_ast).to eql(
180
97
  [:and, [
181
- [:val, [:predicate, [:hash?, []]]],
98
+ [:val, p(:hash?)],
182
99
  [:and, [
183
- [:val, [:predicate, [:key?, [:address]]]],
100
+ [:val, p(:key?, :address)],
184
101
  [:and, [
185
- [:val, [:predicate, [:hash?, []]]],
102
+ [:val, p(:hash?)],
186
103
  [:key, [
187
104
  :address, [:set, [
188
105
  [:and, [
189
- [:val, [:predicate, [:key?, [:city]]]],
190
- [:key, [:city, [:predicate, [:filled?, []]]]]]],
106
+ [:val, p(:key?, :city)],
107
+ [:key, [:city, p(:filled?)]]]],
191
108
  [:and, [
192
- [:val, [:predicate, [:key?, [:zipcode]]]],
193
- [:key, [:zipcode, [:predicate, [:filled?, []]]]]]]
109
+ [:val, p(:key?, :zipcode)],
110
+ [:key, [:zipcode, p(:filled?)]]]]
194
111
  ]]
195
112
  ]]
196
113
  ]]
@@ -201,15 +118,15 @@ RSpec.describe Schema::Value do
201
118
  end
202
119
 
203
120
  describe '#not' do
204
- subject(:user) { Schema::Value.new }
121
+ subject(:user) { Schema::Value.new(registry: registry) }
205
122
 
206
123
  it 'builds a negated rule' do
207
- not_email = user.key(:email) { str?.not }
124
+ not_email = user.required(:email) { str?.not }
208
125
 
209
126
  expect(not_email.to_ast).to eql([
210
127
  :and, [
211
- [:val, [:predicate, [:key?, [:email]]]],
212
- [:not, [:key, [:email, [:predicate, [:str?, []]]]]]
128
+ [:val, p(:key?, :email)],
129
+ [:not, [:key, [:email, p(:str?)]]]
213
130
  ]
214
131
  ])
215
132
  end