objecheck 0.1.0 → 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
  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