json-ld 1.1.7 → 1.1.8
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 +4 -4
- data/README.md +9 -3
- data/VERSION +1 -1
- data/bin/jsonld +42 -23
- data/lib/json/ld.rb +6 -6
- data/lib/json/ld/api.rb +68 -93
- data/lib/json/ld/compact.rb +15 -15
- data/lib/json/ld/context.rb +47 -22
- data/lib/json/ld/expand.rb +7 -7
- data/lib/json/ld/extensions.rb +2 -2
- data/lib/json/ld/flatten.rb +1 -1
- data/lib/json/ld/format.rb +5 -5
- data/lib/json/ld/frame.rb +5 -5
- data/lib/json/ld/from_rdf.rb +2 -2
- data/lib/json/ld/reader.rb +0 -2
- data/lib/json/ld/resource.rb +4 -4
- data/lib/json/ld/streaming_writer.rb +123 -0
- data/lib/json/ld/to_rdf.rb +6 -6
- data/lib/json/ld/writer.rb +29 -6
- data/spec/api_spec.rb +57 -4
- data/spec/compact_spec.rb +92 -92
- data/spec/context_spec.rb +43 -23
- data/spec/expand_spec.rb +142 -142
- data/spec/flatten_spec.rb +17 -17
- data/spec/format_spec.rb +17 -17
- data/spec/frame_spec.rb +47 -47
- data/spec/from_rdf_spec.rb +25 -25
- data/spec/matchers.rb +9 -9
- data/spec/reader_spec.rb +4 -4
- data/spec/resource_spec.rb +1 -1
- data/spec/spec_helper.rb +14 -9
- data/spec/streaming_writer_spec.rb +142 -0
- data/spec/suite_helper.rb +29 -88
- data/spec/to_rdf_spec.rb +17 -17
- data/spec/writer_spec.rb +43 -20
- metadata +40 -15
data/spec/from_rdf_spec.rb
CHANGED
@@ -69,7 +69,7 @@ describe JSON::LD::API do
|
|
69
69
|
|
70
70
|
it "integer" do
|
71
71
|
input = %(@prefix ex: <http://example.com/> . ex:a ex:b 1 .)
|
72
|
-
expect(serialize(input, :
|
72
|
+
expect(serialize(input, useNativeTypes: true)).to produce([{
|
73
73
|
'@id' => "http://example.com/a",
|
74
74
|
"http://example.com/b" => [{"@value" => 1}]
|
75
75
|
}], @debug)
|
@@ -77,7 +77,7 @@ describe JSON::LD::API do
|
|
77
77
|
|
78
78
|
it "integer (non-native)" do
|
79
79
|
input = %(@prefix ex: <http://example.com/> . ex:a ex:b 1 .)
|
80
|
-
expect(serialize(input, :
|
80
|
+
expect(serialize(input, useNativeTypes: false)).to produce([{
|
81
81
|
'@id' => "http://example.com/a",
|
82
82
|
"http://example.com/b" => [{"@value" => "1","@type" => "http://www.w3.org/2001/XMLSchema#integer"}]
|
83
83
|
}], @debug)
|
@@ -85,7 +85,7 @@ describe JSON::LD::API do
|
|
85
85
|
|
86
86
|
it "boolean" do
|
87
87
|
input = %(@prefix ex: <http://example.com/> . ex:a ex:b true .)
|
88
|
-
expect(serialize(input, :
|
88
|
+
expect(serialize(input, useNativeTypes: true)).to produce([{
|
89
89
|
'@id' => "http://example.com/a",
|
90
90
|
"http://example.com/b" => [{"@value" => true}]
|
91
91
|
}], @debug)
|
@@ -93,7 +93,7 @@ describe JSON::LD::API do
|
|
93
93
|
|
94
94
|
it "boolean (non-native)" do
|
95
95
|
input = %(@prefix ex: <http://example.com/> . ex:a ex:b true .)
|
96
|
-
expect(serialize(input, :
|
96
|
+
expect(serialize(input, useNativeTypes: false)).to produce([{
|
97
97
|
'@id' => "http://example.com/a",
|
98
98
|
"http://example.com/b" => [{"@value" => "true","@type" => "http://www.w3.org/2001/XMLSchema#boolean"}]
|
99
99
|
}], @debug)
|
@@ -101,7 +101,7 @@ describe JSON::LD::API do
|
|
101
101
|
|
102
102
|
it "decmal" do
|
103
103
|
input = %(@prefix ex: <http://example.com/> . ex:a ex:b 1.0 .)
|
104
|
-
expect(serialize(input, :
|
104
|
+
expect(serialize(input, useNativeTypes: true)).to produce([{
|
105
105
|
'@id' => "http://example.com/a",
|
106
106
|
"http://example.com/b" => [{"@value" => "1.0", "@type" => "http://www.w3.org/2001/XMLSchema#decimal"}]
|
107
107
|
}], @debug)
|
@@ -109,7 +109,7 @@ describe JSON::LD::API do
|
|
109
109
|
|
110
110
|
it "double" do
|
111
111
|
input = %(@prefix ex: <http://example.com/> . ex:a ex:b 1.0e0 .)
|
112
|
-
expect(serialize(input, :
|
112
|
+
expect(serialize(input, useNativeTypes: true)).to produce([{
|
113
113
|
'@id' => "http://example.com/a",
|
114
114
|
"http://example.com/b" => [{"@value" => 1.0E0}]
|
115
115
|
}], @debug)
|
@@ -117,7 +117,7 @@ describe JSON::LD::API do
|
|
117
117
|
|
118
118
|
it "double (non-native)" do
|
119
119
|
input = %(@prefix ex: <http://example.com/> . ex:a ex:b 1.0e0 .)
|
120
|
-
expect(serialize(input, :
|
120
|
+
expect(serialize(input, useNativeTypes: false)).to produce([{
|
121
121
|
'@id' => "http://example.com/a",
|
122
122
|
"http://example.com/b" => [{"@value" => "1.0E0","@type" => "http://www.w3.org/2001/XMLSchema#double"}]
|
123
123
|
}], @debug)
|
@@ -126,12 +126,12 @@ describe JSON::LD::API do
|
|
126
126
|
|
127
127
|
context "datatyped (non-native)" do
|
128
128
|
{
|
129
|
-
:
|
130
|
-
:
|
131
|
-
:
|
132
|
-
:
|
133
|
-
:
|
134
|
-
:
|
129
|
+
integer: 1,
|
130
|
+
unsignedInteger: 1,
|
131
|
+
nonNegativeInteger: 1,
|
132
|
+
float: 1,
|
133
|
+
nonPositiveInteger: -1,
|
134
|
+
negativeInteger: -1,
|
135
135
|
}.each do |t, v|
|
136
136
|
it "#{t}" do
|
137
137
|
input = %(
|
@@ -139,7 +139,7 @@ describe JSON::LD::API do
|
|
139
139
|
@prefix ex: <http://example.com/> .
|
140
140
|
ex:a ex:b "#{v}"^^xsd:#{t} .
|
141
141
|
)
|
142
|
-
expect(serialize(input, :
|
142
|
+
expect(serialize(input, useNativeTypes: false)).to produce([{
|
143
143
|
'@id' => "http://example.com/a",
|
144
144
|
"http://example.com/b" => [{"@value" => "#{v}","@type" => "http://www.w3.org/2001/XMLSchema##{t}"}]
|
145
145
|
}], @debug)
|
@@ -273,7 +273,7 @@ describe JSON::LD::API do
|
|
273
273
|
],
|
274
274
|
}.each do |name, (input, output, reader)|
|
275
275
|
it name do
|
276
|
-
r = serialize(input, :
|
276
|
+
r = serialize(input, reader: reader)
|
277
277
|
expect(r).to produce(output, @debug)
|
278
278
|
end
|
279
279
|
end
|
@@ -282,10 +282,10 @@ describe JSON::LD::API do
|
|
282
282
|
context "quads" do
|
283
283
|
{
|
284
284
|
"simple named graph" => {
|
285
|
-
:
|
285
|
+
input: %(
|
286
286
|
<http://example.com/a> <http://example.com/b> <http://example.com/c> <http://example.com/U> .
|
287
287
|
),
|
288
|
-
:
|
288
|
+
output: [
|
289
289
|
{
|
290
290
|
"@id" => "http://example.com/U",
|
291
291
|
"@graph" => [{
|
@@ -296,11 +296,11 @@ describe JSON::LD::API do
|
|
296
296
|
]
|
297
297
|
},
|
298
298
|
"with properties" => {
|
299
|
-
:
|
299
|
+
input: %(
|
300
300
|
<http://example.com/a> <http://example.com/b> <http://example.com/c> <http://example.com/U> .
|
301
301
|
<http://example.com/U> <http://example.com/d> <http://example.com/e> .
|
302
302
|
),
|
303
|
-
:
|
303
|
+
output: [
|
304
304
|
{
|
305
305
|
"@id" => "http://example.com/U",
|
306
306
|
"@graph" => [{
|
@@ -312,7 +312,7 @@ describe JSON::LD::API do
|
|
312
312
|
]
|
313
313
|
},
|
314
314
|
"with lists" => {
|
315
|
-
:
|
315
|
+
input: %(
|
316
316
|
<http://example.com/a> <http://example.com/b> _:a <http://example.com/U> .
|
317
317
|
_:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <http://example.com/c> <http://example.com/U> .
|
318
318
|
_:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> <http://example.com/U> .
|
@@ -320,7 +320,7 @@ describe JSON::LD::API do
|
|
320
320
|
_:b <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <http://example.com/e> .
|
321
321
|
_:b <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
|
322
322
|
),
|
323
|
-
:
|
323
|
+
output: [
|
324
324
|
{
|
325
325
|
"@id" => "http://example.com/U",
|
326
326
|
"@graph" => [{
|
@@ -332,7 +332,7 @@ describe JSON::LD::API do
|
|
332
332
|
]
|
333
333
|
},
|
334
334
|
"Two Graphs with same subject and lists" => {
|
335
|
-
:
|
335
|
+
input: %(
|
336
336
|
<http://example.com/a> <http://example.com/b> _:a <http://example.com/U> .
|
337
337
|
_:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <http://example.com/c> <http://example.com/U> .
|
338
338
|
_:a <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> <http://example.com/U> .
|
@@ -340,7 +340,7 @@ describe JSON::LD::API do
|
|
340
340
|
_:b <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <http://example.com/e> <http://example.com/V> .
|
341
341
|
_:b <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> <http://example.com/V> .
|
342
342
|
),
|
343
|
-
:
|
343
|
+
output: [
|
344
344
|
{
|
345
345
|
"@id" => "http://example.com/U",
|
346
346
|
"@graph" => [
|
@@ -367,7 +367,7 @@ describe JSON::LD::API do
|
|
367
367
|
},
|
368
368
|
}.each_pair do |name, properties|
|
369
369
|
it name do
|
370
|
-
r = serialize(properties[:input], :
|
370
|
+
r = serialize(properties[:input], reader: RDF::NQuads::Reader)
|
371
371
|
expect(r).to produce(properties[:output], @debug)
|
372
372
|
end
|
373
373
|
end
|
@@ -409,6 +409,6 @@ describe JSON::LD::API do
|
|
409
409
|
g = ntstr.is_a?(String) ? parse(ntstr, options) : ntstr
|
410
410
|
@debug << g.dump(:trig)
|
411
411
|
statements = g.each_statement.to_a
|
412
|
-
JSON::LD::API.fromRdf(statements, options.merge(:
|
412
|
+
JSON::LD::API.fromRdf(statements, options.merge(debug: @debug))
|
413
413
|
end
|
414
414
|
end
|
data/spec/matchers.rb
CHANGED
@@ -8,22 +8,22 @@ def normalize(graph)
|
|
8
8
|
case graph
|
9
9
|
when RDF::Enumerable then graph
|
10
10
|
when IO, StringIO
|
11
|
-
RDF::Graph.new.load(graph, :
|
11
|
+
RDF::Graph.new.load(graph, base: @info.about)
|
12
12
|
else
|
13
13
|
# Figure out which parser to use
|
14
14
|
g = RDF::Repository.new
|
15
15
|
reader_class = detect_format(graph)
|
16
|
-
reader_class.new(graph, :
|
16
|
+
reader_class.new(graph, base: @info.about).each {|s| g << s}
|
17
17
|
g
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
RSpec::Matchers.define :be_equivalent_graph do |expected, info|
|
22
22
|
match do |actual|
|
23
|
-
@info = if info.respond_to?(:
|
23
|
+
@info = if info.respond_to?(:input)
|
24
24
|
info
|
25
25
|
elsif info.is_a?(Hash)
|
26
|
-
identifier = info[:identifier] ||
|
26
|
+
identifier = info[:identifier] || info[:about]
|
27
27
|
trace = info[:trace]
|
28
28
|
trace = trace.join("\n") if trace.is_a?(Array)
|
29
29
|
Info.new(identifier, info[:information] || "", trace, info[:inputDocument])
|
@@ -45,8 +45,8 @@ RSpec::Matchers.define :be_equivalent_graph do |expected, info|
|
|
45
45
|
"Graph differs"
|
46
46
|
end +
|
47
47
|
"\n#{info + "\n" unless info.empty?}" +
|
48
|
-
"Unsorted Expected:\n#{@expected.dump(:nquads, :
|
49
|
-
"Unsorted Results:\n#{@actual.dump(:nquads, :
|
48
|
+
"Unsorted Expected:\n#{@expected.dump(:nquads, standard_prefixes: true)}" +
|
49
|
+
"Unsorted Results:\n#{@actual.dump(:nquads, standard_prefixes: true)}" +
|
50
50
|
(@info.inputDocument ? "Input file: #{@info.inputDocument}\n" : "") +
|
51
51
|
(@info.outputDocument ? "Output file: #{@info.outputDocument}\n" : "") +
|
52
52
|
(@info.trace ? "\nDebug:\n#{@info.trace}" : "")
|
@@ -59,9 +59,9 @@ RSpec::Matchers.define :produce do |expected, info|
|
|
59
59
|
end
|
60
60
|
|
61
61
|
failure_message do |actual|
|
62
|
-
"Expected: #{expected.is_a?(String) ? expected : expected.to_json(JSON_STATE)}\n" +
|
63
|
-
"Actual : #{actual.is_a?(String) ? actual : actual.to_json(JSON_STATE)}\n" +
|
64
|
-
#(expected.is_a?(Hash) && actual.is_a?(Hash) ? "Diff: #{expected.diff(actual).to_json(JSON_STATE)}\n" : "") +
|
62
|
+
"Expected: #{expected.is_a?(String) ? expected : expected.to_json(JSON_STATE) rescue 'malformed json'}\n" +
|
63
|
+
"Actual : #{actual.is_a?(String) ? actual : actual.to_json(JSON_STATE) rescue 'malformed json'}\n" +
|
64
|
+
#(expected.is_a?(Hash) && actual.is_a?(Hash) ? "Diff: #{expected.diff(actual).to_json(JSON_STATE) rescue 'malformed json'}\n" : "") +
|
65
65
|
"Processing results:\n#{info.join("\n")}"
|
66
66
|
end
|
67
67
|
end
|
data/spec/reader_spec.rb
CHANGED
@@ -23,10 +23,10 @@ describe JSON::LD::Reader do
|
|
23
23
|
formats = [
|
24
24
|
:jsonld,
|
25
25
|
"etc/doap.jsonld",
|
26
|
-
{:
|
27
|
-
{:
|
28
|
-
{:
|
29
|
-
{:
|
26
|
+
{file_name: 'etc/doap.jsonld'},
|
27
|
+
{file_extension: 'jsonld'},
|
28
|
+
{content_type: 'application/ld+json'},
|
29
|
+
{content_type: 'application/x-ld+json'},
|
30
30
|
].each do |arg|
|
31
31
|
it "discovers with #{arg.inspect}" do
|
32
32
|
expect(RDF::Reader.for(arg)).to eq JSON::LD::Reader
|
data/spec/resource_spec.rb
CHANGED
@@ -18,7 +18,7 @@ describe JSON::LD::Resource do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
describe "compacted with context" do
|
21
|
-
subject {JSON::LD::Resource.new({'@id' => '_:foo', "http://schema.org/name" => "foo"}, :
|
21
|
+
subject {JSON::LD::Resource.new({'@id' => '_:foo', "http://schema.org/name" => "foo"}, compact: true, context: {"@vocab" => "http://schema.org/"})}
|
22
22
|
specify {expect(subject).not_to be_nil}
|
23
23
|
specify {expect(subject).to be_a(JSON::LD::Resource)}
|
24
24
|
specify {expect(subject).not_to be_clean}
|
data/spec/spec_helper.rb
CHANGED
@@ -12,27 +12,32 @@ require 'rdf/trig'
|
|
12
12
|
require 'rdf/spec'
|
13
13
|
require 'rdf/spec/matchers'
|
14
14
|
require 'yaml'
|
15
|
-
require '
|
15
|
+
require 'restclient/components'
|
16
|
+
require 'rack/cache'
|
16
17
|
require 'matchers'
|
17
18
|
|
18
19
|
JSON_STATE = JSON::State.new(
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
20
|
+
indent: " ",
|
21
|
+
space: " ",
|
22
|
+
space_before: "",
|
23
|
+
object_nl: "\n",
|
24
|
+
array_nl: "\n"
|
24
25
|
)
|
25
26
|
|
26
27
|
# Create and maintain a cache of downloaded URIs
|
27
28
|
URI_CACHE = File.expand_path(File.join(File.dirname(__FILE__), "uri-cache"))
|
28
29
|
Dir.mkdir(URI_CACHE) unless File.directory?(URI_CACHE)
|
29
|
-
|
30
|
+
# Cache client requests
|
31
|
+
RestClient.enable Rack::Cache,
|
32
|
+
verbose: false,
|
33
|
+
metastore: "file:" + ::File.expand_path("../uri-cache/meta", __FILE__),
|
34
|
+
entitystore: "file:" + ::File.expand_path("../uri-cache/body", __FILE__)
|
30
35
|
|
31
36
|
::RSpec.configure do |c|
|
32
|
-
c.filter_run :
|
37
|
+
c.filter_run focus: true
|
33
38
|
c.run_all_when_everything_filtered = true
|
34
39
|
c.exclusion_filter = {
|
35
|
-
:
|
40
|
+
ruby: lambda { |version| !(RUBY_VERSION.to_s =~ /^#{version.to_s}/) },
|
36
41
|
}
|
37
42
|
c.include(RDF::Spec::Matchers)
|
38
43
|
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
$:.unshift "."
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'rdf/spec/writer'
|
5
|
+
require 'json/ld/streaming_writer'
|
6
|
+
|
7
|
+
describe JSON::LD::StreamingWriter do
|
8
|
+
before :each do
|
9
|
+
@writer = JSON::LD::Writer.new(StringIO.new(""), stream: true)
|
10
|
+
end
|
11
|
+
|
12
|
+
include RDF_Writer
|
13
|
+
|
14
|
+
context "simple tests" do
|
15
|
+
it "should use full URIs without base" do
|
16
|
+
input = %(<http://a/b> <http://a/c> <http://a/d> .)
|
17
|
+
obj = serialize(input)
|
18
|
+
expect(parse(obj.to_json, format: :jsonld)).to be_equivalent_graph(parse input)
|
19
|
+
expect(obj).to produce([{
|
20
|
+
'@id' => "http://a/b",
|
21
|
+
"http://a/c" => [{"@id" => "http://a/d"}]
|
22
|
+
}], @debug)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "writes multiple kinds of statements" do
|
26
|
+
input = %(
|
27
|
+
<https://senet.org/gm> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://vocab.org/frbr/core#Work> .
|
28
|
+
<https://senet.org/gm> <http://purl.org/dc/terms/title> "Rhythm Paradise"@en .
|
29
|
+
<https://senet.org/gm> <https://senet.org/ns#unofficialTitle> "Rhythm Tengoku"@en .
|
30
|
+
<https://senet.org/gm> <https://senet.org/ns#urlkey> "rhythm-tengoku" .
|
31
|
+
)
|
32
|
+
obj = serialize(input)
|
33
|
+
expect(parse(obj.to_json, format: :jsonld)).to be_equivalent_graph(parse input)
|
34
|
+
expect(obj).to eql JSON.parse(%{[{
|
35
|
+
"@id": "https://senet.org/gm",
|
36
|
+
"@type": ["http://vocab.org/frbr/core#Work"],
|
37
|
+
"http://purl.org/dc/terms/title": [{"@value": "Rhythm Paradise", "@language": "en"}],
|
38
|
+
"https://senet.org/ns#unofficialTitle": [{"@value": "Rhythm Tengoku", "@language": "en"}],
|
39
|
+
"https://senet.org/ns#urlkey": [{"@value": "rhythm-tengoku"}]
|
40
|
+
}]})
|
41
|
+
end
|
42
|
+
|
43
|
+
it "serializes multiple subjects" do
|
44
|
+
input = %q(
|
45
|
+
@prefix : <http://www.w3.org/2006/03/test-description#> .
|
46
|
+
@prefix dc: <http://purl.org/dc/terms/> .
|
47
|
+
<http://example.com/test-cases/0001> a :TestCase .
|
48
|
+
<http://example.com/test-cases/0002> a :TestCase .
|
49
|
+
)
|
50
|
+
obj = serialize(input)
|
51
|
+
expect(parse(obj.to_json, format: :jsonld)).to be_equivalent_graph(parse input)
|
52
|
+
expect(obj).to eql JSON.parse(%{[
|
53
|
+
{"@id": "http://example.com/test-cases/0001", "@type": ["http://www.w3.org/2006/03/test-description#TestCase"]},
|
54
|
+
{"@id": "http://example.com/test-cases/0002", "@type": ["http://www.w3.org/2006/03/test-description#TestCase"]}
|
55
|
+
]})
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "Named Graphs" do
|
60
|
+
{
|
61
|
+
"default" => [
|
62
|
+
%q({<a> <b> <c> .}),
|
63
|
+
%q([{"@id": "a", "b": [{"@id": "c"}]}])
|
64
|
+
],
|
65
|
+
"named" => [
|
66
|
+
%q(<C> {<a> <b> <c> .}),
|
67
|
+
%q([{"@id" : "C", "@graph" : [{"@id": "a", "b": [{"@id": "c"}]}]}])
|
68
|
+
],
|
69
|
+
"combo" => [
|
70
|
+
%q(
|
71
|
+
<a> <b> <c> .
|
72
|
+
<C> {<A> <b> <c> .}
|
73
|
+
),
|
74
|
+
%q([
|
75
|
+
{"@id": "a", "b": [{"@id": "c"}]},
|
76
|
+
{"@id": "C", "@graph": [{"@id": "A", "b": [{"@id": "c"}]}]}
|
77
|
+
])
|
78
|
+
],
|
79
|
+
"combo with duplicated statement" => [
|
80
|
+
%q(
|
81
|
+
<a> <b> <c> .
|
82
|
+
<C> {<a> <b> <c> .}
|
83
|
+
),
|
84
|
+
%q([
|
85
|
+
{"@id": "a", "b": [{"@id": "c"}]},
|
86
|
+
{"@id": "C", "@graph": [{"@id": "a", "b": [{"@id": "c"}]}]}
|
87
|
+
])
|
88
|
+
],
|
89
|
+
}.each_pair do |title, (input, matches)|
|
90
|
+
context title do
|
91
|
+
subject {serialize(input)}
|
92
|
+
it "matches expected json" do
|
93
|
+
expect(subject).to produce(JSON.parse(matches), @debug)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
context "Writes fromRdf tests to isomorphic graph", skip: ENV['CI'] do
|
101
|
+
require 'suite_helper'
|
102
|
+
m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}tests/fromRdf-manifest.jsonld")
|
103
|
+
[nil, {}].each do |ctx|
|
104
|
+
context "with context #{ctx.inspect}" do
|
105
|
+
describe m.name do
|
106
|
+
m.entries.each do |t|
|
107
|
+
next unless t.positiveTest? && !t.property('input').include?('0016')
|
108
|
+
t.debug = ["test: #{t.inspect}", "source: #{t.input}"]
|
109
|
+
specify "#{t.property('input')}: #{t.name}" do
|
110
|
+
repo = RDF::Repository.load(t.input_loc, format: :nquads)
|
111
|
+
jsonld = JSON::LD::Writer.buffer(stream: true, context: ctx, debug: t.debug) do |writer|
|
112
|
+
writer << repo
|
113
|
+
end
|
114
|
+
t.debug << "Generated: #{jsonld}"
|
115
|
+
|
116
|
+
# And then, re-generate jsonld as RDF
|
117
|
+
expect(parse(jsonld, format: :jsonld)).to be_equivalent_graph(repo, t)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def parse(input, options = {})
|
126
|
+
format = options.fetch(:format, :trig)
|
127
|
+
reader = RDF::Reader.for(format)
|
128
|
+
RDF::Repository.new << reader.new(input, options)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Serialize ntstr to a string and compare against regexps
|
132
|
+
def serialize(ntstr, options = {})
|
133
|
+
g = ntstr.is_a?(String) ? parse(ntstr, options) : ntstr
|
134
|
+
@debug = [] << g.dump(:ttl)
|
135
|
+
result = JSON::LD::Writer.buffer(options.merge(debug: @debug, stream: true)) do |writer|
|
136
|
+
writer << g
|
137
|
+
end
|
138
|
+
puts result if $verbose
|
139
|
+
|
140
|
+
JSON.parse(result)
|
141
|
+
end
|
142
|
+
end
|
data/spec/suite_helper.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'json/ld'
|
2
|
-
require 'open-uri'
|
3
2
|
require 'support/extensions'
|
4
3
|
|
5
4
|
module Fixtures
|
@@ -44,7 +43,7 @@ module Fixtures
|
|
44
43
|
|
45
44
|
def options
|
46
45
|
@options ||= begin
|
47
|
-
opts = {:
|
46
|
+
opts = {documentLoader: Fixtures::SuiteTest.method(:documentLoader)}
|
48
47
|
{'processingMode' => "json-ld-1.0"}.merge(property('option') || {}).each do |k, v|
|
49
48
|
opts[k.to_sym] = v
|
50
49
|
end
|
@@ -57,7 +56,7 @@ module Fixtures
|
|
57
56
|
define_method(m.to_sym) do
|
58
57
|
return nil unless property(m)
|
59
58
|
res = nil
|
60
|
-
Fixtures::SuiteTest.documentLoader("#{SUITE}tests/#{property(m)}", :
|
59
|
+
Fixtures::SuiteTest.documentLoader("#{SUITE}tests/#{property(m)}", safe: true) do |remote_doc|
|
61
60
|
res = remote_doc.document
|
62
61
|
end
|
63
62
|
res
|
@@ -86,13 +85,13 @@ module Fixtures
|
|
86
85
|
|
87
86
|
# Execute the test
|
88
87
|
def run(rspec_example = nil)
|
89
|
-
debug = ["test: #{inspect}", "source: #{input}"]
|
90
|
-
debug << "context: #{context}" if context_loc
|
91
|
-
debug << "options: #{options.inspect}" unless options.empty?
|
92
|
-
debug << "frame: #{frame}" if frame_loc
|
88
|
+
@debug = ["test: #{inspect}", "source: #{input}"]
|
89
|
+
@debug << "context: #{context}" if context_loc
|
90
|
+
@debug << "options: #{options.inspect}" unless options.empty?
|
91
|
+
@debug << "frame: #{frame}" if frame_loc
|
93
92
|
|
94
93
|
options = if self.options[:useDocumentLoader]
|
95
|
-
self.options.merge(:
|
94
|
+
self.options.merge(documentLoader: Fixtures::SuiteTest.method(:documentLoader))
|
96
95
|
else
|
97
96
|
self.options.dup
|
98
97
|
end
|
@@ -102,19 +101,19 @@ module Fixtures
|
|
102
101
|
begin
|
103
102
|
result = case testType
|
104
103
|
when "jld:ExpandTest"
|
105
|
-
JSON::LD::API.expand(input_loc, options.merge(:
|
104
|
+
JSON::LD::API.expand(input_loc, options.merge(debug: @debug))
|
106
105
|
when "jld:CompactTest"
|
107
|
-
JSON::LD::API.compact(input_loc, context_json['@context'], options.merge(:
|
106
|
+
JSON::LD::API.compact(input_loc, context_json['@context'], options.merge(debug: @debug))
|
108
107
|
when "jld:FlattenTest"
|
109
|
-
JSON::LD::API.flatten(input_loc, context_loc, options.merge(:
|
108
|
+
JSON::LD::API.flatten(input_loc, context_loc, options.merge(debug: @debug))
|
110
109
|
when "jld:FrameTest"
|
111
|
-
JSON::LD::API.frame(input_loc, frame_loc, options.merge(:
|
110
|
+
JSON::LD::API.frame(input_loc, frame_loc, options.merge(debug: @debug))
|
112
111
|
when "jld:FromRDFTest"
|
113
|
-
repo = RDF::Repository.load(input_loc, :
|
114
|
-
debug << "repo: #{repo.dump(id == '#t0012' ? :nquads : :trig)}"
|
115
|
-
JSON::LD::API.fromRdf(repo, options.merge(:
|
112
|
+
repo = RDF::Repository.load(input_loc, format: :nquads)
|
113
|
+
@debug << "repo: #{repo.dump(id == '#t0012' ? :nquads : :trig)}"
|
114
|
+
JSON::LD::API.fromRdf(repo, options.merge(debug: @debug))
|
116
115
|
when "jld:ToRDFTest"
|
117
|
-
JSON::LD::API.toRdf(input_loc, options.merge(:
|
116
|
+
JSON::LD::API.toRdf(input_loc, options.merge(debug: @debug)).map do |statement|
|
118
117
|
to_quad(statement)
|
119
118
|
end
|
120
119
|
else
|
@@ -124,12 +123,12 @@ module Fixtures
|
|
124
123
|
if testType == "jld:ToRDFTest"
|
125
124
|
expected = expect
|
126
125
|
rspec_example.instance_eval {
|
127
|
-
expect(result.sort.join("")).to produce(expected, debug)
|
126
|
+
expect(result.sort.join("")).to produce(expected, @debug)
|
128
127
|
}
|
129
128
|
else
|
130
129
|
expected = JSON.load(expect)
|
131
130
|
rspec_example.instance_eval {
|
132
|
-
expect(result).to produce(expected, debug)
|
131
|
+
expect(result).to produce(expected, @debug)
|
133
132
|
}
|
134
133
|
end
|
135
134
|
else
|
@@ -143,26 +142,26 @@ module Fixtures
|
|
143
142
|
fail("Invalid Frame: #{e.message}")
|
144
143
|
end
|
145
144
|
else
|
146
|
-
debug << "expected: #{property('expect')}" if property('expect')
|
145
|
+
@debug << "expected: #{property('expect')}" if property('expect')
|
147
146
|
t = self
|
148
147
|
rspec_example.instance_eval do
|
149
148
|
if t.evaluationTest?
|
150
149
|
expect do
|
151
150
|
case t.testType
|
152
151
|
when "jld:ExpandTest"
|
153
|
-
JSON::LD::API.expand(t.input_loc, options.merge(:
|
152
|
+
JSON::LD::API.expand(t.input_loc, options.merge(debug: @debug))
|
154
153
|
when "jld:CompactTest"
|
155
|
-
JSON::LD::API.compact(t.input_loc, t.context_json['@context'], options.merge(:
|
154
|
+
JSON::LD::API.compact(t.input_loc, t.context_json['@context'], options.merge(debug: @debug))
|
156
155
|
when "jld:FlattenTest"
|
157
|
-
JSON::LD::API.flatten(t.input_loc, t.context_loc, options.merge(:
|
156
|
+
JSON::LD::API.flatten(t.input_loc, t.context_loc, options.merge(debug: @debug))
|
158
157
|
when "jld:FrameTest"
|
159
|
-
JSON::LD::API.frame(t.input_loc, t.frame_loc, options.merge(:
|
158
|
+
JSON::LD::API.frame(t.input_loc, t.frame_loc, options.merge(debug: @debug))
|
160
159
|
when "jld:FromRDFTest"
|
161
160
|
repo = RDF::Repository.load(t.input_loc)
|
162
|
-
debug << "repo: #{repo.dump(id == '#t0012' ? :nquads : :trig)}"
|
163
|
-
JSON::LD::API.fromRdf(repo, options.merge(:
|
161
|
+
@debug << "repo: #{repo.dump(id == '#t0012' ? :nquads : :trig)}"
|
162
|
+
JSON::LD::API.fromRdf(repo, options.merge(debug: @debug))
|
164
163
|
when "jld:ToRDFTest"
|
165
|
-
JSON::LD::API.toRdf(t.input_loc, options.merge(:
|
164
|
+
JSON::LD::API.toRdf(t.input_loc, options.merge(debug: @debug)).map do |statement|
|
166
165
|
t.to_quad(statement)
|
167
166
|
end
|
168
167
|
else
|
@@ -229,8 +228,7 @@ module Fixtures
|
|
229
228
|
# @yield remote_document
|
230
229
|
# @yieldparam [RemoteDocument] remote_document
|
231
230
|
# @raise [JsonLdError]
|
232
|
-
def documentLoader(url, options = {})
|
233
|
-
require 'net/http' unless defined?(Net::HTTP)
|
231
|
+
def documentLoader(url, options = {}, &block)
|
234
232
|
remote_document = nil
|
235
233
|
options[:headers] ||= JSON::LD::API::OPEN_OPTS[:headers]
|
236
234
|
|
@@ -247,66 +245,9 @@ module Fixtures
|
|
247
245
|
end
|
248
246
|
end
|
249
247
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
until remote_document do
|
254
|
-
Net::HTTP::start(parsed_url.host, parsed_url.port) do |http|
|
255
|
-
request = Net::HTTP::Get.new(parsed_url.request_uri, options[:headers])
|
256
|
-
http.request(request) do |response|
|
257
|
-
case response
|
258
|
-
when Net::HTTPSuccess
|
259
|
-
# found object
|
260
|
-
content_type, ct_param = response.content_type.to_s.downcase.split(";")
|
261
|
-
if content_type && options[:validate]
|
262
|
-
main, sub = content_type.split("/")
|
263
|
-
raise JSON::LD::JsonLdError::LoadingDocumentFailed, "content_type: #{content_type}" if
|
264
|
-
main != 'application' ||
|
265
|
-
sub !~ /^(.*\+)?json$/
|
266
|
-
end
|
267
|
-
|
268
|
-
remote_document = JSON::LD::API::RemoteDocument.new(parsed_url.to_s, response.body)
|
269
|
-
|
270
|
-
unless content_type.to_s.start_with?("application/ld+json")
|
271
|
-
links = response["link"].to_s.
|
272
|
-
split(",").
|
273
|
-
map(&:strip).
|
274
|
-
select {|h| h =~ %r{rel=\"http://www.w3.org/ns/json-ld#context\"}}
|
275
|
-
case links.length
|
276
|
-
when 0 then #nothing to do
|
277
|
-
when 1
|
278
|
-
remote_document.contextUrl = links.first.match(/<([^>]*)>/) && $1
|
279
|
-
else
|
280
|
-
raise JSON::LD::JsonLdError::MultipleContextLinkHeaders,
|
281
|
-
"expected at most 1 Link header with rel=jsonld:context, got #{links.length}"
|
282
|
-
end
|
283
|
-
end
|
284
|
-
return block_given? ? yield(remote_document) : remote_document
|
285
|
-
when Net::HTTPRedirection
|
286
|
-
# Follow redirection
|
287
|
-
parsed_url = ::URI.parse(response["Location"])
|
288
|
-
else
|
289
|
-
raise JSON::LD::JsonLdError::LoadingDocumentFailed,
|
290
|
-
"<#{parsed_url}>: #{response.msg}(#{response.code})"
|
291
|
-
end
|
292
|
-
end
|
293
|
-
end
|
294
|
-
end
|
295
|
-
else
|
296
|
-
# Use regular open
|
297
|
-
RDF::Util::File.open_file(url, options) do |f|
|
298
|
-
remote_document = JSON::LD::API::RemoteDocument.new(url, f.read)
|
299
|
-
content_type, ct_param = f.content_type.to_s.downcase.split(";") if f.respond_to?(:content_type)
|
300
|
-
if content_type && options[:validate]
|
301
|
-
main, sub = content_type.split("/")
|
302
|
-
raise JSON::LD::JsonLdError::LoadingDocumentFailed, "content_type: #{content_type}" if
|
303
|
-
main != 'application' ||
|
304
|
-
sub !~ /^(.*\+)?json$/
|
305
|
-
end
|
306
|
-
|
307
|
-
return block_given? ? yield(remote_document) : remote_document
|
308
|
-
end
|
309
|
-
end
|
248
|
+
# don't cache for these specs
|
249
|
+
options = options.merge(use_net_http: true) if url.to_s =~ /remote-doc/
|
250
|
+
JSON::LD::API.documentLoader(url, options, &block)
|
310
251
|
rescue JSON::LD::JsonLdError::LoadingDocumentFailed, JSON::LD::JsonLdError::MultipleContextLinkHeaders
|
311
252
|
raise unless options[:safe]
|
312
253
|
"don't raise error"
|