json-ld 2.2.1 → 3.0.0

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.
@@ -18,21 +18,21 @@ describe JSON::LD::API do
18
18
  "foaf" => RDF::Vocab::FOAF.to_s
19
19
  },
20
20
  "@id" => "http://greggkellogg.net/foaf",
21
- "@type" => ["foaf:PersonalProfileDocument"],
21
+ "@type" => "http://xmlns.com/foaf/0.1/PersonalProfileDocument",
22
22
  "foaf:primaryTopic" => [{
23
23
  "@id" => "http://greggkellogg.net/foaf#me",
24
- "@type" => ["foaf:Person"]
24
+ "@type" => "http://xmlns.com/foaf/0.1/Person"
25
25
  }]
26
26
  },
27
27
  output: [
28
28
  {
29
29
  "@id" => "http://greggkellogg.net/foaf",
30
- "@type" => [RDF::Vocab::FOAF.PersonalProfileDocument.to_s],
31
- RDF::Vocab::FOAF.primaryTopic.to_s => [{"@id" => "http://greggkellogg.net/foaf#me"}]
30
+ "@type" => ["http://xmlns.com/foaf/0.1/PersonalProfileDocument"],
31
+ "http://xmlns.com/foaf/0.1/primaryTopic" => [{"@id" => "http://greggkellogg.net/foaf#me"}]
32
32
  },
33
33
  {
34
34
  "@id" => "http://greggkellogg.net/foaf#me",
35
- "@type" => [RDF::Vocab::FOAF.Person.to_s]
35
+ "@type" => ["http://xmlns.com/foaf/0.1/Person"]
36
36
  }
37
37
  ]
38
38
  },
@@ -60,7 +60,7 @@ describe JSON::LD::API do
60
60
  ]
61
61
  },
62
62
  "reverse properties" => {
63
- input: ::JSON.parse(%([
63
+ input: %([
64
64
  {
65
65
  "@id": "http://example.com/people/markus",
66
66
  "@reverse": {
@@ -75,8 +75,8 @@ describe JSON::LD::API do
75
75
  },
76
76
  "http://xmlns.com/foaf/0.1/name": [ { "@value": "Markus Lanthaler" } ]
77
77
  }
78
- ])),
79
- output: ::JSON.parse(%([
78
+ ]),
79
+ output: %([
80
80
  {
81
81
  "@id": "http://example.com/people/dave",
82
82
  "http://xmlns.com/foaf/0.1/knows": [
@@ -101,10 +101,10 @@ describe JSON::LD::API do
101
101
  }
102
102
  ]
103
103
  }
104
- ]))
104
+ ])
105
105
  },
106
106
  "Simple named graph (Wikidata)" => {
107
- input: ::JSON.parse(%q({
107
+ input: %q({
108
108
  "@context": {
109
109
  "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
110
110
  "ex": "http://example.org/",
@@ -133,8 +133,8 @@ describe JSON::LD::API do
133
133
  "ex:hasReference": "http://www.wikipedia.org/"
134
134
  }
135
135
  ]
136
- })),
137
- output: ::JSON.parse(%q([{
136
+ }),
137
+ output: %q([{
138
138
  "@id": "http://example.org/ParisFact1",
139
139
  "@type": ["http://www.w3.org/1999/02/22-rdf-syntax-ns#Graph"],
140
140
  "http://example.org/hasReference": [
@@ -154,10 +154,10 @@ describe JSON::LD::API do
154
154
  "@id": "http://example.org/location/Paris#this",
155
155
  "http://example.org/hasPopulation": [{"@value": 7000000}]
156
156
  }]
157
- }])),
157
+ }]),
158
158
  },
159
159
  "Test Manifest (shortened)" => {
160
- input: ::JSON.parse(%q{
160
+ input: %q{
161
161
  {
162
162
  "@id": "",
163
163
  "http://example/sequence": {"@list": [
@@ -168,8 +168,8 @@ describe JSON::LD::API do
168
168
  }
169
169
  ]}
170
170
  }
171
- }),
172
- output: ::JSON.parse(%q{
171
+ },
172
+ output: %q{
173
173
  [{
174
174
  "@id": "",
175
175
  "http://example/sequence": [{"@list": [{"@id": "#t0001"}]}]
@@ -178,11 +178,10 @@ describe JSON::LD::API do
178
178
  "http://example/input": [{"@id": "error-expand-0001-in.jsonld"}],
179
179
  "http://example/name": [{"@value": "Keywords cannot be aliased to other keywords"}]
180
180
  }]
181
- }),
182
- options: {}
181
+ },
183
182
  },
184
183
  "@reverse bnode issue (0045)" => {
185
- input: ::JSON.parse(%q{
184
+ input: %q{
186
185
  {
187
186
  "@context": {
188
187
  "foo": "http://example.org/foo",
@@ -191,8 +190,8 @@ describe JSON::LD::API do
191
190
  "foo": "Foo",
192
191
  "bar": [ "http://example.org/origin", "_:b0" ]
193
192
  }
194
- }),
195
- output: ::JSON.parse(%q{
193
+ },
194
+ output: %q{
196
195
  [
197
196
  {
198
197
  "@id": "_:b0",
@@ -207,14 +206,95 @@ describe JSON::LD::API do
207
206
  "http://example.org/bar": [ { "@id": "_:b0" } ]
208
207
  }
209
208
  ]
209
+ }
210
+ },
211
+ "@list with embedded object": {
212
+ input: %([{
213
+ "http://example.com/foo": [{
214
+ "@list": [{
215
+ "@id": "http://example.com/baz",
216
+ "http://example.com/bar": "buz"}
217
+ ]}
218
+ ]}
219
+ ]),
220
+ output: %([
221
+ {
222
+ "@id": "_:b0",
223
+ "http://example.com/foo": [{
224
+ "@list": [
225
+ {
226
+ "@id": "http://example.com/baz"
227
+ }
228
+ ]
229
+ }]
230
+ },
231
+ {
232
+ "@id": "http://example.com/baz",
233
+ "http://example.com/bar": [{"@value": "buz"}]
234
+ }
235
+ ])
236
+ },
237
+ "coerced @list containing an deep list" => {
238
+ input: %([{
239
+ "http://example.com/foo": [{"@list": [{"@list": [{"@list": [{"@value": "baz"}]}]}]}]
240
+ }]),
241
+ output: %([{
242
+ "@id": "_:b0",
243
+ "http://example.com/foo": [{"@list": [{"@list": [{"@list": [{"@value": "baz"}]}]}]}]
244
+ }]),
245
+ },
246
+ "@list containing empty @list" => {
247
+ input: %({
248
+ "http://example.com/foo": {"@list": [{"@list": []}]}
249
+ }),
250
+ output: %([{
251
+ "@id": "_:b0",
252
+ "http://example.com/foo": [{"@list": [{"@list": []}]}]
253
+ }])
254
+ },
255
+ "coerced @list containing mixed list values" => {
256
+ input: %({
257
+ "@context": {"foo": {"@id": "http://example.com/foo", "@container": "@list"}},
258
+ "foo": [
259
+ [{"@id": "http://example/a", "@type": "http://example/Bar"}],
260
+ {"@id": "http://example/b", "@type": "http://example/Baz"}]
210
261
  }),
211
- options: {}
212
- }
262
+ output: %([{
263
+ "@id": "_:b0",
264
+ "http://example.com/foo": [{"@list": [
265
+ {"@list": [{"@id": "http://example/a"}]},
266
+ {"@id": "http://example/b"}
267
+ ]}]
268
+ },
269
+ {
270
+ "@id": "http://example/a",
271
+ "@type": [
272
+ "http://example/Bar"
273
+ ]
274
+ },
275
+ {
276
+ "@id": "http://example/b",
277
+ "@type": [
278
+ "http://example/Baz"
279
+ ]
280
+ }])
281
+ },
213
282
  }.each do |title, params|
214
- it title do
215
- jld = JSON::LD::API.flatten(params[:input], nil, (params[:options] || {}).merge(logger: logger))
216
- expect(jld).to produce(params[:output], logger)
217
- end
283
+ it(title) {run_flatten(params)}
284
+ end
285
+ end
286
+
287
+ def run_flatten(params)
288
+ input, output, context = params[:input], params[:output], params[:context]
289
+ input = ::JSON.parse(input) if input.is_a?(String)
290
+ output = ::JSON.parse(output) if output.is_a?(String)
291
+ context = ::JSON.parse(context) if context.is_a?(String)
292
+ pending params.fetch(:pending, "test implementation") unless input
293
+ if params[:exception]
294
+ expect {JSON::LD::API.flatten(input, context, params.merge(logger: logger))}.to raise_error(params[:exception])
295
+ else
296
+ jld = JSON::LD::API.flatten(input, context, params.merge(logger: logger))
297
+ expect(jld).to produce(output, logger)
218
298
  end
219
299
  end
220
300
  end
@@ -667,7 +667,8 @@ describe JSON::LD::API do
667
667
  "name": "Test 0001"
668
668
  }]
669
669
  }]
670
- })
670
+ }),
671
+ processingMode: 'json-ld-1.1'
671
672
  },
672
673
  "library" => {
673
674
  frame: %({
@@ -1133,7 +1134,8 @@ describe JSON::LD::API do
1133
1134
  "@type": "Class",
1134
1135
  "preserve": {}
1135
1136
  }]
1136
- })
1137
+ }),
1138
+ processingMode: 'json-ld-1.1'
1137
1139
  },
1138
1140
  "Frame default graph if outer @graph is used" => {
1139
1141
  frame: %({
@@ -1160,13 +1162,14 @@ describe JSON::LD::API do
1160
1162
  "@type": "Class",
1161
1163
  "preserve": {
1162
1164
  "@id": "urn:gr-1",
1163
- "@graph": [{
1165
+ "@graph": {
1164
1166
  "@id": "urn:id-2",
1165
1167
  "term": "data"
1166
- }]
1168
+ }
1167
1169
  }
1168
1170
  }]
1169
- })
1171
+ }),
1172
+ processingMode: 'json-ld-1.1'
1170
1173
  },
1171
1174
  "Merge one graph and preserve another" => {
1172
1175
  frame: %({
@@ -1206,13 +1209,14 @@ describe JSON::LD::API do
1206
1209
  },
1207
1210
  "preserve": {
1208
1211
  "@id": "urn:graph-1",
1209
- "@graph": [{
1212
+ "@graph": {
1210
1213
  "@id": "urn:id-3",
1211
1214
  "term": "bar"
1212
- }]
1215
+ }
1213
1216
  }
1214
1217
  }]
1215
- })
1218
+ }),
1219
+ processingMode: 'json-ld-1.1'
1216
1220
  },
1217
1221
  "Merge one graph and deep preserve another" => {
1218
1222
  frame: %({
@@ -1255,14 +1259,15 @@ describe JSON::LD::API do
1255
1259
  },
1256
1260
  "preserve": {
1257
1261
  "deep": {
1258
- "@graph": [{
1262
+ "@graph": {
1259
1263
  "@id": "urn:id-3",
1260
1264
  "term": "bar"
1261
- }]
1265
+ }
1262
1266
  }
1263
1267
  }
1264
1268
  }]
1265
- })
1269
+ }),
1270
+ processingMode: 'json-ld-1.1'
1266
1271
  },
1267
1272
  "library" => {
1268
1273
  frame: %({
@@ -1303,24 +1308,23 @@ describe JSON::LD::API do
1303
1308
  "name": "Library",
1304
1309
  "contains": {
1305
1310
  "@id": "http://example.org/graphs/books",
1306
- "@graph": [
1307
- {
1308
- "@id": "http://example.org/library/the-republic",
1309
- "@type": "Book",
1310
- "creator": "Plato",
1311
- "title": "The Republic",
1312
- "contains": {
1313
- "@id": "http://example.org/library/the-republic#introduction",
1314
- "@type": "Chapter",
1315
- "description": "An introductory chapter on The Republic.",
1316
- "title": "The Introduction"
1317
- }
1311
+ "@graph": {
1312
+ "@id": "http://example.org/library/the-republic",
1313
+ "@type": "Book",
1314
+ "creator": "Plato",
1315
+ "title": "The Republic",
1316
+ "contains": {
1317
+ "@id": "http://example.org/library/the-republic#introduction",
1318
+ "@type": "Chapter",
1319
+ "description": "An introductory chapter on The Republic.",
1320
+ "title": "The Introduction"
1318
1321
  }
1319
- ]
1322
+ }
1320
1323
  }
1321
1324
  }
1322
1325
  ]
1323
- })
1326
+ }),
1327
+ processingMode: 'json-ld-1.1'
1324
1328
  }
1325
1329
  }.each do |title, params|
1326
1330
  it title do
@@ -1330,8 +1334,8 @@ describe JSON::LD::API do
1330
1334
  end
1331
1335
  end
1332
1336
 
1333
- describe "pruneBlankNodeIdentifiers" do
1334
- it "preserves single-use bnode identifiers if option set to false" do
1337
+ describe "prune blank nodes" do
1338
+ it "preserves single-use bnode identifiers if @version 1.0" do
1335
1339
  do_frame(
1336
1340
  input: %({
1337
1341
  "@context": {
@@ -1380,8 +1384,7 @@ describe JSON::LD::API do
1380
1384
  }
1381
1385
  }
1382
1386
  ]
1383
- }),
1384
- prune: false
1387
+ })
1385
1388
  )
1386
1389
  end
1387
1390
  end
@@ -1423,7 +1426,7 @@ describe JSON::LD::API do
1423
1426
  end
1424
1427
 
1425
1428
  it "issue #28" do
1426
- input = JSON.parse %({
1429
+ input = %({
1427
1430
  "@context": {
1428
1431
  "rdfs": "http://www.w3.org/2000/01/rdf-schema#"
1429
1432
  },
@@ -1440,7 +1443,7 @@ describe JSON::LD::API do
1440
1443
  }
1441
1444
  ]
1442
1445
  })
1443
- frame = JSON.parse %({
1446
+ frame = %({
1444
1447
  "@context": {
1445
1448
  "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
1446
1449
  "talksAbout": {
@@ -1454,7 +1457,7 @@ describe JSON::LD::API do
1454
1457
  },
1455
1458
  "@id": "http://www.myresource/uuid"
1456
1459
  })
1457
- expected = JSON.parse %({
1460
+ expected = %({
1458
1461
  "@context": {
1459
1462
  "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
1460
1463
  "talksAbout": {
@@ -1478,15 +1481,233 @@ describe JSON::LD::API do
1478
1481
  })
1479
1482
  do_frame(input: input, frame: frame, output: expected)
1480
1483
  end
1484
+
1485
+ it "framing with @version: 1.1 prunes identifiers" do
1486
+ input = %({
1487
+ "@context": {
1488
+ "@version": 1.1,
1489
+ "@vocab": "https://example.com#",
1490
+ "ex": "http://example.org/",
1491
+ "claim": {
1492
+ "@id": "ex:claim",
1493
+ "@container": "@graph"
1494
+ },
1495
+ "id": "@id"
1496
+ },
1497
+ "claim": {
1498
+ "id": "ex:1",
1499
+ "test": "foo"
1500
+ }
1501
+ })
1502
+ frame = %({
1503
+ "@context": {
1504
+ "@version": 1.1,
1505
+ "@vocab": "https://example.com#",
1506
+ "ex": "http://example.org/",
1507
+ "claim": {
1508
+ "@id": "ex:claim",
1509
+ "@container": "@graph"
1510
+ },
1511
+ "id": "@id"
1512
+ },
1513
+ "claim": {}
1514
+ })
1515
+ expected = %({
1516
+ "@context": {
1517
+ "@version": 1.1,
1518
+ "@vocab": "https://example.com#",
1519
+ "ex": "http://example.org/",
1520
+ "claim": {
1521
+ "@id": "ex:claim",
1522
+ "@container": "@graph"
1523
+ },
1524
+ "id": "@id"
1525
+ },
1526
+ "@graph": [
1527
+ {
1528
+ "claim": {
1529
+ "id": "ex:1",
1530
+ "test": "foo"
1531
+ }
1532
+ }
1533
+ ]
1534
+ })
1535
+ do_frame(input: input, frame: frame, output: expected, processingMode: 'json-ld-1.1')
1536
+ end
1537
+
1538
+ it "PR #663" do
1539
+ input = %({
1540
+ "@context": {
1541
+ "@vocab": "http://example.com/",
1542
+ "loves": {
1543
+ "@type": "@id"
1544
+ },
1545
+ "unionOf": {
1546
+ "@type": "@id",
1547
+ "@id": "owl:unionOf",
1548
+ "@container": "@list"
1549
+ },
1550
+ "Class": "owl:Class"
1551
+ },
1552
+ "@graph": [
1553
+ {
1554
+ "@type": "Act",
1555
+ "@graph": [
1556
+ {
1557
+ "@id": "Romeo",
1558
+ "@type": "Person"
1559
+ },
1560
+ {
1561
+ "@id": "Juliet",
1562
+ "@type": "Person"
1563
+ }
1564
+ ]
1565
+ },
1566
+ {
1567
+ "@id": "ActTwo",
1568
+ "@type": "Act",
1569
+ "@graph": [
1570
+ {
1571
+ "@id": "Romeo",
1572
+ "@type": "Person",
1573
+ "loves": "Juliet"
1574
+ },
1575
+ {
1576
+ "@id": "Juliet",
1577
+ "@type": "Person",
1578
+ "loves": "Romeo"
1579
+ }
1580
+ ]
1581
+ },
1582
+ {
1583
+ "@id": "Person",
1584
+ "@type": "Class",
1585
+ "unionOf": {
1586
+ "@list": [
1587
+ {
1588
+ "@id": "Montague",
1589
+ "@type": "Class"
1590
+ },
1591
+ {
1592
+ "@id": "Capulet",
1593
+ "@type": "Class"
1594
+ }
1595
+ ]
1596
+ }
1597
+ }
1598
+ ]
1599
+ })
1600
+ frame = %({
1601
+ "@context": {
1602
+ "@vocab": "http://example.com/",
1603
+ "loves": {
1604
+ "@type": "@id"
1605
+ },
1606
+ "unionOf": {
1607
+ "@type": "@id",
1608
+ "@id": "owl:unionOf",
1609
+ "@container": "@list"
1610
+ },
1611
+ "Class": "owl:Class"
1612
+ },
1613
+ "@graph": [
1614
+ {
1615
+ "@explicit": false,
1616
+ "@embed": "@last",
1617
+ "@type": [
1618
+ "Act",
1619
+ "Class"
1620
+ ],
1621
+ "@graph": [{
1622
+ "@explicit": true,
1623
+ "@embed": "@always",
1624
+ "@type": "Person",
1625
+ "@id": {},
1626
+ "loves": {"@embed": "@never"}
1627
+ }]
1628
+ }
1629
+ ]
1630
+ })
1631
+ expected = %({
1632
+ "@context": {
1633
+ "@vocab": "http://example.com/",
1634
+ "loves": {
1635
+ "@type": "@id"
1636
+ },
1637
+ "unionOf": {
1638
+ "@type": "@id",
1639
+ "@id": "owl:unionOf",
1640
+ "@container": "@list"
1641
+ },
1642
+ "Class": "owl:Class"
1643
+ },
1644
+ "@graph": [
1645
+ {
1646
+ "@graph": [
1647
+ {
1648
+ "@id": "Juliet",
1649
+ "@type": "Person",
1650
+ "loves": "Romeo"
1651
+ },
1652
+ {
1653
+ "@id": "Romeo",
1654
+ "@type": "Person",
1655
+ "loves": "Juliet"
1656
+ }
1657
+ ],
1658
+ "@id": "ActTwo",
1659
+ "@type": "Act"
1660
+ },
1661
+ {
1662
+ "@id": "Capulet",
1663
+ "@type": "Class"
1664
+ },
1665
+ {
1666
+ "@id": "Montague",
1667
+ "@type": "Class"
1668
+ },
1669
+ {
1670
+ "@id": "Person",
1671
+ "@type": "Class",
1672
+ "unionOf": [
1673
+ {
1674
+ "@id": "Montague",
1675
+ "@type": "Class"
1676
+ },
1677
+ {
1678
+ "@id": "Capulet",
1679
+ "@type": "Class"
1680
+ }
1681
+ ]
1682
+ },
1683
+ {
1684
+ "@graph": [
1685
+ {
1686
+ "@id": "Juliet",
1687
+ "@type": "Person",
1688
+ "loves": null
1689
+ },
1690
+ {
1691
+ "@id": "Romeo",
1692
+ "@type": "Person",
1693
+ "loves": null
1694
+ }
1695
+ ],
1696
+ "@type": "Act"
1697
+ }
1698
+ ]
1699
+ })
1700
+ do_frame(input: input, frame: frame, output: expected, processingMode: 'json-ld-1.1')
1701
+ end
1481
1702
  end
1482
1703
 
1483
1704
  def do_frame(params)
1484
1705
  begin
1485
- input, frame, output, prune = params[:input], params[:frame], params[:output], params.fetch(:prune, true)
1706
+ input, frame, output, processingMode = params[:input], params[:frame], params[:output], params.fetch(:processingMode, 'json-ld-1.0')
1486
1707
  input = ::JSON.parse(input) if input.is_a?(String)
1487
1708
  frame = ::JSON.parse(frame) if frame.is_a?(String)
1488
1709
  output = ::JSON.parse(output) if output.is_a?(String)
1489
- jld = JSON::LD::API.frame(input, frame, logger: logger, pruneBlankNodeIdentifiers: prune)
1710
+ jld = JSON::LD::API.frame(input, frame, logger: logger, processingMode: processingMode)
1490
1711
  expect(jld).to produce(output, logger)
1491
1712
  rescue JSON::LD::JsonLdError => e
1492
1713
  fail("#{e.class}: #{e.message}\n" +