nakischema 0.1.4 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +5 -5
  2. data/lib/nakischema.rb +57 -18
  3. data/nakischema.gemspec +4 -1
  4. metadata +32 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 271b63150c8a6eead2fba711f312b2e2f82ba24a
4
- data.tar.gz: 829b656fc7a75c629d3ccea2ac44ca4de98d4598
2
+ SHA256:
3
+ metadata.gz: 17bf09e8fde06d6abca6cb282d3bfe74195c6b3ea77a0c840d903b728b4441ad
4
+ data.tar.gz: a2b7b578d4f54481c6c990626625ad09d7e1314e9d8623e1a1fa9e4e6c8b14a7
5
5
  SHA512:
6
- metadata.gz: 07bd982a7331b8ec0937b97d682b623d4c85ac14bcb71512dc85bc16536f40f8a01dfcac0df379097614f84748a93d2d426c2addb45b0f0ca703ee1b0c069ef6
7
- data.tar.gz: c2716c3ad3e8e804891ef364c31ca7ffc3a2289b16a32f203905362b866bc3f832932be3a0350c25edd41b60d7d22c3b1739d2e279aebd0f1987d76655e07ee2
6
+ metadata.gz: b1efdd78b40f3980d4b1176f4702f614e3afef78db35e4c1395a744a1bae47fef0f159b24012b880bb1038174ad1e3ea9f4f9111ee21799759baff5bc696032f
7
+ data.tar.gz: 3dd739593892acd46186e49959f0f8d5b7680decbaafc9c95b424b40d7d6af0bf7ef9f7c264e38be54506a44b43a4aa90ca5ab8903c5d07b5f99782ffcf0e694
data/lib/nakischema.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  module Nakischema
2
2
  Error = Class.new RuntimeError
3
3
 
4
- def self.validate object, schema, path = []
4
+ def self.validate object, schema, message = nil, path: []
5
5
  raise_with_path = lambda do |msg, _path = path|
6
- raise Error.new "#{msg}#{" (at #{_path})" unless _path.empty?}"
6
+ raise Error.new "#{msg}#{" (at #{_path})" unless _path.empty?}#{" #{message}" if message}"
7
7
  end
8
8
  # TODO: maybe move '(at ...)' to the beginning
9
9
  case schema
@@ -14,26 +14,32 @@ module Nakischema
14
14
  when Range ; raise_with_path.call "expected #{schema } != #{object }" unless schema.include? object
15
15
  when Hash
16
16
  raise_with_path.call "expected Hash != #{object.class}" unless object.is_a? Hash unless (schema.keys & %i{ keys each_key each_value }).empty?
17
- raise_with_path.call "expected Array != #{object.class}" unless object.is_a? Array unless (schema.keys & %i{ size }).empty?
17
+ raise_with_path.call "expected Array != #{object.class}" unless object.is_a? Array unless (schema.keys & %i{ size }).empty? # TODO: maybe allow Hash object?
18
18
  schema.each do |k, v|
19
19
  case k
20
- when :size ; raise_with_path.call "expected explicit size #{v} != #{object.size}" unless v.include? object.size
20
+ when :size ; raise_with_path.call "expected Range != #{v.class}" unless v.is_a? Range
21
+ raise_with_path.call "expected explicit size #{v} != #{object.size}" unless v.include? object.size
21
22
  # when Fixnum
22
23
  # raise_with_path.call "expected Array != #{object.class}" unless object.is_a? Array
23
- # validate object[k], v, [*path, :"##{k}"]
24
- when :keys ; validate object.keys, v, [*path, :keys]
25
- when :values ; validate object.values, v, [*path, :values]
26
- when :keys_sorted ; validate object.keys.sort, v, [*path, :keys_sorted]
27
- when :hash_opt ; v.each{ |k, v| validate object.fetch(k), v, [*path, k] if object.key? k }
28
- when :hash_req ; v.each{ |k, v| validate object.fetch(k), v, [*path, k] }
24
+ # validate object[k], v, path: [*path, :"##{k}"]
25
+ when :keys ; validate object.keys, v, path: [*path, :keys]
26
+ when :values ; validate object.values, v, path: [*path, :values]
27
+ when :keys_sorted ; validate object.keys.sort, v, path: [*path, :keys_sorted] # TODO: maybe copypaste the Array validation to reduce [] nesting
28
+ when :hash_opt ; raise_with_path.call "expected Hash != #{object.class}" unless object.is_a? Hash
29
+ v.each{ |k, v| validate object.fetch(k), v, path: [*path, k] if object.key? k }
30
+ when :hash_req ; raise_with_path.call "expected Hash != #{object.class}" unless object.is_a? Hash
31
+ raise_with_path.call "expected required keys #{v.keys.sort} ∉ #{object.keys.sort}" unless (v.keys - object.keys).empty?
32
+ v.each{ |k, v| validate object.fetch(k), v, path: [*path, k] }
29
33
  when :hash ; raise_with_path.call "expected Hash != #{object.class}" unless object.is_a? Hash
30
- raise_with_path.call "expected implicit keys #{v.keys} != #{object.keys.sort}" unless v.keys.sort == object.keys.sort
31
- v.each{ |k, v| validate object.fetch(k), v, [*path, k] }
32
- when :each_key ; object.keys.each_with_index{ |k, i| validate k, v, [*path, :"key##{i}"] }
33
- when :each_value ; object.values.each_with_index{ |v_, i| validate v_, v, [*path, :"value##{i}"] }
34
+ hash_wo_opt = object.keys.sort - schema.fetch(:hash_opt, {}).keys
35
+ raise_with_path.call "expected implicit keys #{v.keys.sort} != #{hash_wo_opt}" unless v.keys.sort == hash_wo_opt
36
+ v.each{ |k, v| validate object.fetch(k), v, path: [*path, k] }
37
+ when :each_key ; object.keys.each_with_index{ |k, i| validate k, v, path: [*path, :"key##{i}"] }
38
+ when :each_value ; object.values.each_with_index{ |v_, i| validate v_, v, path: [*path, :"value##{i}"] }
39
+ when :method ; v.each{ |m, e| validate object.public_method(m).call, e, path: [*path, :"method##{m}"] }
34
40
  when :each
35
41
  raise_with_path.call "expected iterable != #{object.class}" unless object.respond_to? :each_with_index
36
- object.each_with_index{ |e, i| validate e, v, [*path, :"##{i}"] }
42
+ object.each_with_index{ |e, i| validate e, v, path: [*path, :"##{i}"] }
37
43
  # when :case
38
44
  # raise_with_path.call "expected at least one of #{v.size} cases to match the #{object.inspect}" if v.map.with_index do |(k, v), i|
39
45
  # next if begin
@@ -42,7 +48,7 @@ module Nakischema
42
48
  # rescue Error => e
43
49
  # e
44
50
  # end
45
- # validate object, v, [*path, :"case##{i}"]
51
+ # validate object, v, path: [*path, :"case##{i}"]
46
52
  # true
47
53
  # end.none?
48
54
  when :assertions
@@ -61,12 +67,12 @@ module Nakischema
61
67
  if schema.map(&:class) == [Array]
62
68
  raise_with_path.call "expected Array != #{object.class}" unless object.is_a? Array
63
69
  raise_with_path.call "expected implicit size #{schema[0].size} != #{object.size} for #{object.inspect}" unless schema[0].size == object.size
64
- object.zip(schema[0]).each_with_index{ |(o, v), i| validate o, v, [*path, :"##{i}"] }
70
+ object.zip(schema[0]).each_with_index{ |(o, v), i| validate o, v, path: [*path, :"##{i}"] }
65
71
  else
66
72
  results = schema.lazy.with_index.map do |v, i|
67
73
  # raise_with_path.call "unsupported nested Array" if v.is_a? Array
68
74
  begin
69
- validate object, v, [*path, :"variant##{i}"]
75
+ validate object, v, path: [*path, :"variant##{i}"]
70
76
  nil
71
77
  rescue Error => e
72
78
  e
@@ -134,4 +140,37 @@ module Nakischema
134
140
  raise_with_path.call "unsupported rule class #{schema.class}"
135
141
  end
136
142
  end
143
+
144
+ def self.fixture _
145
+ require "regexp-examples"
146
+ require "addressable"
147
+ case _
148
+ when Hash
149
+ case _.keys
150
+ when %i{ hash } ; _[:hash ].map{ |k,v| [k,fixture(v)] }.shuffle.to_h
151
+ when %i{ hash_req } ; [*_[:hash_req].map{ |k,v| [k,fixture(v)] }, ["foo","bar"]].shuffle.to_h # TODO: assert no collision
152
+ when %i{ size each } ; Array.new(fixture _[:size]){ fixture _[:each] }
153
+ else ; fail _.keys.inspect
154
+ end
155
+ when Array ; [Array] == _.map(&:class) ? _[0].map(&method(:fixture)) : fixture(_.sample)
156
+ when Regexp
157
+ t = _.random_example
158
+ tt = begin
159
+ URI t
160
+ rescue URI::InvalidURIError
161
+ URI Addressable::URI.escape t
162
+ end
163
+ tt.is_a?(URI::HTTP) ? tt.to_s : t
164
+ when Range ; rand _
165
+ when String ; _
166
+ when Class
167
+ case _.name
168
+ when "Integer" ; -rand(1000000)
169
+ when "Hash" ; {}
170
+ else ; fail "bad fixture node class name: #{_.name}"
171
+ end
172
+ else ; fail "bad fixture node class: #{_.class.inspect}"
173
+ end
174
+ end
175
+
137
176
  end
data/nakischema.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "nakischema"
3
- spec.version = "0.1.4"
3
+ spec.version = "0.2.1"
4
4
  spec.summary = "compact yet powerful arbitrary nested objects validator"
5
5
  spec.description = "The most compact yet powerful arbitrary nested objects validator. Especially handy to validate JSONs."
6
6
 
@@ -9,5 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.license = "MIT"
10
10
  spec.metadata = {"source_code_uri" => "https://github.com/nakilon/nakischema"}
11
11
 
12
+ spec.add_dependency "regexp-examples"
13
+ spec.add_dependency "addressable"
14
+
12
15
  spec.files = %w{ LICENSE nakischema.gemspec lib/nakischema.rb }
13
16
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nakischema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Maslov aka Nakilon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-12 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2023-05-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: regexp-examples
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: addressable
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  description: The most compact yet powerful arbitrary nested objects validator. Especially
14
42
  handy to validate JSONs.
15
43
  email: nakilon@gmail.com
@@ -40,8 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
40
68
  - !ruby/object:Gem::Version
41
69
  version: '0'
42
70
  requirements: []
43
- rubyforge_project:
44
- rubygems_version: 2.5.2.3
71
+ rubygems_version: 3.3.25
45
72
  signing_key:
46
73
  specification_version: 4
47
74
  summary: compact yet powerful arbitrary nested objects validator