Skip to content

Commit 0fa6515

Browse files
tplookerdavidlehn
authored andcommitted
feat: extend expansion map for detecting relative IRIs for @id and @type terms
1 parent ee976d2 commit 0fa6515

File tree

2 files changed

+245
-6
lines changed

2 files changed

+245
-6
lines changed

lib/expand.js

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -505,10 +505,27 @@ async function _expandObject({
505505
}
506506
}
507507

508+
const expandedValues = _asArray(value).map(v =>
509+
_isString(v) ? _expandIri(activeCtx, v, {base: true}, options) : v);
510+
511+
for(const i in expandedValues) {
512+
if(_isString(expandedValues[i]) && !_isAbsoluteIri(expandedValues[i])) {
513+
const expansionMapResult = await expansionMap({
514+
relativeIri: {type: key, value: expandedValues[i]},
515+
activeCtx,
516+
activeProperty,
517+
options,
518+
insideList
519+
});
520+
if(expansionMapResult !== undefined) {
521+
expandedValues[i] = expansionMapResult;
522+
}
523+
}
524+
}
525+
508526
_addValue(
509527
expandedParent, '@id',
510-
_asArray(value).map(v =>
511-
_isString(v) ? _expandIri(activeCtx, v, {base: true}, options) : v),
528+
expandedValues,
512529
{propertyIsArray: options.isFrame});
513530
continue;
514531
}
@@ -525,12 +542,30 @@ async function _expandObject({
525542
]));
526543
}
527544
_validateTypeValue(value, options.isFrame);
545+
546+
const expandedValues = _asArray(value).map(v =>
547+
_isString(v) ?
548+
_expandIri(typeScopedContext, v,
549+
{base: true, vocab: true}, options) : v);
550+
551+
for(const i in expandedValues) {
552+
if(_isString(expandedValues[i]) && !_isAbsoluteIri(expandedValues[i])) {
553+
const expansionMapResult = await expansionMap({
554+
relativeIri: {type: key, value: expandedValues[i]},
555+
activeCtx,
556+
activeProperty,
557+
options,
558+
insideList
559+
});
560+
if(expansionMapResult !== undefined) {
561+
expandedValues[i] = expansionMapResult;
562+
}
563+
}
564+
}
565+
528566
_addValue(
529567
expandedParent, '@type',
530-
_asArray(value).map(v =>
531-
_isString(v) ?
532-
_expandIri(typeScopedContext, v,
533-
{base: true, vocab: true}, options) : v),
568+
expandedValues,
534569
{propertyIsArray: options.isFrame});
535570
continue;
536571
}

tests/misc.js

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,3 +478,207 @@ describe('literal JSON', () => {
478478
});
479479
});
480480
});
481+
482+
describe('expansionMap', () => {
483+
it('should be called on un-mapped term', async () => {
484+
const docWithUnMappedTerm = {
485+
'@context': {
486+
'definedTerm': 'https://example.com#definedTerm'
487+
},
488+
definedTerm: "is defined",
489+
testUndefined: "is undefined"
490+
};
491+
492+
let expansionMapCalled = false;
493+
const expansionMap = info => {
494+
if(info.unmappedProperty === 'testUndefined') {
495+
expansionMapCalled = true;
496+
}
497+
};
498+
499+
await jsonld.expand(docWithUnMappedTerm, {expansionMap});
500+
501+
assert.equal(expansionMapCalled, true);
502+
});
503+
504+
it('should be called on nested un-mapped term', async () => {
505+
const docWithUnMappedTerm = {
506+
'@context': {
507+
'definedTerm': 'https://example.com#definedTerm'
508+
},
509+
definedTerm: {
510+
testUndefined: "is undefined"
511+
}
512+
};
513+
514+
let expansionMapCalled = false;
515+
const expansionMap = info => {
516+
if(info.unmappedProperty === 'testUndefined') {
517+
expansionMapCalled = true;
518+
}
519+
};
520+
521+
await jsonld.expand(docWithUnMappedTerm, {expansionMap});
522+
523+
assert.equal(expansionMapCalled, true);
524+
});
525+
526+
it('should be called on relative iri for id term', async () => {
527+
const docWithRelativeIriId = {
528+
'@context': {
529+
'definedTerm': 'https://example.com#definedTerm'
530+
},
531+
'@id': "relativeiri",
532+
definedTerm: "is defined"
533+
};
534+
535+
let expansionMapCalled = false;
536+
const expansionMap = info => {
537+
if(info.relativeIri && info.relativeIri.value === 'relativeiri') {
538+
expansionMapCalled = true;
539+
}
540+
};
541+
542+
await jsonld.expand(docWithRelativeIriId, {expansionMap});
543+
544+
assert.equal(expansionMapCalled, true);
545+
});
546+
547+
it('should be called on relative iri for id term (nested)', async () => {
548+
const docWithRelativeIriId = {
549+
'@context': {
550+
'definedTerm': 'https://example.com#definedTerm'
551+
},
552+
'@id': "urn:absoluteIri",
553+
definedTerm: {
554+
'@id': "relativeiri"
555+
}
556+
};
557+
558+
let expansionMapCalled = false;
559+
const expansionMap = info => {
560+
if(info.relativeIri && info.relativeIri.value === 'relativeiri') {
561+
expansionMapCalled = true;
562+
}
563+
};
564+
565+
await jsonld.expand(docWithRelativeIriId, {expansionMap});
566+
567+
assert.equal(expansionMapCalled, true);
568+
});
569+
570+
it('should be called on relative iri for aliased id term', async () => {
571+
const docWithRelativeIriId = {
572+
'@context': {
573+
'id': '@id',
574+
'definedTerm': 'https://example.com#definedTerm'
575+
},
576+
'id': "relativeiri",
577+
definedTerm: "is defined"
578+
};
579+
580+
let expansionMapCalled = false;
581+
const expansionMap = info => {
582+
if(info.relativeIri && info.relativeIri.value === 'relativeiri') {
583+
expansionMapCalled = true;
584+
}
585+
};
586+
587+
await jsonld.expand(docWithRelativeIriId, {expansionMap});
588+
589+
assert.equal(expansionMapCalled, true);
590+
});
591+
592+
it('should be called on relative iri for type term', async () => {
593+
const docWithRelativeIriId = {
594+
'@context': {
595+
'definedTerm': 'https://example.com#definedTerm'
596+
},
597+
'id': "urn:absoluteiri",
598+
'@type': "relativeiri",
599+
definedTerm: "is defined"
600+
};
601+
602+
let expansionMapCalled = false;
603+
const expansionMap = info => {
604+
if(info.relativeIri && info.relativeIri.value === 'relativeiri') {
605+
expansionMapCalled = true;
606+
}
607+
};
608+
609+
await jsonld.expand(docWithRelativeIriId, {expansionMap});
610+
611+
assert.equal(expansionMapCalled, true);
612+
});
613+
614+
it('should be called on relative iri for \
615+
type term with multiple relative iri types', async () => {
616+
const docWithRelativeIriId = {
617+
'@context': {
618+
'definedTerm': 'https://example.com#definedTerm'
619+
},
620+
'id': "urn:absoluteiri",
621+
'@type': ["relativeiri", "anotherRelativeiri" ],
622+
definedTerm: "is defined"
623+
};
624+
625+
let expansionMapCalledTimes = 0;
626+
const expansionMap = info => {
627+
if(info.relativeIri &&
628+
(info.relativeIri.value === 'relativeiri' ||
629+
info.relativeIri.value === 'anotherRelativeiri')) {
630+
expansionMapCalledTimes++;
631+
}
632+
};
633+
634+
await jsonld.expand(docWithRelativeIriId, {expansionMap});
635+
636+
assert.equal(expansionMapCalledTimes, 2);
637+
});
638+
639+
it('should be called on relative iri for \
640+
type term with multiple types', async () => {
641+
const docWithRelativeIriId = {
642+
'@context': {
643+
'definedTerm': 'https://example.com#definedTerm'
644+
},
645+
'id': "urn:absoluteiri",
646+
'@type': ["relativeiri", "definedTerm" ],
647+
definedTerm: "is defined"
648+
};
649+
650+
let expansionMapCalled = false;
651+
const expansionMap = info => {
652+
if(info.relativeIri && info.relativeIri.value === 'relativeiri') {
653+
expansionMapCalled = true;
654+
}
655+
};
656+
657+
await jsonld.expand(docWithRelativeIriId, {expansionMap});
658+
659+
assert.equal(expansionMapCalled, true);
660+
});
661+
662+
it('should be called on relative iri for aliased type term', async () => {
663+
const docWithRelativeIriId = {
664+
'@context': {
665+
'type': "@type",
666+
'definedTerm': 'https://example.com#definedTerm'
667+
},
668+
'id': "urn:absoluteiri",
669+
'type': "relativeiri",
670+
definedTerm: "is defined"
671+
};
672+
673+
let expansionMapCalled = false;
674+
const expansionMap = info => {
675+
if(info.relativeIri && info.relativeIri.value === 'relativeiri') {
676+
expansionMapCalled = true;
677+
}
678+
};
679+
680+
await jsonld.expand(docWithRelativeIriId, {expansionMap});
681+
682+
assert.equal(expansionMapCalled, true);
683+
});
684+
});

0 commit comments

Comments
 (0)