objecheck 0.3.0 → 0.4.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: 0e5e64af44a98f5a68b9a29c37c3aebb76b07838cab71bf1855b043f2e4c81f3
4
- data.tar.gz: 1aab0ebbeb4d062fef6cfd2d89ae063ee9429864c11ed83f99523c053eeea677
3
+ metadata.gz: 29c7a9581a27191aa05d1df83b5743bb7ad31b82cc4bad3e14c88730e65ffcd5
4
+ data.tar.gz: a58f1b7f322487a8211ab49ddb2188e5fa88729378bdcdc5740c4ab96ea12a1a
5
5
  SHA512:
6
- metadata.gz: 8b670597d9010ea8b5abb053f9e2a13f6c6c3b810e7b6b042421dc6a24ceee0b9de8607ba4bcb36e1f26c25fa015fae3e6146b900eab481fff703bae657f65db
7
- data.tar.gz: e381afd9b7169b6bf6b38062df731bb4d9738fcbc483f25519c392acfb87e9e2b4da8f54598d189e29f378bfb798d9f5a922ae7ddceae836d0d18f6a93259042
6
+ metadata.gz: c6ad10d126d6b66c26c6c5c4d8e9ee8c1ff44ec93a69dbb4a0b509af64f1f5a421b85b2f8f8d7200653a95764cf905bb758ce5a7a0e7e339238d3431acd1044a
7
+ data.tar.gz: 1f21d8d7f8245f9a0e4c640b91740e8adc44cc3da1bfd3750936af45b2d6c4b52278d9d3b80c16115501c4ed6086cd23ff5a7d4d6e860b83060a141097e91872
data/.rubocop.yml CHANGED
@@ -58,6 +58,9 @@ Metrics/PerceivedComplexity:
58
58
  Metrics/CyclomaticComplexity:
59
59
  Max: 7
60
60
 
61
+ Naming/UncommunicativeMethodParamName:
62
+ Enabled: false
63
+
61
64
  Performance/RedundantMerge:
62
65
  Enabled: false
63
66
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Change Log
2
2
 
3
+ ## v0.4.0
4
+
5
+ - Add `AnyRule` as `any`
6
+ - Add transaction API to collector for commit/rollback errors
7
+
3
8
  ## v0.3.0
4
9
 
5
10
  - Add `EqRule` as `eq`
data/README.md CHANGED
@@ -151,6 +151,20 @@ Example schema:
151
151
  }
152
152
  ```
153
153
 
154
+ ### `any`
155
+
156
+ `any` makes disjunction of rules.
157
+
158
+ Example schema:
159
+ ```ruby
160
+ {
161
+ any: [
162
+ { type: Integer },
163
+ { type: String }
164
+ ]
165
+ }
166
+ ```
167
+
154
168
  ## Contributing
155
169
 
156
170
  Bug reports and pull requests are welcome on GitHub at https://github.com/autopp/objecheck.
@@ -0,0 +1,4 @@
1
+ # Error is used to represent internal error
2
+ #
3
+ class Objecheck::Error < StandardError
4
+ end
@@ -0,0 +1,42 @@
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
+ # AnyRule validates that object meets one of the give rules
18
+ #
19
+ class Objecheck::Validator::AnyRule
20
+ def initialize(validator, schemas)
21
+ @child_rules = schemas.map do |schema|
22
+ validator.compile_schema(schema)
23
+ end
24
+ end
25
+
26
+ def validate(target, collector)
27
+ t = collector.transaction
28
+ t.add_error("should satisfy one of the #{@child_rules.size} schemas")
29
+ t_for_nested_rules = t.transaction
30
+ result = @child_rules.each.with_index(1).any? do |rules, i|
31
+ t_for_nested_rules.add_prefix_in("(option #{i})") { t_for_nested_rules.validate(target, rules) }
32
+ end
33
+
34
+ if result
35
+ t.rollback(t_for_nested_rules)
36
+ collector.rollback(t)
37
+ else
38
+ t.commit(t_for_nested_rules)
39
+ collector.commit(t)
40
+ end
41
+ end
42
+ end
@@ -17,11 +17,15 @@
17
17
  # Collector is used in Validator#validate to aggregate errors
18
18
  #
19
19
  class Objecheck::Validator::Collector
20
- def initialize(validator)
20
+ attr_reader :current_rule_name, :prefix_stack, :current_t
21
+
22
+ def initialize(validator, parent = nil)
21
23
  @validator = validator
22
- @current_rule_name = nil
23
- @prefix_stack = []
24
+ @current_validation_result = true
25
+ @current_rule_name = parent ? parent.current_rule_name : nil
26
+ @prefix_stack = parent ? [parent.prefix_stack.join('')] : []
24
27
  @errors = []
28
+ @current_t = nil
25
29
  end
26
30
 
27
31
  def add_prefix_in(prefix)
@@ -32,20 +36,51 @@ class Objecheck::Validator::Collector
32
36
  end
33
37
 
34
38
  def add_error(msg)
39
+ @current_validation_result = false
35
40
  @errors << "#{@prefix_stack.join('')}: #{@current_rule_name}: #{msg}"
36
41
  end
37
42
 
38
43
  def validate(target, rules)
39
44
  prev_rule_name = @current_rule_name
45
+ prev_validation_result = @current_validation_result
40
46
  rules.each do |name, rule|
41
47
  @current_rule_name = name
42
48
  rule.validate(target, self)
43
49
  end
50
+ @current_validation_result
44
51
  ensure
45
52
  @current_rule_name = prev_rule_name
53
+ @current_validation_result = prev_validation_result
46
54
  end
47
55
 
48
56
  def errors
49
57
  @errors.dup
50
58
  end
59
+
60
+ def transaction
61
+ raise Objecheck::Error, 'another transaction is already created' if @current_t
62
+
63
+ @current_t = self.class.new(@validator, self)
64
+ end
65
+
66
+ def commit(t)
67
+ check_transaction(t)
68
+ @current_t = nil
69
+ @errors.concat(t.errors)
70
+ end
71
+
72
+ def rollback(t)
73
+ check_transaction(t)
74
+ @current_t = nil
75
+ end
76
+
77
+ private
78
+
79
+ def check_transaction(t)
80
+ raise Objecheck::Error, 'transaction is not created' if !@current_t
81
+
82
+ raise Objecheck::Error, "invalid transaction #{t} (current: #{@current_t})" if !t.equal?(@current_t)
83
+
84
+ raise Objecheck::Error, "transaction hash uncommited nested transaction (#{t.current_t})" if t.current_t
85
+ end
51
86
  end
@@ -23,12 +23,14 @@ class Objecheck::Validator
23
23
  require 'objecheck/validator/each_value_rule'
24
24
  require 'objecheck/validator/key_value_rule'
25
25
  require 'objecheck/validator/eq_rule'
26
+ require 'objecheck/validator/any_rule'
26
27
  DEFAULT_RULES = {
27
28
  type: TypeRule,
28
29
  each: EachRule,
29
30
  each_key: EachKeyRule,
30
31
  each_value: EachValueRule,
31
- key_value: KeyValueRule
32
+ key_value: KeyValueRule,
33
+ any: AnyRule
32
34
  }.freeze
33
35
 
34
36
  def initialize(schema, rule_map = DEFAULT_RULES)
data/lib/objecheck.rb CHANGED
@@ -19,4 +19,5 @@
19
19
  module Objecheck
20
20
  end
21
21
 
22
+ require 'objecheck/error'
22
23
  require 'objecheck/validator'
data/objecheck.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'objecheck'
3
- spec.version = '0.3.0'
3
+ spec.version = '0.4.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.3.0
4
+ version: 0.4.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-26 00:00:00.000000000 Z
11
+ date: 2018-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -85,7 +85,9 @@ files:
85
85
  - bin/console
86
86
  - bin/setup
87
87
  - lib/objecheck.rb
88
+ - lib/objecheck/error.rb
88
89
  - lib/objecheck/validator.rb
90
+ - lib/objecheck/validator/any_rule.rb
89
91
  - lib/objecheck/validator/collector.rb
90
92
  - lib/objecheck/validator/each_key_rule.rb
91
93
  - lib/objecheck/validator/each_rule.rb