dry-validation 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -2
  3. data/Gemfile +4 -0
  4. data/README.md +131 -42
  5. data/config/errors.yml +36 -27
  6. data/examples/basic.rb +2 -4
  7. data/examples/each.rb +2 -2
  8. data/examples/form.rb +1 -2
  9. data/examples/nested.rb +2 -4
  10. data/examples/rule_ast.rb +0 -8
  11. data/lib/dry/validation.rb +0 -5
  12. data/lib/dry/validation/error.rb +2 -6
  13. data/lib/dry/validation/error_compiler.rb +19 -5
  14. data/lib/dry/validation/input_type_compiler.rb +2 -1
  15. data/lib/dry/validation/messages.rb +7 -58
  16. data/lib/dry/validation/messages/abstract.rb +75 -0
  17. data/lib/dry/validation/messages/i18n.rb +24 -0
  18. data/lib/dry/validation/messages/namespaced.rb +27 -0
  19. data/lib/dry/validation/messages/yaml.rb +50 -0
  20. data/lib/dry/validation/result.rb +19 -49
  21. data/lib/dry/validation/rule.rb +2 -2
  22. data/lib/dry/validation/rule/group.rb +21 -0
  23. data/lib/dry/validation/rule/result.rb +73 -0
  24. data/lib/dry/validation/rule_compiler.rb +5 -0
  25. data/lib/dry/validation/schema.rb +33 -14
  26. data/lib/dry/validation/schema/definition.rb +16 -0
  27. data/lib/dry/validation/schema/result.rb +21 -3
  28. data/lib/dry/validation/schema/rule.rb +1 -1
  29. data/lib/dry/validation/schema/value.rb +2 -1
  30. data/lib/dry/validation/version.rb +1 -1
  31. data/spec/fixtures/locales/en.yml +5 -0
  32. data/spec/fixtures/locales/pl.yml +14 -0
  33. data/spec/integration/custom_error_messages_spec.rb +4 -16
  34. data/spec/{unit → integration}/error_compiler_spec.rb +81 -39
  35. data/spec/integration/localized_error_messages_spec.rb +52 -0
  36. data/spec/integration/messages/i18n_spec.rb +71 -0
  37. data/spec/integration/rule_groups_spec.rb +35 -0
  38. data/spec/integration/schema_form_spec.rb +9 -9
  39. data/spec/integration/schema_spec.rb +2 -2
  40. data/spec/shared/predicates.rb +2 -0
  41. data/spec/spec_helper.rb +1 -0
  42. data/spec/unit/rule/group_spec.rb +12 -0
  43. data/spec/unit/schema_spec.rb +35 -0
  44. metadata +24 -6
  45. data/spec/fixtures/errors.yml +0 -4
@@ -0,0 +1,52 @@
1
+ RSpec.describe Dry::Validation, 'with localized messages' do
2
+ subject(:validation) { schema.new }
3
+
4
+ before do
5
+ I18n.config.available_locales_set << :pl
6
+ I18n.load_path = %w(en pl).map { |l| SPEC_ROOT.join("fixtures/locales/#{l}.yml") }
7
+ I18n.backend.load_translations
8
+ end
9
+
10
+ describe 'defining schema' do
11
+ context 'without a namespace' do
12
+ let(:schema) do
13
+ Class.new(Dry::Validation::Schema) do
14
+ configure do |config|
15
+ config.messages = :i18n
16
+ end
17
+
18
+ key(:email) { |email| email.filled? }
19
+ end
20
+ end
21
+
22
+ describe '#messages' do
23
+ it 'returns localized error messages' do
24
+ expect(validation.(email: '').messages(locale: :pl)).to match_array([
25
+ [:email, [['Proszę podać adres email', '']]]
26
+ ])
27
+ end
28
+ end
29
+ end
30
+
31
+ context 'with a namespace' do
32
+ let(:schema) do
33
+ Class.new(Dry::Validation::Schema) do
34
+ configure do |config|
35
+ config.messages = :i18n
36
+ config.namespace = :user
37
+ end
38
+
39
+ key(:email) { |email| email.filled? }
40
+ end
41
+ end
42
+
43
+ describe '#messages' do
44
+ it 'returns localized error messages' do
45
+ expect(validation.(email: '').messages(locale: :pl)).to match_array([
46
+ [:email, [['Hej user! Dawaj ten email no!', '']]]
47
+ ])
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,71 @@
1
+ require 'dry/validation/messages/i18n'
2
+
3
+ RSpec.describe Messages::I18n do
4
+ subject(:messages) { Messages::I18n.new }
5
+
6
+ before do
7
+ I18n.config.available_locales_set << :pl
8
+ I18n.load_path << %w(en pl).map { |l| SPEC_ROOT.join("fixtures/locales/#{l}.yml") }
9
+ I18n.backend.load_translations
10
+ end
11
+
12
+ describe '#[]' do
13
+ context 'with the default locale' do
14
+ it 'returns a message for a predicate' do
15
+ message = messages[:filled?, rule: :name]
16
+
17
+ expect(message).to eql("%{name} must be filled")
18
+ end
19
+
20
+ it 'returns a message for a specific rule' do
21
+ message = messages[:filled?, rule: :email]
22
+
23
+ expect(message).to eql("Please provide your email")
24
+ end
25
+
26
+ it 'returns a message for a specific val type' do
27
+ message = messages[:size?, rule: :pages, val_type: String]
28
+
29
+ expect(message).to eql("%{name} length must be %{num}")
30
+ end
31
+
32
+ it 'returns a message for a specific rule and its default arg type' do
33
+ message = messages[:size?, rule: :pages]
34
+
35
+ expect(message).to eql("%{name} size must be %{num}")
36
+ end
37
+
38
+ it 'returns a message for a specific rule and its arg type' do
39
+ message = messages[:size?, rule: :pages, arg_type: Range]
40
+
41
+ expect(message).to eql("%{name} size must be within %{left} - %{right}")
42
+ end
43
+ end
44
+
45
+ context 'with a different locale' do
46
+ it 'returns a message for a predicate' do
47
+ message = messages[:filled?, rule: :name, locale: :pl]
48
+
49
+ expect(message).to eql("%{name} nie może być pusty")
50
+ end
51
+
52
+ it 'returns a message for a specific rule' do
53
+ message = messages[:filled?, rule: :email, locale: :pl]
54
+
55
+ expect(message).to eql("Proszę podać adres email")
56
+ end
57
+
58
+ it 'returns a message for a specific rule and its default arg type' do
59
+ message = messages[:size?, rule: :pages, locale: :pl]
60
+
61
+ expect(message).to eql("wielkość musi być równa %{num}")
62
+ end
63
+
64
+ it 'returns a message for a specific rule and its arg type' do
65
+ message = messages[:size?, rule: :pages, arg_type: Range, locale: :pl]
66
+
67
+ expect(message).to eql("wielkość musi być między %{left} a %{right}")
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,35 @@
1
+ RSpec.describe Dry::Validation::Schema do
2
+ subject(:validation) { schema.new }
3
+
4
+ describe 'defining schema with rule groups' do
5
+ let(:schema) do
6
+ Class.new(Dry::Validation::Schema) do
7
+ confirmation(:password)
8
+ end
9
+ end
10
+
11
+ describe '#call' do
12
+ it 'returns empty errors when password matches confirmation' do
13
+ expect(validation.(password: 'foo', password_confirmation: 'foo')).to be_empty
14
+ end
15
+
16
+ it 'returns error for a failed group rule' do
17
+ expect(validation.(password: 'foo', password_confirmation: 'bar')).to match_array([
18
+ [:error, [
19
+ :input, [
20
+ :password_confirmation,
21
+ ["foo", "bar"],
22
+ [[:group, [:password_confirmation, [:predicate, [:eql?, []]]]]]]]
23
+ ]
24
+ ])
25
+ end
26
+
27
+ it 'returns errors for the dependent predicates, not the group rule, when any of the dependent predicates fail' do
28
+ expect(validation.(password: '', password_confirmation: '')).to match_array([
29
+ [:error, [:input, [:password, "", [[:val, [:password, [:predicate, [:filled?, []]]]]]]]],
30
+ [:error, [:input, [:password_confirmation, "", [[:val, [:password_confirmation, [:predicate, [:filled?, []]]]]]]]]
31
+ ])
32
+ end
33
+ end
34
+ end
35
+ end
@@ -22,17 +22,19 @@ RSpec.describe Dry::Validation::Schema::Form do
22
22
  end
23
23
  end
24
24
 
25
- optional(:phone_number) { |phone_number| phone_number.none? | phone_number.str? }
25
+ optional(:phone_number) do |phone_number|
26
+ phone_number.none? | (phone_number.int? & phone_number.gt?(0))
27
+ end
26
28
  end
27
29
  end
28
30
 
29
31
  describe '#messages' do
30
32
  it 'returns compiled error messages' do
31
- result = validation.messages('email' => '', 'age' => '19')
33
+ result = validation.('email' => '', 'age' => '19')
32
34
 
33
- expect(result).to match_array([
34
- [:email, ["email must be filled"]],
35
- [:address, ["address is missing"]]
35
+ expect(result.messages).to match_array([
36
+ [:email, [['email must be filled', '']]],
37
+ [:address, [['address is missing', nil]]]
36
38
  ])
37
39
 
38
40
  expect(result.params).to eql(email: '', age: 19)
@@ -74,7 +76,7 @@ RSpec.describe Dry::Validation::Schema::Form do
74
76
  result = validation.(
75
77
  'email' => 'jane@doe.org',
76
78
  'age' => '19',
77
- 'phone_number' => 12,
79
+ 'phone_number' => '12',
78
80
  'address' => {
79
81
  'city' => 'NYC',
80
82
  'street' => 'Street 1/2',
@@ -82,9 +84,7 @@ RSpec.describe Dry::Validation::Schema::Form do
82
84
  }
83
85
  )
84
86
 
85
- expect(result).to match_array([
86
- [:error, [:input, [:phone_number, 12, [[:val, [:phone_number, [:predicate, [:str?, []]]]]]]]],
87
- ])
87
+ expect(result).to be_empty
88
88
 
89
89
  expect(result.params).to eql(
90
90
  email: 'jane@doe.org', age: 19, phone_number: 12,
@@ -46,8 +46,8 @@ RSpec.describe Dry::Validation::Schema do
46
46
 
47
47
  describe '#messages' do
48
48
  it 'returns compiled error messages' do
49
- expect(validation.messages(attrs.merge(email: ''))).to match_array([
50
- [:email, ["email must be filled"]]
49
+ expect(validation.(attrs.merge(email: '')).messages).to match_array([
50
+ [:email, [['email must be filled', '']]]
51
51
  ])
52
52
  end
53
53
  end
@@ -8,6 +8,8 @@ RSpec.shared_examples 'predicates' do
8
8
  let(:min_size?) { Dry::Validation::Predicates[:min_size?] }
9
9
 
10
10
  let(:key?) { Dry::Validation::Predicates[:key?] }
11
+
12
+ let(:eql?) { Dry::Validation::Predicates[:eql?] }
11
13
  end
12
14
 
13
15
  RSpec.shared_examples 'a passing predicate' do
@@ -1,5 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require 'i18n'
3
4
  require 'dry-validation'
4
5
 
5
6
  begin
@@ -0,0 +1,12 @@
1
+ RSpec.describe Rule::Group do
2
+ include_context 'predicates'
3
+
4
+ subject(:rule) { Rule::Group.new([:pass, :pass_confirm], eql?) }
5
+
6
+ describe '#call' do
7
+ it 'calls predicate with result values' do
8
+ expect(rule.('foo', 'foo')).to be_success
9
+ expect(rule.('foo', 'bar')).to be_failure
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,35 @@
1
+ require 'dry/validation/messages/i18n'
2
+
3
+ RSpec.describe Schema do
4
+ describe '.messages' do
5
+ context 'with default setting' do
6
+ let(:schema) do
7
+ Class.new(Schema)
8
+ end
9
+
10
+ it 'returns default yaml messages' do
11
+ expect(schema.messages).to be_instance_of(Messages::YAML)
12
+ end
13
+ end
14
+
15
+ context 'with i18n setting' do
16
+ let(:schema) do
17
+ Class.new(Schema) { configure { config.messages = :i18n } }
18
+ end
19
+
20
+ it 'returns default i18n messages' do
21
+ expect(schema.messages).to be_instance_of(Messages::I18n)
22
+ end
23
+ end
24
+
25
+ context 'with an invalid setting' do
26
+ let(:schema) do
27
+ Class.new(Schema) { configure { config.messages = :oops } }
28
+ end
29
+
30
+ it 'returns default i18n messages' do
31
+ expect { schema.messages }.to raise_error(RuntimeError, /oops/)
32
+ end
33
+ end
34
+ end
35
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-validation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Holland
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-11-30 00:00:00.000000000 Z
12
+ date: 2015-12-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: dry-configurable
@@ -152,6 +152,10 @@ files:
152
152
  - lib/dry/validation/error_compiler.rb
153
153
  - lib/dry/validation/input_type_compiler.rb
154
154
  - lib/dry/validation/messages.rb
155
+ - lib/dry/validation/messages/abstract.rb
156
+ - lib/dry/validation/messages/i18n.rb
157
+ - lib/dry/validation/messages/namespaced.rb
158
+ - lib/dry/validation/messages/yaml.rb
155
159
  - lib/dry/validation/predicate.rb
156
160
  - lib/dry/validation/predicate_set.rb
157
161
  - lib/dry/validation/predicates.rb
@@ -159,7 +163,9 @@ files:
159
163
  - lib/dry/validation/rule.rb
160
164
  - lib/dry/validation/rule/composite.rb
161
165
  - lib/dry/validation/rule/each.rb
166
+ - lib/dry/validation/rule/group.rb
162
167
  - lib/dry/validation/rule/key.rb
168
+ - lib/dry/validation/rule/result.rb
163
169
  - lib/dry/validation/rule/set.rb
164
170
  - lib/dry/validation/rule/value.rb
165
171
  - lib/dry/validation/rule_compiler.rb
@@ -172,15 +178,19 @@ files:
172
178
  - lib/dry/validation/schema/value.rb
173
179
  - lib/dry/validation/version.rb
174
180
  - rakelib/rubocop.rake
175
- - spec/fixtures/errors.yml
181
+ - spec/fixtures/locales/en.yml
182
+ - spec/fixtures/locales/pl.yml
176
183
  - spec/integration/custom_error_messages_spec.rb
177
184
  - spec/integration/custom_predicates_spec.rb
185
+ - spec/integration/error_compiler_spec.rb
186
+ - spec/integration/localized_error_messages_spec.rb
187
+ - spec/integration/messages/i18n_spec.rb
178
188
  - spec/integration/optional_keys_spec.rb
189
+ - spec/integration/rule_groups_spec.rb
179
190
  - spec/integration/schema_form_spec.rb
180
191
  - spec/integration/schema_spec.rb
181
192
  - spec/shared/predicates.rb
182
193
  - spec/spec_helper.rb
183
- - spec/unit/error_compiler_spec.rb
184
194
  - spec/unit/input_type_compiler_spec.rb
185
195
  - spec/unit/predicate_spec.rb
186
196
  - spec/unit/predicates/bool_spec.rb
@@ -209,11 +219,13 @@ files:
209
219
  - spec/unit/rule/conjunction_spec.rb
210
220
  - spec/unit/rule/disjunction_spec.rb
211
221
  - spec/unit/rule/each_spec.rb
222
+ - spec/unit/rule/group_spec.rb
212
223
  - spec/unit/rule/implication_spec.rb
213
224
  - spec/unit/rule/key_spec.rb
214
225
  - spec/unit/rule/set_spec.rb
215
226
  - spec/unit/rule/value_spec.rb
216
227
  - spec/unit/rule_compiler_spec.rb
228
+ - spec/unit/schema_spec.rb
217
229
  homepage: https://github.com/dryrb/dry-validation
218
230
  licenses:
219
231
  - MIT
@@ -239,15 +251,19 @@ signing_key:
239
251
  specification_version: 4
240
252
  summary: A simple validation library
241
253
  test_files:
242
- - spec/fixtures/errors.yml
254
+ - spec/fixtures/locales/en.yml
255
+ - spec/fixtures/locales/pl.yml
243
256
  - spec/integration/custom_error_messages_spec.rb
244
257
  - spec/integration/custom_predicates_spec.rb
258
+ - spec/integration/error_compiler_spec.rb
259
+ - spec/integration/localized_error_messages_spec.rb
260
+ - spec/integration/messages/i18n_spec.rb
245
261
  - spec/integration/optional_keys_spec.rb
262
+ - spec/integration/rule_groups_spec.rb
246
263
  - spec/integration/schema_form_spec.rb
247
264
  - spec/integration/schema_spec.rb
248
265
  - spec/shared/predicates.rb
249
266
  - spec/spec_helper.rb
250
- - spec/unit/error_compiler_spec.rb
251
267
  - spec/unit/input_type_compiler_spec.rb
252
268
  - spec/unit/predicate_spec.rb
253
269
  - spec/unit/predicates/bool_spec.rb
@@ -276,9 +292,11 @@ test_files:
276
292
  - spec/unit/rule/conjunction_spec.rb
277
293
  - spec/unit/rule/disjunction_spec.rb
278
294
  - spec/unit/rule/each_spec.rb
295
+ - spec/unit/rule/group_spec.rb
279
296
  - spec/unit/rule/implication_spec.rb
280
297
  - spec/unit/rule/key_spec.rb
281
298
  - spec/unit/rule/set_spec.rb
282
299
  - spec/unit/rule/value_spec.rb
283
300
  - spec/unit/rule_compiler_spec.rb
301
+ - spec/unit/schema_spec.rb
284
302
  has_rdoc:
@@ -1,4 +0,0 @@
1
- user:
2
- attributes:
3
- email:
4
- filled?: "%{name} can't be blank"