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.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/lib/jschema.rb +41 -0
  3. data/lib/jschema/json_reference.rb +65 -0
  4. data/lib/jschema/schema.rb +84 -0
  5. data/lib/jschema/schema_ref.rb +13 -0
  6. data/lib/jschema/simple_validator.rb +86 -0
  7. data/lib/jschema/string_length_validator.rb +17 -0
  8. data/lib/jschema/validator.rb +14 -0
  9. data/lib/jschema/validator/all_of.rb +29 -0
  10. data/lib/jschema/validator/any_of.rb +29 -0
  11. data/lib/jschema/validator/dependencies.rb +63 -0
  12. data/lib/jschema/validator/enum.rb +23 -0
  13. data/lib/jschema/validator/format.rb +75 -0
  14. data/lib/jschema/validator/items.rb +79 -0
  15. data/lib/jschema/validator/max_items.rb +28 -0
  16. data/lib/jschema/validator/max_length.rb +23 -0
  17. data/lib/jschema/validator/max_properties.rb +31 -0
  18. data/lib/jschema/validator/maximum.rb +31 -0
  19. data/lib/jschema/validator/min_items.rb +28 -0
  20. data/lib/jschema/validator/min_length.rb +23 -0
  21. data/lib/jschema/validator/min_properties.rb +31 -0
  22. data/lib/jschema/validator/minimum.rb +31 -0
  23. data/lib/jschema/validator/multiple_of.rb +32 -0
  24. data/lib/jschema/validator/not.rb +23 -0
  25. data/lib/jschema/validator/one_of.rb +29 -0
  26. data/lib/jschema/validator/pattern.rb +36 -0
  27. data/lib/jschema/validator/properties.rb +106 -0
  28. data/lib/jschema/validator/required.rb +34 -0
  29. data/lib/jschema/validator/type.rb +57 -0
  30. data/lib/jschema/validator/unique_items.rb +27 -0
  31. data/test/assert_received.rb +15 -0
  32. data/test/string_length_validator_tests.rb +18 -0
  33. data/test/test_assert_received.rb +39 -0
  34. data/test/test_integration.rb +30 -0
  35. data/test/test_json_reference.rb +84 -0
  36. data/test/test_schema.rb +125 -0
  37. data/test/test_schema_ref.rb +11 -0
  38. data/test/test_validator.rb +29 -0
  39. data/test/validator/argument_is_array_of_schemas_tests.rb +22 -0
  40. data/test/validator/assertions.rb +56 -0
  41. data/test/validator/properties_limit_tests.rb +13 -0
  42. data/test/validator/schema_validation_helpers.rb +29 -0
  43. data/test/validator/test_all_of.rb +30 -0
  44. data/test/validator/test_any_of.rb +31 -0
  45. data/test/validator/test_dependencies.rb +106 -0
  46. data/test/validator/test_enum.rb +30 -0
  47. data/test/validator/test_format.rb +70 -0
  48. data/test/validator/test_items.rb +113 -0
  49. data/test/validator/test_max_items.rb +26 -0
  50. data/test/validator/test_max_length.rb +30 -0
  51. data/test/validator/test_max_properties.rb +29 -0
  52. data/test/validator/test_maximum.rb +58 -0
  53. data/test/validator/test_min_items.rb +27 -0
  54. data/test/validator/test_min_length.rb +30 -0
  55. data/test/validator/test_min_properties.rb +29 -0
  56. data/test/validator/test_minimum.rb +58 -0
  57. data/test/validator/test_multiple_of.rb +38 -0
  58. data/test/validator/test_not.rb +32 -0
  59. data/test/validator/test_one_of.rb +31 -0
  60. data/test/validator/test_pattern.rb +32 -0
  61. data/test/validator/test_properties.rb +136 -0
  62. data/test/validator/test_required.rb +30 -0
  63. data/test/validator/test_simple_validator.rb +100 -0
  64. data/test/validator/test_type.rb +97 -0
  65. data/test/validator/test_unique_items.rb +30 -0
  66. data/test/validator/validation_against_schemas_tests.rb +24 -0
  67. 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