Properly serialize non-json values in parser tests (#10858)
This commit is contained in:
parent
25f7e6808e
commit
0b3f883ed1
@ -91,7 +91,7 @@
|
|||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
"$$ babel internal serialized type": "BigInt",
|
"$$ babel internal serialized type": "BigInt",
|
||||||
"value": "1n"
|
"value": "1"
|
||||||
},
|
},
|
||||||
"raw": "1n",
|
"raw": "1n",
|
||||||
"bigint": "1"
|
"bigint": "1"
|
||||||
|
|||||||
@ -89,7 +89,11 @@
|
|||||||
"column": 13
|
"column": 13
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"value": "/.*/i",
|
"value": {
|
||||||
|
"$$ babel internal serialized type": "RegExp",
|
||||||
|
"source": ".*",
|
||||||
|
"flags": "i"
|
||||||
|
},
|
||||||
"raw": "/.*/i",
|
"raw": "/.*/i",
|
||||||
"regex": {
|
"regex": {
|
||||||
"pattern": ".*",
|
"pattern": ".*",
|
||||||
|
|||||||
@ -111,41 +111,12 @@ export function runThrowTestsWithEstree(fixturesPath, parseFunction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function save(test, ast) {
|
function save(test, ast) {
|
||||||
overrideToJSON(() =>
|
fs.writeFileSync(
|
||||||
fs.writeFileSync(test.expect.loc, JSON.stringify(ast, null, 2)),
|
test.expect.loc,
|
||||||
|
JSON.stringify(ast, (k, v) => serialize(v), 2),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that RegExp, BigInt, and Errors are serialized as strings
|
|
||||||
function overrideToJSON(cb) {
|
|
||||||
const originalToJSONMap = new Map();
|
|
||||||
const notJSONparseableObj = [RegExp, Error];
|
|
||||||
|
|
||||||
if (typeof BigInt !== "undefined") {
|
|
||||||
notJSONparseableObj.push(BigInt);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const obj of notJSONparseableObj) {
|
|
||||||
const { toJSON } = obj.prototype;
|
|
||||||
originalToJSONMap.set(obj, toJSON);
|
|
||||||
obj.prototype.toJSON = function() {
|
|
||||||
if (typeof this === "bigint") {
|
|
||||||
return { [serialized]: "BigInt", value: serialize(this) };
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.toString();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = cb();
|
|
||||||
|
|
||||||
for (const obj of notJSONparseableObj) {
|
|
||||||
obj.prototype.toJSON = originalToJSONMap.get(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function runTest(test, parseFunction) {
|
function runTest(test, parseFunction) {
|
||||||
const opts = test.options;
|
const opts = test.options;
|
||||||
|
|
||||||
@ -223,20 +194,41 @@ function runTest(test, parseFunction) {
|
|||||||
|
|
||||||
function serialize(value) {
|
function serialize(value) {
|
||||||
if (typeof value === "bigint") {
|
if (typeof value === "bigint") {
|
||||||
return value.toString() + "n";
|
return {
|
||||||
|
[serialized]: "BigInt",
|
||||||
|
value: value.toString(),
|
||||||
|
};
|
||||||
|
} else if (value instanceof RegExp) {
|
||||||
|
return {
|
||||||
|
[serialized]: "RegExp",
|
||||||
|
source: value.source,
|
||||||
|
flags: value.flags,
|
||||||
|
};
|
||||||
|
} else if (value instanceof Error) {
|
||||||
|
// Errors are serialized to a simple string, because are used frequently
|
||||||
|
return value.toString();
|
||||||
}
|
}
|
||||||
return JSON.stringify(value, null, 2);
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ppJSON(v) {
|
function ppJSON(v) {
|
||||||
|
if (typeof v === "bigint" || v instanceof Error || v instanceof RegExp) {
|
||||||
|
return ppJSON(serialize(v));
|
||||||
|
}
|
||||||
|
|
||||||
if (v && typeof v === "object" && v[serialized]) {
|
if (v && typeof v === "object" && v[serialized]) {
|
||||||
switch (v[serialized]) {
|
switch (v[serialized]) {
|
||||||
case "BigInt":
|
case "BigInt":
|
||||||
return typeof BigInt === "undefined" ? "null" : v.value;
|
return typeof BigInt === "undefined" ? "null" : v.value + "n";
|
||||||
|
case "RegExp":
|
||||||
|
return `/${v.source}/${v.flags}`;
|
||||||
}
|
}
|
||||||
|
} else if (typeof v === "string" && /^[A-Z][a-z]+Error: /.test(v)) {
|
||||||
|
// Errors are serialized to a simple string, because are used frequently
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
return serialize(v);
|
return JSON.stringify(v, (k, v) => serialize(v), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPath(str, pt) {
|
function addPath(str, pt) {
|
||||||
@ -248,49 +240,42 @@ function addPath(str, pt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function misMatch(exp, act) {
|
function misMatch(exp, act) {
|
||||||
return overrideToJSON(() => {
|
if (
|
||||||
if (
|
act instanceof RegExp ||
|
||||||
act instanceof RegExp ||
|
act instanceof Error ||
|
||||||
act instanceof Error ||
|
typeof act === "bigint" ||
|
||||||
typeof act === "bigint" ||
|
(exp && typeof exp === "object" && exp[serialized])
|
||||||
(exp && typeof exp === "object" && exp[serialized])
|
) {
|
||||||
) {
|
const left = ppJSON(exp);
|
||||||
const left = ppJSON(exp);
|
const right = ppJSON(act);
|
||||||
const right = ppJSON(act);
|
if (left !== right) return left + " !== " + right;
|
||||||
if (left !== right) return left + " !== " + right;
|
} else if (Array.isArray(exp)) {
|
||||||
} else if (Array.isArray(exp)) {
|
if (!Array.isArray(act)) return ppJSON(exp) + " != " + ppJSON(act);
|
||||||
if (!Array.isArray(act)) return ppJSON(exp) + " != " + ppJSON(act);
|
if (act.length != exp.length) {
|
||||||
if (act.length != exp.length) {
|
return "array length mismatch " + exp.length + " != " + act.length;
|
||||||
return "array length mismatch " + exp.length + " != " + act.length;
|
}
|
||||||
}
|
for (let i = 0; i < act.length; ++i) {
|
||||||
for (let i = 0; i < act.length; ++i) {
|
const mis = misMatch(exp[i], act[i]);
|
||||||
const mis = misMatch(exp[i], act[i]);
|
if (mis) return addPath(mis, i);
|
||||||
if (mis) return addPath(mis, i);
|
}
|
||||||
}
|
} else if (!exp || !act || typeof exp != "object" || typeof act != "object") {
|
||||||
} else if (
|
if (exp !== act && typeof exp != "function") {
|
||||||
!exp ||
|
return ppJSON(exp) + " !== " + ppJSON(act);
|
||||||
!act ||
|
}
|
||||||
typeof exp != "object" ||
|
} else {
|
||||||
typeof act != "object"
|
for (const prop of Object.keys(exp)) {
|
||||||
) {
|
const mis = misMatch(exp[prop], act[prop]);
|
||||||
if (exp !== act && typeof exp != "function") {
|
if (mis) return addPath(mis, prop);
|
||||||
return ppJSON(exp) + " !== " + ppJSON(act);
|
}
|
||||||
}
|
|
||||||
} else {
|
for (const prop of Object.keys(act)) {
|
||||||
for (const prop of Object.keys(exp)) {
|
if (typeof act[prop] === "function") {
|
||||||
const mis = misMatch(exp[prop], act[prop]);
|
continue;
|
||||||
if (mis) return addPath(mis, prop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const prop of Object.keys(act)) {
|
if (!(prop in exp) && act[prop] !== undefined) {
|
||||||
if (typeof act[prop] === "function") {
|
return `Did not expect a property '${prop}'`;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(prop in exp) && act[prop] !== undefined) {
|
|
||||||
return `Did not expect a property '${prop}'`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user