jschema 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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