jschema 0.0.2
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 +7 -0
- data/lib/jschema.rb +41 -0
- data/lib/jschema/json_reference.rb +65 -0
- data/lib/jschema/schema.rb +84 -0
- data/lib/jschema/schema_ref.rb +13 -0
- data/lib/jschema/simple_validator.rb +86 -0
- data/lib/jschema/string_length_validator.rb +17 -0
- data/lib/jschema/validator.rb +14 -0
- data/lib/jschema/validator/all_of.rb +29 -0
- data/lib/jschema/validator/any_of.rb +29 -0
- data/lib/jschema/validator/dependencies.rb +63 -0
- data/lib/jschema/validator/enum.rb +23 -0
- data/lib/jschema/validator/format.rb +75 -0
- data/lib/jschema/validator/items.rb +79 -0
- data/lib/jschema/validator/max_items.rb +28 -0
- data/lib/jschema/validator/max_length.rb +23 -0
- data/lib/jschema/validator/max_properties.rb +31 -0
- data/lib/jschema/validator/maximum.rb +31 -0
- data/lib/jschema/validator/min_items.rb +28 -0
- data/lib/jschema/validator/min_length.rb +23 -0
- data/lib/jschema/validator/min_properties.rb +31 -0
- data/lib/jschema/validator/minimum.rb +31 -0
- data/lib/jschema/validator/multiple_of.rb +32 -0
- data/lib/jschema/validator/not.rb +23 -0
- data/lib/jschema/validator/one_of.rb +29 -0
- data/lib/jschema/validator/pattern.rb +36 -0
- data/lib/jschema/validator/properties.rb +106 -0
- data/lib/jschema/validator/required.rb +34 -0
- data/lib/jschema/validator/type.rb +57 -0
- data/lib/jschema/validator/unique_items.rb +27 -0
- data/test/assert_received.rb +15 -0
- data/test/string_length_validator_tests.rb +18 -0
- data/test/test_assert_received.rb +39 -0
- data/test/test_integration.rb +30 -0
- data/test/test_json_reference.rb +84 -0
- data/test/test_schema.rb +125 -0
- data/test/test_schema_ref.rb +11 -0
- data/test/test_validator.rb +29 -0
- data/test/validator/argument_is_array_of_schemas_tests.rb +22 -0
- data/test/validator/assertions.rb +56 -0
- data/test/validator/properties_limit_tests.rb +13 -0
- data/test/validator/schema_validation_helpers.rb +29 -0
- data/test/validator/test_all_of.rb +30 -0
- data/test/validator/test_any_of.rb +31 -0
- data/test/validator/test_dependencies.rb +106 -0
- data/test/validator/test_enum.rb +30 -0
- data/test/validator/test_format.rb +70 -0
- data/test/validator/test_items.rb +113 -0
- data/test/validator/test_max_items.rb +26 -0
- data/test/validator/test_max_length.rb +30 -0
- data/test/validator/test_max_properties.rb +29 -0
- data/test/validator/test_maximum.rb +58 -0
- data/test/validator/test_min_items.rb +27 -0
- data/test/validator/test_min_length.rb +30 -0
- data/test/validator/test_min_properties.rb +29 -0
- data/test/validator/test_minimum.rb +58 -0
- data/test/validator/test_multiple_of.rb +38 -0
- data/test/validator/test_not.rb +32 -0
- data/test/validator/test_one_of.rb +31 -0
- data/test/validator/test_pattern.rb +32 -0
- data/test/validator/test_properties.rb +136 -0
- data/test/validator/test_required.rb +30 -0
- data/test/validator/test_simple_validator.rb +100 -0
- data/test/validator/test_type.rb +97 -0
- data/test/validator/test_unique_items.rb +30 -0
- data/test/validator/validation_against_schemas_tests.rb +24 -0
- metadata +144 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
module JSchema
|
2
|
+
module Validator
|
3
|
+
class Enum < SimpleValidator
|
4
|
+
private
|
5
|
+
|
6
|
+
self.keywords = ['enum']
|
7
|
+
|
8
|
+
def validate_args(enum)
|
9
|
+
unique_non_empty_array?(enum) || invalid_schema('enum', enum)
|
10
|
+
end
|
11
|
+
|
12
|
+
def post_initialize(enum)
|
13
|
+
@enum = enum
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate_instance(instance)
|
17
|
+
unless @enum.include? instance
|
18
|
+
"#{instance} must be one of: #{@enum.join(', ')}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
module JSchema
|
4
|
+
module Validator
|
5
|
+
class Format < SimpleValidator
|
6
|
+
private
|
7
|
+
|
8
|
+
self.keywords = ['format']
|
9
|
+
|
10
|
+
def validate_args(format)
|
11
|
+
allowed_formats =
|
12
|
+
['date-time', 'email', 'hostname', 'ipv4', 'ipv6', 'uri']
|
13
|
+
|
14
|
+
if allowed_formats.include?(format)
|
15
|
+
true
|
16
|
+
else
|
17
|
+
invalid_schema 'format', format
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def post_initialize(format)
|
22
|
+
@validator_method = format.gsub('-', '_')
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate_instance(instance)
|
26
|
+
unless send(@validator_method, instance)
|
27
|
+
"#{instance} must be a #{@validator_method}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def applicable_types
|
32
|
+
[String]
|
33
|
+
end
|
34
|
+
|
35
|
+
def date_time(instance)
|
36
|
+
true if DateTime.rfc3339(instance)
|
37
|
+
rescue ArgumentError
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
def email(instance)
|
42
|
+
instance.include? '@'
|
43
|
+
end
|
44
|
+
|
45
|
+
# Acc.to RFC 1034, 3.1
|
46
|
+
def hostname(instance)
|
47
|
+
if instance.length.between?(1, 255)
|
48
|
+
instance.split('.').all? do |label|
|
49
|
+
label =~ /^[\da-z\-]{1,63}$/i
|
50
|
+
end
|
51
|
+
else
|
52
|
+
false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def ipv4(instance)
|
57
|
+
IPAddr.new(instance).ipv4?
|
58
|
+
rescue ArgumentError
|
59
|
+
false
|
60
|
+
end
|
61
|
+
|
62
|
+
def ipv6(instance)
|
63
|
+
IPAddr.new(instance).ipv6?
|
64
|
+
rescue ArgumentError
|
65
|
+
false
|
66
|
+
end
|
67
|
+
|
68
|
+
def uri(instance)
|
69
|
+
URI.parse instance
|
70
|
+
rescue URI::InvalidURIError
|
71
|
+
false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module JSchema
|
2
|
+
module Validator
|
3
|
+
class Items < SimpleValidator
|
4
|
+
private
|
5
|
+
|
6
|
+
self.keywords = ['items', 'additionalItems']
|
7
|
+
|
8
|
+
def validate_args(items, additional_items)
|
9
|
+
additional_items_valid? additional_items
|
10
|
+
items_valid? items
|
11
|
+
end
|
12
|
+
|
13
|
+
def additional_items_valid?(additional_items)
|
14
|
+
additional_items.nil? ||
|
15
|
+
boolean?(additional_items) ||
|
16
|
+
valid_schema?(additional_items, 'additionalItems') ||
|
17
|
+
invalid_schema('additionalItems', additional_items)
|
18
|
+
end
|
19
|
+
|
20
|
+
def items_valid?(items)
|
21
|
+
items.nil? ||
|
22
|
+
valid_schema?(items, 'items') ||
|
23
|
+
schema_array?(items, 'items') ||
|
24
|
+
invalid_schema('items', items)
|
25
|
+
end
|
26
|
+
|
27
|
+
def post_initialize(items, additional_items)
|
28
|
+
@items = items
|
29
|
+
@additional_items = additional_items
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate_instance(instance)
|
33
|
+
validate_additional_items(instance) ||
|
34
|
+
validate_all_items(instance)
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate_additional_items(instance)
|
38
|
+
if @additional_items == false &&
|
39
|
+
@items.is_a?(Array) &&
|
40
|
+
@items.size < instance.size
|
41
|
+
|
42
|
+
"#{instance} must not contain any additional items"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def validate_all_items(instance)
|
47
|
+
instance.to_enum.each_with_index do |item, index|
|
48
|
+
schema = schema_for_item(index)
|
49
|
+
validation_errors = schema.validate(item)
|
50
|
+
unless validation_errors.empty?
|
51
|
+
return validation_errors.first
|
52
|
+
end
|
53
|
+
end
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
|
57
|
+
def schema_for_item(index)
|
58
|
+
case @items
|
59
|
+
when Array
|
60
|
+
if index < @items.size
|
61
|
+
Schema.build @items[index], parent, "items/#{index}"
|
62
|
+
elsif @additional_items.is_a?(Hash)
|
63
|
+
Schema.build @additional_items, parent, 'additionalItems'
|
64
|
+
else
|
65
|
+
Schema.build
|
66
|
+
end
|
67
|
+
when Hash
|
68
|
+
Schema.build @items, parent, 'items'
|
69
|
+
else
|
70
|
+
fail UnknownError
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def applicable_types
|
75
|
+
[Array]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module JSchema
|
2
|
+
module Validator
|
3
|
+
class MaxItems < SimpleValidator
|
4
|
+
private
|
5
|
+
|
6
|
+
self.keywords = ['maxItems']
|
7
|
+
|
8
|
+
def validate_args(max_items)
|
9
|
+
greater_or_equal_to?(max_items, 0) ||
|
10
|
+
invalid_schema('maxItems', max_items)
|
11
|
+
end
|
12
|
+
|
13
|
+
def post_initialize(max_items)
|
14
|
+
@max_items = max_items
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate_instance(instance)
|
18
|
+
if instance.size > @max_items
|
19
|
+
"#{instance} has too many items"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def applicable_types
|
24
|
+
[Array]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module JSchema
|
2
|
+
module Validator
|
3
|
+
class MaxLength < StringLengthValidator
|
4
|
+
private
|
5
|
+
|
6
|
+
self.keywords = ['maxLength']
|
7
|
+
|
8
|
+
def validate_args(max_length)
|
9
|
+
if valid_length_limit?(max_length, 1)
|
10
|
+
true
|
11
|
+
else
|
12
|
+
invalid_schema 'maxLength', max_length
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate_instance(instance)
|
17
|
+
if instance.size > @length_limit
|
18
|
+
"#{instance} is too long"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module JSchema
|
2
|
+
module Validator
|
3
|
+
class MaxProperties < SimpleValidator
|
4
|
+
private
|
5
|
+
|
6
|
+
self.keywords = ['maxProperties']
|
7
|
+
|
8
|
+
def validate_args(max_properties)
|
9
|
+
if greater_or_equal_to?(max_properties, 0)
|
10
|
+
true
|
11
|
+
else
|
12
|
+
invalid_schema 'maxProperties', max_properties
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def post_initialize(max_properties)
|
17
|
+
@max_properties = max_properties
|
18
|
+
end
|
19
|
+
|
20
|
+
def applicable_types
|
21
|
+
[Hash]
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate_instance(instance)
|
25
|
+
if instance.keys.size > @max_properties
|
26
|
+
"#{instance} has too many properties"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module JSchema
|
2
|
+
module Validator
|
3
|
+
class Maximum < SimpleValidator
|
4
|
+
private
|
5
|
+
|
6
|
+
self.keywords = ['maximum', 'exclusiveMaximum']
|
7
|
+
|
8
|
+
def validate_args(maximum, exclusive_maximum)
|
9
|
+
number?(maximum) || invalid_schema('maximum', maximum)
|
10
|
+
exclusive_maximum.nil? || boolean?(exclusive_maximum) ||
|
11
|
+
invalid_schema('exclusiveMaximum', exclusive_maximum)
|
12
|
+
end
|
13
|
+
|
14
|
+
def post_initialize(maximum, exclusive_maximum)
|
15
|
+
@maximum = maximum
|
16
|
+
@exclusive_maximum = exclusive_maximum
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate_instance(instance)
|
20
|
+
method = @exclusive_maximum ? :< : :<=
|
21
|
+
unless instance.public_send(method, @maximum)
|
22
|
+
"#{instance} must be #{method} than #{@maximum}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def applicable_types
|
27
|
+
[Fixnum, Bignum, Float, BigDecimal]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module JSchema
|
2
|
+
module Validator
|
3
|
+
class MinItems < SimpleValidator
|
4
|
+
private
|
5
|
+
|
6
|
+
self.keywords = ['minItems']
|
7
|
+
|
8
|
+
def validate_args(min_items)
|
9
|
+
greater_or_equal_to?(min_items, 0) ||
|
10
|
+
invalid_schema('minItems', min_items)
|
11
|
+
end
|
12
|
+
|
13
|
+
def post_initialize(min_items)
|
14
|
+
@min_items = min_items
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate_instance(instance)
|
18
|
+
if instance.size < @min_items
|
19
|
+
"#{instance} has too few items"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def applicable_types
|
24
|
+
[Array]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module JSchema
|
2
|
+
module Validator
|
3
|
+
class MinLength < JSchema::StringLengthValidator
|
4
|
+
private
|
5
|
+
|
6
|
+
self.keywords = ['minLength']
|
7
|
+
|
8
|
+
def validate_args(min_length)
|
9
|
+
if valid_length_limit?(min_length, 0)
|
10
|
+
true
|
11
|
+
else
|
12
|
+
invalid_schema 'minLength', min_length
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate_instance(instance)
|
17
|
+
if instance.size < @length_limit
|
18
|
+
"#{instance} is too short"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module JSchema
|
2
|
+
module Validator
|
3
|
+
class MinProperties < SimpleValidator
|
4
|
+
private
|
5
|
+
|
6
|
+
self.keywords = ['minProperties']
|
7
|
+
|
8
|
+
def validate_args(min_properties)
|
9
|
+
if greater_or_equal_to?(min_properties, 0)
|
10
|
+
true
|
11
|
+
else
|
12
|
+
invalid_schema 'minProperties', min_properties
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def post_initialize(min_properties)
|
17
|
+
@min_properties = min_properties
|
18
|
+
end
|
19
|
+
|
20
|
+
def applicable_types
|
21
|
+
[Hash]
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate_instance(instance)
|
25
|
+
if instance.keys.size < @min_properties
|
26
|
+
"#{instance} has too few properties"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module JSchema
|
2
|
+
module Validator
|
3
|
+
class Minimum < SimpleValidator
|
4
|
+
private
|
5
|
+
|
6
|
+
self.keywords = ['minimum', 'exclusiveMinimum']
|
7
|
+
|
8
|
+
def validate_args(minimum, exclusive_minimum)
|
9
|
+
number?(minimum) || invalid_schema('minimum', minimum)
|
10
|
+
exclusive_minimum.nil? || boolean?(exclusive_minimum) ||
|
11
|
+
invalid_schema('exclusiveMinimum', exclusive_minimum)
|
12
|
+
end
|
13
|
+
|
14
|
+
def post_initialize(minimum, exclusive_minimum)
|
15
|
+
@minimum = minimum
|
16
|
+
@exclusive_minimum = exclusive_minimum
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate_instance(instance)
|
20
|
+
method = @exclusive_minimum ? :> : :>=
|
21
|
+
unless instance.public_send(method, @minimum)
|
22
|
+
"#{instance} must be #{method} than #{@minimum}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def applicable_types
|
27
|
+
[Fixnum, Bignum, Float, BigDecimal]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module JSchema
|
2
|
+
module Validator
|
3
|
+
class MultipleOf < SimpleValidator
|
4
|
+
private
|
5
|
+
|
6
|
+
self.keywords = ['multipleOf']
|
7
|
+
|
8
|
+
def validate_args(multiple_of)
|
9
|
+
if number?(multiple_of) && multiple_of > 0
|
10
|
+
true
|
11
|
+
else
|
12
|
+
invalid_schema('multipleOf', multiple_of)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def post_initialize(multiple_of)
|
17
|
+
@multiple_of = multiple_of
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate_instance(instance)
|
21
|
+
div_remainder = instance.abs % @multiple_of
|
22
|
+
unless div_remainder.abs < 1e-6
|
23
|
+
"#{instance} must be a multiple of #{@multiple_of}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def applicable_types
|
28
|
+
[Fixnum, Bignum, Float, BigDecimal]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|