Skip to content

Commit 32d9beb

Browse files
committed
Implement deep compare for term definitions.
1 parent 1c00ec3 commit 32d9beb

File tree

1 file changed

+32
-29
lines changed

1 file changed

+32
-29
lines changed

lib/context.js

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ api.createTermDefinition = (
664664
// be equal
665665
activeCtx.protected[term] = true;
666666
mapping.protected = true;
667-
if(!_areTermDefinitionsEqual(previousMapping, mapping)) {
667+
if(!_deepCompare(previousMapping, mapping)) {
668668
const protectedMode = (options && options.protectedMode) || 'error';
669669
if(protectedMode === 'error') {
670670
throw new JsonLdError(
@@ -1317,42 +1317,45 @@ function _findContextUrls(input, urls, replace, base) {
13171317
}
13181318
}
13191319

1320-
function _areTermDefinitionsEqual(d1, d2) {
1321-
const k1 = Object.keys(d1);
1322-
const k2 = Object.keys(d2);
1323-
if(k1.length !== k2.length) {
1320+
function _deepCompare(x1, x2) {
1321+
// compare `null` or primitive types directly
1322+
if((!(x1 && typeof x1 === 'object')) ||
1323+
(!(x2 && typeof x2 === 'object'))) {
1324+
return x1 === x2;
1325+
}
1326+
// x1 and x2 are objects (also potentially arrays)
1327+
const x1Array = Array.isArray(x1);
1328+
if(x1Array !== Array.isArray(x2)) {
13241329
return false;
13251330
}
1326-
1327-
for(const k of k1) {
1328-
const v1 = d1[k];
1329-
const v2 = d2[k];
1330-
if(k === '@context') {
1331-
// FIXME: temporary hack, use deep comparison instead
1332-
if(JSON.stringify(v1) !== JSON.stringify(v2)) {
1333-
return false;
1334-
}
1335-
continue;
1336-
}
1337-
const isArray = Array.isArray(v1);
1338-
if(isArray !== Array.isArray(v2)) {
1331+
if(x1Array) {
1332+
if(x1.length !== x2.length) {
13391333
return false;
13401334
}
1341-
// `@container`
1342-
if(isArray) {
1343-
if(v1.length !== v2.length) {
1335+
for(let i = 0; i < x1.length; ++i) {
1336+
if(!_deepCompare(x1[i], x2[i])) {
13441337
return false;
13451338
}
1346-
v1.sort();
1347-
v2.sort();
1348-
for(let i = 0; i < v1.length; ++i) {
1349-
if(v1[i] !== v2[i]) {
1350-
return false;
1351-
}
1339+
}
1340+
return true;
1341+
}
1342+
// x1 and x2 are non-array objects
1343+
const k1s = Object.keys(x1);
1344+
const k2s = Object.keys(x2);
1345+
if(k1s.length !== k2s.length) {
1346+
return false;
1347+
}
1348+
for(const k1 in x1) {
1349+
let v1 = x1[k1];
1350+
let v2 = x2[k1];
1351+
// special case: `@container` can be in any order
1352+
if(k1 === '@container') {
1353+
if(Array.isArray(v1) && Array.isArray(v2)) {
1354+
v1 = v1.slice().sort();
1355+
v2 = v2.slice().sort();
13521356
}
13531357
}
1354-
// strings
1355-
if(v1 !== v2) {
1358+
if(!_deepCompare(v1, v2)) {
13561359
return false;
13571360
}
13581361
}

0 commit comments

Comments
 (0)