hv 0.1.1 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9ce070297444b94651fa7b6123b493acc5711fff
4
- data.tar.gz: 1d560767fb9fad4d9e92743ad1a5d8fd8e0f3808
3
+ metadata.gz: 382af5e307f795cc879af3a04448005e158c1411
4
+ data.tar.gz: ed1fb6de9cbc9484422611da80b6b596d7e33492
5
5
  SHA512:
6
- metadata.gz: d821845aba2b7d75ad702f4020b080443cdf29822f772a51d9b529200186ad2b9146e6d89d69e5683c8285bf3ef88f0e7e0dc002657c5605cbfc04e7ba85e429
7
- data.tar.gz: 70dff345ce9442850dde2fbfa3d6b67b5056cfebd7db73fa5f5a3f6a89140511c2e7de17495fd86f49f926457f88667a61ef838f99637f54e694642213936223
6
+ metadata.gz: 72147820be7345306117a71fa16213366899af3400e6da653719c2b482ef85452c1ab3b20443b2bc46ef68079f854af0664e03fff4b328450df1120390aaa5d3
7
+ data.tar.gz: b91bb0731afe3ce6df264aa2f3ea67315883980768f839435fdb93d911b45f3789bcfae7f92a0452df10bf558928d7db5e45f6a78e332c6cae2c4f14beda4da2
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hv (0.1.0)
4
+ hv (0.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -32,6 +32,74 @@ schema = Schema.new(schema)
32
32
  schema.validates?({people: [{name: "juan"}, {name: "chus"}]}) # => true
33
33
  ```
34
34
 
35
+ Another example with custom validators and error processing
36
+
37
+ ```ruby
38
+
39
+ module MyAwesomeErrorProcessor
40
+
41
+ def self.call(result, i18n_errors_hash)
42
+ result.map do |path, validator, spec, given|
43
+ path_text = path.empty? ? "" : " in #{path}"
44
+ i18n_errors_hash[validator] % {path: path_text, validator: validator, spec: spec, given: given.inspect}
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ module I18nErrors
51
+
52
+ def self.translations
53
+ keys = {
54
+ type?: "Expected %{given} to be a %{spec}",
55
+ accept_if_underage: "You must accept if you're under 18"
56
+ }
57
+ keys.default = "Expected %{given}%{path} to be %{validator}:%{spec}"
58
+ keys
59
+ end
60
+
61
+ end
62
+
63
+
64
+ signUpForm = Hv::Schema.new do
65
+
66
+ # set_schema: set the schema structure.
67
+ set_schema ({
68
+ name: {type?: String},
69
+ # Custom validator :email?
70
+ email: {email?: true},
71
+ age: {type?: Integer},
72
+ accept_underage: {types?: [TrueClass, FalseClass]}
73
+ })
74
+
75
+ # set_error_processor: accepts is an object that respond to call(result, i18n), it could be a block
76
+ set_error_processor MyAwesomeErrorProcessor
77
+
78
+ # set_i18n_errors: accepts a hash with validators names as keys
79
+ set_i18n_errors I18nErrors.translations
80
+
81
+ # validator: define a new validator key
82
+ validator :email? do |spec, value, path|
83
+ is_email = validate_type?(String, value, path) &&
84
+ validate_format?(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i, value, path)
85
+ !(is_email ^ spec)
86
+ end
87
+
88
+ # validate: define a custom validation block. You must add_error() if validation doesn't match.
89
+ validate :accept_if_underage do |input|
90
+ if (!input[:accept_underage] && input[:age] < 18)
91
+ add_error([:accept_underage], :accept_if_underage, true, input[:accept_underage])
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ signUpForm.validates?({name: "Jhon", email: "jhon@me.com", age: 15, accept_underage: false})
98
+ # => false
99
+ signUpForm.errors
100
+ # => ["You must accept if you're under 18"]
101
+ ```
102
+
35
103
  Check 'test' folder for more validators examples.
36
104
 
37
105
 
data/Rakefile CHANGED
@@ -8,3 +8,7 @@ Rake::TestTask.new(:test) do |t|
8
8
  end
9
9
 
10
10
  task :default => :test
11
+
12
+ task :benchmark do
13
+ puts `bundle exec ruby benchmarks/validate_input.rb`
14
+ end
@@ -1,9 +1,18 @@
1
1
  module Hv
2
2
  module ErrorsProcessor
3
- def self.call(result)
3
+
4
+ def self.i18n_errors
5
+ keys = {
6
+ type?: "Expected %{given} to be a %{spec}"
7
+ }
8
+ keys.default = "Expected %{given}%{path} to be %{validator}:%{spec}"
9
+ keys
10
+ end
11
+
12
+ def self.call(result, i18n_errors_hash)
4
13
  result.map do |path, validator, spec, given|
5
14
  path_text = path.empty? ? "" : " in #{path}"
6
- "Expected #{given.inspect}#{path_text} to be #{validator}:#{spec}"
15
+ i18n_errors_hash[validator] % {path: path_text, validator: validator, spec: spec, given: given.inspect}
7
16
  end
8
17
  end
9
18
  end
@@ -1,36 +1,79 @@
1
1
  module Hv
2
2
  class Schema
3
3
 
4
- def initialize(schema)
4
+ def initialize(schema={}, &block)
5
5
  @schema = schema
6
+ @custom_validators = {}
7
+ @custom_validators_keys = []
8
+ @errors_processor = Hv::ErrorsProcessor
9
+ @i18n_errors = Hv::ErrorsProcessor.i18n_errors
10
+ self.instance_eval(&block) if block_given?
6
11
  end
7
12
 
8
13
  def result
9
14
  @result
10
15
  end
11
16
 
17
+ def set_schema(schema)
18
+ @schema = schema
19
+ end
20
+
12
21
  def validates?(input)
22
+ @skip_paths = []
13
23
  @result = []
14
24
  validate_schema(@schema, input, [])
25
+ run_custom_validators(input)
26
+ @result.empty?
27
+ end
28
+
29
+ def errors(errors_processor=nil, i18n_errors=nil)
30
+ i18n_errors = i18n_errors || @i18n_errors
31
+ errors_processor = errors_processor || @errors_processor
32
+ errors_processor.call(@result, i18n_errors)
15
33
  end
16
34
 
17
- def errors(errors_processor=Hv::ErrorsProcessor)
18
- errors_processor.call(@result)
35
+ def validate(custom_validator_name, &block)
36
+ @custom_validators[custom_validator_name] = block
37
+ end
38
+
39
+ def validator(key, &block)
40
+ @custom_validators_keys << key
41
+ define_singleton_method "validate_#{key}", block
42
+ end
43
+
44
+ def set_error_processor(error_processor)
45
+ @errors_processor = error_processor
46
+ end
47
+
48
+ def set_i18n_errors(hash)
49
+ @i18n_errors = hash
19
50
  end
20
51
 
21
52
  private
22
53
 
23
54
  def validator_key?(key)
24
55
  allowed_validators.include?(key) ||
25
- custom_validators.include?(key)
56
+ @custom_validators_keys.include?(key)
26
57
  end
27
58
 
28
59
  def allowed_validators
29
60
  [:optional?, :format?, :min_size?, :max_size?, :size?, :lt?, :gt?, :types?, :type?, :enum?, :proc?, :array?, :empty?]
30
61
  end
31
62
 
32
- def custom_validators
33
- []
63
+ def parent_is_optional?(path)
64
+ @skip_paths.any? { |parent_path|
65
+ (parent_path - path).empty?
66
+ }
67
+ end
68
+
69
+ def run_custom_validators(input)
70
+ @custom_validators.each do |name, blk|
71
+ blk.call(input)
72
+ end
73
+ end
74
+
75
+ def add_error(path, key, _spec, value)
76
+ @result << [path, key, _spec, value]
34
77
  end
35
78
 
36
79
  def validate_schema(spec, value, path=nil)
@@ -40,19 +83,24 @@ module Hv
40
83
  validate_schema(_spec, _value, [path, key].flatten)
41
84
  else
42
85
  match = if value.nil? && optional_attr?(path)
86
+ @skip_paths << path
43
87
  true
44
88
  else
45
89
  next if key == :optional?
46
- method("validate_#{key}").call(_spec, value, path)
90
+ next if parent_is_optional?(path)
91
+ send("validate_#{key}",_spec, value, path)
47
92
  end
48
- @result << [path, key, _spec, value] unless match
93
+ add_error(path, key, _spec, value) unless match
49
94
  end
50
95
  end
51
- @result.empty?
52
96
  end
53
97
 
54
- def optional_attr?(path)
55
- (@schema.dig(*path) || {})[:optional?]
98
+ def optional_attr?(path=[])
99
+ if path.empty?
100
+ @schema[:optional?]
101
+ else
102
+ (@schema.dig(*path) || {})[:optional?]
103
+ end
56
104
  end
57
105
 
58
106
  def validate_enum?(spec, value, path)
@@ -1,3 +1,3 @@
1
1
  module Hv
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Monkey Square Lab
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-07 00:00:00.000000000 Z
11
+ date: 2018-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -89,6 +89,7 @@ files:
89
89
  - lib/hv/schema.rb
90
90
  - lib/hv/version.rb
91
91
  - releases/hv-0.1.0.gem
92
+ - releases/hv-0.1.1.gem
92
93
  homepage: https://github.com/monkeysquarelab/hv
93
94
  licenses:
94
95
  - MIT