objecheck 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c34dee3669dc8ba5d6da6601f2691dfa1cdf596b23cdb575ce99fec568e84283
4
- data.tar.gz: 5a190c9ad765f40ae422a87462134a2066c48497acb63518f2cc63f1cded79e1
3
+ metadata.gz: affc792d7a719592fb092a7e9c8bf3aa3bfbc06afca7fad8809ba1d053d1edbf
4
+ data.tar.gz: d776e2cb69dcf8193f60f526bc07adec05aa8c27c80a4bb51c0d19ceba365f00
5
5
  SHA512:
6
- metadata.gz: 57c538a3674c233bbf7ba84a6bd0a454b8f0532306d62530adce569b6965143180c60be60e3899064eb671f293d31886ae515d65b6418641e13c66d6ac36f2e0
7
- data.tar.gz: df4388871daec2f26406fa2bd91e0c9e9779d70fbef3a8c32a11187bd6effb43f90130dab742c4e094ced95f182356e058a5c2cfbc23b2f8bab1b6a6c20fa3de
6
+ metadata.gz: 5ccebbd3396d7f066cb2e7f6cb56c36de1e839d6ee12511e52128355b5e56708f614ed323fab8df3f9b48350d584eb486515376eb96cad4abe76bf9fd83258bf
7
+ data.tar.gz: bbb8f479f54c1461e9b3c8a690d11fa86eaf6471a31d36c4d393312d47be60c14dfd29aa146791627eabc412a96a84cd4381a46172e0b57a779bdf2f091834d5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Change Log
2
2
 
3
+ ## v0.2.0
4
+
5
+ - Change signature of rule's `#validate` to enable nested schema
6
+ - Include rule name in error message
7
+ - Add `EachRule` as `each_rule`
8
+ - Add `EachKeyRule` as `each_key_rule`
9
+ - Add `EachValueRule` as `each_value_rule`
10
+ - Add `KeyValueRule` as `key_value_rule`
11
+
3
12
  ## v0.1.0
4
13
 
5
14
  First release
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Objecheck
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/objecheck.svg)](https://badge.fury.io/rb/objecheck)
3
4
  [![CircleCI](https://circleci.com/gh/autopp/objecheck/tree/master.svg?style=shield)](https://circleci.com/gh/autopp/objecheck/tree/master)
4
5
 
5
6
  Objecheck provides a simple and extensible object validator
@@ -33,6 +34,32 @@ validator = Objecheck::Validator.new({
33
34
  # Validator#validate checks the given object and returns error messages as a array
34
35
  p validator.validate({ a: 1, b: 2 }) # => []
35
36
  p validator.validate([1, 2]) # => ["root: the type should be a Hash (got Array)"]
37
+
38
+ # Validate type of keys and values
39
+ validator = Objecheck::Validator.new({
40
+ each_key: { type: Symbol }
41
+ each_value: { type: Integer }
42
+ })
43
+
44
+ p validator.validate({ a: 1, b: 2 }) # => []
45
+
46
+ # Validate array that contains specific key/value
47
+ validator = Objecheck::Validator.new({
48
+ type: Array,
49
+ each: {
50
+ key_value: {
51
+ name: {
52
+ value: { type: String }
53
+ },
54
+ age: {
55
+ required: false,
56
+ value: { type: Integer }
57
+ }
58
+ }
59
+ }
60
+ })
61
+
62
+ p validator.validate([{ name: 'Jhon', age: 20 }, { name: 'Tom' }]) # => []
36
63
  ```
37
64
 
38
65
  ## Builtin rules
@@ -48,6 +75,64 @@ Example schema:
48
75
  }
49
76
  ```
50
77
 
78
+ ### `each`
79
+
80
+ `each` checks elements of the object by using `each`.
81
+
82
+ Example schema:
83
+ ```ruby
84
+ {
85
+ each: {
86
+ type: Integer
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### `each_key`
92
+
93
+ `each_key` checks keys of the object by using `each_key`.
94
+
95
+ Example schema:
96
+ ```ruby
97
+ {
98
+ each_key: {
99
+ type: Symbol
100
+ }
101
+ }
102
+ ```
103
+
104
+ ### `each_value`
105
+
106
+ `each_value` checks values of the object by using `each_pair`.
107
+
108
+ Example schema:
109
+ ```ruby
110
+ {
111
+ each_value: {
112
+ type: Integer
113
+ }
114
+ }
115
+ ```
116
+
117
+ ### `key_value`
118
+
119
+ `key_value` checks key/values of the object by using `each_pair`.
120
+
121
+ Example schema:
122
+ ```ruby
123
+ {
124
+ key_value: {
125
+ name: {
126
+ value: { type: String }
127
+ },
128
+ age: {
129
+ required: false # Default is true
130
+ value: { type: Integer }
131
+ }
132
+ }
133
+ }
134
+ ```
135
+
51
136
  ## Contributing
52
137
 
53
138
  Bug reports and pull requests are welcome on GitHub at https://github.com/autopp/objecheck.
@@ -19,6 +19,7 @@
19
19
  class Objecheck::Validator::Collector
20
20
  def initialize(validator)
21
21
  @validator = validator
22
+ @current_rule_name = nil
22
23
  @prefix_stack = []
23
24
  @errors = []
24
25
  end
@@ -31,7 +32,17 @@ class Objecheck::Validator::Collector
31
32
  end
32
33
 
33
34
  def add_error(msg)
34
- @errors << "#{@prefix_stack.join('')}: #{msg}"
35
+ @errors << "#{@prefix_stack.join('')}: #{@current_rule_name}: #{msg}"
36
+ end
37
+
38
+ def validate(target, rules)
39
+ prev_rule_name = @current_rule_name
40
+ rules.each do |name, rule|
41
+ @current_rule_name = name
42
+ rule.validate(target, self)
43
+ end
44
+ ensure
45
+ @current_rule_name = prev_rule_name
35
46
  end
36
47
 
37
48
  def errors
@@ -0,0 +1,36 @@
1
+ #
2
+ # Objecheck
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ # EachKeyRule validates keys in the target by using each_key
18
+ #
19
+ class Objecheck::Validator::EachKeyRule
20
+ def initialize(validator, key_schema)
21
+ @key_rules = validator.compile_schema(key_schema)
22
+ end
23
+
24
+ def validate(target, collector)
25
+ if !target.respond_to?(:each_key)
26
+ collector.add_error('should respond to `each_key`')
27
+ return
28
+ end
29
+
30
+ target.each_key do |key|
31
+ collector.add_prefix_in(".key(#{key.inspect})") do
32
+ collector.validate(key, @key_rules)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ #
2
+ # Objecheck
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ # EachRule validates elements in the target by using each
18
+ #
19
+ class Objecheck::Validator::EachRule
20
+ def initialize(validator, element_schema)
21
+ @element_rules = validator.compile_schema(element_schema)
22
+ end
23
+
24
+ def validate(target, collector)
25
+ if !target.respond_to?(:each)
26
+ collector.add_error('should respond to `each`')
27
+ return
28
+ end
29
+
30
+ target.each.with_index do |elem, i|
31
+ collector.add_prefix_in("[#{i}]") do
32
+ collector.validate(elem, @element_rules)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ #
2
+ # Objecheck
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ # EachValueRule validates values in the target by using each_pair
18
+ #
19
+ class Objecheck::Validator::EachValueRule
20
+ def initialize(validator, value_schema)
21
+ @value_rules = validator.compile_schema(value_schema)
22
+ end
23
+
24
+ def validate(target, collector)
25
+ if !target.respond_to?(:each_pair)
26
+ collector.add_error('should respond to `each_pair`')
27
+ return
28
+ end
29
+
30
+ target.each_pair do |key, value|
31
+ collector.add_prefix_in("[#{key.inspect}]") do
32
+ collector.validate(value, @value_rules)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,45 @@
1
+ #
2
+ # Objecheck
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ # KeyValueRule validates key/value in the target by using each_pair
18
+ #
19
+ class Objecheck::Validator::KeyValueRule
20
+ def initialize(validator, key_value_schema)
21
+ @key_value_rules = key_value_schema.each_with_object({}) do |(key, schema), rules|
22
+ rules[key] = {
23
+ required: schema.fetch(:required, true),
24
+ rule: validator.compile_schema(schema[:value])
25
+ }
26
+ end
27
+ end
28
+
29
+ def validate(target, collector)
30
+ if !target.respond_to?(:each_pair)
31
+ collector.add_error('should respond to `each_pair`')
32
+ return
33
+ end
34
+
35
+ @key_value_rules.each_pair do |key, rule|
36
+ if target.key?(key)
37
+ collector.add_prefix_in("[#{key.inspect}]") do
38
+ collector.validate(target[key], rule[:rule])
39
+ end
40
+ elsif rule[:required]
41
+ collector.add_error("should contain key #{key.inspect}")
42
+ end
43
+ end
44
+ end
45
+ end
@@ -17,11 +17,11 @@
17
17
  # TypeRule validates type of a target
18
18
  #
19
19
  class Objecheck::Validator::TypeRule
20
- def initialize(type)
20
+ def initialize(_validator, type)
21
21
  @type = type
22
22
  end
23
23
 
24
24
  def validate(target, collector)
25
- collector.add_error("the type should be a #{@type} (got #{target.class})") if !target.is_a?(@type)
25
+ collector.add_error("should be a #{@type} (got #{target.class})") if !target.is_a?(@type)
26
26
  end
27
27
  end
@@ -18,25 +18,36 @@
18
18
  #
19
19
  class Objecheck::Validator
20
20
  require 'objecheck/validator/type_rule'
21
+ require 'objecheck/validator/each_rule'
22
+ require 'objecheck/validator/each_key_rule'
23
+ require 'objecheck/validator/each_value_rule'
24
+ require 'objecheck/validator/key_value_rule'
21
25
  DEFAULT_RULES = {
22
- type: TypeRule
26
+ type: TypeRule,
27
+ each: EachRule,
28
+ each_key: EachKeyRule,
29
+ each_value: EachValueRule,
30
+ key_value: KeyValueRule
23
31
  }.freeze
24
32
 
25
- def initialize(schema, rules = DEFAULT_RULES)
26
- @rules = schema.map do |rule_name, param|
27
- rules[rule_name].new(param)
28
- end
33
+ def initialize(schema, rule_map = DEFAULT_RULES)
34
+ @rule_map = rule_map
35
+ @rules = compile_schema(schema)
29
36
  end
30
37
 
31
38
  def validate(target)
32
39
  collector = Collector.new(self)
33
40
  collector.add_prefix_in('root') do
34
- @rules.each do |rule|
35
- rule.validate(target, collector)
36
- end
41
+ collector.validate(target, @rules)
37
42
  end
38
43
  collector.errors
39
44
  end
45
+
46
+ def compile_schema(schema)
47
+ schema.each_with_object({}) do |(rule_name, param), rules|
48
+ rules[rule_name] = @rule_map[rule_name].new(self, param)
49
+ end
50
+ end
40
51
  end
41
52
 
42
53
  require 'objecheck/validator/collector'
data/objecheck.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'objecheck'
3
- spec.version = '0.1.0'
3
+ spec.version = '0.2.0'
4
4
  spec.authors = ['autopp']
5
5
  spec.email = ['autopp.inc@gmail.com']
6
6
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: objecheck
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - autopp
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-09-18 00:00:00.000000000 Z
11
+ date: 2018-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -87,6 +87,10 @@ files:
87
87
  - lib/objecheck.rb
88
88
  - lib/objecheck/validator.rb
89
89
  - lib/objecheck/validator/collector.rb
90
+ - lib/objecheck/validator/each_key_rule.rb
91
+ - lib/objecheck/validator/each_rule.rb
92
+ - lib/objecheck/validator/each_value_rule.rb
93
+ - lib/objecheck/validator/key_value_rule.rb
90
94
  - lib/objecheck/validator/type_rule.rb
91
95
  - objecheck.gemspec
92
96
  homepage: https://github.com/autopp/objecheck