json-ld-validate 0.0.3 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b842c8a5568175c193e71d16e26fa41bab31e1bae79143487620096fa890ec4
4
- data.tar.gz: 6daf575322e3247089f2f3e4d0ed9fc4b8959accfd5254de9e15261a0320d566
3
+ metadata.gz: 24f7e49ba2ad97d5ec2c2746ac541e17167eea91a9c618a364e3c866e979500a
4
+ data.tar.gz: 31a0660a604c9713e91648086fe6945078df30cba88da859eb00a579b6fc6589
5
5
  SHA512:
6
- metadata.gz: 3060a4e2e85af2ae2ef40ffb1a20c95c2864ee1ecf51dfeba746034e0c313d2ab51bd462febf4951dc6f8a21a4549fd63fa3c23eb866dc58a1d307d582d03306
7
- data.tar.gz: 54fadf3ffd1807c70223c637afe7b81fa4d6adbcdf9060baafe372b7a44b7448f20df13249d36aa2ea1d0746f69167c773217609b3ff31298703ce95c1911006
6
+ metadata.gz: 006dc0932bce4be731d5078afbf4d98bee88b2b63af946bbfd3e3614cc956baa09e163810b23a1cb16aecbf5aeedb6d405c82354f3e7949a02d080131c8b7c9f
7
+ data.tar.gz: 5ceaccc40e461010b5037ebf713f6df68f7d9a3028a3c749db7bd979a23ad9edcd434eb1f12ea9b691882b2c0a6e2c30ed2b1829dfc534baa2e5a1e4900194be
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json/ld'
4
-
5
3
  module JsonldValidate
6
4
  module Matchers
7
5
  class BeValidJsonLd
@@ -1,8 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json/ld'
4
+ require_relative 'xsd_type_validator'
5
+
3
6
  module JsonldValidate
4
7
  class Validator
5
- attr_accessor :content, :errors
8
+ include XsdTypeValidator
9
+
10
+ attr_reader :content, :errors
6
11
 
7
12
  def initialize(content)
8
13
  @content = content
@@ -10,21 +15,50 @@ module JsonldValidate
10
15
  end
11
16
 
12
17
  def valid?
18
+ @errors = []
13
19
  return false if content.nil?
14
20
  return true if content.empty?
15
21
 
22
+ validate_document
23
+ errors.empty?
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :doc, :expanded_doc
29
+
30
+ def validate_document
31
+ if content.is_a?(Array)
32
+ validate_array_items
33
+ return
34
+ end
35
+
36
+ return if hash_missing_context? && (@errors << 'missing @context')
37
+
16
38
  build_expanded_doc
17
39
  build_doc
18
- return false unless errors.empty?
40
+ return unless errors.empty?
19
41
 
42
+ validate_typed_values
20
43
  find_unknown_fields(content, doc, [])
21
-
22
- errors.empty?
23
44
  end
24
45
 
25
- private
46
+ def validate_array_items
47
+ content.each_with_index do |item, i|
48
+ item_validator = self.class.new(item)
49
+ next if item_validator.valid?
26
50
 
27
- attr_reader :doc, :expanded_doc
51
+ if item_validator.errors.empty?
52
+ @errors << "#{i}: invalid document"
53
+ else
54
+ item_validator.errors.each { |e| @errors << "#{i}.#{e}" }
55
+ end
56
+ end
57
+ end
58
+
59
+ def hash_missing_context?
60
+ content.is_a?(Hash) && (!content.key?('@context') || content['@context'].nil?)
61
+ end
28
62
 
29
63
  def build_doc
30
64
  return if expanded_doc.nil?
@@ -36,7 +70,7 @@ module JsonldValidate
36
70
  @expanded_doc = clean_expanded_doc(JSON::LD::API.expand(content))
37
71
  rescue JSON::LD::JsonLdError::LoadingDocumentFailed
38
72
  @errors << 'failed loading document'
39
- rescue JSON::LD::JsonLdError::InvalidLanguageMapValue => e
73
+ rescue JSON::LD::JsonLdError => e
40
74
  @errors << e.to_s
41
75
  end
42
76
 
@@ -52,18 +86,20 @@ module JsonldValidate
52
86
  original.each_key do |key|
53
87
  next if key.start_with?('@')
54
88
 
55
- errors << "found unknown fields: #{(path + [key]).join('.')}"
89
+ errors << "found unknown field: #{(path + [key]).join('.')}"
56
90
  end
57
91
  end
58
92
 
59
93
  def report_unknown_keys(original, compacted, path)
60
94
  (original.keys - compacted.keys).each do |field|
61
- errors << "found unknown fields: #{(path + [field]).join('.')}"
95
+ errors << "found unknown field: #{(path + [field]).join('.')}"
62
96
  end
63
97
  end
64
98
 
65
99
  def recurse_known_keys(original, compacted, path)
66
100
  (original.keys & compacted.keys).each do |key|
101
+ next if key.start_with?('@')
102
+
67
103
  recurse_field(original[key], compacted[key], path + [key])
68
104
  end
69
105
  end
@@ -74,8 +110,10 @@ module JsonldValidate
74
110
  orig_val.each_with_index do |item, i|
75
111
  find_unknown_fields(item, comp_val[i], path + [i.to_s])
76
112
  end
77
- else
113
+ elsif orig_val.is_a?(Hash)
78
114
  find_unknown_fields(orig_val, comp_val, path)
115
+ elsif orig_val != comp_val
116
+ @errors << "invalid value at #{path.join('.')}: #{orig_val.inspect}"
79
117
  end
80
118
  end
81
119
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JsonldValidate
4
- VERSION = '0.0.3'
4
+ VERSION = '0.1.0'
5
5
  end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JsonldValidate
4
+ module XsdTypeValidator
5
+ XSD = 'http://www.w3.org/2001/XMLSchema#'
6
+
7
+ INTEGER_TYPES = %w[
8
+ integer int long short byte
9
+ unsignedInt unsignedLong unsignedShort unsignedByte
10
+ nonNegativeInteger positiveInteger nonPositiveInteger negativeInteger
11
+ ].to_set { |t| "#{XSD}#{t}" }.freeze
12
+
13
+ DECIMAL_TYPES = %w[decimal double float].to_set { |t| "#{XSD}#{t}" }.freeze
14
+
15
+ BOOLEAN_TYPE = "#{XSD}boolean".freeze
16
+
17
+ def validate_typed_values
18
+ return unless expanded_doc
19
+
20
+ iri_to_term, vocab = build_iri_map
21
+ expanded_doc.each { |node| check_node_types(node, iri_to_term, vocab, []) }
22
+ end
23
+
24
+ def build_iri_map
25
+ ctx = JSON::LD::Context.parse(content['@context'])
26
+ map = ctx.term_definitions.each_with_object({}) do |(term, defn), h|
27
+ h[defn.id] = term if defn.id
28
+ end
29
+ [map, ctx.vocab]
30
+ rescue StandardError
31
+ [{}, nil]
32
+ end
33
+
34
+ def check_node_types(node, iri_to_term, vocab, path)
35
+ return unless node.is_a?(Hash)
36
+
37
+ node.each do |iri, values|
38
+ next if iri.start_with?('@')
39
+
40
+ term = compact_term(iri, iri_to_term, vocab)
41
+ Array(values).each_with_index do |value, i|
42
+ child_path = Array(values).length > 1 ? path + [term, i.to_s] : path + [term]
43
+ check_typed_value(value, child_path, iri_to_term, vocab)
44
+ end
45
+ end
46
+ end
47
+
48
+ def check_typed_value(value, path, iri_to_term, vocab)
49
+ return unless value.is_a?(Hash)
50
+
51
+ if value.key?('@value') && value.key?('@type')
52
+ report_type_mismatch(value['@value'], value['@type'], path)
53
+ else
54
+ check_node_types(value, iri_to_term, vocab, path)
55
+ end
56
+ end
57
+
58
+ def report_type_mismatch(val, type_iri, path)
59
+ return if valid_xsd_value?(val, type_iri)
60
+
61
+ @errors << "invalid type for #{path.join('.')}: #{val.inspect}"
62
+ end
63
+
64
+ def valid_xsd_value?(val, type_iri)
65
+ if INTEGER_TYPES.include?(type_iri)
66
+ val.is_a?(Integer)
67
+ elsif DECIMAL_TYPES.include?(type_iri)
68
+ val.is_a?(Numeric)
69
+ elsif type_iri == BOOLEAN_TYPE
70
+ [true, false].include?(val)
71
+ else
72
+ true
73
+ end
74
+ end
75
+
76
+ def compact_term(iri, iri_to_term, vocab)
77
+ return iri_to_term[iri] if iri_to_term.key?(iri)
78
+ return iri.delete_prefix(vocab) if vocab && iri.start_with?(vocab)
79
+
80
+ iri
81
+ end
82
+ end
83
+ end
@@ -4,5 +4,4 @@ module JsonldValidate
4
4
  end
5
5
 
6
6
  require 'jsonld_validate/validator'
7
- require 'jsonld_validate/matchers'
8
7
  require 'jsonld_validate/version'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-ld-validate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damien MATHIEU
@@ -23,20 +23,6 @@ dependencies:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
25
  version: '3.0'
26
- - !ruby/object:Gem::Dependency
27
- name: rspec-core
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - "~>"
31
- - !ruby/object:Gem::Version
32
- version: '3.0'
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: '3.0'
40
26
  description: JSON-LD documents validation
41
27
  email:
42
28
  - 42@dmathieu.com
@@ -51,6 +37,7 @@ files:
51
37
  - lib/jsonld_validate/matchers/be_valid_json_ld.rb
52
38
  - lib/jsonld_validate/validator.rb
53
39
  - lib/jsonld_validate/version.rb
40
+ - lib/jsonld_validate/xsd_type_validator.rb
54
41
  homepage: https://codeberg.org/dmathieu/json-ld-validate
55
42
  licenses:
56
43
  - AGPL
@@ -70,7 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
57
  - !ruby/object:Gem::Version
71
58
  version: '0'
72
59
  requirements: []
73
- rubygems_version: 4.0.3
60
+ rubygems_version: 4.0.6
74
61
  specification_version: 4
75
62
  summary: JSON-LD documents validation
76
63
  test_files: []