# coding: utf-8 require_relative 'spec_helper' describe JSON::LD::API do let(:logger) {RDF::Spec.logger} describe ".frame" do { "exact @type match": { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": "ex:Type1" }), input: %([ { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub2", "@type": "ex:Type2" } ]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1" }] }) }, "wildcard @type match": { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": {} }), input: %([ { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub2", "@type": "ex:Type2" } ]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1" }, { "@id": "ex:Sub2", "@type": "ex:Type2" }] }) }, "match none @type match": { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": [] }), input: %([ { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1", "ex:p": "Foo" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub2", "ex:p": "Bar" } ]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub2", "ex:p": "Bar" }] }) }, "multiple matches on @type": { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": "ex:Type1" }), input: %([{ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1" }, { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub2", "@type": "ex:Type1" }, { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub3", "@type": ["ex:Type1", "ex:Type2"] }]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1" }, { "@id": "ex:Sub2", "@type": "ex:Type1" }, { "@id": "ex:Sub3", "@type": ["ex:Type1", "ex:Type2"] }] }) }, "single @id match": { frame: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1" }), input: %([ { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub2", "@type": "ex:Type2" } ]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1" }] }) }, "multiple @id match": { frame: %({ "@context": {"ex": "http://example.org/"}, "@id": ["ex:Sub1", "ex:Sub2"] }), input: %([ { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub2", "@type": "ex:Type2" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub3", "@type": "ex:Type3" } ]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1" }, { "@id": "ex:Sub2", "@type": "ex:Type2" }] }) }, "wildcard and match none": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": [], "ex:q": {} }), input: %([ { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:q": "bar" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub2", "ex:p": "foo", "ex:q": "bar" } ]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:p": null, "ex:q": "bar" }] }) }, "match on any property if @requireAll is false": { frame: %({ "@context": {"ex": "http://example.org/"}, "@requireAll": false, "ex:p": {}, "ex:q": {} }), input: %([ { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:p": "foo" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub2", "ex:q": "bar" } ]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:p": "foo", "ex:q": null }, { "@id": "ex:Sub2", "ex:p": null, "ex:q": "bar" }] }) }, "match on defeaults if @requireAll is true and at least one property matches": { frame: %({ "@context": {"ex": "http://example.org/"}, "@requireAll": true, "ex:p": {"@default": "Foo"}, "ex:q": {"@default": "Bar"} }), input: %([ { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:p": "foo" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub2", "ex:q": "bar" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub3", "ex:p": "foo", "ex:q": "bar" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub4", "ex:r": "baz" } ]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:p": "foo", "ex:q": "Bar" }, { "@id": "ex:Sub2", "ex:p": "Foo", "ex:q": "bar" }, { "@id": "ex:Sub3", "ex:p": "foo", "ex:q": "bar" }] }) }, "match with @requireAll with one default": { frame: %({ "@context": {"ex": "http://example.org/"}, "@requireAll": true, "ex:p": {}, "ex:q": {"@default": "Bar"} }), input: %([ { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:p": "foo" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub2", "ex:q": "bar" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub3", "ex:p": "foo", "ex:q": "bar" } ]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:p": "foo", "ex:q": "Bar" }, { "@id": "ex:Sub3", "ex:p": "foo", "ex:q": "bar" }] }) }, "don't match with @requireAll, matching @type but no matching property": { frame: %({ "@context": {"ex": "http://example.org/"}, "@requireAll": true, "@type": "ex:Type", "ex:p": {} }), input: %([ { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type", "ex:p": "foo" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub2", "@type": "ex:Type" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub3", "ex:p": "foo" } ]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type", "ex:p": "foo" }] }) }, "don't match with @requireAll, matching @id but no matching @type": { frame: %({ "@context": {"ex": "http://example.org/"}, "@requireAll": true, "@id": ["ex:Sub1", "ex:Sub2"], "@type": "ex:Type" }), input: %([ { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type", "ex:p": "foo" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub2", "@type": "ex:OtherType" }, { "@context": { "ex":"http://example.org/"}, "@id": "ex:Sub3", "@type": "ex:Type", "ex:p": "foo" } ]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type", "ex:p": "foo" }] }) }, "issue #40 - example": { frame: %({ "@context": { "@version": 1.1, "@vocab": "https://schema.org/" }, "@type": "Person", "@requireAll": true, "givenName": "John", "familyName": "Doe" }), input: %({ "@context": { "@version": 1.1, "@vocab": "https://schema.org/" }, "@graph": [ { "@id": "1", "@type": "Person", "name": "John Doe", "givenName": "John", "familyName": "Doe" }, { "@id": "2", "@type": "Person", "name": "Jane Doe", "givenName": "Jane" } ] }), output: %({ "@context": { "@version": 1.1, "@vocab": "https://schema.org/" }, "@id": "1", "@type": "Person", "familyName": "Doe", "givenName": "John", "name": "John Doe" }), processingMode: 'json-ld-1.1' }, "implicitly includes unframed properties (default @explicit false)": { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": "ex:Type1" }), input: %q({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1", "ex:prop1": "Property 1", "ex:prop2": {"@id": "ex:Obj1"} }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1", "ex:prop1": "Property 1", "ex:prop2": {"@id": "ex:Obj1"} }] }) }, "explicitly includes unframed properties @explicit false": { frame: %({ "@context": {"ex": "http://example.org/"}, "@explicit": false, "@type": "ex:Type1" }), input: %q({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1", "ex:prop1": "Property 1", "ex:prop2": {"@id": "ex:Obj1"} }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1", "ex:prop1": "Property 1", "ex:prop2": {"@id": "ex:Obj1"} }] }) }, "explicitly excludes unframed properties (@explicit: true)": { frame: %({ "@context": {"ex": "http://example.org/"}, "@explicit": true, "@type": "ex:Type1" }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1", "ex:prop1": "Property 1", "ex:prop2": {"@id": "ex:Obj1"} }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1" }] }) }, "non-existent framed properties create null property": { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": "ex:Type1", "ex:null": [] }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1", "ex:prop1": "Property 1", "ex:prop2": {"@id": "ex:Obj1"} }), output: %({ "@context": { "ex": "http://example.org/" }, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1", "ex:prop1": "Property 1", "ex:prop2": { "@id": "ex:Obj1" }, "ex:null": null }] }) }, "non-existent framed properties create default property": { frame: %({ "@context": { "ex": "http://example.org/", "ex:null": {"@container": "@set"} }, "@type": "ex:Type1", "ex:null": [{"@default": "foo"}] }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1", "ex:prop1": "Property 1", "ex:prop2": {"@id": "ex:Obj1"} }), output: %({ "@context": { "ex": "http://example.org/", "ex:null": {"@container": "@set"} }, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1", "ex:prop1": "Property 1", "ex:prop2": {"@id": "ex:Obj1"}, "ex:null": ["foo"] }] }) }, "default value for @type": { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": {"@default": "ex:Foo"}, "ex:foo": "bar" }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:foo": "bar" }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Foo", "ex:foo": "bar" }] }) }, "mixed content": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:mixed": {"@embed": "@never"} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:mixed": [ {"@id": "ex:Sub2"}, "literal1" ] }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:mixed": [ {"@id": "ex:Sub2"}, "literal1" ] }] }) }, "no embedding (@embed: @never)": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:embed": {"@embed": "@never"} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:embed": { "@id": "ex:Sub2", "ex:prop": "property" } }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:embed": {"@id": "ex:Sub2"} }] }) }, "first embed (@embed: @once)": { frame: %({ "@context": {"ex": "http://www.example.com/#"}, "@type": "ex:Thing", "@embed": "@once" }), input: %({ "@context": {"ex": "http://www.example.com/#"}, "@id": "http://example/outer", "@type": "ex:Thing", "ex:embed1": {"@id": "http://example/embedded", "ex:name": "Embedded"}, "ex:embed2": {"@id": "http://example/embedded", "ex:name": "Embedded"} }), output: %({ "@context": {"ex": "http://www.example.com/#"}, "@graph": [ { "@id": "http://example/outer", "@type": "ex:Thing", "ex:embed1": {"@id": "http://example/embedded", "ex:name": "Embedded"}, "ex:embed2": {"@id": "http://example/embedded"} } ] }), ordered: true }, "always embed (@embed: @always)": { frame: %({ "@context": {"ex": "http://www.example.com/#"}, "@type": "ex:Thing", "@embed": "@always" }), input: %({ "@context": {"ex": "http://www.example.com/#"}, "@id": "http://example/outer", "@type": "ex:Thing", "ex:embed1": {"@id": "http://example/embedded", "ex:name": "Embedded"}, "ex:embed2": {"@id": "http://example/embedded", "ex:name": "Embedded"} }), output: %({ "@context": {"ex": "http://www.example.com/#"}, "@graph": [ { "@id": "http://example/outer", "@type": "ex:Thing", "ex:embed1": {"@id": "http://example/embedded", "ex:name": "Embedded"}, "ex:embed2": {"@id": "http://example/embedded", "ex:name": "Embedded"} } ] }) }, "mixed list": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:mixedlist": {} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1", "ex:mixedlist": { "@list": [ {"@id": "ex:Sub2", "@type": "ex:Type2"}, "literal1" ] } }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1", "ex:mixedlist": { "@list": [ {"@id": "ex:Sub2", "@type": "ex:Type2"}, "literal1" ] } }] }) }, "framed list": { frame: %({ "@context": { "ex": "http://example.org/", "list": {"@id": "ex:list", "@container": "@list"} }, "list": [{"@type": "ex:Element"}] }), input: %({ "@context": { "ex": "http://example.org/", "list": {"@id": "ex:list", "@container": "@list"} }, "@id": "ex:Sub1", "@type": "ex:Type1", "list": [ {"@id": "ex:Sub2", "@type": "ex:Element"}, "literal1" ] }), output: %({ "@context": { "ex": "http://example.org/", "list": {"@id": "ex:list", "@container": "@list"} }, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1", "list": [ {"@id": "ex:Sub2", "@type": "ex:Element"}, "literal1" ] }] }) }, "presentation example": { frame: %({ "@context": { "primaryTopic": { "@id": "http://xmlns.com/foaf/0.1/primaryTopic", "@type": "@id" }, "sameAs": { "@id": "http://www.w3.org/2002/07/owl#sameAs", "@type": "@id" } }, "primaryTopic": { "@type": "http://dbpedia.org/class/yago/Buzzwords", "sameAs": {} } }), input: %([{ "@id": "http://en.wikipedia.org/wiki/Linked_Data", "http://xmlns.com/foaf/0.1/primaryTopic": {"@id": "http://dbpedia.org/resource/Linked_Data"} }, { "@id": "http://www4.wiwiss.fu-berlin.de/flickrwrappr/photos/Linked_Data", "http://www.w3.org/2002/07/owl#sameAs": {"@id": "http://dbpedia.org/resource/Linked_Data"} }, { "@id": "http://dbpedia.org/resource/Linked_Data", "@type": "http://dbpedia.org/class/yago/Buzzwords", "http://www.w3.org/2002/07/owl#sameAs": {"@id": "http://rdf.freebase.com/ns/m/02r2kb1"} }, { "@id": "http://mpii.de/yago/resource/Linked_Data", "http://www.w3.org/2002/07/owl#sameAs": {"@id": "http://dbpedia.org/resource/Linked_Data"} } ]), output: %({ "@context": { "primaryTopic": {"@id": "http://xmlns.com/foaf/0.1/primaryTopic", "@type": "@id"}, "sameAs": {"@id": "http://www.w3.org/2002/07/owl#sameAs", "@type": "@id"} }, "@graph": [{ "@id": "http://en.wikipedia.org/wiki/Linked_Data", "primaryTopic": { "@id": "http://dbpedia.org/resource/Linked_Data", "@type": "http://dbpedia.org/class/yago/Buzzwords", "sameAs": "http://rdf.freebase.com/ns/m/02r2kb1" } }] }) }, "microdata manifest": { frame: %({ "@context": { "xsd": "http://www.w3.org/2001/XMLSchema#", "rdfs": "http://www.w3.org/2000/01/rdf-schema#", "mf": "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#", "mq": "http://www.w3.org/2001/sw/DataAccess/tests/test-query#", "comment": "rdfs:comment", "entries": {"@id": "mf:entries", "@container": "@list"}, "name": "mf:name", "action": "mf:action", "data": {"@id": "mq:data", "@type": "@id"}, "query": {"@id": "mq:query", "@type": "@id"}, "result": {"@id": "mf:result", "@type": "xsd:boolean"} }, "@type": "mf:Manifest", "entries": [{ "@type": "mf:ManifestEntry", "action": { "@type": "mq:QueryTest" } }] }), input: %q({ "@context": { "md": "http://www.w3.org/ns/md#", "mf": "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#", "mq": "http://www.w3.org/2001/sw/DataAccess/tests/test-query#", "rdfs": "http://www.w3.org/2000/01/rdf-schema#" }, "@graph": [{ "@id": "_:manifest", "@type": "mf:Manifest", "mf:entries": {"@list": [{"@id": "_:entry"}]}, "rdfs:comment": "Positive processor tests" }, { "@id": "_:entry", "@type": "mf:ManifestEntry", "mf:action": {"@id": "_:query"}, "mf:name": "Test 0001", "mf:result": "true", "rdfs:comment": "Item with no itemtype and literal itemprop" }, { "@id": "_:query", "@type": "mq:QueryTest", "mq:data": {"@id": "http://www.w3.org/TR/microdata-rdf/tests/0001.html"}, "mq:query": {"@id": "http://www.w3.org/TR/microdata-rdf/tests/0001.ttl"} }] }), output: %({ "@context": { "xsd": "http://www.w3.org/2001/XMLSchema#", "rdfs": "http://www.w3.org/2000/01/rdf-schema#", "mf": "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#", "mq": "http://www.w3.org/2001/sw/DataAccess/tests/test-query#", "comment": "rdfs:comment", "entries": {"@id": "mf:entries","@container": "@list"}, "name": "mf:name", "action": "mf:action", "data": {"@id": "mq:data", "@type": "@id"}, "query": {"@id": "mq:query", "@type": "@id"}, "result": {"@id": "mf:result", "@type": "xsd:boolean"} }, "@type": "mf:Manifest", "comment": "Positive processor tests", "entries": [{ "@type": "mf:ManifestEntry", "action": { "@type": "mq:QueryTest", "data": "http://www.w3.org/TR/microdata-rdf/tests/0001.html", "query": "http://www.w3.org/TR/microdata-rdf/tests/0001.ttl" }, "comment": "Item with no itemtype and literal itemprop", "mf:result": "true", "name": "Test 0001" }] }), processingMode: 'json-ld-1.1' }, "library": { frame: %({ "@context": { "dc": "http://purl.org/dc/elements/1.1/", "ex": "http://example.org/vocab#", "xsd": "http://www.w3.org/2001/XMLSchema#", "ex:contains": { "@type": "@id" } }, "@type": "ex:Library", "ex:contains": {} }), input: %({ "@context": { "dc": "http://purl.org/dc/elements/1.1/", "ex": "http://example.org/vocab#", "xsd": "http://www.w3.org/2001/XMLSchema#" }, "@id": "http://example.org/library", "@type": "ex:Library", "dc:name": "Library", "ex:contains": { "@id": "http://example.org/library/the-republic", "@type": "ex:Book", "dc:creator": "Plato", "dc:title": "The Republic", "ex:contains": { "@id": "http://example.org/library/the-republic#introduction", "@type": "ex:Chapter", "dc:description": "An introductory chapter on The Republic.", "dc:title": "The Introduction" } } }), output: %({ "@context": { "dc": "http://purl.org/dc/elements/1.1/", "ex": "http://example.org/vocab#", "xsd": "http://www.w3.org/2001/XMLSchema#", "ex:contains": { "@type": "@id" } }, "@graph": [ { "@id": "http://example.org/library", "@type": "ex:Library", "dc:name": "Library", "ex:contains": { "@id": "http://example.org/library/the-republic", "@type": "ex:Book", "dc:creator": "Plato", "dc:title": "The Republic", "ex:contains": { "@id": "http://example.org/library/the-republic#introduction", "@type": "ex:Chapter", "dc:description": "An introductory chapter on The Republic.", "dc:title": "The Introduction" } } } ] }) } }.each do |title, params| it title do do_frame(params) end end describe "@reverse" do { "embed matched frames with @reverse": { frame: %({ "@context": {"ex": "http://example.org/"}, "@type": "ex:Type1", "@reverse": {"ex:includes": {}} }), input: %([{ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1" }, { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub2", "@type": "ex:Type2", "ex:includes": {"@id": "ex:Sub1"} }]), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1", "@reverse": { "ex:includes": { "@id": "ex:Sub2", "@type": "ex:Type2", "ex:includes": { "@id": "ex:Sub1" } } } }] }) }, "embed matched frames with reversed property": { frame: %({ "@context": { "ex": "http://example.org/", "excludes": {"@reverse": "ex:includes"} }, "@type": "ex:Type1", "excludes": {} }), input: %([{ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "@type": "ex:Type1" }, { "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub2", "@type": "ex:Type2", "ex:includes": {"@id": "ex:Sub1"} }]), output: %({ "@context": { "ex": "http://example.org/", "excludes": {"@reverse": "ex:includes"} }, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1", "excludes": { "@id": "ex:Sub2", "@type": "ex:Type2", "ex:includes": {"@id": "ex:Sub1"} } }] }) }, }.each do |title, params| it title do do_frame(params) end end end context "omitGraph option" do { "Defaults to false in 1.0": { input: %([{ "http://example.org/prop": [{"@value": "value"}], "http://example.org/foo": [{"@value": "bar"}] }]), frame: %({ "@context": { "@vocab": "http://example.org/" } }), output: %({ "@context": { "@vocab": "http://example.org/" }, "@graph": [{ "foo": "bar", "prop": "value" }] }), processingMode: "json-ld-1.0" }, "Set with option in 1.0": { input: %([{ "http://example.org/prop": [{"@value": "value"}], "http://example.org/foo": [{"@value": "bar"}] }]), frame: %({ "@context": { "@vocab": "http://example.org/" } }), output: %({ "@context": { "@vocab": "http://example.org/" }, "foo": "bar", "prop": "value" }), processingMode: "json-ld-1.0", omitGraph: true }, "Defaults to true in 1.1": { input: %([{ "http://example.org/prop": [{"@value": "value"}], "http://example.org/foo": [{"@value": "bar"}] }]), frame: %({ "@context": { "@vocab": "http://example.org/" } }), output: %({ "@context": { "@vocab": "http://example.org/" }, "foo": "bar", "prop": "value" }), processingMode: "json-ld-1.1" }, "Set with option in 1.1": { input: %([{ "http://example.org/prop": [{"@value": "value"}], "http://example.org/foo": [{"@value": "bar"}] }]), frame: %({ "@context": { "@vocab": "http://example.org/" } }), output: %({ "@context": { "@vocab": "http://example.org/" }, "@graph": [{ "foo": "bar", "prop": "value" }] }), processingMode: "json-ld-1.1", omitGraph: false }, }.each do |title, params| it(title) {do_frame(params.merge(pruneBlankNodeIdentifiers: true))} end end context "@included" do { "Basic Included array": { input: %([{ "http://example.org/prop": [{"@value": "value"}], "http://example.org/foo": [{"@value": "bar"}] }, { "http://example.org/prop": [{"@value": "value2"}], "http://example.org/foo": [{"@value": "bar"}] }]), frame: %({ "@context": { "@version": 1.1, "@vocab": "http://example.org/", "included": {"@id": "@included", "@container": "@set"} }, "@requireAll": true, "foo": "bar", "prop": "value", "@included": [{ "@requireAll": true, "foo": "bar", "prop": "value2" }] }), output: %({ "@context": { "@version": 1.1, "@vocab": "http://example.org/", "included": {"@id": "@included", "@container": "@set"} }, "foo": "bar", "included": [{ "foo": "bar", "prop": "value2" }], "prop": "value" }) }, "Basic Included object": { input: %([{ "http://example.org/prop": [{"@value": "value"}], "http://example.org/foo": [{"@value": "bar"}] }, { "http://example.org/prop": [{"@value": "value2"}], "http://example.org/foo": [{"@value": "bar"}] }]), frame: %({ "@context": { "@version": 1.1, "@vocab": "http://example.org/" }, "@requireAll": true, "foo": "bar", "prop": "value", "@included": [{ "@requireAll": true, "foo": "bar", "prop": "value2" }] }), output: %({ "@context": { "@version": 1.1, "@vocab": "http://example.org/" }, "foo": "bar", "prop": "value", "@included": { "prop": "value2", "foo": "bar" } }) }, "json.api example": { input: %([{ "@id": "http://example.org/base/1", "@type": ["http://example.org/vocab#articles"], "http://example.org/vocab#title": [{"@value": "JSON:API paints my bikeshed!"}], "http://example.org/vocab#self": [{"@id": "http://example.com/articles/1"}], "http://example.org/vocab#author": [{ "@id": "http://example.org/base/9", "@type": ["http://example.org/vocab#people"], "http://example.org/vocab#self": [{"@id": "http://example.com/articles/1/relationships/author"}], "http://example.org/vocab#related": [{"@id": "http://example.com/articles/1/author"}] }], "http://example.org/vocab#comments": [{ "http://example.org/vocab#self": [{"@id": "http://example.com/articles/1/relationships/comments"}], "http://example.org/vocab#related": [{"@id": "http://example.com/articles/1/comments"}] }], "@included": [{ "@id": "http://example.org/base/9", "@type": ["http://example.org/vocab#people"], "http://example.org/vocab#first-name": [{"@value": "Dan"}], "http://example.org/vocab#last-name": [{"@value": "Gebhardt"}], "http://example.org/vocab#twitter": [{"@value": "dgeb"}], "http://example.org/vocab#self": [{"@id": "http://example.com/people/9"}] }, { "@id": "http://example.org/base/5", "@type": ["http://example.org/vocab#comments"], "http://example.org/vocab#body": [{"@value": "First!"}], "http://example.org/vocab#author": [{ "@id": "http://example.org/base/2", "@type": ["http://example.org/vocab#people"] }], "http://example.org/vocab#self": [{"@id": "http://example.com/comments/5"}] }, { "@id": "http://example.org/base/12", "@type": ["http://example.org/vocab#comments"], "http://example.org/vocab#body": [{"@value": "I like XML better"}], "http://example.org/vocab#author": [{ "@id": "http://example.org/base/9", "@type": ["http://example.org/vocab#people"] }], "http://example.org/vocab#self": [{"@id": "http://example.com/comments/12"}] }] }]), frame: %({ "@context": { "@version": 1.1, "@vocab": "http://example.org/vocab#", "@base": "http://example.org/base/", "id": "@id", "type": "@type", "data": "@nest", "attributes": "@nest", "links": "@nest", "relationships": "@nest", "included": "@included", "author": {"@type": "@id"}, "self": {"@type": "@id"}, "related": {"@type": "@id"}, "comments": {"@context": {"data": null}} }, "data": {"type": "articles"}, "included": { "@requireAll": true, "type": ["comments", "people"], "self": {} } }), output: %({ "@context": { "@version": 1.1, "@vocab": "http://example.org/vocab#", "@base": "http://example.org/base/", "id": "@id", "type": "@type", "data": "@nest", "attributes": "@nest", "links": "@nest", "relationships": "@nest", "included": "@included", "author": {"@type": "@id"}, "self": {"@type": "@id"}, "related": {"@type": "@id"}, "comments": {"@context": {"data": null}} }, "id": "1", "type": "articles", "title": "JSON:API paints my bikeshed!", "self": "http://example.com/articles/1", "author": "9", "comments": { "self": "http://example.com/articles/1/relationships/comments", "related": "http://example.com/articles/1/comments" }, "included": [{ "id": "5", "type": "comments", "body": "First!", "author": {"id": "2", "type": "people"}, "self": "http://example.com/comments/5" }, { "id": "9", "type": "people", "first-name": "Dan", "last-name": "Gebhardt", "twitter": "dgeb", "self": [ "http://example.com/people/9", "http://example.com/articles/1/relationships/author" ], "related": "http://example.com/articles/1/author" }, { "id": "12", "type": "comments", "body": "I like XML better", "author": "9", "self": "http://example.com/comments/12" }] }), }, }.each do |title, params| it(title) {do_frame(params.merge(processingMode: 'json-ld-1.1'))} end end describe "node pattern" do { "matches a deep node pattern": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": { "ex:q": {} } }), input: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1", "ex:p": { "@id": "ex:Sub2", "@type": "ex:Type2", "ex:q": "foo" } }, { "@id": "ex:Sub3", "@type": "ex:Type1", "ex:q": { "@id": "ex:Sub4", "@type": "ex:Type2", "ex:r": "bar" } }] }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "@type": "ex:Type1", "ex:p": { "@id": "ex:Sub2", "@type": "ex:Type2", "ex:q": "foo" } }] }) }, }.each do |title, params| it title do do_frame(params) end end end describe "value pattern" do { "matches exact values": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": "P", "ex:q": {"@value": "Q", "@type": "ex:q"}, "ex:r": {"@value": "R", "@language": "r"} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:p": "P", "ex:q": {"@value": "Q", "@type": "ex:q"}, "ex:r": {"@value": "R", "@language": "r"} }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:p": "P", "ex:q": {"@value": "Q", "@type": "ex:q"}, "ex:r": {"@value": "R", "@language": "r"} }] }) }, "matches wildcard @value": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": {"@value": {}}, "ex:q": {"@value": {}, "@type": "ex:q"}, "ex:r": {"@value": {}, "@language": "r"} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:p": "P", "ex:q": {"@value": "Q", "@type": "ex:q"}, "ex:r": {"@value": "R", "@language": "r"} }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:p": "P", "ex:q": {"@value": "Q", "@type": "ex:q"}, "ex:r": {"@value": "R", "@language": "r"} }] }) }, "matches wildcard @type": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:q": {"@value": "Q", "@type": {}} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:q": {"@value": "Q", "@type": "ex:q"} }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:q": {"@value": "Q", "@type": "ex:q"} }] }) }, "matches wildcard @language": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:r": {"@value": "R", "@language": {}} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:r": {"@value": "R", "@language": "r"} }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:r": {"@value": "R", "@language": "r"} }] }) }, "match none @type": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": {"@value": {}, "@type": []}, "ex:q": {"@value": {}, "@type": "ex:q"}, "ex:r": {"@value": {}, "@language": "r"} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:p": "P", "ex:q": {"@value": "Q", "@type": "ex:q"}, "ex:r": {"@value": "R", "@language": "r"} }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:p": "P", "ex:q": {"@value": "Q", "@type": "ex:q"}, "ex:r": {"@value": "R", "@language": "r"} }] }) }, "match none @language": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": {"@value": {}, "@language": []}, "ex:q": {"@value": {}, "@type": "ex:q"}, "ex:r": {"@value": {}, "@language": "r"} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:p": "P", "ex:q": {"@value": "Q", "@type": "ex:q"}, "ex:r": {"@value": "R", "@language": "r"} }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:p": "P", "ex:q": {"@value": "Q", "@type": "ex:q"}, "ex:r": {"@value": "R", "@language": "r"} }] }) }, "matches some @value": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": {"@value": ["P", "Q", "R"]}, "ex:q": {"@value": ["P", "Q", "R"], "@type": "ex:q"}, "ex:r": {"@value": ["P", "Q", "R"], "@language": "r"} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:p": "P", "ex:q": {"@value": "Q", "@type": "ex:q"}, "ex:r": {"@value": "R", "@language": "r"} }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:p": "P", "ex:q": {"@value": "Q", "@type": "ex:q"}, "ex:r": {"@value": "R", "@language": "r"} }] }) }, "matches some @type": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:q": {"@value": "Q", "@type": ["ex:q", "ex:Q"]} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:q": {"@value": "Q", "@type": "ex:q"} }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:q": {"@value": "Q", "@type": "ex:q"} }] }) }, "matches some @language": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:r": {"@value": "R", "@language": ["p", "q", "r"]} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:r": {"@value": "R", "@language": "R"} }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:r": {"@value": "R", "@language": "R"} }] }) }, "excludes non-matched values": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:p": {"@value": {}}, "ex:q": {"@value": {}, "@type": "ex:q"}, "ex:r": {"@value": {}, "@language": "R"} }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:p": ["P", {"@value": "P", "@type": "ex:p"}, {"@value": "P", "@language": "P"}], "ex:q": ["Q", {"@value": "Q", "@type": "ex:q"}, {"@value": "Q", "@language": "Q"}], "ex:r": ["R", {"@value": "R", "@type": "ex:r"}, {"@value": "R", "@language": "R"}] }), output: %({ "@context": {"ex": "http://example.org/"}, "@graph": [{ "@id": "ex:Sub1", "ex:p": "P", "ex:q": {"@value": "Q", "@type": "ex:q"}, "ex:r": {"@value": "R", "@language": "R"} }] }) }, }.each do |title, params| it title do do_frame(params) end end end describe "named graphs" do { "Merge graphs if no outer @graph is used": { frame: %({ "@context": {"@vocab": "urn:"}, "@type": "Class" }), input: %({ "@context": {"@vocab": "urn:"}, "@id": "urn:id-1", "@type": "Class", "preserve": { "@graph": { "@id": "urn:id-2", "term": "data" } } }), output: %({ "@context": {"@vocab": "urn:"}, "@id": "urn:id-1", "@type": "Class", "preserve": {} }), processingMode: 'json-ld-1.1' }, "Frame default graph if outer @graph is used": { frame: %({ "@context": {"@vocab": "urn:"}, "@type": "Class", "@graph": {} }), input: %({ "@context": {"@vocab": "urn:"}, "@id": "urn:id-1", "@type": "Class", "preserve": { "@id": "urn:gr-1", "@graph": { "@id": "urn:id-2", "term": "data" } } }), output: %({ "@context": {"@vocab": "urn:"}, "@id": "urn:id-1", "@type": "Class", "preserve": { "@id": "urn:gr-1", "@graph": { "@id": "urn:id-2", "term": "data" } } }), processingMode: 'json-ld-1.1' }, "Merge one graph and preserve another": { frame: %({ "@context": {"@vocab": "urn:"}, "@type": "Class", "preserve": { "@graph": {} } }), input: %({ "@context": {"@vocab": "urn:"}, "@id": "urn:id-1", "@type": "Class", "merge": { "@id": "urn:id-2", "@graph": { "@id": "urn:id-2", "term": "foo" } }, "preserve": { "@id": "urn:graph-1", "@graph": { "@id": "urn:id-3", "term": "bar" } } }), output: %({ "@context": {"@vocab": "urn:"}, "@id": "urn:id-1", "@type": "Class", "merge": { "@id": "urn:id-2", "term": "foo" }, "preserve": { "@id": "urn:graph-1", "@graph": { "@id": "urn:id-3", "term": "bar" } } }), processingMode: 'json-ld-1.1' }, "Merge one graph and deep preserve another": { frame: %({ "@context": {"@vocab": "urn:"}, "@type": "Class", "preserve": { "deep": { "@graph": {} } } }), input: %({ "@context": {"@vocab": "urn:"}, "@id": "urn:id-1", "@type": "Class", "merge": { "@id": "urn:id-2", "@graph": { "@id": "urn:id-2", "term": "foo" } }, "preserve": { "deep": { "@graph": { "@id": "urn:id-3", "term": "bar" } } } }), output: %({ "@context": {"@vocab": "urn:"}, "@id": "urn:id-1", "@type": "Class", "merge": { "@id": "urn:id-2", "term": "foo" }, "preserve": { "deep": { "@graph": { "@id": "urn:id-3", "term": "bar" } } } }), processingMode: 'json-ld-1.1' }, "library": { frame: %({ "@context": {"@vocab": "http://example.org/"}, "@type": "Library", "contains": { "@id": "http://example.org/graphs/books", "@graph": {"@type": "Book"} } }), input: %({ "@context": {"@vocab": "http://example.org/"}, "@id": "http://example.org/library", "@type": "Library", "name": "Library", "contains": { "@id": "http://example.org/graphs/books", "@graph": { "@id": "http://example.org/library/the-republic", "@type": "Book", "creator": "Plato", "title": "The Republic", "contains": { "@id": "http://example.org/library/the-republic#introduction", "@type": "Chapter", "description": "An introductory chapter on The Republic.", "title": "The Introduction" } } } }), output: %({ "@context": {"@vocab": "http://example.org/"}, "@id": "http://example.org/library", "@type": "Library", "name": "Library", "contains": { "@id": "http://example.org/graphs/books", "@graph": { "@id": "http://example.org/library/the-republic", "@type": "Book", "creator": "Plato", "title": "The Republic", "contains": { "@id": "http://example.org/library/the-republic#introduction", "@type": "Chapter", "description": "An introductory chapter on The Republic.", "title": "The Introduction" } } } }), processingMode: 'json-ld-1.1' }, "named graph with @embed: @never": { input: %({ "@id": "ex:cred", "ex:subject": { "@id": "ex:Subject", "ex:name": "the subject" }, "ex:proof": { "@graph": { "@type": "ex:Proof", "ex:name": "the proof", "ex:signer": [{ "@id": "ex:Subject", "ex:name": "something different" }] } } }), frame: %({ "@context": { "@version": 1.1, "proof": {"@id": "ex:proof", "@container": "@graph"} }, "@graph": { "proof": {"@embed": "@never"} } }), output: %({ "@context": { "@version": 1.1, "proof": { "@id": "ex:proof", "@container": "@graph" } }, "@id": "ex:cred", "ex:subject": { "@id": "ex:Subject", "ex:name": "the subject" }, "proof": { "@included": [ { "@type": "ex:Proof", "ex:name": "the proof", "ex:signer": { "@id": "ex:Subject" } }, { "@id": "ex:Subject", "ex:name": "something different" } ] } }), processingMode: 'json-ld-1.1' }, }.each do |title, params| it title do do_frame(params) end end end end describe "prune blank nodes" do { "preserves single-use bnode identifiers if @version 1.0": { frame: %({ "@context": { "dc": "http://purl.org/dc/terms/", "dc:creator": { "@type": "@id" }, "foaf": "http://xmlns.com/foaf/0.1/", "ps": "http://purl.org/payswarm#" }, "@id": "http://example.com/asset", "@type": "ps:Asset", "dc:creator": {} }), input: %({ "@context": { "dc": "http://purl.org/dc/terms/", "dc:creator": { "@type": "@id" }, "foaf": "http://xmlns.com/foaf/0.1/", "ps": "http://purl.org/payswarm#" }, "@id": "http://example.com/asset", "@type": "ps:Asset", "dc:creator": { "foaf:name": "John Doe" } }), output: %({ "@context": { "dc": "http://purl.org/dc/terms/", "dc:creator": { "@type": "@id" }, "foaf": "http://xmlns.com/foaf/0.1/", "ps": "http://purl.org/payswarm#" }, "@graph": [ { "@id": "http://example.com/asset", "@type": "ps:Asset", "dc:creator": { "@id": "_:b0", "foaf:name": "John Doe" } } ] }), processingMode: 'json-ld-1.0' }, "preserves single-use bnode identifiers if pruneBlankNodeIdentifiers=false": { frame: %({ "@context": { "dc": "http://purl.org/dc/terms/", "dc:creator": { "@type": "@id" }, "foaf": "http://xmlns.com/foaf/0.1/", "ps": "http://purl.org/payswarm#" }, "@id": "http://example.com/asset", "@type": "ps:Asset", "dc:creator": {} }), input: %({ "@context": { "dc": "http://purl.org/dc/terms/", "dc:creator": { "@type": "@id" }, "foaf": "http://xmlns.com/foaf/0.1/", "ps": "http://purl.org/payswarm#" }, "@id": "http://example.com/asset", "@type": "ps:Asset", "dc:creator": { "foaf:name": "John Doe" } }), output: %({ "@context": { "dc": "http://purl.org/dc/terms/", "dc:creator": { "@type": "@id" }, "foaf": "http://xmlns.com/foaf/0.1/", "ps": "http://purl.org/payswarm#" }, "@graph": [ { "@id": "http://example.com/asset", "@type": "ps:Asset", "dc:creator": { "@id": "_:b0", "foaf:name": "John Doe" } } ] }), pruneBlankNodeIdentiers: false }, "framing with @version: 1.1 prunes identifiers": { frame: %({ "@context": { "@version": 1.1, "@vocab": "https://example.com#", "ex": "http://example.org/", "claim": { "@id": "ex:claim", "@container": "@graph" }, "id": "@id" }, "claim": {} }), input: %({ "@context": { "@version": 1.1, "@vocab": "https://example.com#", "ex": "http://example.org/", "claim": { "@id": "ex:claim", "@container": "@graph" }, "id": "@id" }, "claim": { "id": "ex:1", "test": "foo" } }), output: %({ "@context": { "@version": 1.1, "@vocab": "https://example.com#", "ex": "http://example.org/", "claim": { "@id": "ex:claim", "@container": "@graph" }, "id": "@id" }, "claim": { "id": "ex:1", "test": "foo" } }), processingMode: 'json-ld-1.1' } }.each do |title, params| it title do do_frame(params) end end end context "problem cases" do { "pr #20": { frame: %({}), input: %([ { "@id": "_:gregg", "@type": "http://xmlns.com/foaf/0.1/Person", "http://xmlns.com/foaf/0.1/name": "Gregg Kellogg" }, { "@id": "http://manu.sporny.org/#me", "@type": "http://xmlns.com/foaf/0.1/Person", "http://xmlns.com/foaf/0.1/knows": {"@id": "_:gregg"}, "http://xmlns.com/foaf/0.1/name": "Manu Sporny" } ]), output: %({ "@graph": [ { "@id": "_:b0", "@type": "http://xmlns.com/foaf/0.1/Person", "http://xmlns.com/foaf/0.1/name": "Gregg Kellogg" }, { "@id": "http://manu.sporny.org/#me", "@type": "http://xmlns.com/foaf/0.1/Person", "http://xmlns.com/foaf/0.1/knows": { "@id": "_:b0", "@type": "http://xmlns.com/foaf/0.1/Person", "http://xmlns.com/foaf/0.1/name": "Gregg Kellogg" }, "http://xmlns.com/foaf/0.1/name": "Manu Sporny" } ] }) }, "issue #28": { frame: %({ "@context": { "rdfs": "http://www.w3.org/2000/01/rdf-schema#", "talksAbout": { "@id": "http://www.myresource.com/ontology/1.0#talksAbout", "@type": "@id" }, "label": { "@id": "rdfs:label", "@language": "en" } }, "@id": "http://www.myresource/uuid" }), input: %({ "@context": { "rdfs": "http://www.w3.org/2000/01/rdf-schema#" }, "@id": "http://www.myresource/uuid", "http://www.myresource.com/ontology/1.0#talksAbout": [ { "@id": "http://rdf.freebase.com/ns/m.018w8", "rdfs:label": [ { "@value": "Basketball", "@language": "en" } ] } ] }), output: %({ "@context": { "rdfs": "http://www.w3.org/2000/01/rdf-schema#", "talksAbout": { "@id": "http://www.myresource.com/ontology/1.0#talksAbout", "@type": "@id" }, "label": { "@id": "rdfs:label", "@language": "en" } }, "@graph": [ { "@id": "http://www.myresource/uuid", "talksAbout": { "@id": "http://rdf.freebase.com/ns/m.018w8", "label": "Basketball" } } ] }) }, "PR #663 - Multiple named graphs": { frame: %({ "@context": { "@vocab": "http://example.com/", "loves": {"@type": "@id"}, "unionOf": { "@type": "@id", "@id": "owl:unionOf", "@container": "@list" }, "Class": "owl:Class" }, "@graph": [ { "@explicit": false, "@embed": "@once", "@type": ["Act", "Class"], "@graph": [{ "@explicit": true, "@embed": "@always", "@type": "Person", "@id": {}, "loves": {"@embed": "@never"} }] } ] }), input: %({ "@context": { "@vocab": "http://example.com/", "loves": {"@type": "@id"}, "unionOf": { "@type": "@id", "@id": "owl:unionOf", "@container": "@list" }, "Class": "owl:Class" }, "@graph": [{ "@type": "Act", "@graph": [ {"@id": "Romeo", "@type": "Person"}, {"@id": "Juliet", "@type": "Person"} ] }, { "@id": "ActTwo", "@type": "Act", "@graph": [ {"@id": "Romeo", "@type": "Person", "loves": "Juliet"}, {"@id": "Juliet", "@type": "Person", "loves": "Romeo"} ] }, { "@id": "Person", "@type": "Class", "unionOf": { "@list": [ {"@id": "Montague", "@type": "Class"}, {"@id": "Capulet", "@type": "Class"} ] } }] }), output: %({ "@context": { "@vocab": "http://example.com/", "loves": {"@type": "@id"}, "unionOf": { "@type": "@id", "@id": "owl:unionOf", "@container": "@list" }, "Class": "owl:Class" }, "@graph": [{ "@id": "ActTwo", "@type": "Act", "@graph": [ {"@id": "Juliet", "@type": "Person", "loves": "Romeo"}, {"@id": "Romeo", "@type": "Person", "loves": "Juliet"} ] }, { "@id": "Capulet", "@type": "Class" }, { "@id": "Montague", "@type": "Class" }, { "@id": "Person", "@type": "Class", "unionOf": [ {"@id": "Montague", "@type": "Class"}, {"@id": "Capulet", "@type": "Class"} ] }, { "@type": "Act", "@graph": [ { "@id": "Juliet", "@type": "Person", "loves": null }, { "@id": "Romeo", "@type": "Person", "loves": null } ] }] }), processingMode: 'json-ld-1.1' }, "w3c/json-ld-framing#5": { frame: %({ "@context" : { "@vocab" : "http://purl.bdrc.io/ontology/core/", "taxSubclassOf" : { "@id" : "http://purl.bdrc.io/ontology/core/taxSubclassOf", "@type" : "@id" }, "bdr" : "http://purl.bdrc.io/resource/", "children": { "@reverse": "http://purl.bdrc.io/ontology/core/taxSubclassOf" } }, "@id" : "bdr:O9TAXTBRC201605", "children": { "children": { "children": {} } } }), input: %({ "@context": { "@vocab": "http://purl.bdrc.io/ontology/core/", "taxSubclassOf": { "@id": "http://purl.bdrc.io/ontology/core/taxSubclassOf", "@type": "@id" }, "bdr": "http://purl.bdrc.io/resource/" }, "@graph": [{ "@id": "bdr:O9TAXTBRC201605", "@type": "Taxonomy" }, { "@id": "bdr:O9TAXTBRC201605_0001", "@type": "Taxonomy", "taxSubclassOf": "bdr:O9TAXTBRC201605" }, { "@id": "bdr:O9TAXTBRC201605_0002", "@type": "Taxonomy", "taxSubclassOf": "bdr:O9TAXTBRC201605_0001" }, { "@id": "bdr:O9TAXTBRC201605_0010", "@type": "Taxonomy", "taxSubclassOf": "bdr:O9TAXTBRC201605" }] }), output: %({ "@context" : { "@vocab" : "http://purl.bdrc.io/ontology/core/", "taxSubclassOf" : { "@id" : "http://purl.bdrc.io/ontology/core/taxSubclassOf", "@type" : "@id" }, "bdr" : "http://purl.bdrc.io/resource/", "children": { "@reverse": "http://purl.bdrc.io/ontology/core/taxSubclassOf" } }, "@id" : "bdr:O9TAXTBRC201605", "@type": "Taxonomy", "children": [{ "@id": "bdr:O9TAXTBRC201605_0001", "@type": "Taxonomy", "taxSubclassOf": "bdr:O9TAXTBRC201605", "children": { "@id": "bdr:O9TAXTBRC201605_0002", "@type": "Taxonomy", "taxSubclassOf": "bdr:O9TAXTBRC201605_0001" } }, { "@id": "bdr:O9TAXTBRC201605_0010", "@type": "Taxonomy", "taxSubclassOf": "bdr:O9TAXTBRC201605" }] }), processingMode: 'json-ld-1.1' }, "issue json-ld-framing#30": { input: %({ "@context": {"eg": "https://example.org/ns/"}, "@id": "https://example.org/what", "eg:sameAs": "https://example.org/what", "eg:age": 42 }), frame: %({ "@context": {"eg": "https://example.org/ns/"}, "@id": "https://example.org/what" }), output: %({ "@context": {"eg": "https://example.org/ns/"}, "@graph": [{ "@id": "https://example.org/what", "eg:age": 42, "eg:sameAs": "https://example.org/what" }] }) }, "issue json-ld-framing#64": { input: %({ "@context": { "@version": 1.1, "@vocab": "http://example.org/vocab#" }, "@id": "http://example.org/1", "@type": "HumanMadeObject", "produced_by": { "@type": "Production", "_label": "Top Production", "part": { "@type": "Production", "_label": "Test Part" } } }), frame: %({ "@context": { "@version": 1.1, "@vocab": "http://example.org/vocab#", "Production": { "@context": { "part": { "@type": "@id", "@container": "@set" } } } }, "@id": "http://example.org/1" }), output: %({ "@context": { "@version": 1.1, "@vocab": "http://example.org/vocab#", "Production": { "@context": { "part": { "@type": "@id", "@container": "@set" } } } }, "@id": "http://example.org/1", "@type": "HumanMadeObject", "produced_by": { "@type": "Production", "part": [{ "@type": "Production", "_label": "Test Part" }], "_label": "Top Production" } }), processingMode: "json-ld-1.1" }, "issue json-ld-framing#27": { input: %({ "@id": "ex:cred", "ex:subject": { "@id": "ex:Subject", "ex:name": "the subject", "ex:knows": { "@id": "ex:issuer", "ex:name": "Someone else" } }, "ex:proof": { "@graph": { "@type": "ex:Proof", "ex:name": "the proof", "ex:signer": [{ "@id": "ex:Subject", "ex:name": "something different" }] } } }), frame: %({ "@context": { "@version": 1.1, "proof": {"@id": "ex:proof", "@container": "@graph"} }, "@graph": { "subject": {}, "proof": {} } }), output: %({ "@context": { "@version": 1.1, "proof": { "@id": "ex:proof", "@container": "@graph" } }, "@id": "ex:cred", "ex:subject": { "@id": "ex:Subject", "ex:name": "the subject", "ex:knows": { "@id": "ex:issuer", "ex:name": "Someone else" } }, "proof": { "@type": "ex:Proof", "ex:name": "the proof", "ex:signer": { "@id": "ex:Subject", "ex:name": "something different" } } }), processingMode: "json-ld-1.1" }, "missing types": { input: %({ "@context": { "ex": "http://example.com#", "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#" }, "@graph": [{ "@id": "ex:graph1", "@graph": [{ "@id": "ex:entity1", "@type": ["ex:Type1","ex:Type2"], "ex:title": "some title", "ex:multipleValues": "ex:One" }] }, { "@id": "ex:graph2", "@graph": [{ "@id": "ex:entity1", "@type": "ex:Type3", "ex:tags": "tag1 tag2", "ex:multipleValues": ["ex:Two","ex:Three"] }] }] }), output: %({ "@context": { "ex": "http://example.com#", "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#" }, "@id": "ex:entity1", "@type": ["ex:Type1", "ex:Type2", "ex:Type3"], "ex:multipleValues": ["ex:One", "ex:Two","ex:Three"], "ex:tags": "tag1 tag2", "ex:title": "some title" }), frame: %({ "@context": { "ex": "http://example.com#", "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#" }, "@id": "ex:entity1" }), processingMode: "json-ld-1.1" }, "don't embed list elements": { frame: %({ "@context": {"ex": "http://example.org/"}, "ex:embed": { "@list": [{"@embed": "@never"}] } }), input: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:embed": { "@list": [{ "@id": "ex:Sub2", "ex:prop": "property" }] } }), output: %({ "@context": {"ex": "http://example.org/"}, "@id": "ex:Sub1", "ex:embed": {"@list": [{"@id": "ex:Sub2"}]} }), processingMode: "json-ld-1.1" }, "issue #142": { input: %({ "@context":{ "ex":"http://example.org/vocab#", "ex:info":{"@type":"@json"}, "ex:other":{"@type":"@json"} }, "@id":"http://example.org/test/#library", "@type":"ex:Library", "ex:info":{ "author":"JOHN", "pages":200 }, "ex:other":{ "publisher":"JANE" } }), frame: %({ "@context":{ "ex":"http://example.org/vocab#", "ex:info":{"@type":"@json"}, "ex:other":{"@type":"@json"} }, "http://example.org/vocab#info":{} }), output: %({ "@context": { "ex": "http://example.org/vocab#", "ex:info": {"@type": "@json"}, "ex:other": {"@type": "@json"} }, "@id": "http://example.org/test/#library", "@type": "ex:Library", "ex:info": { "author": "JOHN", "pages": 200 }, "ex:other": { "publisher": "JANE" } }), processingMode: "json-ld-1.1" } }.each do |title, params| it title do do_frame(params) end end end def do_frame(params) begin input, frame, output = params[:input], params[:frame], params[:output] params = {processingMode: 'json-ld-1.0'}.merge(params) input = ::JSON.parse(input) if input.is_a?(String) frame = ::JSON.parse(frame) if frame.is_a?(String) output = ::JSON.parse(output) if output.is_a?(String) jld = nil if params[:write] expect{jld = JSON::LD::API.frame(input, frame, logger: logger, **params)}.to write(params[:write]).to(:error) else expect{jld = JSON::LD::API.frame(input, frame, logger: logger, **params)}.not_to write.to(:error) end expect(jld).to produce_jsonld(output, logger) # Compare expanded jld/output too to make sure list values remain ordered exp_jld = JSON::LD::API.expand(jld, processingMode: 'json-ld-1.1') exp_output = JSON::LD::API.expand(output, processingMode: 'json-ld-1.1') expect(exp_jld).to produce_jsonld(exp_output, logger) rescue JSON::LD::JsonLdError => e fail("#{e.class}: #{e.message}\n" + "#{logger}\n" + "Backtrace:\n#{e.backtrace.join("\n")}") end end end