dry-validation 0.7.4 → 0.8.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 (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