diff --git a/scripts/build/tests.js b/scripts/build/tests.js index 5c4bcfb07dbfc..5a6297768ee57 100644 --- a/scripts/build/tests.js +++ b/scripts/build/tests.js @@ -77,12 +77,23 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, // timeout normally isn"t necessary but Travis-CI has been timing out on compiler baselines occasionally // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer if (!runInParallel) { - args.push(failed ? "scripts/run-failed-tests.js" : mochaJs); + args.push(mochaJs); args.push("-R", "scripts/failed-tests"); args.push("-O", '"reporter=' + reporter + (keepFailed ? ",keepFailed=true" : "") + '"'); if (tests) { args.push("-g", `"${tests}"`); } + if (failed) { + const grep = fs.readFileSync(".failed-tests", "utf8") + .split(/\r?\n/g) + .map(test => test.trim()) + .filter(test => test.length > 0) + .map(regExpEscape) + .join("|"); + const file = path.join(os.tmpdir(), ".failed-tests.json"); + fs.writeFileSync(file, JSON.stringify({ grep }), "utf8"); + args.push("--config", file); + } if (colors) { args.push("--colors"); } @@ -203,3 +214,7 @@ function restoreSavedNodeEnv() { function deleteTemporaryProjectOutput() { return del(path.join(exports.localBaseline, "projectOutput/")); } + +function regExpEscape(text) { + return text.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&'); +} diff --git a/scripts/run-failed-tests.js b/scripts/run-failed-tests.js deleted file mode 100644 index bde06df11cb0e..0000000000000 --- a/scripts/run-failed-tests.js +++ /dev/null @@ -1,97 +0,0 @@ -const spawn = require('child_process').spawn; -const os = require("os"); -const fs = require("fs"); -const path = require("path"); - -let grep; -try { - const failedTests = fs.readFileSync(".failed-tests", "utf8"); - grep = failedTests - .split(/\r?\n/g) - .map(test => test.trim()) - .filter(test => test.length > 0) - .map(escapeRegExp); -} -catch (e) { - grep = []; -} - -let args = []; -let waitForGrepValue = false; -let grepIndex = -1; -process.argv.slice(2).forEach((arg, index) => { - const [flag, value] = arg.split('='); - if (flag === "g" || flag === "grep") { - grepIndex = index - 1; - waitForGrepValue = arg !== flag; - if (!waitForGrepValue) grep.push(value.replace(/^"|"$/g, "")); - return; - } - if (waitForGrepValue) { - grep.push(arg.replace(/^"|"$/g, "")); - waitForGrepValue = false; - return; - } - args.push(arg); -}); - -let mocha = "./node_modules/mocha/bin/mocha"; -let grepOption; -let grepOptionValue; -let grepFile; -if (grep.length) { - grepOption = "--grep"; - grepOptionValue = grep.join("|"); - if (grepOptionValue.length > 20) { - grepFile = path.resolve(os.tmpdir(), ".failed-tests.opts"); - fs.writeFileSync(grepFile, `--grep ${grepOptionValue}`, "utf8"); - grepOption = "--opts"; - grepOptionValue = grepFile; - mocha = "./node_modules/mocha/bin/_mocha"; - } -} - -if (grepOption) { - if (grepIndex >= 0) { - args.splice(grepIndex, 0, grepOption, grepOptionValue); - } - else { - args.push(grepOption, grepOptionValue); - } -} - -args.unshift(path.resolve(mocha)); - -console.log(args.join(" ")); -const proc = spawn(process.execPath, args, { - stdio: 'inherit' -}); -proc.on('exit', (code, signal) => { - process.on('exit', () => { - if (grepFile) { - try { - fs.unlinkSync(grepFile); - } - catch (e) { - if (e.code !== "ENOENT") throw e; - } - } - - if (signal) { - process.kill(process.pid, signal); - } else { - process.exit(code); - } - }); -}); - -process.on('SIGINT', () => { - proc.kill('SIGINT'); - proc.kill('SIGTERM'); -}); - -function escapeRegExp(pattern) { - return pattern - .replace(/[^-\w\d\s]/g, match => "\\" + match) - .replace(/\s/g, "\\s"); -} \ No newline at end of file