json-ld 2.2.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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" +