json-ld 1.1.7 → 1.1.8
Sign up to get free protection for your applications and to get access to all the features.
- 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"
|