json-ld 3.1.6 → 3.1.10

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.
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