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.
@@ -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? && !@options[:useRdfType]
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
@@ -1,3 +1,5 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # frozen_string_literal: true
1
3
  module JSON::LD
2
4
  ##
3
5
  # A JSON-LD parser in Ruby.
@@ -1,3 +1,5 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # frozen_string_literal: true
1
3
  module JSON::LD
2
4
  # Simple Ruby reflector class to provide native
3
5
  # access to JSON-LD objects
@@ -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
@@ -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
@@ -1,3 +1,5 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # frozen_string_literal: true
1
3
  module JSON::LD
2
4
  module Utils
3
5
  ##
@@ -1,3 +1,5 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # frozen_string_literal: true
1
3
  module JSON::LD::VERSION
2
4
  VERSION_FILE = File.join(File.expand_path(File.dirname(__FILE__)), "..", "..", "..", "VERSION")
3
5
  MAJOR, MINOR, TINY, EXTRA = File.read(VERSION_FILE).chomp.split(".")
@@ -1,3 +1,5 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # frozen_string_literal: true
1
3
  require 'json/ld/streaming_writer'
2
4
  module JSON::LD
3
5
  ##
@@ -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
- expect(subject.
372
- parse({'foo' => "http://example.com/"}).send(:clear_provided_context).
373
- serialize).to produce({
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
@@ -512,7 +512,7 @@ describe JSON::LD::API do
512
512
  end
513
513
  end
514
514
 
515
- describe "@reverse", skip:true do
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