Skip to content

Commit

Permalink
Handle @propagate in prop-scoped contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
rubensworks committed Mar 16, 2020
1 parent 728a92b commit 03b377f
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 4 deletions.
18 changes: 14 additions & 4 deletions lib/ParsingContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,20 @@ export class ParsingContext {
const key = keysOriginal[i];
const contextKeyEntry = context[key];
if (contextKeyEntry && typeof contextKeyEntry === 'object' && '@context' in contextKeyEntry) {
const scopedContext = this.parseContext(contextKeyEntry, context);
this.contextTree.setContext(keysOriginal.slice(0, i + offset), scopedContext);
context = await scopedContext;
delete context[key]['@context'];
const scopedContext = await this.parseContext(contextKeyEntry, context);
const propagate = scopedContext[key]['@context']['@propagate']; // Propagation is true by default

if (propagate !== false || i === keysOriginal.length - 1 - offset) {
if (propagate !== false) {
this.contextTree.setContext(keysOriginal.slice(0, i + offset), Promise.resolve(scopedContext));
}
context = scopedContext;

// Clean up final context
delete context['@propagate'];
context[key] = { ...context[key] };
delete context[key]['@context'];
}
}
}

Expand Down
62 changes: 62 additions & 0 deletions test/JsonLdParser-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7974,6 +7974,68 @@ describe('JsonLdParser', () => {
]);
});

it('should propagate for @propagate: true', async () => {
const stream = streamifyString(`
{
"@context": {
"@vocab": "http://vocab.org/",
"foo": {
"@context": {
"@propagate": true,
"@vocab": "http://ex.org/"
}
}
},
"@id": "http://ex.org/myid",
"foo": {
"@id": "http://ex.org/myinnerid",
"bar1": {
"@id": "http://ex.org/myinnerinnerid",
"bar2": "baz"
}
}
}`);
return expect(await arrayifyStream(stream.pipe(parser))).toBeRdfIsomorphic([
quad(namedNode('http://ex.org/myid'), namedNode('http://vocab.org/foo'),
namedNode('http://ex.org/myinnerid')),
quad(namedNode('http://ex.org/myinnerid'), namedNode('http://ex.org/bar1'),
namedNode('http://ex.org/myinnerinnerid')),
quad(namedNode('http://ex.org/myinnerinnerid'), namedNode('http://ex.org/bar2'),
literal('baz')),
]);
});

it('should not propagate for @propagate: false', async () => {
const stream = streamifyString(`
{
"@context": {
"@vocab": "http://vocab.org/",
"foo": {
"@context": {
"@propagate": false,
"@vocab": "http://ex.org/"
}
}
},
"@id": "http://ex.org/myid",
"foo": {
"@id": "http://ex.org/myinnerid",
"bar1": {
"@id": "http://ex.org/myinnerinnerid",
"bar2": "baz"
}
}
}`);
return expect(await arrayifyStream(stream.pipe(parser))).toBeRdfIsomorphic([
quad(namedNode('http://ex.org/myid'), namedNode('http://vocab.org/foo'),
namedNode('http://ex.org/myinnerid')),
quad(namedNode('http://ex.org/myinnerid'), namedNode('http://ex.org/bar1'),
namedNode('http://ex.org/myinnerinnerid')),
quad(namedNode('http://ex.org/myinnerinnerid'), namedNode('http://vocab.org/bar2'),
literal('baz')),
]);
});

it('should not influence neighbour properties', async () => {
const stream = streamifyString(`
{
Expand Down
55 changes: 55 additions & 0 deletions test/ParsingContext-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,61 @@ describe('ParsingContext', () => {

});

describe('for non-propagating property-scoped contexts', () => {

beforeEach(() => {
parsingContext.contextTree.setContext([''], Promise.resolve({
'@vocab': 'http://vocab.main.org/',
'a': {
'@context': {
'@propagate': false,
'@vocab': 'http://vocab.a.org/',
},
'@id': 'http://a.org',
},
}));
});

it('should ignore non-applicable properties', async () => {
return expect(await parsingContext.getContext(['', 'b', 'subKey']))
.toEqual({
'@vocab': 'http://vocab.main.org/',
'a': {
'@context': {
'@propagate': false,
'@vocab': 'http://vocab.a.org/',
},
'@id': 'http://a.org',
},
});
});

it('should consider an applicable property', async () => {
return expect(await parsingContext.getContext(['', 'a', 'subKey']))
.toEqual({
'@vocab': 'http://vocab.a.org/',
'a': {
'@id': 'http://a.org',
},
});
});

it('should not consider an applicable property when called via sub-properties', async () => {
return expect(await parsingContext.getContext(['', 'a', 'subKey1', 'subKey2', 'subKey3']))
.toEqual({
'@vocab': 'http://vocab.main.org/',
'a': {
'@context': {
'@propagate': false,
'@vocab': 'http://vocab.a.org/',
},
'@id': 'http://a.org',
},
});
});

});

describe('for nested property-scoped contexts', () => {

beforeEach(() => {
Expand Down

0 comments on commit 03b377f

Please sign in to comment.