Make run-external-typescript-tests.js cross-platform (#2737)
The old version had quite a bit of code related to grouping errors, showing the number of errors per group and saving the groups of errors to different files. However, now there are only 12 bad tests so I didn't bother porting that logic to the new version. Instead, the errors a simply printed to stdout.master
parent
c4e5463514
commit
f903ae45ed
|
@ -1,128 +1,89 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/**
|
|
||||||
* There's an issue with this script's assumption that each run of prettier
|
|
||||||
* will result in one output to stderr or stdout.
|
|
||||||
*
|
|
||||||
* On Mac this seems not to hold for stderr, where multiple errors are buffered
|
|
||||||
* into one emit on the stderr stream.
|
|
||||||
*
|
|
||||||
* If you have any ideas on how to fix this, please send a PR!
|
|
||||||
*/
|
|
||||||
if (process.platform !== "win32") {
|
|
||||||
console.log("Warning: this script may not work on macOS.");
|
|
||||||
}
|
|
||||||
|
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
const globby = require("globby");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const spawn = require("child_process").spawn;
|
const format = require("../src/cli-util").format;
|
||||||
const rimraf = require("rimraf");
|
|
||||||
|
|
||||||
const tsRoot = path.resolve(__dirname, "../../TypeScript");
|
function tryFormat(content) {
|
||||||
const testsDir = path.relative(process.cwd(), path.join(tsRoot, "tests"));
|
try {
|
||||||
const errorsPath = "./errors/";
|
format({ "debug-check": true }, content, { parser: "typescript" });
|
||||||
const fileGlob = path.join(testsDir, "**/*.ts");
|
} catch (error) {
|
||||||
|
return error;
|
||||||
if (!fs.existsSync(tsRoot) || !fs.existsSync(testsDir)) {
|
}
|
||||||
console.error(`Error: TypeScript is not cloned at ../TypeScript`);
|
return null;
|
||||||
process.exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const badFiles = [];
|
function runExternalTests(testsDir) {
|
||||||
const errorTypes = {};
|
const testFiles = globby.sync(path.join(testsDir, "**/*.ts"));
|
||||||
let good = 0;
|
|
||||||
let skipped = 0;
|
|
||||||
|
|
||||||
rimraf.sync(errorsPath);
|
if (testFiles.length === 0) {
|
||||||
|
throw new Error(
|
||||||
const cp = spawn("node", [
|
[
|
||||||
"./bin/prettier.js",
|
"Couldn't find any test files.",
|
||||||
"--parser",
|
`Please make sure that \`${testsDir}\` exists and contains the TypeScript tests.`
|
||||||
"typescript",
|
].join("\n")
|
||||||
"--debug-check",
|
);
|
||||||
fileGlob
|
|
||||||
]);
|
|
||||||
|
|
||||||
cp.stdout.on("data", () => {
|
|
||||||
good++;
|
|
||||||
printStatus();
|
|
||||||
});
|
|
||||||
|
|
||||||
cp.stderr.on("data", err => {
|
|
||||||
const error = err.toString();
|
|
||||||
const { file, errorType } = splitFileAndError(error);
|
|
||||||
if (errorType.startsWith("SyntaxError:")) {
|
|
||||||
skipped++;
|
|
||||||
} else {
|
|
||||||
badFiles.push({ file, errorType, error });
|
|
||||||
errorTypes[errorType] = (errorTypes[errorType] || 0) + 1;
|
|
||||||
}
|
}
|
||||||
printStatus();
|
|
||||||
});
|
|
||||||
|
|
||||||
cp.on("close", () => {
|
const results = {
|
||||||
const total = badFiles.length + good + skipped;
|
good: [],
|
||||||
const percentNoError = (100 * (good + skipped) / total).toFixed(0);
|
skipped: [],
|
||||||
console.log(
|
bad: []
|
||||||
`\n${percentNoError}% of ${total} files processed without errors.\n`
|
|
||||||
);
|
|
||||||
Object.keys(errorTypes)
|
|
||||||
.sort((a, b) => errorTypes[b] - errorTypes[a])
|
|
||||||
.forEach(errorType => {
|
|
||||||
console.log(`${errorTypes[errorType]}\t${errorType}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(`\nWriting errors to '${errorsPath}' directory`);
|
|
||||||
writeErrorsToFiles();
|
|
||||||
});
|
|
||||||
|
|
||||||
function printStatus() {
|
|
||||||
process.stdout.write(
|
|
||||||
`\r${good} good, ${skipped} skipped, ${badFiles.length} bad`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function splitFileAndError(err) {
|
|
||||||
const lines = err.split("\n");
|
|
||||||
const [file, ...rest] = lines[0].split(":");
|
|
||||||
if (rest.length) {
|
|
||||||
return {
|
|
||||||
file,
|
|
||||||
errorType: rest
|
|
||||||
.join(":")
|
|
||||||
.replace(/\(\d+:\d+\)/, "")
|
|
||||||
.replace(/(Comment )".*"/, '$1"<omitted>"')
|
|
||||||
.trim()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
console.error("Could not process error:", err);
|
|
||||||
return {
|
|
||||||
file: "?",
|
|
||||||
errorType: err
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
function writeErrorsToFiles() {
|
testFiles.forEach(file => {
|
||||||
const splitter = "@".repeat(80);
|
const content = fs.readFileSync(file, "utf8");
|
||||||
fs.mkdirSync(errorsPath);
|
|
||||||
Object.keys(errorTypes).forEach(errorType => {
|
const error = tryFormat(content);
|
||||||
const files = badFiles.filter(f => f.errorType === errorType);
|
|
||||||
const contents = files
|
if (error instanceof SyntaxError) {
|
||||||
.map(({ file, error }) => {
|
results.skipped.push({ file, error });
|
||||||
// Trim file name from error.
|
} else if (error) {
|
||||||
if (error.startsWith(file)) {
|
results.bad.push({ file, error });
|
||||||
error = error.substring(file.length);
|
} else {
|
||||||
}
|
results.good.push({ file });
|
||||||
return `\n\n${file}\n${error}\n${splitter}\n`;
|
}
|
||||||
})
|
|
||||||
.join("\n");
|
process.stderr.write(
|
||||||
fs.writeFileSync(
|
`\r${results.good.length} good, ${results.skipped
|
||||||
path.join(errorsPath, sanitize(errorType) + ".log"),
|
.length} skipped, ${results.bad.length} bad`
|
||||||
contents
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sanitize(string) {
|
function run(argv) {
|
||||||
return string.replace(/[^A-Z0-9_.() -]/gi, "_").replace(/\.$/, "");
|
if (argv.length !== 1) {
|
||||||
|
console.error(
|
||||||
|
[
|
||||||
|
"You must provide the path to a TypeScript tests directory!",
|
||||||
|
"Example: node scripts/run-external-typescript-tests.js ../TypeScript/tests/"
|
||||||
|
].join("\n")
|
||||||
|
);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const testsDir = argv[0];
|
||||||
|
let results = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
results = runExternalTests(testsDir);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to run external tests.\n${error}`);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("");
|
||||||
|
console.log(
|
||||||
|
results.bad.map(data => `${data.file}\n${data.error}`).join("\n\n\n")
|
||||||
|
);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
const exitCode = run(process.argv.slice(2));
|
||||||
|
process.exit(exitCode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,6 +359,7 @@ function formatFiles(argv, filepatterns) {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
resolveConfig,
|
resolveConfig,
|
||||||
|
format,
|
||||||
formatStdin,
|
formatStdin,
|
||||||
formatFiles
|
formatFiles
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue