json-ld 3.1.2 → 3.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +124 -48
- data/VERSION +1 -1
- data/bin/jsonld +27 -30
- data/lib/json/ld.rb +6 -2
- data/lib/json/ld/api.rb +33 -24
- data/lib/json/ld/compact.rb +65 -37
- data/lib/json/ld/conneg.rb +1 -1
- data/lib/json/ld/context.rb +612 -539
- data/lib/json/ld/expand.rb +158 -77
- data/lib/json/ld/format.rb +20 -7
- data/lib/json/ld/from_rdf.rb +40 -17
- data/lib/json/ld/reader.rb +20 -11
- data/lib/json/ld/streaming_reader.rb +578 -0
- data/lib/json/ld/to_rdf.rb +9 -5
- data/lib/json/ld/writer.rb +10 -3
- data/spec/compact_spec.rb +207 -2
- data/spec/context_spec.rb +13 -60
- data/spec/expand_spec.rb +248 -0
- data/spec/from_rdf_spec.rb +181 -0
- data/spec/matchers.rb +1 -1
- data/spec/reader_spec.rb +33 -34
- data/spec/streaming_reader_spec.rb +237 -0
- data/spec/suite_helper.rb +14 -8
- data/spec/suite_to_rdf_spec.rb +1 -0
- data/spec/to_rdf_spec.rb +206 -0
- data/spec/writer_spec.rb +193 -0
- metadata +9 -6
@@ -0,0 +1,237 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require_relative 'spec_helper'
|
3
|
+
require 'rdf/spec/reader'
|
4
|
+
|
5
|
+
describe JSON::LD::Reader do
|
6
|
+
let!(:doap) {File.expand_path("../../etc/doap.jsonld", __FILE__)}
|
7
|
+
let!(:doap_nt) {File.expand_path("../../etc/doap.nt", __FILE__)}
|
8
|
+
let!(:doap_count) {File.open(doap_nt).each_line.to_a.length}
|
9
|
+
let(:logger) {RDF::Spec.logger}
|
10
|
+
|
11
|
+
after(:each) {|example| puts logger.to_s if example.exception}
|
12
|
+
|
13
|
+
it_behaves_like 'an RDF::Reader' do
|
14
|
+
let(:reader_input) {File.read(doap)}
|
15
|
+
let(:reader) {JSON::LD::Reader.new(reader_input, stream: true)}
|
16
|
+
let(:reader_count) {doap_count}
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when validating", pending: ("JRuby support for jsonlint" if RUBY_ENGINE == "jruby") do
|
20
|
+
it "detects invalid JSON" do
|
21
|
+
expect do |b|
|
22
|
+
described_class.new(StringIO.new(%({"a": "b", "a": "c"})), validate: true, logger: false).each_statement(&b)
|
23
|
+
end.to raise_error(RDF::ReaderError)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context :interface do
|
28
|
+
{
|
29
|
+
plain: %q({
|
30
|
+
"@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
|
31
|
+
"@type": "foaf:Person",
|
32
|
+
"@id": "_:bnode1",
|
33
|
+
"foaf:homepage": "http://example.com/bob/",
|
34
|
+
"foaf:name": "Bob"
|
35
|
+
}),
|
36
|
+
leading_comment: %q(
|
37
|
+
// A comment before content
|
38
|
+
{
|
39
|
+
"@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
|
40
|
+
"@type": "foaf:Person",
|
41
|
+
"@id": "_:bnode1",
|
42
|
+
"foaf:homepage": "http://example.com/bob/",
|
43
|
+
"foaf:name": "Bob"
|
44
|
+
}),
|
45
|
+
script: %q(<script type="application/ld+json">
|
46
|
+
{
|
47
|
+
"@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
|
48
|
+
"@type": "foaf:Person",
|
49
|
+
"@id": "_:bnode1",
|
50
|
+
"foaf:homepage": "http://example.com/bob/",
|
51
|
+
"foaf:name": "Bob"
|
52
|
+
}
|
53
|
+
</script>),
|
54
|
+
script_comments: %q(<script type="application/ld+json">
|
55
|
+
// A comment before content
|
56
|
+
{
|
57
|
+
"@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
|
58
|
+
"@type": "foaf:Person",
|
59
|
+
"@id": "_:bnode1",
|
60
|
+
"foaf:homepage": "http://example.com/bob/",
|
61
|
+
"foaf:name": "Bob"
|
62
|
+
}
|
63
|
+
</script>),
|
64
|
+
}.each do |variant, src|
|
65
|
+
context variant do
|
66
|
+
subject {src}
|
67
|
+
|
68
|
+
describe "#initialize" do
|
69
|
+
it "yields reader given string" do
|
70
|
+
inner = double("inner")
|
71
|
+
expect(inner).to receive(:called).with(JSON::LD::Reader)
|
72
|
+
JSON::LD::Reader.new(subject, stream: true) do |reader|
|
73
|
+
inner.called(reader.class)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "yields reader given IO" do
|
78
|
+
inner = double("inner")
|
79
|
+
expect(inner).to receive(:called).with(JSON::LD::Reader)
|
80
|
+
JSON::LD::Reader.new(StringIO.new(subject), stream: true) do |reader|
|
81
|
+
inner.called(reader.class)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns reader" do
|
86
|
+
expect(JSON::LD::Reader.new(subject, stream: true)).to be_a(JSON::LD::Reader)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#each_statement" do
|
91
|
+
it "yields statements" do
|
92
|
+
inner = double("inner")
|
93
|
+
expect(inner).to receive(:called).with(RDF::Statement).exactly(3)
|
94
|
+
JSON::LD::Reader.new(subject, stream: true).each_statement do |statement|
|
95
|
+
inner.called(statement.class)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "#each_triple" do
|
101
|
+
it "yields statements" do
|
102
|
+
inner = double("inner")
|
103
|
+
expect(inner).to receive(:called).exactly(3)
|
104
|
+
JSON::LD::Reader.new(subject, stream: true).each_triple do |subject, predicate, object|
|
105
|
+
inner.called(subject.class, predicate.class, object.class)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "Selected toRdf tests" do
|
114
|
+
{
|
115
|
+
"e004": {
|
116
|
+
input: %({
|
117
|
+
"@context": {
|
118
|
+
"mylist1": {"@id": "http://example.com/mylist1", "@container": "@list"}
|
119
|
+
},
|
120
|
+
"@id": "http://example.org/id",
|
121
|
+
"mylist1": { "@list": [ ] },
|
122
|
+
"http://example.org/list1": { "@list": [ null ] },
|
123
|
+
"http://example.org/list2": { "@list": [ {"@value": null} ] }
|
124
|
+
}),
|
125
|
+
expect: %(
|
126
|
+
<http://example.org/id> <http://example.com/mylist1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
|
127
|
+
<http://example.org/id> <http://example.org/list1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
|
128
|
+
<http://example.org/id> <http://example.org/list2> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
|
129
|
+
)
|
130
|
+
},
|
131
|
+
"e015": {
|
132
|
+
input: %({
|
133
|
+
"@context": {
|
134
|
+
"myset2": {"@id": "http://example.com/myset2", "@container": "@set" }
|
135
|
+
},
|
136
|
+
"@id": "http://example.org/id",
|
137
|
+
"myset2": [ [], { "@set": [ null ] }, [ null ] ]
|
138
|
+
}),
|
139
|
+
expect: %(
|
140
|
+
)
|
141
|
+
},
|
142
|
+
"in06": {
|
143
|
+
input: %({
|
144
|
+
"@context": {
|
145
|
+
"@version": 1.1,
|
146
|
+
"@vocab": "http://example.org/vocab#",
|
147
|
+
"@base": "http://example.org/base/",
|
148
|
+
"id": "@id",
|
149
|
+
"type": "@type",
|
150
|
+
"data": "@nest",
|
151
|
+
"links": "@nest",
|
152
|
+
"relationships": "@nest",
|
153
|
+
"self": {"@type": "@id"},
|
154
|
+
"related": {"@type": "@id"}
|
155
|
+
},
|
156
|
+
"data": [{
|
157
|
+
"type": "articles",
|
158
|
+
"id": "1",
|
159
|
+
"author": {
|
160
|
+
"data": { "type": "people", "id": "9" }
|
161
|
+
}
|
162
|
+
}]
|
163
|
+
}),
|
164
|
+
expect: %(
|
165
|
+
<http://example.org/base/1> <http://example.org/vocab#author> <http://example.org/base/9> .
|
166
|
+
<http://example.org/base/1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/vocab#articles> .
|
167
|
+
<http://example.org/base/9> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/vocab#people> .
|
168
|
+
),
|
169
|
+
pending: "@nest defining @id"
|
170
|
+
}
|
171
|
+
}.each do |name, params|
|
172
|
+
it name do
|
173
|
+
run_to_rdf params
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "test suite" do
|
179
|
+
require_relative 'suite_helper'
|
180
|
+
m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::STREAM_SUITE}stream-toRdf-manifest.jsonld")
|
181
|
+
describe m.name do
|
182
|
+
m.entries.each do |t|
|
183
|
+
specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
|
184
|
+
pending "Generalized RDF" if t.options[:produceGeneralizedRdf]
|
185
|
+
pending "@nest defining @id" if %w(#tin06).include?(t.property('@id'))
|
186
|
+
pending "double @reverse" if %w(#te043).include?(t.property('@id'))
|
187
|
+
pending "graph map containing named graph" if %w(#te084 #te087 #te098 #te101 #te105 #te106).include?(t.property('@id'))
|
188
|
+
pending "named graphs" if %w(#t0029 #te021).include?(t.property('@id'))
|
189
|
+
|
190
|
+
if %w(#t0118).include?(t.property('@id'))
|
191
|
+
expect {t.run self}.to write(/Statement .* is invalid/).to(:error)
|
192
|
+
elsif %w(#twf07).include?(t.property('@id'))
|
193
|
+
expect {t.run self}.to write(/skipping graph statement within invalid graph name/).to(:error)
|
194
|
+
elsif %w(#te075).include?(t.property('@id'))
|
195
|
+
expect {t.run self}.to write(/is invalid/).to(:error)
|
196
|
+
elsif %w(#te005 #tpr34 #tpr35 #tpr36 #tpr37 #tpr38 #tpr39 #te119 #te120).include?(t.property('@id'))
|
197
|
+
expect {t.run self}.to write("beginning with '@' are reserved for future use").to(:error)
|
198
|
+
elsif %w(#te068).include?(t.property('@id'))
|
199
|
+
expect {t.run self}.to write("[DEPRECATION]").to(:error)
|
200
|
+
elsif %w(#twf05).include?(t.property('@id'))
|
201
|
+
expect {t.run self}.to write("@language must be valid BCP47").to(:error)
|
202
|
+
else
|
203
|
+
expect {t.run self}.not_to write.to(:error)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end unless ENV['CI']
|
209
|
+
|
210
|
+
def run_to_rdf(params)
|
211
|
+
input = params[:input]
|
212
|
+
logger.info("input: #{input}")
|
213
|
+
output = RDF::Repository.new
|
214
|
+
if params[:expect]
|
215
|
+
RDF::NQuads::Reader.new(params[:expect], validate: false) {|r| output << r}
|
216
|
+
logger.info("expect (quads): #{output.dump(:nquads, validate: false)}")
|
217
|
+
else
|
218
|
+
logger.info("expect: #{Regexp.new params[:exception]}")
|
219
|
+
end
|
220
|
+
|
221
|
+
graph = params[:graph] || RDF::Repository.new
|
222
|
+
pending params.fetch(:pending, "test implementation") if !input || params[:pending]
|
223
|
+
if params[:exception]
|
224
|
+
expect do |b|
|
225
|
+
JSON::LD::Reader.new(input, stream: true, validate: true, logger: false, **params).each_statement(&b)
|
226
|
+
end.to raise_error {|er| expect(er.message).to include params[:exception]}
|
227
|
+
else
|
228
|
+
if params[:write]
|
229
|
+
expect{JSON::LD::Reader.new(input, stream: true, logger: logger, **params) {|st| graph << st}}.to write(params[:write]).to(:error)
|
230
|
+
else
|
231
|
+
expect{JSON::LD::Reader.new(input, stream: true, logger: logger, **params) {|st| graph << st}}.not_to write.to(:error)
|
232
|
+
end
|
233
|
+
logger.info("results (quads): #{graph.dump(:nquads, validate: false)}")
|
234
|
+
expect(graph).to be_equivalent_graph(output, logger: logger, inputDocument: input)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
data/spec/suite_helper.rb
CHANGED
@@ -6,6 +6,7 @@ module RDF::Util
|
|
6
6
|
LOCAL_PATHS = {
|
7
7
|
"https://w3c.github.io/json-ld-api/tests/" => ::File.expand_path("../json-ld-api/tests", __FILE__) + '/',
|
8
8
|
"https://w3c.github.io/json-ld-framing/tests/" => ::File.expand_path("../json-ld-framing/tests", __FILE__) + '/',
|
9
|
+
"https://w3c.github.io/json-ld-streaming/tests/" => ::File.expand_path("../json-ld-streaming/tests", __FILE__) + '/',
|
9
10
|
"file:" => ""
|
10
11
|
}
|
11
12
|
|
@@ -74,6 +75,7 @@ module Fixtures
|
|
74
75
|
module SuiteTest
|
75
76
|
SUITE = RDF::URI("https://w3c.github.io/json-ld-api/tests/")
|
76
77
|
FRAME_SUITE = RDF::URI("https://w3c.github.io/json-ld-framing/tests/")
|
78
|
+
STREAM_SUITE = RDF::URI("https://w3c.github.io/json-ld-streaming/tests/")
|
77
79
|
|
78
80
|
class Manifest < JSON::LD::Resource
|
79
81
|
attr_accessor :manifest_url
|
@@ -228,14 +230,14 @@ module Fixtures
|
|
228
230
|
JSON::LD::API.fromRdf(repo, logger: logger, **options)
|
229
231
|
when "jld:ToRDFTest"
|
230
232
|
repo = RDF::Repository.new
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
233
|
+
if manifest_url.to_s.include?('stream')
|
234
|
+
JSON::LD::Reader.open(input_loc, stream: true, logger: logger, **options) do |statement|
|
235
|
+
repo << statement
|
236
|
+
end
|
237
|
+
else
|
238
|
+
JSON::LD::API.toRdf(input_loc, logger: logger, **options) do |statement|
|
239
|
+
repo << statement
|
237
240
|
end
|
238
|
-
repo << statement
|
239
241
|
end
|
240
242
|
logger.info "nq: #{repo.map(&:to_nquads)}"
|
241
243
|
repo
|
@@ -320,7 +322,11 @@ module Fixtures
|
|
320
322
|
raise "Expected status #{t.property('expectErrorCode')}, not #{last_response.status}"
|
321
323
|
end
|
322
324
|
when "jld:ToRDFTest"
|
323
|
-
|
325
|
+
if t.manifest_url.to_s.include?('stream')
|
326
|
+
JSON::LD::Reader.open(t.input_loc, stream: true, logger: logger, **options).each_statement {}
|
327
|
+
else
|
328
|
+
JSON::LD::API.toRdf(t.input_loc, logger: logger, **options) {}
|
329
|
+
end
|
324
330
|
else
|
325
331
|
success("Unknown test type: #{testType}")
|
326
332
|
end
|
data/spec/suite_to_rdf_spec.rb
CHANGED
@@ -9,6 +9,7 @@ describe JSON::LD do
|
|
9
9
|
m.entries.each do |t|
|
10
10
|
specify "#{t.property('@id')}: #{t.name}#{' (negative test)' unless t.positiveTest?}" do
|
11
11
|
pending "Generalized RDF" if t.options[:produceGeneralizedRdf]
|
12
|
+
pending "RDF*" if t.property('@id') == '#te122'
|
12
13
|
if %w(#t0118).include?(t.property('@id'))
|
13
14
|
expect {t.run self}.to write(/Statement .* is invalid/).to(:error)
|
14
15
|
elsif %w(#te075).include?(t.property('@id'))
|
data/spec/to_rdf_spec.rb
CHANGED
@@ -1175,6 +1175,212 @@ describe JSON::LD::API do
|
|
1175
1175
|
end
|
1176
1176
|
end
|
1177
1177
|
|
1178
|
+
context "JSON-LD*" do
|
1179
|
+
{
|
1180
|
+
"node with embedded subject without rdfstar option": {
|
1181
|
+
input: %({
|
1182
|
+
"@id": {
|
1183
|
+
"@id": "ex:rei",
|
1184
|
+
"ex:prop": "value"
|
1185
|
+
},
|
1186
|
+
"ex:prop": "value2"
|
1187
|
+
}),
|
1188
|
+
exception: JSON::LD::JsonLdError::InvalidIdValue
|
1189
|
+
},
|
1190
|
+
}.each do |title, params|
|
1191
|
+
it(title) {run_to_rdf params}
|
1192
|
+
end
|
1193
|
+
|
1194
|
+
{
|
1195
|
+
"node with embedded subject having no @id": {
|
1196
|
+
input: %({
|
1197
|
+
"@id": {
|
1198
|
+
"ex:prop": "value"
|
1199
|
+
},
|
1200
|
+
"ex:prop": "value2"
|
1201
|
+
}),
|
1202
|
+
expected: %(
|
1203
|
+
<<_:b0 <ex:prop> "value">> <ex:prop> "value2" .
|
1204
|
+
),
|
1205
|
+
},
|
1206
|
+
"node with embedded subject having IRI @id": {
|
1207
|
+
input: %({
|
1208
|
+
"@id": {
|
1209
|
+
"@id": "ex:rei",
|
1210
|
+
"ex:prop": "value"
|
1211
|
+
},
|
1212
|
+
"ex:prop": "value2"
|
1213
|
+
}),
|
1214
|
+
expected: %(
|
1215
|
+
<<<ex:rei> <ex:prop> "value">> <ex:prop> "value2" .
|
1216
|
+
),
|
1217
|
+
},
|
1218
|
+
"node with embedded subject having BNode @id": {
|
1219
|
+
input: %({
|
1220
|
+
"@id": {
|
1221
|
+
"@id": "_:rei",
|
1222
|
+
"ex:prop": "value"
|
1223
|
+
},
|
1224
|
+
"ex:prop": "value2"
|
1225
|
+
}),
|
1226
|
+
expected: %(
|
1227
|
+
<<_:b0 <ex:prop> "value">> <ex:prop> "value2" .
|
1228
|
+
),
|
1229
|
+
},
|
1230
|
+
"node with embedded subject having a type": {
|
1231
|
+
input: %({
|
1232
|
+
"@id": {
|
1233
|
+
"@id": "ex:rei",
|
1234
|
+
"@type": "ex:Type"
|
1235
|
+
},
|
1236
|
+
"ex:prop": "value2"
|
1237
|
+
}),
|
1238
|
+
expected: %(
|
1239
|
+
<<<ex:rei> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <ex:Type>>> <ex:prop> "value2" .
|
1240
|
+
),
|
1241
|
+
},
|
1242
|
+
"node with embedded subject having an IRI value": {
|
1243
|
+
input: %({
|
1244
|
+
"@id": {
|
1245
|
+
"@id": "ex:rei",
|
1246
|
+
"ex:prop": {"@id": "ex:value"}
|
1247
|
+
},
|
1248
|
+
"ex:prop": "value2"
|
1249
|
+
}),
|
1250
|
+
expected: %(
|
1251
|
+
<<<ex:rei> <ex:prop> <ex:value>>> <ex:prop> "value2" .
|
1252
|
+
),
|
1253
|
+
},
|
1254
|
+
"node with embedded subject having an BNode value": {
|
1255
|
+
input: %({
|
1256
|
+
"@id": {
|
1257
|
+
"@id": "ex:rei",
|
1258
|
+
"ex:prop": {"@id": "_:value"}
|
1259
|
+
},
|
1260
|
+
"ex:prop": "value2"
|
1261
|
+
}),
|
1262
|
+
expected: %(
|
1263
|
+
<<<ex:rei> <ex:prop> _:b0>> <ex:prop> "value2" .
|
1264
|
+
),
|
1265
|
+
},
|
1266
|
+
"node with recursive embedded subject": {
|
1267
|
+
input: %({
|
1268
|
+
"@id": {
|
1269
|
+
"@id": {
|
1270
|
+
"@id": "ex:rei",
|
1271
|
+
"ex:prop": "value3"
|
1272
|
+
},
|
1273
|
+
"ex:prop": "value"
|
1274
|
+
},
|
1275
|
+
"ex:prop": "value2"
|
1276
|
+
}),
|
1277
|
+
expected: %(
|
1278
|
+
<<<<<ex:rei> <ex:prop> "value3">> <ex:prop> "value">> <ex:prop> "value2" .
|
1279
|
+
),
|
1280
|
+
},
|
1281
|
+
"illegal node with subject having no property": {
|
1282
|
+
input: %({
|
1283
|
+
"@id": {
|
1284
|
+
"@id": "ex:rei"
|
1285
|
+
},
|
1286
|
+
"ex:prop": "value3"
|
1287
|
+
}),
|
1288
|
+
exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
|
1289
|
+
},
|
1290
|
+
"illegal node with subject having multiple properties": {
|
1291
|
+
input: %({
|
1292
|
+
"@id": {
|
1293
|
+
"@id": "ex:rei",
|
1294
|
+
"ex:prop": ["value1", "value2"]
|
1295
|
+
},
|
1296
|
+
"ex:prop": "value3"
|
1297
|
+
}),
|
1298
|
+
exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
|
1299
|
+
},
|
1300
|
+
"illegal node with subject having multiple types": {
|
1301
|
+
input: %({
|
1302
|
+
"@id": {
|
1303
|
+
"@id": "ex:rei",
|
1304
|
+
"@type": ["ex:Type1", "ex:Type2"]
|
1305
|
+
},
|
1306
|
+
"ex:prop": "value3"
|
1307
|
+
}),
|
1308
|
+
exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
|
1309
|
+
},
|
1310
|
+
"illegal node with subject having type and property": {
|
1311
|
+
input: %({
|
1312
|
+
"@id": {
|
1313
|
+
"@id": "ex:rei",
|
1314
|
+
"@type": "ex:Type",
|
1315
|
+
"ex:prop": "value"
|
1316
|
+
},
|
1317
|
+
"ex:prop": "value2"
|
1318
|
+
}),
|
1319
|
+
exception: JSON::LD::JsonLdError::InvalidEmbeddedNode
|
1320
|
+
},
|
1321
|
+
"node with embedded object": {
|
1322
|
+
input: %({
|
1323
|
+
"@id": "ex:subj",
|
1324
|
+
"ex:value": {
|
1325
|
+
"@id": {
|
1326
|
+
"@id": "ex:rei",
|
1327
|
+
"ex:prop": "value"
|
1328
|
+
}
|
1329
|
+
}
|
1330
|
+
}),
|
1331
|
+
expected: %(
|
1332
|
+
<ex:subj> <ex:value> <<<ex:rei> <ex:prop> "value">> .
|
1333
|
+
),
|
1334
|
+
},
|
1335
|
+
"node with embedded object having properties": {
|
1336
|
+
input: %({
|
1337
|
+
"@id": "ex:subj",
|
1338
|
+
"ex:value": {
|
1339
|
+
"@id": {
|
1340
|
+
"@id": "ex:rei",
|
1341
|
+
"ex:prop": "value"
|
1342
|
+
},
|
1343
|
+
"ex:prop": "value2"
|
1344
|
+
}
|
1345
|
+
}),
|
1346
|
+
expected: %(
|
1347
|
+
<ex:subj> <ex:value> <<<ex:rei> <ex:prop> "value">> .
|
1348
|
+
<<<ex:rei> <ex:prop> "value">> <ex:prop> "value2" .
|
1349
|
+
),
|
1350
|
+
},
|
1351
|
+
"node with recursive embedded object": {
|
1352
|
+
input: %({
|
1353
|
+
"@id": "ex:subj",
|
1354
|
+
"ex:value": {
|
1355
|
+
"@id": {
|
1356
|
+
"@id": {
|
1357
|
+
"@id": "ex:rei",
|
1358
|
+
"ex:prop": "value3"
|
1359
|
+
},
|
1360
|
+
"ex:prop": "value"
|
1361
|
+
},
|
1362
|
+
"ex:prop": "value2"
|
1363
|
+
}
|
1364
|
+
}),
|
1365
|
+
expected: %(
|
1366
|
+
<ex:subj> <ex:value> <<<<<ex:rei> <ex:prop> "value3">> <ex:prop> "value">> .
|
1367
|
+
<<<<<ex:rei> <ex:prop> "value3">> <ex:prop> "value">> <ex:prop> "value2" .
|
1368
|
+
),
|
1369
|
+
},
|
1370
|
+
}.each do |title, params|
|
1371
|
+
context(title) do
|
1372
|
+
it "Generates statements" do
|
1373
|
+
output_graph = RDF::Graph.new {|g| g << RDF::NTriples::Reader.new(params[:expected], rdfstar: true)}
|
1374
|
+
run_to_rdf params.merge(rdfstar: true, output: output_graph)
|
1375
|
+
end if params[:expected]
|
1376
|
+
|
1377
|
+
it "Exception" do
|
1378
|
+
run_to_rdf params.merge(rdfstar: true)
|
1379
|
+
end if params[:exception]
|
1380
|
+
end
|
1381
|
+
end
|
1382
|
+
end
|
1383
|
+
|
1178
1384
|
context "exceptions" do
|
1179
1385
|
{
|
1180
1386
|
"Invalid subject" => {
|