45 lines
1.2 KiB
JavaScript
45 lines
1.2 KiB
JavaScript
"use strict";
|
|
|
|
// Checks if the source ast implements the target ast. Ignores extra keys on source ast
|
|
module.exports = function assertImplementsAST(target, source, path) {
|
|
if (!path) {
|
|
path = [];
|
|
}
|
|
|
|
function error(text) {
|
|
const err = new Error(`At ${path.join(".")}: ${text}:`);
|
|
err.depth = path.length + 1;
|
|
throw err;
|
|
}
|
|
|
|
const typeA = target === null ? "null" : typeof target;
|
|
const typeB = source === null ? "null" : typeof source;
|
|
if (typeA !== typeB) {
|
|
error(
|
|
`have different types (${typeA} !== ${typeB}) (${target} !== ${source})`
|
|
);
|
|
} else if (
|
|
typeA === "object" &&
|
|
["RegExp"].indexOf(target.constructor.name) !== -1 &&
|
|
target.constructor.name !== source.constructor.name
|
|
) {
|
|
error(
|
|
`object have different constructors (${target.constructor.name} !== ${
|
|
source.constructor.name
|
|
}`
|
|
);
|
|
} else if (typeA === "object") {
|
|
const keysTarget = Object.keys(target);
|
|
for (const i in keysTarget) {
|
|
const key = keysTarget[i];
|
|
path.push(key);
|
|
assertImplementsAST(target[key], source[key], path);
|
|
path.pop();
|
|
}
|
|
} else if (target !== source) {
|
|
error(
|
|
`are different (${JSON.stringify(target)} !== ${JSON.stringify(source)})`
|
|
);
|
|
}
|
|
};
|