yaml-ld 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -2
- data/VERSION +1 -1
- data/lib/yaml_ld/representation.rb +44 -6
- data/lib/yaml_ld.rb +7 -0
- data/spec/suite_helper.rb +410 -0
- data/spec/suite_spec.rb +22 -0
- data/spec/support/extensions.rb +8 -0
- metadata +28 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff85402eb62829682e62261e3313de8456944793866fb56dcd7d822c9f8568bb
|
4
|
+
data.tar.gz: af3f18f8c3f34bc297962180db33188999c7366da516b0d07bf157b9e590c1d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e253462895a4505847fc9ba8483005b384ba93acbfd2461c84d142d02b5d2b14c3529d9bce31098d89fae86c285381e8f037caa569be0de3e49d54fee56d47d9
|
7
|
+
data.tar.gz: 25939722e72692aa251abca8d472ddb8f05ef47d12830774f0139f87b53e1f279c1a6f9c29e10ba874f826b0e2a5e652b5b81d21f88ecb85450d5604e09b2b1b
|
data/README.md
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
Ruby [YAML-LD][] reader/writer for RDF.rb
|
4
4
|
|
5
|
-
[![Gem Version](https://badge.fury.io/rb/yaml-ld.
|
6
|
-
[![Build Status](https://
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/yaml-ld.svg)](https://rubygems.org/gems/yaml-ld)
|
6
|
+
[![Build Status](https://github.com/ruby-rdf/yaml-ld/workflows/CI/badge.svg?branch=develop)](https://github.com/ruby-rdf/yaml-ld/actions?query=workflow%3ACI)
|
7
7
|
[![Coverage Status](https://coveralls.io/repos/ruby-rdf/yaml-ld/badge.svg?branch=develop)](https://coveralls.io/github/ruby-rdf/yaml-ld?branch=develop)
|
8
8
|
[![Gitter chat](https://badges.gitter.im/ruby-rdf.png)](https://gitter.im/gitterHQ/gitter)
|
9
9
|
|
@@ -102,12 +102,17 @@ In addition to the input, both a `context` and `frame` may be specified using ei
|
|
102
102
|
* [Psych](https://rubygems.org/gems/psych) (>= 4.0)
|
103
103
|
* [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.2)
|
104
104
|
|
105
|
+
### Ubuntu limitation
|
106
|
+
|
107
|
+
As of October 2023, Ubuntu distributions are running with libyaml 0.2.1, which does not support YAML 1.2. The minimum version needed is libyaml 0.2.5.
|
108
|
+
|
105
109
|
## Installation
|
106
110
|
The recommended installation method is via [RubyGems](https://rubygems.org/).
|
107
111
|
To install the latest official release of the `JSON-LD` gem, do:
|
108
112
|
|
109
113
|
% [sudo] gem install yaml-ld
|
110
114
|
|
115
|
+
|
111
116
|
## Download
|
112
117
|
To get a local working copy of the development repository, do:
|
113
118
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
@@ -39,6 +39,16 @@ module YAML_LD
|
|
39
39
|
end
|
40
40
|
|
41
41
|
result.is_a?(Array) && result.empty? ? fallback : result
|
42
|
+
rescue Psych::SyntaxError => e
|
43
|
+
msg = filename ? "file: #{filename} #{e.message}" : e.message
|
44
|
+
if yaml.respond_to?(:read)
|
45
|
+
msg << "Content:\n" + yaml.tap(:rewind).read
|
46
|
+
end
|
47
|
+
if e.message.match?(/invalid leading UTF-8 octet/)
|
48
|
+
raise YAML_LD::Error::InvalidEncoding, msg
|
49
|
+
else
|
50
|
+
raise JSON::LD::JsonLdError::LoadingDocumentFailed, msg
|
51
|
+
end
|
42
52
|
end
|
43
53
|
module_function :load_stream
|
44
54
|
|
@@ -100,18 +110,46 @@ module YAML_LD
|
|
100
110
|
def as_jsonld_ir(node, **options)
|
101
111
|
# Scans scalars for built-in classes
|
102
112
|
@ss ||= Psych::ScalarScanner.new(Psych::ClassLoader::Restricted.new([], %i()))
|
113
|
+
|
114
|
+
# Record in-scope anchors to check for circular alias references.
|
115
|
+
in_scope_anchors = options[:in_scope_anchors] ||= {}
|
116
|
+
|
103
117
|
case node
|
104
118
|
when Psych::Nodes::Stream
|
105
119
|
node.children.map {|n| as_jsonld_ir(n, **options)}
|
106
|
-
when Psych::Nodes::Document
|
107
|
-
|
120
|
+
when Psych::Nodes::Document
|
121
|
+
as_jsonld_ir(node.children.first, named_nodes: {}, **options)
|
122
|
+
when Psych::Nodes::Sequence
|
123
|
+
value = []
|
124
|
+
if node.anchor
|
125
|
+
options = options.merge(in_scope_anchors: in_scope_anchors.merge(node.anchor => true))
|
126
|
+
options[:named_nodes][node.anchor] = value
|
127
|
+
end
|
128
|
+
node.children.each {|n| value << as_jsonld_ir(n, **options)}
|
129
|
+
value
|
108
130
|
when Psych::Nodes::Mapping
|
109
|
-
|
110
|
-
|
131
|
+
value = {}
|
132
|
+
if node.anchor
|
133
|
+
options = options.merge(in_scope_anchors: in_scope_anchors.merge(node.anchor => true))
|
134
|
+
options[:named_nodes][node.anchor] = value
|
135
|
+
end
|
136
|
+
node.children.each_slice(2) do |k, v|
|
137
|
+
key = as_jsonld_ir(k)
|
138
|
+
raise YAML_LD::Error::MappingKeyError, "mapping key #{k} (#{key.inspect}) not a string" unless key.is_a?(String)
|
139
|
+
value[as_jsonld_ir(k)] = as_jsonld_ir(v, **options)
|
140
|
+
end
|
141
|
+
value
|
142
|
+
when ::Psych::Nodes::Scalar
|
143
|
+
value = scan_scalar(node, **options)
|
144
|
+
if node.anchor
|
145
|
+
options = options.merge(in_scope_anchors: in_scope_anchors.merge(node.anchor => true))
|
146
|
+
options[:named_nodes][node.anchor] = value
|
111
147
|
end
|
112
|
-
|
148
|
+
value
|
113
149
|
when ::Psych::Nodes::Alias
|
114
|
-
|
150
|
+
raise JSON::LD::JsonLdError::LoadingDocumentFailed, "anchor for *#{node.anchor} not found" unless options[:named_nodes].key?(node.anchor)
|
151
|
+
raise JSON::LD::JsonLdError::LoadingDocumentFailed, "anchor for *#{node.anchor} creates a cycle" if in_scope_anchors.key?(node.anchor)
|
152
|
+
options[:named_nodes][node.anchor]
|
115
153
|
end
|
116
154
|
end
|
117
155
|
module_function :as_jsonld_ir
|
data/lib/yaml_ld.rb
CHANGED
@@ -35,4 +35,11 @@ module YAML_LD
|
|
35
35
|
# YAML-LD profiles
|
36
36
|
YAML_LD_NS = "http://www.w3.org/ns/yaml-ld#"
|
37
37
|
PROFILES = %w(extended).map {|p| YAML_LD_NS + p}.freeze
|
38
|
+
|
39
|
+
class Error < JSON::LD::JsonLdError
|
40
|
+
class InvalidEncoding < YAML_LD::Error; @code = "invalid encoding"; end
|
41
|
+
class MappingKeyError < YAML_LD::Error; @code = "mapping-key-error"; end
|
42
|
+
class ProfileError < YAML_LD::Error; @code = "profile-error"; end
|
43
|
+
end
|
44
|
+
|
38
45
|
end
|
@@ -0,0 +1,410 @@
|
|
1
|
+
require 'yaml_ld'
|
2
|
+
|
3
|
+
# For now, override RDF::Utils::File.open_file to look for the file locally before attempting to retrieve it
|
4
|
+
module RDF::Util
|
5
|
+
module File
|
6
|
+
LOCAL_PATHS = {
|
7
|
+
"https://json-ld.github.io/yaml-ld/tests/" => ::File.expand_path("../../../w3c-yaml-ld/tests", __FILE__) + '/',
|
8
|
+
"file:" => ""
|
9
|
+
}
|
10
|
+
|
11
|
+
class << self
|
12
|
+
alias_method :original_open_file, :open_file
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Override to use Patron for http and https, Kernel.open otherwise.
|
17
|
+
#
|
18
|
+
# @param [String] filename_or_url to open
|
19
|
+
# @param [Hash{Symbol => Object}] options
|
20
|
+
# @option options [Array, String] :headers
|
21
|
+
# HTTP Request headers.
|
22
|
+
# @return [IO] File stream
|
23
|
+
# @yield [IO] File stream
|
24
|
+
def self.open_file(filename_or_url, **options, &block)
|
25
|
+
LOCAL_PATHS.each do |r, l|
|
26
|
+
next unless Dir.exist?(l) && filename_or_url.start_with?(r)
|
27
|
+
#puts "attempt to open #{filename_or_url} locally"
|
28
|
+
url_no_frag_or_query = RDF::URI(filename_or_url).dup
|
29
|
+
url_no_frag_or_query.query = nil
|
30
|
+
url_no_frag_or_query.fragment = nil
|
31
|
+
localpath = url_no_frag_or_query.to_s.sub(r, l)
|
32
|
+
response = begin
|
33
|
+
::File.open(localpath)
|
34
|
+
rescue Errno::ENOENT => e
|
35
|
+
raise IOError, e.message
|
36
|
+
end
|
37
|
+
|
38
|
+
document_options = {
|
39
|
+
base_uri: RDF::URI(filename_or_url),
|
40
|
+
charset: Encoding::UTF_8,
|
41
|
+
code: 200,
|
42
|
+
headers: options.fetch(:headers, {})
|
43
|
+
}
|
44
|
+
#puts "use #{filename_or_url} locally"
|
45
|
+
document_options[:headers][:content_type] = case localpath
|
46
|
+
when /\.ttl$/ then 'text/turtle'
|
47
|
+
when /\.nq$/ then 'application/n-quads'
|
48
|
+
when /\.nt$/ then 'application/n-triples'
|
49
|
+
when /\.html$/ then 'text/html'
|
50
|
+
when /\.jsonld$/ then 'application/ld+json'
|
51
|
+
when /\.json$/ then 'application/json'
|
52
|
+
when /\.yamlld$/ then 'application/ld+yaml'
|
53
|
+
when /\.yaml$/ then 'application/yaml'
|
54
|
+
else 'unknown'
|
55
|
+
end
|
56
|
+
|
57
|
+
document_options[:headers][:content_type] = response.content_type if response.respond_to?(:content_type)
|
58
|
+
# For overriding content type from test data
|
59
|
+
document_options[:headers][:content_type] = options[:contentType] if options[:contentType]
|
60
|
+
|
61
|
+
remote_document = RDF::Util::File::RemoteDocument.new(response.read, **document_options)
|
62
|
+
response.close
|
63
|
+
if block_given?
|
64
|
+
return yield remote_document
|
65
|
+
else
|
66
|
+
return remote_document
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
original_open_file(filename_or_url, **options, &block)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
module Fixtures
|
76
|
+
module SuiteTest
|
77
|
+
SUITE = RDF::URI("https://json-ld.github.io/yaml-ld/tests/")
|
78
|
+
|
79
|
+
class Manifest < JSON::LD::Resource
|
80
|
+
attr_accessor :manifest_url
|
81
|
+
|
82
|
+
def self.open(file)
|
83
|
+
RDF::Util::File.open_file(file) do |remote|
|
84
|
+
json = JSON.parse(remote.read)
|
85
|
+
if block_given?
|
86
|
+
yield self.from_jsonld(json, manifest_url: RDF::URI(file))
|
87
|
+
else
|
88
|
+
self.from_jsonld(json, manifest_url: RDF::URI(file))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def initialize(json, manifest_url:)
|
94
|
+
@manifest_url = manifest_url
|
95
|
+
super
|
96
|
+
end
|
97
|
+
|
98
|
+
# @param [Hash] json framed JSON-LD
|
99
|
+
# @return [Array<Manifest>]
|
100
|
+
def self.from_jsonld(json, manifest_url: )
|
101
|
+
Manifest.new(json, manifest_url: manifest_url)
|
102
|
+
end
|
103
|
+
|
104
|
+
def entries
|
105
|
+
# Map entries to resources
|
106
|
+
attributes['sequence'].map do |e|
|
107
|
+
e.is_a?(String) ? Manifest.open(manifest_url.join(e).to_s) : Entry.new(e, manifest_url: manifest_url)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
class Entry < JSON::LD::Resource
|
113
|
+
attr_accessor :logger
|
114
|
+
attr_accessor :manifest_url
|
115
|
+
|
116
|
+
def initialize(json, manifest_url:)
|
117
|
+
@manifest_url = manifest_url
|
118
|
+
super
|
119
|
+
end
|
120
|
+
|
121
|
+
# Base is expanded input if not specified
|
122
|
+
def base
|
123
|
+
options.fetch('base', manifest_url.join(property('input')).to_s)
|
124
|
+
end
|
125
|
+
|
126
|
+
def options
|
127
|
+
@options ||= begin
|
128
|
+
opts = {
|
129
|
+
documentLoader: Fixtures::SuiteTest.method(:documentLoader),
|
130
|
+
validate: true,
|
131
|
+
lowercaseLanguage: true,
|
132
|
+
}
|
133
|
+
(property('option') || {}).each do |k, v|
|
134
|
+
opts[k.to_sym] = v
|
135
|
+
end
|
136
|
+
if opts[:expandContext] && !RDF::URI(opts[:expandContext]).absolute?
|
137
|
+
# Resolve relative to manifest location
|
138
|
+
opts[:expandContext] = manifest_url.join(opts[:expandContext]).to_s
|
139
|
+
end
|
140
|
+
opts
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Alias input, context, expect and frame
|
145
|
+
%w(input context expect frame).each do |m|
|
146
|
+
define_method(m.to_sym) do
|
147
|
+
return nil unless property(m)
|
148
|
+
res = nil
|
149
|
+
file = self.send("#{m}_loc".to_sym)
|
150
|
+
|
151
|
+
dl_opts = {safe: true}
|
152
|
+
dl_opts[:contentType] = options[:contentType] if m == 'input' && options[:contentType]
|
153
|
+
RDF::Util::File.open_file(file, **dl_opts) do |remote_doc|
|
154
|
+
res = remote_doc.read
|
155
|
+
end
|
156
|
+
res
|
157
|
+
end
|
158
|
+
|
159
|
+
define_method("#{m}_loc".to_sym) do
|
160
|
+
file = property(m)
|
161
|
+
|
162
|
+
# Handle redirection internally
|
163
|
+
if m == "input" && options[:redirectTo]
|
164
|
+
file = options[:redirectTo]
|
165
|
+
end
|
166
|
+
|
167
|
+
property(m) && manifest_url.join(file).to_s
|
168
|
+
end
|
169
|
+
|
170
|
+
define_method("#{m}_json".to_sym) do
|
171
|
+
JSON.parse(self.send(m)) if property(m)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def testType
|
176
|
+
property('@type').reject {|t| t =~ /EvaluationTest|SyntaxTest/}.first
|
177
|
+
end
|
178
|
+
|
179
|
+
def evaluationTest?
|
180
|
+
property('@type').to_s.include?('EvaluationTest')
|
181
|
+
end
|
182
|
+
|
183
|
+
def positiveTest?
|
184
|
+
property('@type').to_s.include?('Positive')
|
185
|
+
end
|
186
|
+
|
187
|
+
def syntaxTest?
|
188
|
+
property('@type').to_s.include?('Syntax')
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
# Execute the test
|
193
|
+
def run(rspec_example = nil)
|
194
|
+
logger = @logger = RDF::Spec.logger
|
195
|
+
logger.info "test: #{inspect}"
|
196
|
+
logger.info "purpose: #{purpose}"
|
197
|
+
logger.info "source: #{input rescue nil}"
|
198
|
+
logger.info "context: #{context}" if context_loc
|
199
|
+
logger.info "options: #{options.inspect}" unless options.empty?
|
200
|
+
logger.info "frame: #{frame}" if frame_loc
|
201
|
+
|
202
|
+
options = self.options
|
203
|
+
if options[:specVersion] == "json-ld-1.0"
|
204
|
+
skip "1.0 test"
|
205
|
+
return
|
206
|
+
end
|
207
|
+
|
208
|
+
# Because we're doing exact comparisons when ordered.
|
209
|
+
options[:lowercaseLanguage] = true if options[:ordered]
|
210
|
+
|
211
|
+
if positiveTest?
|
212
|
+
logger.info "expected: #{expect rescue nil}" if expect_loc
|
213
|
+
begin
|
214
|
+
result = case testType
|
215
|
+
when "jld:ExpandTest"
|
216
|
+
YAML_LD::API.expand(input_loc, logger: logger, **options)
|
217
|
+
when "jld:CompactTest"
|
218
|
+
YAML_LD::API.compact(input_loc, context_json['@context'], logger: logger, **options)
|
219
|
+
when "jld:FlattenTest"
|
220
|
+
YAML_LD::API.flatten(input_loc, (context_json['@context'] if context_loc), logger: logger, **options)
|
221
|
+
when "jld:FrameTest"
|
222
|
+
YAML_LD::API.frame(input_loc, frame_loc, logger: logger, **options)
|
223
|
+
when "jld:FromRDFTest"
|
224
|
+
# Use an array, to preserve input order
|
225
|
+
repo = RDF::NQuads::Reader.open(input_loc, rdfstar: options[:rdfstar]) do |reader|
|
226
|
+
reader.each_statement.to_a
|
227
|
+
end.to_a.uniq.extend(RDF::Enumerable)
|
228
|
+
logger.info "repo: #{repo.dump(self.id == '#t0012' ? :nquads : :trig)}"
|
229
|
+
YAML_LD::API.fromRdf(repo, logger: logger, **options)
|
230
|
+
when "jld:ToRDFTest"
|
231
|
+
repo = RDF::Repository.new
|
232
|
+
if manifest_url.to_s.include?('stream')
|
233
|
+
YAML_LD::Reader.open(input_loc, stream: true, logger: logger, **options) do |statement|
|
234
|
+
repo << statement
|
235
|
+
end
|
236
|
+
else
|
237
|
+
YAML_LD::API.toRdf(input_loc, rename_bnodes: false, logger: logger, **options) do |statement|
|
238
|
+
repo << statement
|
239
|
+
end
|
240
|
+
end
|
241
|
+
logger.info "nq: #{repo.map(&:to_nquads)}"
|
242
|
+
repo
|
243
|
+
when "jld:HttpTest"
|
244
|
+
res = input_json
|
245
|
+
rspec_example.instance_eval do
|
246
|
+
# use the parsed input file as @result for Rack Test application
|
247
|
+
@results = res
|
248
|
+
get "/", {}, "HTTP_ACCEPT" => options.fetch(:httpAccept, ""), "HTTP_LINK" => options.fetch(:httpLink, nil)
|
249
|
+
expect(last_response.status).to eq 200
|
250
|
+
expect(last_response.content_type).to eq options.fetch(:contentType, "")
|
251
|
+
last_response.body
|
252
|
+
end
|
253
|
+
else
|
254
|
+
fail("Unknown test type: #{testType}")
|
255
|
+
end
|
256
|
+
|
257
|
+
result = YAML_LD::Representation.load(result, extendedYAML: options[:extendedYAML]) if result.is_a?(String)
|
258
|
+
|
259
|
+
if evaluationTest?
|
260
|
+
if testType == "jld:ToRDFTest"
|
261
|
+
expected = RDF::Repository.new << RDF::NQuads::Reader.new(expect, rdfstar: options[:rdfstar], logger: [])
|
262
|
+
rspec_example.instance_eval {
|
263
|
+
expect(result).to be_equivalent_graph(expected, logger)
|
264
|
+
}
|
265
|
+
else
|
266
|
+
expected = YAML_LD::Representation.load(expect, extendedYAML: options[:extendedYAML])
|
267
|
+
|
268
|
+
# If called for, remap bnodes
|
269
|
+
result = remap_bnodes(result, expected) if options[:remap_bnodes]
|
270
|
+
|
271
|
+
if options[:ordered]
|
272
|
+
# Compare without transformation
|
273
|
+
rspec_example.instance_eval {
|
274
|
+
expect(result).to produce(expected, logger)
|
275
|
+
}
|
276
|
+
else
|
277
|
+
# Without key ordering, reorder result and expected embedded array values and compare
|
278
|
+
# If results are compacted, expand both, reorder and re-compare
|
279
|
+
rspec_example.instance_eval {
|
280
|
+
expect(result).to produce_yamlld(expected, logger)
|
281
|
+
}
|
282
|
+
|
283
|
+
# If results are compacted, expand both, reorder and re-compare
|
284
|
+
if result.to_s.include?('@context')
|
285
|
+
exp_expected = JSON::LD::API.expand(expected, **options)
|
286
|
+
exp_result = JSON::LD::API.expand(result, **options)
|
287
|
+
rspec_example.instance_eval {
|
288
|
+
expect(exp_result).to produce_yamlld(exp_expected, logger)
|
289
|
+
}
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
else
|
294
|
+
rspec_example.instance_eval {
|
295
|
+
expect(result).to_not be_nil
|
296
|
+
}
|
297
|
+
end
|
298
|
+
rescue JSON::LD::JsonLdError => e
|
299
|
+
fail("Processing error: #{e.message}")
|
300
|
+
end
|
301
|
+
else
|
302
|
+
logger.info "expected: #{property('expect')}" if property('expect')
|
303
|
+
t = self
|
304
|
+
rspec_example.instance_eval do
|
305
|
+
if t.evaluationTest?
|
306
|
+
expect do
|
307
|
+
case t.testType
|
308
|
+
when "jld:ExpandTest"
|
309
|
+
JSON::LD::API.expand(t.input_loc, logger: logger, **options)
|
310
|
+
when "jld:CompactTest"
|
311
|
+
JSON::LD::API.compact(t.input_loc, t.context_json['@context'], logger: logger, **options)
|
312
|
+
when "jld:FlattenTest"
|
313
|
+
JSON::LD::API.flatten(t.input_loc, t.context_loc, logger: logger, **options)
|
314
|
+
when "jld:FrameTest"
|
315
|
+
JSON::LD::API.frame(t.input_loc, t.frame_loc, logger: logger, **options)
|
316
|
+
when "jld:FromRDFTest"
|
317
|
+
repo = RDF::Repository.load(t.input_loc, rdfstar: options[:rdfstar])
|
318
|
+
logger.info "repo: #{repo.dump(t.id == '#t0012' ? :nquads : :trig)}"
|
319
|
+
JSON::LD::API.fromRdf(repo, logger: logger, **options)
|
320
|
+
when "jld:HttpTest"
|
321
|
+
rspec_example.instance_eval do
|
322
|
+
# use the parsed input file as @result for Rack Test application
|
323
|
+
@results = t.input_json
|
324
|
+
get "/", {}, "HTTP_ACCEPT" => options.fetch(:httpAccept, "")
|
325
|
+
expect(last_response.status).to eq t.property('expect')
|
326
|
+
expect(last_response.content_type).to eq options.fetch(:contentType, "")
|
327
|
+
raise "406" if t.property('expect') == 406
|
328
|
+
raise "Expected status #{t.property('expectErrorCode')}, not #{last_response.status}"
|
329
|
+
end
|
330
|
+
when "jld:ToRDFTest"
|
331
|
+
if t.manifest_url.to_s.include?('stream')
|
332
|
+
JSON::LD::Reader.open(t.input_loc, stream: true, logger: logger, **options).each_statement {}
|
333
|
+
else
|
334
|
+
JSON::LD::API.toRdf(t.input_loc, rename_bnodes: false, logger: logger, **options) {}
|
335
|
+
end
|
336
|
+
else
|
337
|
+
success("Unknown test type: #{testType}")
|
338
|
+
end
|
339
|
+
end.to raise_error(/#{t.property('expectErrorCode')}/)
|
340
|
+
else
|
341
|
+
fail("No support for NegativeSyntaxTest")
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
# Don't use NQuads writer so that we don't escape Unicode
|
348
|
+
def to_quad(thing)
|
349
|
+
case thing
|
350
|
+
when RDF::URI
|
351
|
+
thing.to_ntriples
|
352
|
+
when RDF::Node
|
353
|
+
escaped(thing)
|
354
|
+
when RDF::Literal::Double
|
355
|
+
thing.canonicalize.to_ntriples
|
356
|
+
when RDF::Literal
|
357
|
+
v = quoted(escaped(thing.value))
|
358
|
+
case thing.datatype
|
359
|
+
when nil, "http://www.w3.org/2001/XMLSchema#string", "http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"
|
360
|
+
# Ignore these
|
361
|
+
else
|
362
|
+
v += "^^#{to_quad(thing.datatype)}"
|
363
|
+
end
|
364
|
+
v += "@#{thing.language}" if thing.language
|
365
|
+
v
|
366
|
+
when RDF::Statement
|
367
|
+
thing.to_quad.map {|r| to_quad(r)}.compact.join(" ") + " .\n"
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
##
|
372
|
+
# @param [String] string
|
373
|
+
# @return [String]
|
374
|
+
def quoted(string)
|
375
|
+
"\"#{string}\""
|
376
|
+
end
|
377
|
+
|
378
|
+
##
|
379
|
+
# @param [String, #to_s] string
|
380
|
+
# @return [String]
|
381
|
+
def escaped(string)
|
382
|
+
string.to_s.gsub('\\', '\\\\').gsub("\t", '\\t').
|
383
|
+
gsub("\n", '\\n').gsub("\r", '\\r').gsub('"', '\\"')
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
##
|
388
|
+
# Document loader to use for tests having `useDocumentLoader` option
|
389
|
+
#
|
390
|
+
# @param [RDF::URI, String] url
|
391
|
+
# @param [Hash<Symbol => Object>] options
|
392
|
+
# @option options [Boolean] :validate
|
393
|
+
# Allow only appropriate content types
|
394
|
+
# @return [RDF::Util::File::RemoteDocument] retrieved remote document and context information unless block given
|
395
|
+
# @yield remote_document
|
396
|
+
# @yieldparam [RDF::Util::File::RemoteDocument] remote_document
|
397
|
+
# @raise [JsonLdError]
|
398
|
+
def documentLoader(url, **options, &block)
|
399
|
+
options[:headers] ||= JSON::LD::API::OPEN_OPTS[:headers].dup
|
400
|
+
options[:headers][:link] = Array(options[:httpLink]).join(',') if options[:httpLink]
|
401
|
+
|
402
|
+
url = url.to_s[5..-1] if url.to_s.start_with?("file:")
|
403
|
+
YAML_LD::API.documentLoader(url, **options, &block)
|
404
|
+
rescue JSON::LD::JsonLdError::LoadingDocumentFailed, JSON::LD::JsonLdError::MultipleContextLinkHeaders
|
405
|
+
raise unless options[:safe]
|
406
|
+
"don't raise error"
|
407
|
+
end
|
408
|
+
module_function :documentLoader
|
409
|
+
end
|
410
|
+
end
|
data/spec/suite_spec.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require_relative 'spec_helper'
|
3
|
+
|
4
|
+
describe YAML_LD do
|
5
|
+
describe "test suite" do
|
6
|
+
require_relative 'suite_helper'
|
7
|
+
m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}manifest.jsonld")
|
8
|
+
describe m.name do
|
9
|
+
m.entries.each do |t|
|
10
|
+
specify "#{t.property('@id')}: #{t.name} #{t.positiveTest? ? 'unordered' : '(negative test)'}" do
|
11
|
+
t.options[:ordered] = false
|
12
|
+
expect{t.run self}.not_to write.to(:error)
|
13
|
+
end
|
14
|
+
|
15
|
+
specify "#{t.property('@id')}: #{t.name} ordered" do
|
16
|
+
t.options[:ordered] = true
|
17
|
+
expect {t.run self}.not_to write.to(:error)
|
18
|
+
end if t.positiveTest?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end unless ENV['CI']
|
data/spec/support/extensions.rb
CHANGED
@@ -42,3 +42,11 @@ class Array
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
|
+
|
46
|
+
class String
|
47
|
+
def equivalent_yamlld?(other, ordered: false, extendedYAML: false)
|
48
|
+
actual = YAML_LD::Representation.load(self, aliases: true, extendedYAML: extendedYAML)
|
49
|
+
expected = other.is_a?(String) ? YAML_LD::Representation.load(other, aliases: true, extendedYAML: extendedYAML) : other
|
50
|
+
actual.equivalent_structure?(expected, ordered: ordered)
|
51
|
+
end
|
52
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yaml-ld
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gregg Kellogg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-10-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json-ld
|
@@ -16,20 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '3.
|
20
|
-
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 3.2.3
|
19
|
+
version: '3.3'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: '3.
|
30
|
-
- - ">="
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 3.2.3
|
26
|
+
version: '3.3'
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: psych
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,132 +44,126 @@ dependencies:
|
|
50
44
|
requirements:
|
51
45
|
- - "~>"
|
52
46
|
- !ruby/object:Gem::Version
|
53
|
-
version: '3.
|
54
|
-
- - ">="
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version: 3.2.9
|
47
|
+
version: '3.3'
|
57
48
|
type: :runtime
|
58
49
|
prerelease: false
|
59
50
|
version_requirements: !ruby/object:Gem::Requirement
|
60
51
|
requirements:
|
61
52
|
- - "~>"
|
62
53
|
- !ruby/object:Gem::Version
|
63
|
-
version: '3.
|
64
|
-
- - ">="
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
version: 3.2.9
|
54
|
+
version: '3.3'
|
67
55
|
- !ruby/object:Gem::Dependency
|
68
56
|
name: rdf-xsd
|
69
57
|
requirement: !ruby/object:Gem::Requirement
|
70
58
|
requirements:
|
71
59
|
- - "~>"
|
72
60
|
- !ruby/object:Gem::Version
|
73
|
-
version: '3.
|
61
|
+
version: '3.3'
|
74
62
|
type: :runtime
|
75
63
|
prerelease: false
|
76
64
|
version_requirements: !ruby/object:Gem::Requirement
|
77
65
|
requirements:
|
78
66
|
- - "~>"
|
79
67
|
- !ruby/object:Gem::Version
|
80
|
-
version: '3.
|
68
|
+
version: '3.3'
|
81
69
|
- !ruby/object:Gem::Dependency
|
82
70
|
name: rdf-isomorphic
|
83
71
|
requirement: !ruby/object:Gem::Requirement
|
84
72
|
requirements:
|
85
73
|
- - "~>"
|
86
74
|
- !ruby/object:Gem::Version
|
87
|
-
version: '3.
|
75
|
+
version: '3.3'
|
88
76
|
type: :development
|
89
77
|
prerelease: false
|
90
78
|
version_requirements: !ruby/object:Gem::Requirement
|
91
79
|
requirements:
|
92
80
|
- - "~>"
|
93
81
|
- !ruby/object:Gem::Version
|
94
|
-
version: '3.
|
82
|
+
version: '3.3'
|
95
83
|
- !ruby/object:Gem::Dependency
|
96
84
|
name: rdf-spec
|
97
85
|
requirement: !ruby/object:Gem::Requirement
|
98
86
|
requirements:
|
99
87
|
- - "~>"
|
100
88
|
- !ruby/object:Gem::Version
|
101
|
-
version: '3.
|
89
|
+
version: '3.3'
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
93
|
requirements:
|
106
94
|
- - "~>"
|
107
95
|
- !ruby/object:Gem::Version
|
108
|
-
version: '3.
|
96
|
+
version: '3.3'
|
109
97
|
- !ruby/object:Gem::Dependency
|
110
98
|
name: rdf-trig
|
111
99
|
requirement: !ruby/object:Gem::Requirement
|
112
100
|
requirements:
|
113
101
|
- - "~>"
|
114
102
|
- !ruby/object:Gem::Version
|
115
|
-
version: '3.
|
103
|
+
version: '3.3'
|
116
104
|
type: :development
|
117
105
|
prerelease: false
|
118
106
|
version_requirements: !ruby/object:Gem::Requirement
|
119
107
|
requirements:
|
120
108
|
- - "~>"
|
121
109
|
- !ruby/object:Gem::Version
|
122
|
-
version: '3.
|
110
|
+
version: '3.3'
|
123
111
|
- !ruby/object:Gem::Dependency
|
124
112
|
name: rdf-turtle
|
125
113
|
requirement: !ruby/object:Gem::Requirement
|
126
114
|
requirements:
|
127
115
|
- - "~>"
|
128
116
|
- !ruby/object:Gem::Version
|
129
|
-
version: '3.
|
117
|
+
version: '3.3'
|
130
118
|
type: :development
|
131
119
|
prerelease: false
|
132
120
|
version_requirements: !ruby/object:Gem::Requirement
|
133
121
|
requirements:
|
134
122
|
- - "~>"
|
135
123
|
- !ruby/object:Gem::Version
|
136
|
-
version: '3.
|
124
|
+
version: '3.3'
|
137
125
|
- !ruby/object:Gem::Dependency
|
138
126
|
name: rdf-vocab
|
139
127
|
requirement: !ruby/object:Gem::Requirement
|
140
128
|
requirements:
|
141
129
|
- - "~>"
|
142
130
|
- !ruby/object:Gem::Version
|
143
|
-
version: '3.
|
131
|
+
version: '3.3'
|
144
132
|
type: :development
|
145
133
|
prerelease: false
|
146
134
|
version_requirements: !ruby/object:Gem::Requirement
|
147
135
|
requirements:
|
148
136
|
- - "~>"
|
149
137
|
- !ruby/object:Gem::Version
|
150
|
-
version: '3.
|
138
|
+
version: '3.3'
|
151
139
|
- !ruby/object:Gem::Dependency
|
152
140
|
name: rdf-xsd
|
153
141
|
requirement: !ruby/object:Gem::Requirement
|
154
142
|
requirements:
|
155
143
|
- - "~>"
|
156
144
|
- !ruby/object:Gem::Version
|
157
|
-
version: '3.
|
145
|
+
version: '3.3'
|
158
146
|
type: :development
|
159
147
|
prerelease: false
|
160
148
|
version_requirements: !ruby/object:Gem::Requirement
|
161
149
|
requirements:
|
162
150
|
- - "~>"
|
163
151
|
- !ruby/object:Gem::Version
|
164
|
-
version: '3.
|
152
|
+
version: '3.3'
|
165
153
|
- !ruby/object:Gem::Dependency
|
166
154
|
name: rspec
|
167
155
|
requirement: !ruby/object:Gem::Requirement
|
168
156
|
requirements:
|
169
157
|
- - "~>"
|
170
158
|
- !ruby/object:Gem::Version
|
171
|
-
version: '3.
|
159
|
+
version: '3.12'
|
172
160
|
type: :development
|
173
161
|
prerelease: false
|
174
162
|
version_requirements: !ruby/object:Gem::Requirement
|
175
163
|
requirements:
|
176
164
|
- - "~>"
|
177
165
|
- !ruby/object:Gem::Version
|
178
|
-
version: '3.
|
166
|
+
version: '3.12'
|
179
167
|
- !ruby/object:Gem::Dependency
|
180
168
|
name: rspec-its
|
181
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -234,6 +222,8 @@ files:
|
|
234
222
|
- spec/reader_spec.rb
|
235
223
|
- spec/representation_spec.rb
|
236
224
|
- spec/spec_helper.rb
|
225
|
+
- spec/suite_helper.rb
|
226
|
+
- spec/suite_spec.rb
|
237
227
|
- spec/support/extensions.rb
|
238
228
|
- spec/test-files/test-1-compacted.jsonld
|
239
229
|
- spec/test-files/test-1-compacted.yamlld
|
@@ -302,14 +292,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
302
292
|
requirements:
|
303
293
|
- - ">="
|
304
294
|
- !ruby/object:Gem::Version
|
305
|
-
version: '
|
295
|
+
version: '3.0'
|
306
296
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
307
297
|
requirements:
|
308
298
|
- - ">="
|
309
299
|
- !ruby/object:Gem::Version
|
310
300
|
version: '0'
|
311
301
|
requirements: []
|
312
|
-
rubygems_version: 3.
|
302
|
+
rubygems_version: 3.4.19
|
313
303
|
signing_key:
|
314
304
|
specification_version: 4
|
315
305
|
summary: YAML-LD reader/writer for Ruby.
|
@@ -325,6 +315,8 @@ test_files:
|
|
325
315
|
- spec/reader_spec.rb
|
326
316
|
- spec/representation_spec.rb
|
327
317
|
- spec/spec_helper.rb
|
318
|
+
- spec/suite_helper.rb
|
319
|
+
- spec/suite_spec.rb
|
328
320
|
- spec/support/extensions.rb
|
329
321
|
- spec/to_rdf_spec.rb
|
330
322
|
- spec/writer_spec.rb
|