/
assert-implements-ast.js
40 lines (38 loc) 路 1.21 KB
/
assert-implements-ast.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Checks if the source ast implements the target ast. Ignores extra keys on source ast
export default 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)})`,
);
}
}