json_schema 0.20.5 → 0.21.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 +4 -4
- data/README.md +2 -1
- data/bin/validate-schema +10 -12
- data/lib/json_schema/parser.rb +22 -18
- data/lib/json_schema/reference_expander.rb +1 -0
- data/lib/json_schema/validator.rb +1 -1
- data/test/bin_test.rb +5 -6
- data/test/json_schema/reference_expander_test.rb +32 -0
- data/test/json_schema/validator_test.rb +8 -0
- metadata +7 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3cef7b24665bb90268f4feaac55fedc33027cab76886b05a54be71767c55802c
|
4
|
+
data.tar.gz: d20911da20ffffdecb4c8335cc081e9bc96c6236cd350dc0b4148e1d8a351edc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79671495e3e027b3ee4b76f68d76f651fa93df94a4102569970e40c8444105b30f04b441850dda768d063cce7d091163fb7d9de37a352e9c50e2e439b8068d11
|
7
|
+
data.tar.gz: 5d331de53da190de60e53c13293a54a0e26aa56c48c4b7676725a3862cfc074aff4c56e91aca53bb7abe257e9ac60afa9a4b99ff671fb2780cfb47376cf3a03d
|
data/README.md
CHANGED
@@ -67,7 +67,8 @@ ruby -Ilib -Itest test/json_schema/validator_test.rb -n /anyOf/
|
|
67
67
|
|
68
68
|
1. Update the version in `json_schema.gemspec` as appropriate for [semantic
|
69
69
|
versioning](http://semver.org) and add details to `CHANGELOG`.
|
70
|
-
2.
|
70
|
+
2. `git commit` those changes with a message like "Bump version to x.y.z".
|
71
|
+
3. Run the `release` task:
|
71
72
|
|
72
73
|
```
|
73
74
|
bundle exec rake release
|
data/bin/validate-schema
CHANGED
@@ -26,17 +26,15 @@ parser = OptionParser.new { |opts|
|
|
26
26
|
end
|
27
27
|
}
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
success = command.run(ARGV.dup)
|
29
|
+
parser.parse!
|
30
|
+
success = command.run(ARGV.dup)
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
32
|
+
if success
|
33
|
+
command.messages.each { |m| $stdout.puts(m) }
|
34
|
+
elsif !command.errors.empty?
|
35
|
+
command.errors.each { |e| $stderr.puts(e) }
|
36
|
+
exit(1)
|
37
|
+
else
|
38
|
+
print_usage!
|
39
|
+
exit(1)
|
42
40
|
end
|
data/lib/json_schema/parser.rb
CHANGED
@@ -17,6 +17,10 @@ module JsonSchema
|
|
17
17
|
TrueClass => "boolean",
|
18
18
|
}
|
19
19
|
|
20
|
+
# Reuse these frozen objects to avoid allocations
|
21
|
+
EMPTY_ARRAY = [].freeze
|
22
|
+
EMPTY_HASH = {}.freeze
|
23
|
+
|
20
24
|
attr_accessor :errors
|
21
25
|
|
22
26
|
# Basic parsing of a schema. May return a malformed schema! (Use `#parse!`
|
@@ -101,21 +105,21 @@ module JsonSchema
|
|
101
105
|
end
|
102
106
|
|
103
107
|
def parse_all_of(schema)
|
104
|
-
if schema.all_of
|
108
|
+
if schema.all_of && !schema.all_of.empty?
|
105
109
|
schema.all_of = schema.all_of.each_with_index.
|
106
110
|
map { |s, i| parse_data(s, schema, "allOf/#{i}") }
|
107
111
|
end
|
108
112
|
end
|
109
113
|
|
110
114
|
def parse_any_of(schema)
|
111
|
-
if schema.any_of
|
115
|
+
if schema.any_of && !schema.any_of.empty?
|
112
116
|
schema.any_of = schema.any_of.each_with_index.
|
113
117
|
map { |s, i| parse_data(s, schema, "anyOf/#{i}") }
|
114
118
|
end
|
115
119
|
end
|
116
120
|
|
117
121
|
def parse_one_of(schema)
|
118
|
-
if schema.one_of
|
122
|
+
if schema.one_of && !schema.one_of.empty?
|
119
123
|
schema.one_of = schema.one_of.each_with_index.
|
120
124
|
map { |s, i| parse_data(s, schema, "oneOf/#{i}") }
|
121
125
|
end
|
@@ -140,7 +144,7 @@ module JsonSchema
|
|
140
144
|
end
|
141
145
|
|
142
146
|
def parse_definitions(schema)
|
143
|
-
if schema.definitions
|
147
|
+
if schema.definitions && !schema.definitions.empty?
|
144
148
|
# leave the original data reference intact
|
145
149
|
schema.definitions = schema.definitions.dup
|
146
150
|
schema.definitions.each do |key, definition|
|
@@ -151,7 +155,7 @@ module JsonSchema
|
|
151
155
|
end
|
152
156
|
|
153
157
|
def parse_dependencies(schema)
|
154
|
-
if schema.dependencies
|
158
|
+
if schema.dependencies && !schema.dependencies.empty?
|
155
159
|
# leave the original data reference intact
|
156
160
|
schema.dependencies = schema.dependencies.dup
|
157
161
|
schema.dependencies.each do |k, s|
|
@@ -181,7 +185,7 @@ module JsonSchema
|
|
181
185
|
end
|
182
186
|
|
183
187
|
def parse_links(schema)
|
184
|
-
if schema.links
|
188
|
+
if schema.links && !schema.links.empty?
|
185
189
|
schema.links = schema.links.each_with_index.map { |l, i|
|
186
190
|
link = Schema::Link.new
|
187
191
|
link.parent = schema
|
@@ -231,7 +235,7 @@ module JsonSchema
|
|
231
235
|
end
|
232
236
|
|
233
237
|
def parse_pattern_properties(schema)
|
234
|
-
if schema.pattern_properties
|
238
|
+
if schema.pattern_properties && !schema.pattern_properties.empty?
|
235
239
|
# leave the original data reference intact
|
236
240
|
properties = schema.pattern_properties.dup
|
237
241
|
properties = properties.map do |k, s|
|
@@ -254,8 +258,8 @@ module JsonSchema
|
|
254
258
|
|
255
259
|
def parse_properties(schema)
|
256
260
|
# leave the original data reference intact
|
257
|
-
schema.properties
|
258
|
-
|
261
|
+
if schema.properties && schema.properties.is_a?(Hash) && !schema.properties.empty?
|
262
|
+
schema.properties = schema.properties.dup
|
259
263
|
schema.properties.each do |key, definition|
|
260
264
|
subschema = parse_data(definition, schema, "properties/#{key}")
|
261
265
|
schema.properties[key] = subschema
|
@@ -282,11 +286,11 @@ module JsonSchema
|
|
282
286
|
schema.default = schema.data["default"]
|
283
287
|
|
284
288
|
# validation: any
|
285
|
-
schema.all_of = validate_type(schema, [Array], "allOf") ||
|
286
|
-
schema.any_of = validate_type(schema, [Array], "anyOf") ||
|
287
|
-
schema.definitions = validate_type(schema, [Hash], "definitions") ||
|
289
|
+
schema.all_of = validate_type(schema, [Array], "allOf") || EMPTY_ARRAY
|
290
|
+
schema.any_of = validate_type(schema, [Array], "anyOf") || EMPTY_ARRAY
|
291
|
+
schema.definitions = validate_type(schema, [Hash], "definitions") || EMPTY_HASH
|
288
292
|
schema.enum = validate_type(schema, [Array], "enum")
|
289
|
-
schema.one_of = validate_type(schema, [Array], "oneOf") ||
|
293
|
+
schema.one_of = validate_type(schema, [Array], "oneOf") || EMPTY_ARRAY
|
290
294
|
schema.not = validate_type(schema, [Hash], "not")
|
291
295
|
schema.type = validate_type(schema, [Array, String], "type")
|
292
296
|
schema.type = [schema.type] if schema.type.is_a?(String)
|
@@ -309,11 +313,11 @@ module JsonSchema
|
|
309
313
|
# validation: object
|
310
314
|
schema.additional_properties =
|
311
315
|
validate_type(schema, BOOLEAN + [Hash], "additionalProperties")
|
312
|
-
schema.dependencies = validate_type(schema, [Hash], "dependencies") ||
|
316
|
+
schema.dependencies = validate_type(schema, [Hash], "dependencies") || EMPTY_HASH
|
313
317
|
schema.max_properties = validate_type(schema, [Integer], "maxProperties")
|
314
318
|
schema.min_properties = validate_type(schema, [Integer], "minProperties")
|
315
|
-
schema.pattern_properties = validate_type(schema, [Hash], "patternProperties") ||
|
316
|
-
schema.properties = validate_type(schema, [Hash], "properties") ||
|
319
|
+
schema.pattern_properties = validate_type(schema, [Hash], "patternProperties") || EMPTY_HASH
|
320
|
+
schema.properties = validate_type(schema, [Hash], "properties") || EMPTY_HASH
|
317
321
|
schema.required = validate_type(schema, [Array], "required")
|
318
322
|
schema.strict_properties = validate_type(schema, BOOLEAN, "strictProperties")
|
319
323
|
|
@@ -358,10 +362,10 @@ module JsonSchema
|
|
358
362
|
end
|
359
363
|
|
360
364
|
def validate_type(schema, types, field)
|
361
|
-
friendly_types =
|
362
|
-
types.map { |t| FRIENDLY_TYPES[t] || t }.sort.uniq.join("/")
|
363
365
|
value = schema.data[field]
|
364
366
|
if !value.nil? && !types.any? { |t| value.is_a?(t) }
|
367
|
+
friendly_types =
|
368
|
+
types.map { |t| FRIENDLY_TYPES[t] || t }.sort.uniq.join("/")
|
365
369
|
message = %{#{value.inspect} is not a valid "#{field}", must be a #{friendly_types}.}
|
366
370
|
@errors << SchemaError.new(schema, message, :invalid_type)
|
367
371
|
nil
|
@@ -93,6 +93,7 @@ module JsonSchema
|
|
93
93
|
if !ref
|
94
94
|
schema_children(ref_schema) do |subschema|
|
95
95
|
next unless subschema.reference
|
96
|
+
next if ref_schema.uri == parent_ref.uri.to_s
|
96
97
|
|
97
98
|
if !subschema.reference.uri && parent_ref
|
98
99
|
subschema.reference = JsonReference::Reference.new("#{parent_ref.uri}#{subschema.reference.pointer}")
|
@@ -567,7 +567,7 @@ module JsonSchema
|
|
567
567
|
end
|
568
568
|
|
569
569
|
DEFAULT_FORMAT_VALIDATORS = {
|
570
|
-
"date" => ->(data) { data =~ DATE_PATTERN },
|
570
|
+
"date" => ->(data) { data =~ DATE_PATTERN && Date.parse(data) rescue false },
|
571
571
|
"date-time" => ->(data) { data =~ DATE_TIME_PATTERN },
|
572
572
|
"email" => ->(data) { data =~ EMAIL_PATTERN },
|
573
573
|
"hostname" => ->(data) { data =~ HOSTNAME_PATTERN },
|
data/test/bin_test.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
3
|
#
|
4
|
-
# The purpose of this sets of tests is just to
|
5
|
-
# where possible so that we can get very basic sanity checks on their syntax
|
6
|
-
# (which is something that of course Ruby can't do by default).
|
4
|
+
# The purpose of this sets of tests is just to test our Ruby executables
|
5
|
+
# where possible so that we can get very basic sanity checks on their syntax.
|
7
6
|
#
|
8
|
-
# We can do this without actually executing them
|
9
|
-
# $0 == __FILE__` statements.
|
7
|
+
# We can do this without actually executing them with a "ruby -c" call.
|
10
8
|
#
|
11
9
|
|
12
10
|
describe "executables in bin/" do
|
@@ -15,6 +13,7 @@ describe "executables in bin/" do
|
|
15
13
|
end
|
16
14
|
|
17
15
|
it "has roughly valid Ruby structure for validate-schema" do
|
18
|
-
|
16
|
+
IO.popen(["ruby", "-c", File.join(@bin_dir, "validate-schema")]) { |io| io.read }
|
17
|
+
assert_equal $?.exitstatus, 0, "Ruby syntax check failed; see error above"
|
19
18
|
end
|
20
19
|
end
|
@@ -454,6 +454,38 @@ describe JsonSchema::ReferenceExpander do
|
|
454
454
|
assert_equal 3, schema1.properties["foo"].properties["bar"].one_of[1].properties["baz"].max_length
|
455
455
|
end
|
456
456
|
|
457
|
+
it "does not infinitely recurse when external ref is local to its schema" do
|
458
|
+
sample1 = {
|
459
|
+
"id" => "http://json-schema.org/draft-04/schema#",
|
460
|
+
"$schema" => "http://json-schema.org/draft-04/schema#",
|
461
|
+
"properties" => {
|
462
|
+
"additionalItems" => {
|
463
|
+
"anyOf" => [ { "$ref" => "#" } ]
|
464
|
+
}
|
465
|
+
}
|
466
|
+
}
|
467
|
+
schema1 = JsonSchema::Parser.new.parse!(sample1)
|
468
|
+
sample2 = {
|
469
|
+
"$schema" => "http://json-schema.org/draft-04/hyper-schema#",
|
470
|
+
"id" => "http://json-schema.org/draft-04/hyper-schema#",
|
471
|
+
"allOf" => [
|
472
|
+
{ "$ref" => "http://json-schema.org/draft-04/schema#" }
|
473
|
+
]
|
474
|
+
}
|
475
|
+
schema2 = JsonSchema::Parser.new.parse!(sample2)
|
476
|
+
|
477
|
+
store = JsonSchema::DocumentStore.new
|
478
|
+
expander = JsonSchema::ReferenceExpander.new
|
479
|
+
|
480
|
+
store.add_schema(schema1)
|
481
|
+
store.add_schema(schema2)
|
482
|
+
|
483
|
+
expander.expand!(schema2, store: store)
|
484
|
+
|
485
|
+
assert schema1.expanded?
|
486
|
+
assert schema2.expanded?
|
487
|
+
end
|
488
|
+
|
457
489
|
it "it handles oneOf with nested references to a local schema" do
|
458
490
|
sample1 = {
|
459
491
|
"$schema" => "http://json-schema.org/draft-04/hyper-schema",
|
@@ -718,6 +718,14 @@ describe JsonSchema::Validator do
|
|
718
718
|
refute_valid
|
719
719
|
end
|
720
720
|
|
721
|
+
it "validates date format when month and day exceed valid range unsuccessfully" do
|
722
|
+
pointer("#/definitions/app/definitions/owner").merge!(
|
723
|
+
"format" => "date"
|
724
|
+
)
|
725
|
+
data_sample["owner"] = "2014-24-60"
|
726
|
+
refute_valid
|
727
|
+
end
|
728
|
+
|
721
729
|
it "validates date-time format successfully" do
|
722
730
|
pointer("#/definitions/app/definitions/owner").merge!(
|
723
731
|
"format" => "date-time"
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_schema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.21.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandur
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
13
|
+
description:
|
14
14
|
email:
|
15
15
|
- brandur@mutelight.org
|
16
16
|
executables:
|
@@ -54,7 +54,7 @@ homepage: https://github.com/brandur/json_schema
|
|
54
54
|
licenses:
|
55
55
|
- MIT
|
56
56
|
metadata: {}
|
57
|
-
post_install_message:
|
57
|
+
post_install_message:
|
58
58
|
rdoc_options: []
|
59
59
|
require_paths:
|
60
60
|
- lib
|
@@ -69,9 +69,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
69
|
- !ruby/object:Gem::Version
|
70
70
|
version: '0'
|
71
71
|
requirements: []
|
72
|
-
|
73
|
-
|
74
|
-
signing_key:
|
72
|
+
rubygems_version: 3.2.3
|
73
|
+
signing_key:
|
75
74
|
specification_version: 4
|
76
75
|
summary: A JSON Schema V4 and Hyperschema V4 parser and validator.
|
77
76
|
test_files: []
|