json-ld 3.1.6 → 3.1.10

Sign up to get free protection for your applications and to get access to all the features.
data/spec/spec_helper.rb CHANGED
@@ -15,10 +15,16 @@ require_relative 'matchers'
15
15
  require 'yaml'
16
16
  begin
17
17
  require 'simplecov'
18
- require 'coveralls' unless ENV['NOCOVERALLS']
18
+ require 'simplecov-lcov'
19
+ SimpleCov::Formatter::LcovFormatter.config do |config|
20
+ #Coveralls is coverage by default/lcov. Send info results
21
+ config.report_with_single_file = true
22
+ config.single_report_path = 'coverage/lcov.info'
23
+ end
24
+
19
25
  SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
20
26
  SimpleCov::Formatter::HTMLFormatter,
21
- (Coveralls::SimpleCov::Formatter unless ENV['NOCOVERALLS'])
27
+ SimpleCov::Formatter::LcovFormatter
22
28
  ])
23
29
  SimpleCov.start do
24
30
  add_filter "/spec/"
@@ -67,6 +73,38 @@ def detect_format(stream)
67
73
  end
68
74
  end
69
75
 
76
+ # Creates a bijection between the two objects and replaces nodes in actual from expected.
77
+ def remap_bnodes(actual, expected)
78
+ # Transform each to RDF and perform a blank node bijection.
79
+ # Replace the blank nodes in action with the mapping from bijection.
80
+ ds_actual = RDF::Repository.new << JSON::LD::API.toRdf(actual, rdfstar: true, rename_bnodes: false)
81
+ ds_expected = RDF::Repository.new << JSON::LD::API.toRdf(expected, rdfstar: true, rename_bnodes: false)
82
+ if bijection = ds_actual.bijection_to(ds_expected)
83
+ bijection = bijection.inject({}) {|memo, (k, v)| memo.merge(k.to_s => v.to_s)}
84
+
85
+ # Recursively replace blank nodes in actual with the bijection
86
+ replace_nodes(actual, bijection)
87
+ else
88
+ actual
89
+ end
90
+ end
91
+
92
+ def replace_nodes(object, bijection)
93
+ case object
94
+ when Array
95
+ object.map {|o| replace_nodes(o, bijection)}
96
+ when Hash
97
+ object.inject({}) do |memo, (k, v)|
98
+ memo.merge(bijection.fetch(k, k) => replace_nodes(v, bijection))
99
+ end
100
+ when String
101
+ bijection.fetch(object, object)
102
+ else
103
+ object
104
+ end
105
+ end
106
+
107
+
70
108
  LIBRARY_INPUT = JSON.parse(%([
71
109
  {
72
110
  "@id": "http://example.org/library",
@@ -7,6 +7,8 @@ describe JSON::LD do
7
7
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}flatten-manifest.jsonld")
8
8
  describe m.name do
9
9
  m.entries.each do |t|
10
+ t.options[:remap_bnodes] = %w(#t0045).include?(t.property('@id'))
11
+
10
12
  specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do
11
13
  t.options[:ordered] = false
12
14
  if %w(#t0005).include?(t.property('@id'))
@@ -16,6 +18,8 @@ describe JSON::LD do
16
18
  end
17
19
  end
18
20
 
21
+ # Skip ordered tests when remapping bnodes
22
+ next if t.options[:remap_bnodes]
19
23
  specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do
20
24
  t.options[:ordered] = true
21
25
  if %w(#t0005).include?(t.property('@id'))
@@ -7,13 +7,20 @@ describe JSON::LD do
7
7
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::FRAME_SUITE}frame-manifest.jsonld")
8
8
  describe m.name do
9
9
  m.entries.each do |t|
10
+ t.options[:remap_bnodes] = %w(#t0021 #tp021).include?(t.property('@id'))
11
+
10
12
  specify "#{t.property('@id')}: #{t.name} unordered#{' (negative test)' unless t.positiveTest?}" do
11
13
  t.options[:ordered] = false
12
14
  expect {t.run self}.not_to write.to(:error)
13
15
  end
14
16
 
17
+ # Skip ordered tests when remapping bnodes
18
+ next if t.options[:remap_bnodes]
15
19
  specify "#{t.property('@id')}: #{t.name} ordered#{' (negative test)' unless t.positiveTest?}" do
16
20
  t.options[:ordered] = true
21
+ if %w(#tp021).include?(t.property('@id'))
22
+ pending("changes due to blank node reordering")
23
+ end
17
24
  expect {t.run self}.not_to write.to(:error)
18
25
  end
19
26
  end
data/spec/suite_helper.rb CHANGED
@@ -7,6 +7,7 @@ module RDF::Util
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
9
  "https://w3c.github.io/json-ld-streaming/tests/" => ::File.expand_path("../json-ld-streaming/tests", __FILE__) + '/',
10
+ "https://json-ld.github.io/json-ld-star/tests/" => ::File.expand_path("../json-ld-star/tests", __FILE__) + '/',
10
11
  "file:" => ""
11
12
  }
12
13
 
@@ -76,6 +77,7 @@ module Fixtures
76
77
  SUITE = RDF::URI("https://w3c.github.io/json-ld-api/tests/")
77
78
  FRAME_SUITE = RDF::URI("https://w3c.github.io/json-ld-framing/tests/")
78
79
  STREAM_SUITE = RDF::URI("https://w3c.github.io/json-ld-streaming/tests/")
80
+ STAR_SUITE = RDF::URI("https://json-ld.github.io/json-ld-star/tests/")
79
81
 
80
82
  class Manifest < JSON::LD::Resource
81
83
  attr_accessor :manifest_url
@@ -201,8 +203,8 @@ module Fixtures
201
203
  logger.info "frame: #{frame}" if frame_loc
202
204
 
203
205
  options = self.options
204
- unless options[:specVersion] == "json-ld-1.1"
205
- skip "not a 1.1 test"
206
+ if options[:specVersion] == "json-ld-1.0"
207
+ skip "1.0 test"
206
208
  return
207
209
  end
208
210
 
@@ -223,7 +225,7 @@ module Fixtures
223
225
  JSON::LD::API.frame(input_loc, frame_loc, logger: logger, **options)
224
226
  when "jld:FromRDFTest"
225
227
  # Use an array, to preserve input order
226
- repo = RDF::NQuads::Reader.open(input_loc) do |reader|
228
+ repo = RDF::NQuads::Reader.open(input_loc, rdfstar: options[:rdfstar]) do |reader|
227
229
  reader.each_statement.to_a
228
230
  end.to_a.uniq.extend(RDF::Enumerable)
229
231
  logger.info "repo: #{repo.dump(self.id == '#t0012' ? :nquads : :trig)}"
@@ -235,7 +237,7 @@ module Fixtures
235
237
  repo << statement
236
238
  end
237
239
  else
238
- JSON::LD::API.toRdf(input_loc, logger: logger, **options) do |statement|
240
+ JSON::LD::API.toRdf(input_loc, rename_bnodes: false, logger: logger, **options) do |statement|
239
241
  repo << statement
240
242
  end
241
243
  end
@@ -256,12 +258,16 @@ module Fixtures
256
258
  end
257
259
  if evaluationTest?
258
260
  if testType == "jld:ToRDFTest"
259
- expected = RDF::Repository.new << RDF::NQuads::Reader.new(expect, logger: [])
261
+ expected = RDF::Repository.new << RDF::NQuads::Reader.new(expect, rdfstar: options[:rdfstar], logger: [])
260
262
  rspec_example.instance_eval {
261
263
  expect(result).to be_equivalent_graph(expected, logger)
262
264
  }
263
265
  else
264
266
  expected = JSON.load(expect)
267
+
268
+ # If called for, remap bnodes
269
+ result = remap_bnodes(result, expected) if options[:remap_bnodes]
270
+
265
271
  if options[:ordered]
266
272
  # Compare without transformation
267
273
  rspec_example.instance_eval {
@@ -308,7 +314,7 @@ module Fixtures
308
314
  when "jld:FrameTest"
309
315
  JSON::LD::API.frame(t.input_loc, t.frame_loc, logger: logger, **options)
310
316
  when "jld:FromRDFTest"
311
- repo = RDF::Repository.load(t.input_loc)
317
+ repo = RDF::Repository.load(t.input_loc, rdfstar: options[:rdfstar])
312
318
  logger.info "repo: #{repo.dump(t.id == '#t0012' ? :nquads : :trig)}"
313
319
  JSON::LD::API.fromRdf(repo, logger: logger, **options)
314
320
  when "jld:HttpTest"
@@ -325,7 +331,7 @@ module Fixtures
325
331
  if t.manifest_url.to_s.include?('stream')
326
332
  JSON::LD::Reader.open(t.input_loc, stream: true, logger: logger, **options).each_statement {}
327
333
  else
328
- JSON::LD::API.toRdf(t.input_loc, logger: logger, **options) {}
334
+ JSON::LD::API.toRdf(t.input_loc, rename_bnodes: false, logger: logger, **options) {}
329
335
  end
330
336
  else
331
337
  success("Unknown test type: #{testType}")
@@ -9,7 +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
+ pending "RDF-star" if t.property('@id') == '#te122'
13
13
  if %w(#t0118).include?(t.property('@id'))
14
14
  expect {t.run self}.to write(/Statement .* is invalid/).to(:error)
15
15
  elsif %w(#te075).include?(t.property('@id'))
data/spec/to_rdf_spec.rb CHANGED
@@ -1175,7 +1175,7 @@ describe JSON::LD::API do
1175
1175
  end
1176
1176
  end
1177
1177
 
1178
- context "JSON-LD*" do
1178
+ context "JSON-LD-star" do
1179
1179
  {
1180
1180
  "node with embedded subject without rdfstar option": {
1181
1181
  input: %({
@@ -1528,7 +1528,7 @@ describe JSON::LD::API do
1528
1528
  def parse(input, **options)
1529
1529
  graph = options[:graph] || RDF::Graph.new
1530
1530
  options = {logger: logger, validate: true, canonicalize: false}.merge(options)
1531
- JSON::LD::API.toRdf(StringIO.new(input), **options) {|st| graph << st}
1531
+ JSON::LD::API.toRdf(StringIO.new(input), rename_bnodes: false, **options) {|st| graph << st}
1532
1532
  graph
1533
1533
  end
1534
1534
 
@@ -1541,9 +1541,9 @@ describe JSON::LD::API do
1541
1541
  expect {JSON::LD::API.toRdf(input, **params)}.to raise_error(params[:exception])
1542
1542
  else
1543
1543
  if params[:write]
1544
- expect{JSON::LD::API.toRdf(input, base: params[:base], logger: logger, **params) {|st| graph << st}}.to write(params[:write]).to(:error)
1544
+ expect{JSON::LD::API.toRdf(input, base: params[:base], logger: logger, rename_bnodes: false, **params) {|st| graph << st}}.to write(params[:write]).to(:error)
1545
1545
  else
1546
- expect{JSON::LD::API.toRdf(input, base: params[:base], logger: logger, **params) {|st| graph << st}}.not_to write.to(:error)
1546
+ expect{JSON::LD::API.toRdf(input, base: params[:base], logger: logger, rename_bnodes: false, **params) {|st| graph << st}}.not_to write.to(:error)
1547
1547
  end
1548
1548
  expect(graph).to be_equivalent_graph(output, logger: logger, inputDocument: input)
1549
1549
  end
data/spec/writer_spec.rb CHANGED
@@ -189,6 +189,199 @@ describe JSON::LD::Writer do
189
189
  end
190
190
  end
191
191
 
192
+ context "RDF-star" do
193
+ {
194
+ "subject-iii": {
195
+ input: RDF::Statement(
196
+ RDF::Statement(
197
+ RDF::URI('http://example/s1'),
198
+ RDF::URI('http://example/p1'),
199
+ RDF::URI('http://example/o1')),
200
+ RDF::URI('http://example/p'),
201
+ RDF::URI('http://example/o')),
202
+ output: %({
203
+ "@context": {"ex": "http://example/"},
204
+ "@id": {
205
+ "@id": "ex:s1",
206
+ "ex:p1": {"@id": "ex:o1"}
207
+ },
208
+ "ex:p": {"@id": "ex:o"}
209
+ })
210
+ },
211
+ "subject-iib": {
212
+ input: RDF::Statement(
213
+ RDF::Statement(
214
+ RDF::URI('http://example/s1'),
215
+ RDF::URI('http://example/p1'),
216
+ RDF::Node.new('o1')),
217
+ RDF::URI('http://example/p'),
218
+ RDF::URI('http://example/o')),
219
+ output: %({
220
+ "@context": {"ex": "http://example/"},
221
+ "@id": {
222
+ "@id": "ex:s1",
223
+ "ex:p1": {"@id": "_:o1"}
224
+ },
225
+ "ex:p": {"@id": "ex:o"}
226
+ })
227
+ },
228
+ "subject-iil": {
229
+ input: RDF::Statement(
230
+ RDF::Statement(
231
+ RDF::URI('http://example/s1'),
232
+ RDF::URI('http://example/p1'),
233
+ RDF::Literal('o1')),
234
+ RDF::URI('http://example/p'),
235
+ RDF::URI('http://example/o')),
236
+ output: %({
237
+ "@context": {"ex": "http://example/"},
238
+ "@id": {
239
+ "@id": "ex:s1",
240
+ "ex:p1": "o1"
241
+ },
242
+ "ex:p": {"@id": "ex:o"}
243
+ })
244
+ },
245
+ "subject-bii": {
246
+ input: RDF::Statement(
247
+ RDF::Statement(
248
+ RDF::Node('s1'),
249
+ RDF::URI('http://example/p1'),
250
+ RDF::URI('http://example/o1')),
251
+ RDF::URI('http://example/p'),
252
+ RDF::URI('http://example/o')),
253
+ output: %({
254
+ "@context": {"ex": "http://example/"},
255
+ "@id": {
256
+ "@id": "_:s1",
257
+ "ex:p1": {"@id": "ex:o1"}
258
+ },
259
+ "ex:p": {"@id": "ex:o"}
260
+ })
261
+ },
262
+ "subject-bib": {
263
+ input: RDF::Statement(
264
+ RDF::Statement(
265
+ RDF::Node('s1'),
266
+ RDF::URI('http://example/p1'),
267
+ RDF::Node.new('o1')),
268
+ RDF::URI('http://example/p'), RDF::URI('http://example/o')),
269
+ output: %({
270
+ "@context": {"ex": "http://example/"},
271
+ "@id": {
272
+ "@id": "_:s1",
273
+ "ex:p1": {"@id": "_:o1"}
274
+ },
275
+ "ex:p": {"@id": "ex:o"}
276
+ })
277
+ },
278
+ "subject-bil": {
279
+ input: RDF::Statement(
280
+ RDF::Statement(
281
+ RDF::Node('s1'),
282
+ RDF::URI('http://example/p1'),
283
+ RDF::Literal('o1')),
284
+ RDF::URI('http://example/p'),
285
+ RDF::URI('http://example/o')),
286
+ output: %({
287
+ "@context": {"ex": "http://example/"},
288
+ "@id": {
289
+ "@id": "_:s1",
290
+ "ex:p1": "o1"
291
+ },
292
+ "ex:p": {"@id": "ex:o"}
293
+ })
294
+ },
295
+ "object-iii": {
296
+ input: RDF::Statement(
297
+ RDF::URI('http://example/s'),
298
+ RDF::URI('http://example/p'),
299
+ RDF::Statement(
300
+ RDF::URI('http://example/s1'),
301
+ RDF::URI('http://example/p1'),
302
+ RDF::URI('http://example/o1'))),
303
+ output: %({
304
+ "@context": {"ex": "http://example/"},
305
+ "@id": "ex:s",
306
+ "ex:p": {
307
+ "@id": {
308
+ "@id": "ex:s1",
309
+ "ex:p1": {"@id": "ex:o1"}
310
+ }
311
+ }
312
+ })
313
+ },
314
+ "object-iib": {
315
+ input: RDF::Statement(
316
+ RDF::URI('http://example/s'),
317
+ RDF::URI('http://example/p'),
318
+ RDF::Statement(
319
+ RDF::URI('http://example/s1'),
320
+ RDF::URI('http://example/p1'),
321
+ RDF::Node.new('o1'))),
322
+ output: %({
323
+ "@context": {"ex": "http://example/"},
324
+ "@id": "ex:s",
325
+ "ex:p": {
326
+ "@id": {
327
+ "@id": "ex:s1",
328
+ "ex:p1": {"@id": "_:o1"}
329
+ }
330
+ }
331
+ })
332
+ },
333
+ "object-iil": {
334
+ input: RDF::Statement(
335
+ RDF::URI('http://example/s'),
336
+ RDF::URI('http://example/p'),
337
+ RDF::Statement(
338
+ RDF::URI('http://example/s1'),
339
+ RDF::URI('http://example/p1'),
340
+ RDF::Literal('o1'))),
341
+ output: %({
342
+ "@context": {"ex": "http://example/"},
343
+ "@id": "ex:s",
344
+ "ex:p": {
345
+ "@id": {
346
+ "@id": "ex:s1",
347
+ "ex:p1": "o1"
348
+ }
349
+ }
350
+ })
351
+ },
352
+ "recursive-subject": {
353
+ input: RDF::Statement(
354
+ RDF::Statement(
355
+ RDF::Statement(
356
+ RDF::URI('http://example/s2'),
357
+ RDF::URI('http://example/p2'),
358
+ RDF::URI('http://example/o2')),
359
+ RDF::URI('http://example/p1'),
360
+ RDF::URI('http://example/o1')),
361
+ RDF::URI('http://example/p'),
362
+ RDF::URI('http://example/o')),
363
+ output: %({
364
+ "@context": {"ex": "http://example/"},
365
+ "@id": {
366
+ "@id": {
367
+ "@id": "ex:s2",
368
+ "ex:p2": {"@id": "ex:o2"}
369
+ },
370
+ "ex:p1": {"@id": "ex:o1"}
371
+ },
372
+ "ex:p": {"@id": "ex:o"}
373
+ })
374
+ },
375
+ }.each do |name, params|
376
+ it name do
377
+ graph = RDF::Graph.new {|g| g << params[:input]}
378
+ expect(
379
+ serialize(graph, rdfstar: true, prefixes: {ex: 'http://example/'})
380
+ ).to produce_jsonld(JSON.parse(params[:output]), logger)
381
+ end
382
+ end
383
+ end
384
+
192
385
  context "Writes fromRdf tests to isomorphic graph" do
193
386
  require 'suite_helper'
194
387
  m = Fixtures::SuiteTest::Manifest.open("#{Fixtures::SuiteTest::SUITE}fromRdf-manifest.jsonld")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-ld
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.6
4
+ version: 3.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg Kellogg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-23 00:00:00.000000000 Z
11
+ date: 2021-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdf
@@ -297,7 +297,7 @@ dependencies:
297
297
  - !ruby/object:Gem::Version
298
298
  version: '0.9'
299
299
  description: JSON::LD parses and serializes JSON-LD into RDF and implements expansion,
300
- compaction and framing API interfaces.
300
+ compaction and framing API interfaces for the Ruby RDF.rb library suite.
301
301
  email: public-linked-json@w3.org
302
302
  executables:
303
303
  - jsonld
@@ -340,6 +340,7 @@ files:
340
340
  - spec/frame_spec.rb
341
341
  - spec/from_rdf_spec.rb
342
342
  - spec/matchers.rb
343
+ - spec/rdfstar_spec.rb
343
344
  - spec/reader_spec.rb
344
345
  - spec/resource_spec.rb
345
346
  - spec/spec_helper.rb
@@ -426,7 +427,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
426
427
  - !ruby/object:Gem::Version
427
428
  version: '0'
428
429
  requirements: []
429
- rubygems_version: 3.2.0.rc.2
430
+ rubygems_version: 3.2.22
430
431
  signing_key:
431
432
  specification_version: 4
432
433
  summary: JSON-LD reader/writer for Ruby.
@@ -441,6 +442,7 @@ test_files:
441
442
  - spec/frame_spec.rb
442
443
  - spec/from_rdf_spec.rb
443
444
  - spec/matchers.rb
445
+ - spec/rdfstar_spec.rb
444
446
  - spec/reader_spec.rb
445
447
  - spec/resource_spec.rb
446
448
  - spec/spec_helper.rb