webpack/test/checkArrayExpectation.js

148 lines
3.5 KiB
JavaScript

"use strict";
const fs = require("graceful-fs");
const path = require("path");
const check = (expected, actual) => {
if (expected instanceof RegExp) {
expected = { message: expected };
}
if (Array.isArray(expected)) {
return expected.every(e => check(e, actual));
}
return Object.keys(expected).every(key => {
let value = actual[key];
if (typeof value === "object") {
value = JSON.stringify(value);
}
return expected[key].test(value);
});
};
const explain = object => {
if (object instanceof RegExp) {
object = { message: object };
}
return Object.keys(object)
.map(key => {
let value = object[key];
if (typeof value === "object" && !(value instanceof RegExp)) {
value = JSON.stringify(value);
}
let msg = `${key} = ${value}`;
if (key !== "stack" && key !== "details" && msg.length > 100)
msg = msg.slice(0, 97) + "...";
return msg;
})
.join("; ");
};
const diffItems = (actual, expected, kind) => {
const tooMuch = actual.slice();
const missing = expected.slice();
for (let i = 0; i < missing.length; i++) {
const current = missing[i];
for (let j = 0; j < tooMuch.length; j++) {
if (check(current, tooMuch[j])) {
tooMuch.splice(j, 1);
missing.splice(i, 1);
i--;
break;
}
}
}
const diff = [];
if (missing.length > 0) {
diff.push(`The following expected ${kind}s are missing:
${missing.map(item => `${explain(item)}`).join("\n\n")}`);
}
if (tooMuch.length > 0) {
diff.push(`The following ${kind}s are unexpected:
${tooMuch.map(item => `${explain(item)}`).join("\n\n")}`);
}
return diff.join("\n\n");
};
module.exports = function checkArrayExpectation(
testDirectory,
object,
kind,
filename,
upperCaseKind,
done
) {
if (!done) {
done = upperCaseKind;
upperCaseKind = filename;
filename = `${kind}s`;
}
let array = object[`${kind}s`];
if (Array.isArray(array)) {
if (kind === "warning") {
array = array.filter(item => !/from Terser/.test(item));
}
}
if (fs.existsSync(path.join(testDirectory, `${filename}.js`))) {
const expectedFilename = path.join(testDirectory, `${filename}.js`);
const expected = require(expectedFilename);
const diff = diffItems(array, expected, kind);
if (expected.length < array.length) {
return (
done(
new Error(
`More ${kind}s (${array.length} instead of ${expected.length}) while compiling than expected:\n\n${diff}\n\nCheck expected ${kind}s: ${expectedFilename}`
)
),
true
);
} else if (expected.length > array.length) {
return (
done(
new Error(
`Less ${kind}s (${array.length} instead of ${expected.length}) while compiling than expected:\n\n${diff}\n\nCheck expected ${kind}s: ${expectedFilename}`
)
),
true
);
}
for (let i = 0; i < array.length; i++) {
if (Array.isArray(expected[i])) {
for (let j = 0; j < expected[i].length; j++) {
if (!check(expected[i][j], array[i])) {
return (
done(
new Error(
`${upperCaseKind} ${i}: ${explain(
array[i]
)} doesn't match ${explain(expected[i][j])}`
)
),
true
);
}
}
} else if (!check(expected[i], array[i]))
return (
done(
new Error(
`${upperCaseKind} ${i}: ${explain(
array[i]
)} doesn't match ${explain(expected[i])}`
)
),
true
);
}
} else if (array.length > 0) {
return (
done(
new Error(
`${upperCaseKind}s while compiling:\n\n${array
.map(explain)
.join("\n\n")}`
)
),
true
);
}
};