json-ld 2.0.0.1 → 2.1.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.
- checksums.yaml +4 -4
- data/README.md +12 -1
- data/VERSION +1 -1
- data/lib/json/ld.rb +3 -1
- data/lib/json/ld/api.rb +23 -20
- data/lib/json/ld/compact.rb +27 -26
- data/lib/json/ld/context.rb +499 -428
- data/lib/json/ld/expand.rb +284 -281
- data/lib/json/ld/extensions.rb +2 -0
- data/lib/json/ld/flatten.rb +84 -88
- data/lib/json/ld/format.rb +3 -1
- data/lib/json/ld/frame.rb +154 -163
- data/lib/json/ld/from_rdf.rb +10 -6
- data/lib/json/ld/reader.rb +2 -0
- data/lib/json/ld/resource.rb +2 -0
- data/lib/json/ld/streaming_writer.rb +8 -6
- data/lib/json/ld/to_rdf.rb +11 -9
- data/lib/json/ld/utils.rb +2 -0
- data/lib/json/ld/version.rb +2 -0
- data/lib/json/ld/writer.rb +2 -0
- data/spec/context_spec.rb +73 -3
- data/spec/frame_spec.rb +97 -1
- metadata +6 -7
data/lib/json/ld/from_rdf.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
1
3
|
require 'rdf/nquads'
|
2
4
|
|
3
5
|
module JSON::LD
|
@@ -9,8 +11,10 @@ module JSON::LD
|
|
9
11
|
# Representation is in expanded form
|
10
12
|
#
|
11
13
|
# @param [Array<RDF::Statement>, RDF::Enumerable] input
|
14
|
+
# @param [Boolean] useRdfType (false)
|
15
|
+
# If set to `true`, the JSON-LD processor will treat `rdf:type` like a normal property instead of using `@type`.
|
12
16
|
# @return [Array<Hash>] the JSON-LD document in normalized form
|
13
|
-
def from_statements(input)
|
17
|
+
def from_statements(input, useRdfType: false)
|
14
18
|
default_graph = {}
|
15
19
|
graph_map = {'@default' => default_graph}
|
16
20
|
node_usages_map = {}
|
@@ -22,7 +26,7 @@ module JSON::LD
|
|
22
26
|
|
23
27
|
# For each triple in input
|
24
28
|
input.each do |statement|
|
25
|
-
log_debug("statement") { statement.to_nquads.chomp}
|
29
|
+
#log_debug("statement") { statement.to_nquads.chomp}
|
26
30
|
|
27
31
|
name = statement.graph_name ? ec.expand_iri(statement.graph_name).to_s : '@default'
|
28
32
|
|
@@ -38,13 +42,13 @@ module JSON::LD
|
|
38
42
|
statement.object.literal?
|
39
43
|
|
40
44
|
# If predicate equals rdf:type, and object is an IRI or blank node identifier, append object to the value of the @type member of node. If no such member exists, create one and initialize it to an array whose only item is object. Finally, continue to the next RDF triple.
|
41
|
-
if statement.predicate == RDF.type && statement.object.resource? &&
|
45
|
+
if statement.predicate == RDF.type && statement.object.resource? && !useRdfType
|
42
46
|
merge_value(node, '@type', statement.object.to_s)
|
43
47
|
next
|
44
48
|
end
|
45
49
|
|
46
50
|
# Set value to the result of using the RDF to Object Conversion algorithm, passing object and use native types.
|
47
|
-
value = ec.expand_value(nil, statement.object, @options)
|
51
|
+
value = ec.expand_value(nil, statement.object, useNativeTypes: @options[:useNativeTypes], log_depth: @options[:log_depth])
|
48
52
|
|
49
53
|
merge_value(node, statement.predicate.to_s, value)
|
50
54
|
|
@@ -71,7 +75,7 @@ module JSON::LD
|
|
71
75
|
list, list_nodes = [], []
|
72
76
|
|
73
77
|
# If property equals rdf:rest, the value associated to the usages member of node has exactly 1 entry, node has a rdf:first and rdf:rest property, both of which have as value an array consisting of a single element, and node has no other members apart from an optional @type member whose value is an array with a single item equal to rdf:List, node represents a well-formed list node. Continue with the following steps:
|
74
|
-
log_debug("list element?") {node.to_json(JSON_STATE) rescue 'malformed json'}
|
78
|
+
#log_debug("list element?") {node.to_json(JSON_STATE) rescue 'malformed json'}
|
75
79
|
while property == RDF.rest.to_s &&
|
76
80
|
node_usages_map[node['@id']].uniq.length == 1 &&
|
77
81
|
blank_node?(node) &&
|
@@ -118,7 +122,7 @@ module JSON::LD
|
|
118
122
|
node.delete(:usages)
|
119
123
|
result << node unless node_reference?(node)
|
120
124
|
end
|
121
|
-
log_debug("fromRdf") {result.to_json(JSON_STATE) rescue 'malformed json'}
|
125
|
+
#log_debug("fromRdf") {result.to_json(JSON_STATE) rescue 'malformed json'}
|
122
126
|
result
|
123
127
|
end
|
124
128
|
end
|
data/lib/json/ld/reader.rb
CHANGED
data/lib/json/ld/resource.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
1
3
|
module JSON::LD
|
2
4
|
##
|
3
5
|
# Streaming writer interface.
|
@@ -17,7 +19,7 @@ module JSON::LD
|
|
17
19
|
else Context.new.parse(@options[:context])
|
18
20
|
end
|
19
21
|
|
20
|
-
log_debug("prologue") {"context: #{context.inspect}"}
|
22
|
+
#log_debug("prologue") {"context: #{context.inspect}"}
|
21
23
|
if context
|
22
24
|
@output.puts %({"@context": #{context.serialize['@context'].to_json}, "@graph": [)
|
23
25
|
else
|
@@ -37,7 +39,7 @@ module JSON::LD
|
|
37
39
|
#
|
38
40
|
# @return [void] `self`
|
39
41
|
def stream_statement(statement)
|
40
|
-
log_debug("ss") {"state: #{@state.inspect}, stmt: #{statement}"}
|
42
|
+
#log_debug("ss") {"state: #{@state.inspect}, stmt: #{statement}"}
|
41
43
|
if @current_graph != statement.graph_name
|
42
44
|
end_graph
|
43
45
|
start_graph(statement.graph_name)
|
@@ -72,7 +74,7 @@ module JSON::LD
|
|
72
74
|
# Complete open statements
|
73
75
|
# @return [void] `self`
|
74
76
|
def stream_epilogue
|
75
|
-
log_debug("epilogue") {"state: #{@state.inspect}"}
|
77
|
+
#log_debug("epilogue") {"state: #{@state.inspect}"}
|
76
78
|
end_graph
|
77
79
|
if context
|
78
80
|
@output.puts "\n]}"
|
@@ -85,7 +87,7 @@ module JSON::LD
|
|
85
87
|
private
|
86
88
|
|
87
89
|
def start_graph(resource)
|
88
|
-
log_debug("start_graph") {"state: #{@state.inspect}, resource: #{resource}"}
|
90
|
+
#log_debug("start_graph") {"state: #{@state.inspect}, resource: #{resource}"}
|
89
91
|
if resource
|
90
92
|
@output.puts(",") if [:wrote_node, :wrote_graph].include?(@state)
|
91
93
|
@output.puts %({"@id": "#{resource}", "@graph": [)
|
@@ -95,7 +97,7 @@ module JSON::LD
|
|
95
97
|
end
|
96
98
|
|
97
99
|
def end_graph
|
98
|
-
log_debug("end_graph") {"state: #{@state.inspect}, ctx: #{@current_graph}"}
|
100
|
+
#log_debug("end_graph") {"state: #{@state.inspect}, ctx: #{@current_graph}"}
|
99
101
|
end_node
|
100
102
|
if @current_graph
|
101
103
|
@output.write %(]})
|
@@ -104,7 +106,7 @@ module JSON::LD
|
|
104
106
|
end
|
105
107
|
|
106
108
|
def end_node
|
107
|
-
log_debug("end_node") {"state: #{@state.inspect}, node: #{@current_node_def.to_json}"}
|
109
|
+
#log_debug("end_node") {"state: #{@state.inspect}, node: #{@current_node_def.to_json}"}
|
108
110
|
@output.puts(",") if [:wrote_node, :wrote_graph].include?(@state)
|
109
111
|
if @current_node_def
|
110
112
|
node_def = if context
|
data/lib/json/ld/to_rdf.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
1
3
|
require 'rdf'
|
2
4
|
require 'rdf/nquads'
|
3
5
|
|
@@ -38,14 +40,14 @@ module JSON::LD
|
|
38
40
|
end
|
39
41
|
|
40
42
|
subject = item['@id'] ? as_resource(item['@id']) : node
|
41
|
-
log_debug("item_to_rdf") {"subject: #{subject.to_ntriples rescue 'malformed rdf'}"}
|
43
|
+
#log_debug("item_to_rdf") {"subject: #{subject.to_ntriples rescue 'malformed rdf'}"}
|
42
44
|
item.each do |property, values|
|
43
45
|
case property
|
44
46
|
when '@type'
|
45
47
|
# If property is @type, construct triple as an RDF Triple composed of id, rdf:type, and object from values where id and object are represented either as IRIs or Blank Nodes
|
46
48
|
values.each do |v|
|
47
49
|
object = as_resource(v)
|
48
|
-
log_debug("item_to_rdf") {"type: #{object.to_ntriples rescue 'malformed rdf'}"}
|
50
|
+
#log_debug("item_to_rdf") {"type: #{object.to_ntriples rescue 'malformed rdf'}"}
|
49
51
|
yield RDF::Statement(subject, RDF.type, object, graph_name: graph_name)
|
50
52
|
end
|
51
53
|
when '@graph'
|
@@ -57,11 +59,11 @@ module JSON::LD
|
|
57
59
|
raise "Huh?" unless values.is_a?(Hash)
|
58
60
|
values.each do |prop, vv|
|
59
61
|
predicate = as_resource(prop)
|
60
|
-
log_debug("item_to_rdf") {"@reverse predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
|
62
|
+
#log_debug("item_to_rdf") {"@reverse predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
|
61
63
|
# For each item in values
|
62
64
|
vv.each do |v|
|
63
65
|
if list?(v)
|
64
|
-
log_debug("item_to_rdf") {"list: #{v.inspect}"}
|
66
|
+
#log_debug("item_to_rdf") {"list: #{v.inspect}"}
|
65
67
|
# If item is a list object, initialize list_results as an empty array, and object to the result of the List Conversion algorithm, passing the value associated with the @list key from item and list_results.
|
66
68
|
object = parse_list(v['@list'], graph_name: graph_name, &block)
|
67
69
|
|
@@ -70,7 +72,7 @@ module JSON::LD
|
|
70
72
|
else
|
71
73
|
# Otherwise, item is a value object or a node definition. Generate object as the result of the Object Converstion algorithm passing item.
|
72
74
|
object = item_to_rdf(v, graph_name: graph_name, &block)
|
73
|
-
log_debug("item_to_rdf") {"subject: #{object.to_ntriples rescue 'malformed rdf'}"}
|
75
|
+
#log_debug("item_to_rdf") {"subject: #{object.to_ntriples rescue 'malformed rdf'}"}
|
74
76
|
# yield subject, prediate, and literal to results.
|
75
77
|
yield RDF::Statement(object, predicate, subject, graph_name: graph_name)
|
76
78
|
end
|
@@ -82,12 +84,12 @@ module JSON::LD
|
|
82
84
|
# Otherwise, property is an IRI or Blank Node identifier
|
83
85
|
# Initialize predicate from property as an IRI or Blank node
|
84
86
|
predicate = as_resource(property)
|
85
|
-
log_debug("item_to_rdf") {"predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
|
87
|
+
#log_debug("item_to_rdf") {"predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
|
86
88
|
|
87
89
|
# For each item in values
|
88
90
|
values.each do |v|
|
89
91
|
if list?(v)
|
90
|
-
log_debug("item_to_rdf") {"list: #{v.inspect}"}
|
92
|
+
#log_debug("item_to_rdf") {"list: #{v.inspect}"}
|
91
93
|
# If item is a list object, initialize list_results as an empty array, and object to the result of the List Conversion algorithm, passing the value associated with the @list key from item and list_results.
|
92
94
|
object = parse_list(v['@list'], graph_name: graph_name, &block)
|
93
95
|
|
@@ -96,7 +98,7 @@ module JSON::LD
|
|
96
98
|
else
|
97
99
|
# Otherwise, item is a value object or a node definition. Generate object as the result of the Object Converstion algorithm passing item.
|
98
100
|
object = item_to_rdf(v, graph_name: graph_name, &block)
|
99
|
-
log_debug("item_to_rdf") {"object: #{object.to_ntriples rescue 'malformed rdf'}"}
|
101
|
+
#log_debug("item_to_rdf") {"object: #{object.to_ntriples rescue 'malformed rdf'}"}
|
100
102
|
# yield subject, prediate, and literal to results.
|
101
103
|
yield RDF::Statement(subject, predicate, object, graph_name: graph_name)
|
102
104
|
end
|
@@ -117,7 +119,7 @@ module JSON::LD
|
|
117
119
|
# @return [Array<RDF::Statement>]
|
118
120
|
# Statements for each item in the list
|
119
121
|
def parse_list(list, graph_name: nil, &block)
|
120
|
-
log_debug('parse_list') {"list: #{list.inspect}"}
|
122
|
+
#log_debug('parse_list') {"list: #{list.inspect}"}
|
121
123
|
|
122
124
|
last = list.pop
|
123
125
|
result = first_bnode = last ? node : RDF.nil
|
data/lib/json/ld/utils.rb
CHANGED
data/lib/json/ld/version.rb
CHANGED
data/lib/json/ld/writer.rb
CHANGED
data/spec/context_spec.rb
CHANGED
@@ -92,6 +92,27 @@ describe JSON::LD::Context do
|
|
92
92
|
expect(ec.provided_context).to produce(ctx, logger)
|
93
93
|
end
|
94
94
|
end
|
95
|
+
|
96
|
+
context "pre-loaded remote" do
|
97
|
+
let(:ctx) {"http://example.com/preloaded"}
|
98
|
+
before(:all) {
|
99
|
+
JSON::LD::Context.add_preloaded("http://example.com/preloaded",
|
100
|
+
JSON::LD::Context.new().parse({'foo' => "http://example.com/"})
|
101
|
+
)}
|
102
|
+
after(:all) {JSON::LD::Context::PRELOADED.clear}
|
103
|
+
|
104
|
+
it "does not load referenced context" do
|
105
|
+
expect(JSON::LD::API).not_to receive(:documentLoader).with(ctx, anything)
|
106
|
+
ec = subject.parse(ctx)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "uses loaded context" do
|
110
|
+
ec = subject.parse(ctx)
|
111
|
+
expect(ec.send(:mappings)).to produce({
|
112
|
+
"foo" => "http://example.com/"
|
113
|
+
}, logger)
|
114
|
+
end
|
115
|
+
end
|
95
116
|
end
|
96
117
|
|
97
118
|
context "Array" do
|
@@ -356,6 +377,7 @@ describe JSON::LD::Context do
|
|
356
377
|
"@language" => "en"
|
357
378
|
}
|
358
379
|
}, logger)
|
380
|
+
expect(subject.to_rb).not_to be_empty
|
359
381
|
end
|
360
382
|
|
361
383
|
it "@vocab" do
|
@@ -365,16 +387,18 @@ describe JSON::LD::Context do
|
|
365
387
|
"@vocab" => "http://example.com/"
|
366
388
|
}
|
367
389
|
}, logger)
|
390
|
+
expect(subject.to_rb).not_to be_empty
|
368
391
|
end
|
369
392
|
|
370
393
|
it "term mappings" do
|
371
|
-
|
372
|
-
parse({'foo' => "http://example.com/"}).send(:clear_provided_context)
|
373
|
-
|
394
|
+
c = subject.
|
395
|
+
parse({'foo' => "http://example.com/"}).send(:clear_provided_context)
|
396
|
+
expect(c.serialize).to produce({
|
374
397
|
"@context" => {
|
375
398
|
"foo" => "http://example.com/"
|
376
399
|
}
|
377
400
|
}, logger)
|
401
|
+
expect(c.to_rb).not_to be_empty
|
378
402
|
end
|
379
403
|
|
380
404
|
it "@type with dependent prefixes in a single context" do
|
@@ -1332,4 +1356,50 @@ describe JSON::LD::Context do
|
|
1332
1356
|
expect(subject.reverse_term('reverse')).to eql subject.term_definitions['ex']
|
1333
1357
|
end
|
1334
1358
|
end
|
1359
|
+
|
1360
|
+
describe JSON::LD::Context::TermDefinition do
|
1361
|
+
context "with nothing" do
|
1362
|
+
subject {described_class.new("term")}
|
1363
|
+
its(:term) {is_expected.to eq "term"}
|
1364
|
+
its(:id) {is_expected.to be_nil}
|
1365
|
+
its(:to_rb) {is_expected.to eq %(TermDefinition.new("term"))}
|
1366
|
+
end
|
1367
|
+
|
1368
|
+
context "with id" do
|
1369
|
+
subject {described_class.new("term", id: "http://example.org/term")}
|
1370
|
+
its(:term) {is_expected.to eq "term"}
|
1371
|
+
its(:id) {is_expected.to eq "http://example.org/term"}
|
1372
|
+
its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", id: "http://example.org/term"))}
|
1373
|
+
end
|
1374
|
+
|
1375
|
+
context "with type_mapping" do
|
1376
|
+
subject {described_class.new("term", type_mapping: "http://example.org/type")}
|
1377
|
+
its(:type_mapping) {is_expected.to eq "http://example.org/type"}
|
1378
|
+
its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", type_mapping: "http://example.org/type"))}
|
1379
|
+
end
|
1380
|
+
|
1381
|
+
context "with container_mapping" do
|
1382
|
+
subject {described_class.new("term", container_mapping: "@set")}
|
1383
|
+
its(:container_mapping) {is_expected.to eq "@set"}
|
1384
|
+
its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", container_mapping: "@set"))}
|
1385
|
+
end
|
1386
|
+
|
1387
|
+
context "with language_mapping" do
|
1388
|
+
subject {described_class.new("term", language_mapping: "en")}
|
1389
|
+
its(:language_mapping) {is_expected.to eq "en"}
|
1390
|
+
its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", language_mapping: "en"))}
|
1391
|
+
end
|
1392
|
+
|
1393
|
+
context "with reverse_property" do
|
1394
|
+
subject {described_class.new("term", reverse_property: true)}
|
1395
|
+
its(:reverse_property) {is_expected.to be_truthy}
|
1396
|
+
its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", reverse_property: true))}
|
1397
|
+
end
|
1398
|
+
|
1399
|
+
context "with simple" do
|
1400
|
+
subject {described_class.new("term", simple: true)}
|
1401
|
+
its(:simple) {is_expected.to be_truthy}
|
1402
|
+
its(:to_rb) {is_expected.to eq %(TermDefinition.new("term", simple: true))}
|
1403
|
+
end
|
1404
|
+
end
|
1335
1405
|
end
|
data/spec/frame_spec.rb
CHANGED
@@ -512,7 +512,7 @@ describe JSON::LD::API do
|
|
512
512
|
end
|
513
513
|
end
|
514
514
|
|
515
|
-
describe "@reverse"
|
515
|
+
describe "@reverse" do
|
516
516
|
{
|
517
517
|
"embed matched frames with @reverse" => {
|
518
518
|
frame: {
|
@@ -550,6 +550,44 @@ describe JSON::LD::API do
|
|
550
550
|
}]
|
551
551
|
}
|
552
552
|
},
|
553
|
+
"embed matched frames with reversed property" => {
|
554
|
+
frame: {
|
555
|
+
"@context" => {
|
556
|
+
"ex" => "http://example.org/",
|
557
|
+
"excludes" => {"@reverse" => "ex:includes"}
|
558
|
+
},
|
559
|
+
"@type" => "ex:Type1",
|
560
|
+
"excludes" => {}
|
561
|
+
},
|
562
|
+
input: [
|
563
|
+
{
|
564
|
+
"@context" => {"ex" => "http://example.org/"},
|
565
|
+
"@id" => "ex:Sub1",
|
566
|
+
"@type" => "ex:Type1"
|
567
|
+
},
|
568
|
+
{
|
569
|
+
"@context" => {"ex" => "http://example.org/"},
|
570
|
+
"@id" => "ex:Sub2",
|
571
|
+
"@type" => "ex:Type2",
|
572
|
+
"ex:includes" => {"@id" => "ex:Sub1"}
|
573
|
+
},
|
574
|
+
],
|
575
|
+
output:{
|
576
|
+
"@context" => {
|
577
|
+
"ex" => "http://example.org/",
|
578
|
+
"excludes" => {"@reverse" => "ex:includes"}
|
579
|
+
},
|
580
|
+
"@graph" => [{
|
581
|
+
"@id" => "ex:Sub1",
|
582
|
+
"@type" => "ex:Type1",
|
583
|
+
"excludes" => {
|
584
|
+
"@id" => "ex:Sub2",
|
585
|
+
"@type" => "ex:Type2",
|
586
|
+
"ex:includes" => {"@id" => "ex:Sub1"}
|
587
|
+
}
|
588
|
+
}]
|
589
|
+
}
|
590
|
+
},
|
553
591
|
}.each do |title, params|
|
554
592
|
it title do
|
555
593
|
begin
|
@@ -583,5 +621,63 @@ describe JSON::LD::API do
|
|
583
621
|
data = framed["@graph"].first
|
584
622
|
expect(data["mising_value"]).to be_nil
|
585
623
|
end
|
624
|
+
|
625
|
+
it "issue #28" do
|
626
|
+
input = JSON.parse %({
|
627
|
+
"@context": {
|
628
|
+
"rdfs": "http://www.w3.org/2000/01/rdf-schema#"
|
629
|
+
},
|
630
|
+
"@id": "http://www.myresource/uuid",
|
631
|
+
"http://www.myresource.com/ontology/1.0#talksAbout": [
|
632
|
+
{
|
633
|
+
"@id": "http://rdf.freebase.com/ns/m.018w8",
|
634
|
+
"rdfs:label": [
|
635
|
+
{
|
636
|
+
"@value": "Basketball",
|
637
|
+
"@language": "en"
|
638
|
+
}
|
639
|
+
]
|
640
|
+
}
|
641
|
+
]
|
642
|
+
})
|
643
|
+
frame = JSON.parse %({
|
644
|
+
"@context": {
|
645
|
+
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
|
646
|
+
"talksAbout": {
|
647
|
+
"@id": "http://www.myresource.com/ontology/1.0#talksAbout",
|
648
|
+
"@type": "@id"
|
649
|
+
},
|
650
|
+
"label": {
|
651
|
+
"@id": "rdfs:label",
|
652
|
+
"@language": "en"
|
653
|
+
}
|
654
|
+
},
|
655
|
+
"@id": "http://www.myresource/uuid"
|
656
|
+
})
|
657
|
+
expected = JSON.parse %({
|
658
|
+
"@context": {
|
659
|
+
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
|
660
|
+
"talksAbout": {
|
661
|
+
"@id": "http://www.myresource.com/ontology/1.0#talksAbout",
|
662
|
+
"@type": "@id"
|
663
|
+
},
|
664
|
+
"label": {
|
665
|
+
"@id": "rdfs:label",
|
666
|
+
"@language": "en"
|
667
|
+
}
|
668
|
+
},
|
669
|
+
"@graph": [
|
670
|
+
{
|
671
|
+
"@id": "http://www.myresource/uuid",
|
672
|
+
"talksAbout": {
|
673
|
+
"@id": "http://rdf.freebase.com/ns/m.018w8",
|
674
|
+
"label": "Basketball"
|
675
|
+
}
|
676
|
+
}
|
677
|
+
]
|
678
|
+
})
|
679
|
+
framed = JSON::LD::API.frame(input, frame, logger: logger)
|
680
|
+
expect(framed).to produce(expected, logger)
|
681
|
+
end
|
586
682
|
end
|
587
683
|
end
|