mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-11 09:24:19 -06:00
Remove RWC runner and related infrastructure (#55187)
This commit is contained in:
parent
9a771d54e8
commit
7eece9f798
@ -14,7 +14,7 @@ import util from "util";
|
||||
import { localizationDirectories } from "./scripts/build/localization.mjs";
|
||||
import cmdLineOptions from "./scripts/build/options.mjs";
|
||||
import { buildProject, cleanProject, watchProject } from "./scripts/build/projects.mjs";
|
||||
import { localBaseline, localRwcBaseline, refBaseline, refRwcBaseline, runConsoleTests } from "./scripts/build/tests.mjs";
|
||||
import { localBaseline, refBaseline, runConsoleTests } from "./scripts/build/tests.mjs";
|
||||
import { Debouncer, Deferred, exec, getDiffTool, memoize, needsUpdate, readJson } from "./scripts/build/utils.mjs";
|
||||
|
||||
const glob = util.promisify(_glob);
|
||||
@ -740,12 +740,6 @@ export const diff = task({
|
||||
run: () => exec(getDiffTool(), [refBaseline, localBaseline], { ignoreExitCode: true, waitForExit: false }),
|
||||
});
|
||||
|
||||
export const diffRwc = task({
|
||||
name: "diff-rwc",
|
||||
description: "Diffs the RWC baselines using the diff tool specified by the 'DIFF' environment variable",
|
||||
run: () => exec(getDiffTool(), [refRwcBaseline, localRwcBaseline], { ignoreExitCode: true, waitForExit: false }),
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {string} localBaseline Path to the local copy of the baselines
|
||||
* @param {string} refBaseline Path to the reference copy of the baselines
|
||||
@ -780,12 +774,6 @@ export const baselineAccept = task({
|
||||
run: baselineAcceptTask(localBaseline, refBaseline),
|
||||
});
|
||||
|
||||
export const baselineAcceptRwc = task({
|
||||
name: "baseline-accept-rwc",
|
||||
description: "Makes the most recent rwc test results the new baseline, overwriting the old baseline",
|
||||
run: baselineAcceptTask(localRwcBaseline, refRwcBaseline),
|
||||
});
|
||||
|
||||
// TODO(rbuckton): Determine if we still need this task. Depending on a relative
|
||||
// path here seems like a bad idea.
|
||||
export const updateSublime = task({
|
||||
@ -799,13 +787,6 @@ export const updateSublime = task({
|
||||
}
|
||||
});
|
||||
|
||||
// TODO(rbuckton): Should the path to DefinitelyTyped be configurable via an environment variable?
|
||||
export const importDefinitelyTypedTests = task({
|
||||
name: "importDefinitelyTypedTests",
|
||||
description: "Runs the importDefinitelyTypedTests script to copy DT's tests to the TS-internal RWC tests",
|
||||
run: () => exec(process.execPath, ["scripts/importDefinitelyTypedTests.mjs", "./", "../DefinitelyTyped"]),
|
||||
});
|
||||
|
||||
|
||||
export const produceLKG = task({
|
||||
name: "LKG",
|
||||
|
||||
@ -12,8 +12,6 @@ import { exec, ExecError } from "./utils.mjs";
|
||||
const mochaJs = path.resolve(findUpRoot(), "node_modules", "mocha", "bin", "_mocha");
|
||||
export const localBaseline = "tests/baselines/local/";
|
||||
export const refBaseline = "tests/baselines/reference/";
|
||||
export const localRwcBaseline = "internal/baselines/rwc/local";
|
||||
export const refRwcBaseline = "internal/baselines/rwc/reference";
|
||||
export const coverageDir = "coverage";
|
||||
|
||||
/**
|
||||
@ -25,7 +23,7 @@ export const coverageDir = "coverage";
|
||||
* @param {boolean} [options.watching]
|
||||
*/
|
||||
export async function runConsoleTests(runJs, defaultReporter, runInParallel, options = {}) {
|
||||
let testTimeout = cmdLineOptions.timeout;
|
||||
const testTimeout = cmdLineOptions.timeout;
|
||||
const tests = cmdLineOptions.tests;
|
||||
const inspect = cmdLineOptions.break || cmdLineOptions.inspect;
|
||||
const runners = cmdLineOptions.runners;
|
||||
@ -67,10 +65,6 @@ export async function runConsoleTests(runJs, defaultReporter, runInParallel, opt
|
||||
workerCount = cmdLineOptions.workers;
|
||||
}
|
||||
|
||||
if (tests && tests.toLocaleLowerCase() === "rwc") {
|
||||
testTimeout = 400000;
|
||||
}
|
||||
|
||||
if (options.watching) {
|
||||
console.log(chalk.yellowBright(`[watch] running tests...`));
|
||||
}
|
||||
@ -174,8 +168,7 @@ export async function runConsoleTests(runJs, defaultReporter, runInParallel, opt
|
||||
}
|
||||
|
||||
export async function cleanTestDirs() {
|
||||
await del([localBaseline, localRwcBaseline]);
|
||||
await fs.promises.mkdir(localRwcBaseline, { recursive: true });
|
||||
await del([localBaseline]);
|
||||
await fs.promises.mkdir(localBaseline, { recursive: true });
|
||||
}
|
||||
|
||||
|
||||
@ -1,178 +0,0 @@
|
||||
import * as childProcess from "child_process";
|
||||
import * as fs from "fs";
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
import url from "url";
|
||||
|
||||
const __filename = url.fileURLToPath(new URL(import.meta.url));
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
main();
|
||||
function main() {
|
||||
const [, progName, tscRoot, definitelyTypedRoot] = process.argv;
|
||||
if (process.argv.length !== 4) {
|
||||
if (process.argv.length < 2) {
|
||||
throw new Error("Expected at least 2 argv elements.");
|
||||
}
|
||||
console.log("Usage:");
|
||||
console.log(` node ${path.relative(__dirname, progName)} [TypeScript Repo Root] [DefinitelyTyped Repo Root]`);
|
||||
return;
|
||||
}
|
||||
|
||||
const tscPath = path.resolve(tscRoot, "built", "local", "tsc.js");
|
||||
const rwcTestPath = path.resolve(tscRoot, "internal", "cases", "rwc");
|
||||
const resolvedDefinitelyTypedRoot = path.resolve(definitelyTypedRoot);
|
||||
|
||||
console.log(`Resolved TypeScript Compiler Path: '${tscPath}'.`);
|
||||
console.log(`Resolved TypeScript RWC Path: '${rwcTestPath}'.`);
|
||||
console.log(`Resolved DefinitelyTyped Repo Root: '${resolvedDefinitelyTypedRoot}'.`);
|
||||
importDefinitelyTypedTests(tscPath, rwcTestPath, resolvedDefinitelyTypedRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @param {string} endingString
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function filePathEndsWith(path, endingString) {
|
||||
const pathLen = path.length;
|
||||
const extLen = endingString.length;
|
||||
return pathLen > extLen && path.substr(pathLen - extLen, extLen).toLocaleLowerCase() === endingString.toLocaleLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} source
|
||||
* @param {string} destination
|
||||
*/
|
||||
function copyFileSync(source, destination) {
|
||||
const text = fs.readFileSync(source);
|
||||
fs.writeFileSync(destination, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} tscPath
|
||||
* @param {string} rwcTestPath
|
||||
* @param {string} testCaseName
|
||||
* @param {string[]} testFiles
|
||||
* @param {string | undefined} responseFile
|
||||
*/
|
||||
function importDefinitelyTypedTest(tscPath, rwcTestPath, testCaseName, testFiles, responseFile) {
|
||||
let cmd = "node " + tscPath + " --module commonjs " + testFiles.join(" ");
|
||||
if (responseFile) {
|
||||
cmd += " @" + responseFile;
|
||||
}
|
||||
|
||||
const testDirectoryName = testCaseName + "_" + Math.floor((Math.random() * 10000) + 1);
|
||||
const testDirectoryPath = path.join(os.tmpdir(), testDirectoryName);
|
||||
if (fs.existsSync(testDirectoryPath)) {
|
||||
throw new Error("Could not create test directory");
|
||||
}
|
||||
fs.mkdirSync(testDirectoryPath);
|
||||
|
||||
childProcess.exec(cmd, {
|
||||
maxBuffer: 1 * 1024 * 1024,
|
||||
cwd: testDirectoryPath
|
||||
}, (error, stdout, stderr) => {
|
||||
console.log("importing " + testCaseName + " ...");
|
||||
console.log(cmd);
|
||||
|
||||
if (error) {
|
||||
console.log("importing " + testCaseName + " ...");
|
||||
console.log(cmd);
|
||||
console.log("==> error " + JSON.stringify(error));
|
||||
console.log("==> stdout " + String(stdout));
|
||||
console.log("==> stderr " + String(stderr));
|
||||
console.log("\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// copy generated file to output location
|
||||
const outputFilePath = path.join(testDirectoryPath, "iocapture0.json");
|
||||
const testCasePath = path.join(rwcTestPath, "DefinitelyTyped_" + testCaseName + ".json");
|
||||
copyFileSync(outputFilePath, testCasePath);
|
||||
|
||||
//console.log("output generated at: " + outputFilePath);
|
||||
|
||||
if (!fs.existsSync(testCasePath)) {
|
||||
throw new Error("could not find test case at: " + testCasePath);
|
||||
}
|
||||
else {
|
||||
fs.unlinkSync(outputFilePath);
|
||||
fs.rmdirSync(testDirectoryPath);
|
||||
//console.log("testcase generated at: " + testCasePath);
|
||||
//console.log("Done.");
|
||||
}
|
||||
//console.log("\r\n");
|
||||
|
||||
}).on("error", (error) => {
|
||||
console.log("==> error " + JSON.stringify(error));
|
||||
console.log("\r\n");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} tscPath
|
||||
* @param {string} rwcTestPath
|
||||
* @param {string} definitelyTypedRoot
|
||||
*/
|
||||
function importDefinitelyTypedTests(tscPath, rwcTestPath, definitelyTypedRoot) {
|
||||
fs.readdir(definitelyTypedRoot, (err, subDirectories) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
// When you just want to test the script out on one or two files,
|
||||
// just add a line like the following:
|
||||
//
|
||||
// .filter(d => d.indexOf("sipml") >= 0 )
|
||||
subDirectories
|
||||
.filter(d => ["_infrastructure", "node_modules", ".git"].indexOf(d) < 0)
|
||||
.filter(i => fs.statSync(path.join(definitelyTypedRoot, i)).isDirectory())
|
||||
.forEach(d => {
|
||||
const directoryPath = path.join(definitelyTypedRoot, d);
|
||||
fs.readdir(directoryPath, (err, files) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
/** @type {string[]} */
|
||||
const tsFiles = [];
|
||||
/** @type {string[]} */
|
||||
const testFiles = [];
|
||||
/** @type {string | undefined} */
|
||||
let paramFile;
|
||||
|
||||
for (const filePath of files.map(f => path.join(directoryPath, f))) {
|
||||
if (filePathEndsWith(filePath, ".ts")) {
|
||||
tsFiles.push(filePath);
|
||||
|
||||
if (filePathEndsWith(filePath, "-tests.ts")) {
|
||||
testFiles.push(filePath);
|
||||
}
|
||||
}
|
||||
else if (filePathEndsWith(filePath, ".tscparams")) {
|
||||
paramFile = filePath;
|
||||
}
|
||||
}
|
||||
|
||||
if (testFiles.length === 0) {
|
||||
// no test files but multiple d.ts's, e.g. winjs
|
||||
const regexp = new RegExp(d + "(([-][0-9])|(\\.d\\.ts))");
|
||||
if (tsFiles.length > 1 && tsFiles.every(t => filePathEndsWith(t, ".d.ts") && regexp.test(t))) {
|
||||
for (const fileName of tsFiles) {
|
||||
importDefinitelyTypedTest(tscPath, rwcTestPath, path.basename(fileName, ".d.ts"), [fileName], paramFile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
importDefinitelyTypedTest(tscPath, rwcTestPath, d, tsFiles, paramFile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const fileName of tsFiles) {
|
||||
importDefinitelyTypedTest(tscPath, rwcTestPath, path.basename(fileName, "-tests.ts"), [fileName], paramFile);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -5,7 +5,7 @@ import {
|
||||
} from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
|
||||
export type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc";
|
||||
export type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project";
|
||||
export type CompilerTestKind = "conformance" | "compiler";
|
||||
export type FourslashTestKind = "fourslash" | "fourslash-shims" | "fourslash-shims-pp" | "fourslash-server";
|
||||
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
/* Generated file to emulate the Harness namespace. */
|
||||
|
||||
export * from "../../harness/_namespaces/Harness";
|
||||
export * from "../loggedIO";
|
||||
@ -1,3 +0,0 @@
|
||||
/* Generated file to emulate the Playback namespace. */
|
||||
|
||||
export * from "../loggedIO";
|
||||
@ -1,7 +0,0 @@
|
||||
/* Generated file to emulate the ts.server namespace. */
|
||||
|
||||
export * from "../../jsTyping/_namespaces/ts.server";
|
||||
export * from "../../server/_namespaces/ts.server";
|
||||
export * from "../../typingsInstallerCore/_namespaces/ts.server";
|
||||
export * from "../../harness/_namespaces/ts.server";
|
||||
export * from "../loggedIO";
|
||||
@ -1,10 +0,0 @@
|
||||
/* Generated file to emulate the ts namespace. */
|
||||
|
||||
export * from "../../compiler/_namespaces/ts";
|
||||
export * from "../../services/_namespaces/ts";
|
||||
export * from "../../jsTyping/_namespaces/ts";
|
||||
export * from "../../server/_namespaces/ts";
|
||||
export * from "../../typingsInstallerCore/_namespaces/ts";
|
||||
export * from "../../harness/_namespaces/ts";
|
||||
import * as server from "./ts.server";
|
||||
export { server };
|
||||
@ -1,450 +0,0 @@
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
|
||||
interface FileInformation {
|
||||
contents?: string;
|
||||
contentsPath?: string;
|
||||
codepage: number;
|
||||
bom?: string;
|
||||
}
|
||||
|
||||
interface FindFileResult {
|
||||
}
|
||||
|
||||
interface IoLogFile {
|
||||
path: string;
|
||||
codepage: number;
|
||||
result?: FileInformation;
|
||||
}
|
||||
|
||||
export interface IoLog {
|
||||
timestamp: string;
|
||||
arguments: string[];
|
||||
executingPath: string;
|
||||
currentDirectory: string;
|
||||
useCustomLibraryFile?: boolean;
|
||||
filesRead: IoLogFile[];
|
||||
filesWritten: {
|
||||
path: string;
|
||||
contents?: string;
|
||||
contentsPath?: string;
|
||||
bom: boolean;
|
||||
}[];
|
||||
filesDeleted: string[];
|
||||
filesAppended: {
|
||||
path: string;
|
||||
contents?: string;
|
||||
contentsPath?: string;
|
||||
}[];
|
||||
fileExists: {
|
||||
path: string;
|
||||
result?: boolean;
|
||||
}[];
|
||||
filesFound: {
|
||||
path: string;
|
||||
pattern: string;
|
||||
result?: FindFileResult;
|
||||
}[];
|
||||
dirs: {
|
||||
path: string;
|
||||
re: string;
|
||||
re_m: boolean;
|
||||
re_g: boolean;
|
||||
re_i: boolean;
|
||||
opts: { recursive?: boolean; };
|
||||
result?: string[];
|
||||
}[];
|
||||
dirExists: {
|
||||
path: string;
|
||||
result?: boolean;
|
||||
}[];
|
||||
dirsCreated: string[];
|
||||
pathsResolved: {
|
||||
path: string;
|
||||
result?: string;
|
||||
}[];
|
||||
directoriesRead: {
|
||||
path: string,
|
||||
extensions: readonly string[] | undefined,
|
||||
exclude: readonly string[] | undefined,
|
||||
include: readonly string[] | undefined,
|
||||
depth: number | undefined,
|
||||
result: readonly string[],
|
||||
}[];
|
||||
useCaseSensitiveFileNames?: boolean;
|
||||
}
|
||||
|
||||
interface PlaybackControl {
|
||||
startReplayFromFile(logFileName: string): void;
|
||||
startReplayFromString(logContents: string): void;
|
||||
startReplayFromData(log: IoLog): void;
|
||||
endReplay(): void;
|
||||
startRecord(logFileName: string): void;
|
||||
endRecord(): void;
|
||||
}
|
||||
|
||||
let recordLog: IoLog | undefined;
|
||||
let replayLog: IoLog | undefined;
|
||||
let replayFilesRead: Map<string, IoLogFile> | undefined;
|
||||
let recordLogFileNameBase = "";
|
||||
|
||||
interface Memoized<T> {
|
||||
(s: string): T;
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
function memoize<T>(func: (s: string) => T): Memoized<T> {
|
||||
let lookup: { [s: string]: T } = {};
|
||||
const run: Memoized<T> = ((s: string) => {
|
||||
if (ts.hasProperty(lookup, s)) return lookup[s];
|
||||
return lookup[s] = func(s);
|
||||
}) as Memoized<T>;
|
||||
run.reset = () => {
|
||||
lookup = undefined!; // TODO: GH#18217
|
||||
};
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
export interface PlaybackIO extends Harness.IO, PlaybackControl { }
|
||||
|
||||
export interface PlaybackSystem extends ts.System, PlaybackControl { }
|
||||
|
||||
function createEmptyLog(): IoLog {
|
||||
return {
|
||||
timestamp: (new Date()).toString(),
|
||||
arguments: [],
|
||||
currentDirectory: "",
|
||||
filesRead: [],
|
||||
directoriesRead: [],
|
||||
filesWritten: [],
|
||||
filesDeleted: [],
|
||||
filesAppended: [],
|
||||
fileExists: [],
|
||||
filesFound: [],
|
||||
dirs: [],
|
||||
dirExists: [],
|
||||
dirsCreated: [],
|
||||
pathsResolved: [],
|
||||
executingPath: ""
|
||||
};
|
||||
}
|
||||
|
||||
export function newStyleLogIntoOldStyleLog(log: IoLog, host: ts.System | Harness.IO, baseName: string) {
|
||||
for (const file of log.filesAppended) {
|
||||
if (file.contentsPath) {
|
||||
file.contents = host.readFile(ts.combinePaths(baseName, file.contentsPath));
|
||||
delete file.contentsPath;
|
||||
}
|
||||
}
|
||||
for (const file of log.filesWritten) {
|
||||
if (file.contentsPath) {
|
||||
file.contents = host.readFile(ts.combinePaths(baseName, file.contentsPath));
|
||||
delete file.contentsPath;
|
||||
}
|
||||
}
|
||||
for (const file of log.filesRead) {
|
||||
const result = file.result!; // TODO: GH#18217
|
||||
if (result.contentsPath) {
|
||||
// `readFile` strips away a BOM (and actually reinerprets the file contents according to the correct encoding)
|
||||
// - but this has the unfortunate sideeffect of removing the BOM from any outputs based on the file, so we readd it here.
|
||||
result.contents = (result.bom || "") + host.readFile(ts.combinePaths(baseName, result.contentsPath));
|
||||
delete result.contentsPath;
|
||||
}
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
const canonicalizeForHarness = ts.createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ false); // This is done so tests work on windows _and_ linux
|
||||
function sanitizeTestFilePath(name: string) {
|
||||
const path = ts.toPath(ts.normalizeSlashes(name.replace(/[\^<>:"|?*%]/g, "_")).replace(/\.\.\//g, "__dotdot/"), "", canonicalizeForHarness);
|
||||
if (ts.startsWith(path, "/")) {
|
||||
return path.substring(1);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
export function oldStyleLogIntoNewStyleLog(log: IoLog, writeFile: typeof Harness.IO.writeFile, baseTestName: string) {
|
||||
if (log.filesAppended) {
|
||||
for (const file of log.filesAppended) {
|
||||
if (file.contents !== undefined) {
|
||||
file.contentsPath = ts.combinePaths("appended", sanitizeTestFilePath(file.path));
|
||||
writeFile(ts.combinePaths(baseTestName, file.contentsPath), file.contents);
|
||||
delete file.contents;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (log.filesWritten) {
|
||||
for (const file of log.filesWritten) {
|
||||
if (file.contents !== undefined) {
|
||||
file.contentsPath = ts.combinePaths("written", sanitizeTestFilePath(file.path));
|
||||
writeFile(ts.combinePaths(baseTestName, file.contentsPath), file.contents);
|
||||
delete file.contents;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (log.filesRead) {
|
||||
for (const file of log.filesRead) {
|
||||
const result = file.result!; // TODO: GH#18217
|
||||
const { contents } = result;
|
||||
if (contents !== undefined) {
|
||||
result.contentsPath = ts.combinePaths("read", sanitizeTestFilePath(file.path));
|
||||
writeFile(ts.combinePaths(baseTestName, result.contentsPath), contents);
|
||||
const len = contents.length;
|
||||
if (len >= 2 && contents.charCodeAt(0) === 0xfeff) {
|
||||
result.bom = "\ufeff";
|
||||
}
|
||||
if (len >= 2 && contents.charCodeAt(0) === 0xfffe) {
|
||||
result.bom = "\ufffe";
|
||||
}
|
||||
if (len >= 3 && contents.charCodeAt(0) === 0xefbb && contents.charCodeAt(1) === 0xbf) {
|
||||
result.bom = "\uefbb\xbf";
|
||||
}
|
||||
delete result.contents;
|
||||
}
|
||||
}
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
export function initWrapper(...[wrapper, underlying]: [PlaybackSystem, ts.System] | [PlaybackIO, Harness.IO]): void {
|
||||
ts.forEach(Object.keys(underlying), prop => {
|
||||
(wrapper as any)[prop] = (underlying as any)[prop];
|
||||
});
|
||||
|
||||
wrapper.startReplayFromString = logString => {
|
||||
wrapper.startReplayFromData(JSON.parse(logString));
|
||||
};
|
||||
wrapper.startReplayFromData = log => {
|
||||
replayLog = log;
|
||||
// Remove non-found files from the log (shouldn't really need them, but we still record them for diagnostic purposes)
|
||||
replayLog.filesRead = replayLog.filesRead.filter(f => f.result!.contents !== undefined);
|
||||
replayFilesRead = new Map();
|
||||
for (const file of replayLog.filesRead) {
|
||||
replayFilesRead.set(ts.normalizeSlashes(file.path).toLowerCase(), file);
|
||||
}
|
||||
};
|
||||
|
||||
wrapper.endReplay = () => {
|
||||
replayLog = undefined;
|
||||
replayFilesRead = undefined;
|
||||
};
|
||||
|
||||
wrapper.startRecord = (fileNameBase) => {
|
||||
recordLogFileNameBase = fileNameBase;
|
||||
recordLog = createEmptyLog();
|
||||
recordLog.useCaseSensitiveFileNames = typeof underlying.useCaseSensitiveFileNames === "function" ? underlying.useCaseSensitiveFileNames() : underlying.useCaseSensitiveFileNames;
|
||||
if (typeof underlying.args !== "function") {
|
||||
recordLog.arguments = underlying.args;
|
||||
}
|
||||
};
|
||||
|
||||
wrapper.startReplayFromFile = logFn => {
|
||||
wrapper.startReplayFromString(underlying.readFile(logFn)!);
|
||||
};
|
||||
wrapper.endRecord = () => {
|
||||
if (recordLog !== undefined) {
|
||||
let i = 0;
|
||||
const getBase = () => recordLogFileNameBase + i;
|
||||
while (underlying.fileExists(ts.combinePaths(getBase(), "test.json"))) i++;
|
||||
const newLog = oldStyleLogIntoNewStyleLog(recordLog, (path, str) => underlying.writeFile(path, str), getBase());
|
||||
underlying.writeFile(ts.combinePaths(getBase(), "test.json"), JSON.stringify(newLog, null, 4)); // eslint-disable-line no-null/no-null
|
||||
const syntheticTsconfig = generateTsconfig(newLog);
|
||||
if (syntheticTsconfig) {
|
||||
underlying.writeFile(ts.combinePaths(getBase(), "tsconfig.json"), JSON.stringify(syntheticTsconfig, null, 4)); // eslint-disable-line no-null/no-null
|
||||
}
|
||||
recordLog = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
function generateTsconfig(newLog: IoLog): undefined | { compilerOptions: ts.CompilerOptions, files: string[] } {
|
||||
if (newLog.filesRead.some(file => /tsconfig.+json$/.test(file.path))) {
|
||||
return;
|
||||
}
|
||||
const files = [];
|
||||
for (const file of newLog.filesRead) {
|
||||
const result = file.result!;
|
||||
if (result.contentsPath &&
|
||||
Harness.isDefaultLibraryFile(result.contentsPath) &&
|
||||
/\.[tj]s$/.test(result.contentsPath)) {
|
||||
files.push(result.contentsPath);
|
||||
}
|
||||
}
|
||||
return { compilerOptions: ts.parseCommandLine(newLog.arguments).options, files };
|
||||
}
|
||||
|
||||
wrapper.fileExists = recordReplay(wrapper.fileExists, underlying)(
|
||||
path => callAndRecord(underlying.fileExists(path), recordLog!.fileExists, { path }),
|
||||
memoize(path => {
|
||||
// If we read from the file, it must exist
|
||||
if (findFileByPath(path, /*throwFileNotFoundError*/ false)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return findResultByFields(replayLog!.fileExists, { path }, /*defaultValue*/ false)!;
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
wrapper.getExecutingFilePath = () => {
|
||||
if (replayLog !== undefined) {
|
||||
return replayLog.executingPath;
|
||||
}
|
||||
else if (recordLog !== undefined) {
|
||||
return recordLog.executingPath = underlying.getExecutingFilePath();
|
||||
}
|
||||
else {
|
||||
return underlying.getExecutingFilePath();
|
||||
}
|
||||
};
|
||||
|
||||
wrapper.getCurrentDirectory = () => {
|
||||
if (replayLog !== undefined) {
|
||||
return replayLog.currentDirectory || "";
|
||||
}
|
||||
else if (recordLog !== undefined) {
|
||||
return recordLog.currentDirectory = underlying.getCurrentDirectory();
|
||||
}
|
||||
else {
|
||||
return underlying.getCurrentDirectory();
|
||||
}
|
||||
};
|
||||
|
||||
wrapper.resolvePath = recordReplay(wrapper.resolvePath, underlying)(
|
||||
path => callAndRecord(underlying.resolvePath(path), recordLog!.pathsResolved, { path }),
|
||||
memoize(path => findResultByFields(replayLog!.pathsResolved, { path }, !ts.isRootedDiskPath(ts.normalizeSlashes(path)) && replayLog!.currentDirectory ? replayLog!.currentDirectory + "/" + path : ts.normalizeSlashes(path))));
|
||||
|
||||
wrapper.readFile = recordReplay(wrapper.readFile, underlying)(
|
||||
(path: string) => {
|
||||
const result = underlying.readFile(path);
|
||||
const logEntry = { path, codepage: 0, result: { contents: result, codepage: 0 } };
|
||||
recordLog!.filesRead.push(logEntry);
|
||||
return result;
|
||||
},
|
||||
memoize(path => findFileByPath(path, /*throwFileNotFoundError*/ true)!.contents));
|
||||
|
||||
wrapper.readDirectory = recordReplay(wrapper.readDirectory, underlying)(
|
||||
(path, extensions, exclude, include, depth) => {
|
||||
const result = (underlying as ts.System).readDirectory(path, extensions, exclude, include, depth);
|
||||
recordLog!.directoriesRead.push({ path, extensions, exclude, include, depth, result });
|
||||
return result;
|
||||
},
|
||||
path => {
|
||||
// Because extensions is an array of all allowed extension, we will want to merge each of the replayLog.directoriesRead into one
|
||||
// if each of the directoriesRead has matched path with the given path (directory with same path but different extension will considered
|
||||
// different entry).
|
||||
// TODO (yuisu): We can certainly remove these once we recapture the RWC using new API
|
||||
const normalizedPath = ts.normalizePath(path).toLowerCase();
|
||||
return ts.flatMap(replayLog!.directoriesRead, directory => {
|
||||
if (ts.normalizeSlashes(directory.path).toLowerCase() === normalizedPath) {
|
||||
return directory.result;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
wrapper.writeFile = recordReplay(wrapper.writeFile, underlying)(
|
||||
(path: string, contents: string) => callAndRecord(underlying.writeFile(path, contents), recordLog!.filesWritten, { path, contents, bom: false }),
|
||||
() => noOpReplay("writeFile"));
|
||||
|
||||
wrapper.exit = (exitCode) => {
|
||||
if (recordLog !== undefined) {
|
||||
wrapper.endRecord();
|
||||
}
|
||||
underlying.exit(exitCode);
|
||||
};
|
||||
|
||||
wrapper.useCaseSensitiveFileNames = () => {
|
||||
if (replayLog !== undefined) {
|
||||
return !!replayLog.useCaseSensitiveFileNames;
|
||||
}
|
||||
return typeof underlying.useCaseSensitiveFileNames === "function" ? underlying.useCaseSensitiveFileNames() : underlying.useCaseSensitiveFileNames;
|
||||
};
|
||||
}
|
||||
|
||||
function recordReplay<T extends ts.AnyFunction>(original: T, underlying: any) {
|
||||
function createWrapper(record: T, replay: T): T {
|
||||
// eslint-disable-next-line local/only-arrow-functions
|
||||
return (function () {
|
||||
if (replayLog !== undefined) {
|
||||
return replay.apply(undefined, arguments);
|
||||
}
|
||||
else if (recordLog !== undefined) {
|
||||
return record.apply(undefined, arguments);
|
||||
}
|
||||
else {
|
||||
return original.apply(underlying, arguments);
|
||||
}
|
||||
} as any);
|
||||
}
|
||||
return createWrapper;
|
||||
}
|
||||
|
||||
function callAndRecord<T, U>(underlyingResult: T, logArray: U[], logEntry: U): T {
|
||||
if (underlyingResult !== undefined) {
|
||||
(logEntry as any).result = underlyingResult;
|
||||
}
|
||||
logArray.push(logEntry);
|
||||
return underlyingResult;
|
||||
}
|
||||
|
||||
function findResultByFields<T>(logArray: { result?: T }[], expectedFields: {}, defaultValue?: T): T | undefined {
|
||||
const predicate = (entry: { result?: T }) => {
|
||||
return Object.getOwnPropertyNames(expectedFields).every((name) => (entry as any)[name] === (expectedFields as any)[name]);
|
||||
};
|
||||
const results = logArray.filter(entry => predicate(entry));
|
||||
if (results.length === 0) {
|
||||
if (defaultValue !== undefined) {
|
||||
return defaultValue;
|
||||
}
|
||||
else {
|
||||
throw new Error("No matching result in log array for: " + JSON.stringify(expectedFields));
|
||||
}
|
||||
}
|
||||
return results[0].result;
|
||||
}
|
||||
|
||||
function findFileByPath(expectedPath: string, throwFileNotFoundError: boolean): FileInformation | undefined {
|
||||
const normalizedName = ts.normalizePath(expectedPath).toLowerCase();
|
||||
// Try to find the result through normal fileName
|
||||
const result = replayFilesRead!.get(normalizedName);
|
||||
if (result) {
|
||||
return result.result;
|
||||
}
|
||||
|
||||
// If we got here, we didn't find a match
|
||||
if (throwFileNotFoundError) {
|
||||
throw new Error("No matching result in log array for path: " + expectedPath);
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function noOpReplay(_name: string) {
|
||||
// console.log("Swallowed write operation during replay: " + name);
|
||||
}
|
||||
|
||||
export function wrapIO(underlying: Harness.IO): PlaybackIO {
|
||||
const wrapper: PlaybackIO = {} as any;
|
||||
initWrapper(wrapper, underlying);
|
||||
|
||||
wrapper.directoryName = notSupported;
|
||||
wrapper.createDirectory = notSupported;
|
||||
wrapper.directoryExists = notSupported;
|
||||
wrapper.deleteFile = notSupported;
|
||||
wrapper.listFiles = notSupported;
|
||||
|
||||
return wrapper;
|
||||
|
||||
function notSupported(): never {
|
||||
throw new Error("NotSupported");
|
||||
}
|
||||
}
|
||||
|
||||
export function wrapSystem(underlying: ts.System): PlaybackSystem {
|
||||
const wrapper: PlaybackSystem = {} as any;
|
||||
initWrapper(wrapper, underlying);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
// empty modules for the module migration script
|
||||
@ -1,17 +0,0 @@
|
||||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"compilerOptions": {
|
||||
"types": [
|
||||
]
|
||||
},
|
||||
"references": [
|
||||
{ "path": "../compiler" },
|
||||
{ "path": "../services" },
|
||||
{ "path": "../jsTyping" },
|
||||
{ "path": "../server" },
|
||||
{ "path": "../typingsInstallerCore" },
|
||||
{ "path": "../harness" },
|
||||
],
|
||||
|
||||
"include": ["**/*"]
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
/* Generated file to emulate the Harness namespace. */
|
||||
|
||||
export * from "../../harness/_namespaces/Harness";
|
||||
export * from "../../loggedIO/_namespaces/Harness";
|
||||
|
||||
import * as Parallel from "./Harness.Parallel";
|
||||
export { Parallel };
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
/* Generated file to emulate the Playback namespace. */
|
||||
|
||||
export * from "../../loggedIO/_namespaces/Playback";
|
||||
@ -1,3 +0,0 @@
|
||||
/* Generated file to emulate the RWC namespace. */
|
||||
|
||||
export * from "../rwcRunner";
|
||||
@ -4,4 +4,3 @@ export * from "../../jsTyping/_namespaces/ts.server";
|
||||
export * from "../../server/_namespaces/ts.server";
|
||||
export * from "../../typingsInstallerCore/_namespaces/ts.server";
|
||||
export * from "../../harness/_namespaces/ts.server";
|
||||
export * from "../../loggedIO/_namespaces/ts.server";
|
||||
|
||||
@ -8,6 +8,5 @@ export * from "../../server/_namespaces/ts";
|
||||
export * from "../../typingsInstallerCore/_namespaces/ts";
|
||||
export * from "../../deprecatedCompat/_namespaces/ts";
|
||||
export * from "../../harness/_namespaces/ts";
|
||||
export * from "../../loggedIO/_namespaces/ts";
|
||||
import * as server from "./ts.server";
|
||||
export { server };
|
||||
|
||||
@ -13,7 +13,6 @@ import {
|
||||
TestRunnerKind,
|
||||
} from "./_namespaces/Harness";
|
||||
import * as project from "./_namespaces/project";
|
||||
import * as RWC from "./_namespaces/RWC";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
|
||||
@ -72,8 +71,6 @@ export function createRunner(kind: TestRunnerKind): RunnerBase {
|
||||
return new FourSlashRunner(FourSlash.FourSlashTestType.Server);
|
||||
case "project":
|
||||
return new project.ProjectRunner();
|
||||
case "rwc":
|
||||
return new RWC.RWCRunner();
|
||||
}
|
||||
return ts.Debug.fail(`Unknown runner kind ${kind}`);
|
||||
}
|
||||
@ -205,8 +202,6 @@ function handleTestConfig() {
|
||||
case "fourslash-generated":
|
||||
runners.push(new GeneratedFourslashRunner(FourSlash.FourSlashTestType.Native));
|
||||
break;
|
||||
case "rwc":
|
||||
runners.push(new RWC.RWCRunner());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,239 +0,0 @@
|
||||
import * as compiler from "./_namespaces/compiler";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as Playback from "./_namespaces/Playback";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
|
||||
// In harness baselines, null is different than undefined. See `generateActual` in `harness.ts`.
|
||||
function runWithIOLog(ioLog: Playback.IoLog, fn: (oldIO: Harness.IO) => void) {
|
||||
const oldIO = Harness.IO;
|
||||
|
||||
const wrappedIO = Playback.wrapIO(oldIO);
|
||||
wrappedIO.startReplayFromData(ioLog);
|
||||
Harness.setHarnessIO(wrappedIO);
|
||||
|
||||
try {
|
||||
fn(oldIO);
|
||||
}
|
||||
finally {
|
||||
wrappedIO.endReplay();
|
||||
Harness.setHarnessIO(oldIO);
|
||||
}
|
||||
}
|
||||
|
||||
export function runRWCTest(jsonPath: string) {
|
||||
describe("Testing a rwc project: " + jsonPath, () => {
|
||||
let inputFiles: Harness.Compiler.TestFile[] = [];
|
||||
let otherFiles: Harness.Compiler.TestFile[] = [];
|
||||
let tsconfigFiles: Harness.Compiler.TestFile[] = [];
|
||||
let compilerResult: compiler.CompilationResult;
|
||||
let compilerOptions: ts.CompilerOptions;
|
||||
const baselineOpts: Harness.Baseline.BaselineOptions = {
|
||||
Subfolder: "rwc",
|
||||
Baselinefolder: "internal/baselines"
|
||||
};
|
||||
const baseName = ts.getBaseFileName(jsonPath);
|
||||
let currentDirectory: string;
|
||||
let useCustomLibraryFile: boolean;
|
||||
let caseSensitive: boolean;
|
||||
after(() => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Therefore we have to clean out large objects after the test is done.
|
||||
inputFiles = [];
|
||||
otherFiles = [];
|
||||
tsconfigFiles = [];
|
||||
compilerResult = undefined!;
|
||||
compilerOptions = undefined!;
|
||||
currentDirectory = undefined!;
|
||||
// useCustomLibraryFile is a flag specified in the json object to indicate whether to use built/local/lib.d.ts
|
||||
// or to use lib.d.ts inside the json object. If the flag is true, use the lib.d.ts inside json file
|
||||
// otherwise use the lib.d.ts from built/local
|
||||
useCustomLibraryFile = false;
|
||||
caseSensitive = false;
|
||||
});
|
||||
|
||||
it("can compile", function (this: Mocha.Context) {
|
||||
this.timeout(800_000); // Allow long timeouts for RWC compilations
|
||||
let opts!: ts.ParsedCommandLine;
|
||||
|
||||
const ioLog: Playback.IoLog = Playback.newStyleLogIntoOldStyleLog(JSON.parse(Harness.IO.readFile(`internal/cases/rwc/${jsonPath}/test.json`)!), Harness.IO, `internal/cases/rwc/${baseName}`);
|
||||
currentDirectory = ioLog.currentDirectory;
|
||||
useCustomLibraryFile = !!ioLog.useCustomLibraryFile;
|
||||
runWithIOLog(ioLog, () => {
|
||||
opts = ts.parseCommandLine(ioLog.arguments, fileName => Harness.IO.readFile(fileName));
|
||||
assert.equal(opts.errors.length, 0);
|
||||
|
||||
// To provide test coverage of output javascript file,
|
||||
// we will set noEmitOnError flag to be false.
|
||||
opts.options.noEmitOnError = false;
|
||||
});
|
||||
let fileNames = opts.fileNames;
|
||||
|
||||
runWithIOLog(ioLog, () => {
|
||||
const tsconfigFile = ts.forEach(ioLog.filesRead, f => vpath.isTsConfigFile(f.path) ? f : undefined);
|
||||
if (tsconfigFile) {
|
||||
const tsconfigFileContents = getHarnessCompilerInputUnit(tsconfigFile.path);
|
||||
tsconfigFiles.push({ unitName: tsconfigFile.path, content: tsconfigFileContents.content });
|
||||
const parsedTsconfigFileContents = ts.parseJsonText(tsconfigFile.path, tsconfigFileContents.content);
|
||||
const configParseHost: ts.ParseConfigHost = {
|
||||
useCaseSensitiveFileNames: Harness.IO.useCaseSensitiveFileNames(),
|
||||
fileExists: Harness.IO.fileExists,
|
||||
readDirectory: Harness.IO.readDirectory,
|
||||
readFile: Harness.IO.readFile
|
||||
};
|
||||
const configParseResult = ts.parseJsonSourceFileConfigFileContent(parsedTsconfigFileContents, configParseHost, ts.getDirectoryPath(tsconfigFile.path));
|
||||
fileNames = configParseResult.fileNames;
|
||||
opts.options = ts.extend(opts.options, configParseResult.options);
|
||||
ts.setConfigFileInOptions(opts.options, configParseResult.options.configFile);
|
||||
}
|
||||
|
||||
// Deduplicate files so they are only printed once in baselines (they are deduplicated within the compiler already)
|
||||
const uniqueNames = new Map<string, true>();
|
||||
for (const fileName of fileNames) {
|
||||
// Must maintain order, build result list while checking map
|
||||
const normalized = ts.normalizeSlashes(Harness.IO.resolvePath(fileName)!);
|
||||
if (!uniqueNames.has(normalized)) {
|
||||
uniqueNames.set(normalized, true);
|
||||
// Load the file
|
||||
inputFiles.push(getHarnessCompilerInputUnit(fileName));
|
||||
}
|
||||
}
|
||||
|
||||
// Add files to compilation
|
||||
for (const fileRead of ioLog.filesRead) {
|
||||
const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileRead.path)!);
|
||||
if (!uniqueNames.has(unitName) && !Harness.isDefaultLibraryFile(fileRead.path)) {
|
||||
uniqueNames.set(unitName, true);
|
||||
otherFiles.push(getHarnessCompilerInputUnit(fileRead.path));
|
||||
}
|
||||
else if (!opts.options.noLib && Harness.isDefaultLibraryFile(fileRead.path) && !uniqueNames.has(unitName) && useCustomLibraryFile) {
|
||||
// If useCustomLibraryFile is true, we will use lib.d.ts from json object
|
||||
// otherwise use the lib.d.ts from built/local
|
||||
// Majority of RWC code will be using built/local/lib.d.ts instead of
|
||||
// lib.d.ts inside json file. However, some RWC cases will still use
|
||||
// their own version of lib.d.ts because they have customized lib.d.ts
|
||||
uniqueNames.set(unitName, true);
|
||||
inputFiles.push(getHarnessCompilerInputUnit(fileRead.path));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (useCustomLibraryFile) {
|
||||
// do not use lib since we already read it in above
|
||||
opts.options.lib = undefined;
|
||||
opts.options.noLib = true;
|
||||
}
|
||||
|
||||
caseSensitive = ioLog.useCaseSensitiveFileNames || false;
|
||||
// Emit the results
|
||||
compilerResult = Harness.Compiler.compileFiles(
|
||||
inputFiles,
|
||||
otherFiles,
|
||||
{ useCaseSensitiveFileNames: "" + caseSensitive },
|
||||
opts.options,
|
||||
// Since each RWC json file specifies its current directory in its json file, we need
|
||||
// to pass this information in explicitly instead of acquiring it from the process.
|
||||
currentDirectory);
|
||||
compilerOptions = compilerResult.options;
|
||||
|
||||
function getHarnessCompilerInputUnit(fileName: string): Harness.Compiler.TestFile {
|
||||
const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName)!);
|
||||
let content: string;
|
||||
try {
|
||||
content = Harness.IO.readFile(unitName)!;
|
||||
}
|
||||
catch (e) {
|
||||
content = Harness.IO.readFile(fileName)!;
|
||||
}
|
||||
return { unitName, content };
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it("has the expected emitted code", function (this: Mocha.Context) {
|
||||
this.timeout(100_000); // Allow longer timeouts for RWC js verification
|
||||
Harness.Baseline.runMultifileBaseline(baseName, "", () => {
|
||||
return Harness.Compiler.iterateOutputs(compilerResult.js.values());
|
||||
}, baselineOpts, [".js", ".jsx"]);
|
||||
});
|
||||
|
||||
it("has the expected declaration file content", () => {
|
||||
Harness.Baseline.runMultifileBaseline(baseName, "", () => {
|
||||
if (!compilerResult.dts.size) {
|
||||
return null; // eslint-disable-line no-null/no-null
|
||||
}
|
||||
|
||||
return Harness.Compiler.iterateOutputs(compilerResult.dts.values());
|
||||
}, baselineOpts, [".d.ts"]);
|
||||
});
|
||||
|
||||
it("has the expected source maps", () => {
|
||||
Harness.Baseline.runMultifileBaseline(baseName, "", () => {
|
||||
if (!compilerResult.maps.size) {
|
||||
return null; // eslint-disable-line no-null/no-null
|
||||
}
|
||||
|
||||
return Harness.Compiler.iterateOutputs(compilerResult.maps.values());
|
||||
}, baselineOpts, [".map"]);
|
||||
});
|
||||
|
||||
it("has the expected errors", () => {
|
||||
Harness.Baseline.runMultifileBaseline(baseName, ".errors.txt", () => {
|
||||
if (compilerResult.diagnostics.length === 0) {
|
||||
return null; // eslint-disable-line no-null/no-null
|
||||
}
|
||||
// Do not include the library in the baselines to avoid noise
|
||||
const baselineFiles = tsconfigFiles.concat(inputFiles, otherFiles).filter(f => !Harness.isDefaultLibraryFile(f.unitName));
|
||||
const errors = compilerResult.diagnostics.filter(e => !e.file || !Harness.isDefaultLibraryFile(e.file.fileName));
|
||||
return Harness.Compiler.iterateErrorBaseline(baselineFiles, errors, { caseSensitive, currentDirectory });
|
||||
}, baselineOpts);
|
||||
});
|
||||
|
||||
// Ideally, a generated declaration file will have no errors. But we allow generated
|
||||
// declaration file errors as part of the baseline.
|
||||
it("has the expected errors in generated declaration files", () => {
|
||||
if (compilerOptions.declaration && !compilerResult.diagnostics.length) {
|
||||
Harness.Baseline.runMultifileBaseline(baseName, ".dts.errors.txt", () => {
|
||||
if (compilerResult.diagnostics.length === 0) {
|
||||
return null; // eslint-disable-line no-null/no-null
|
||||
}
|
||||
|
||||
const declContext = Harness.Compiler.prepareDeclarationCompilationContext(
|
||||
inputFiles, otherFiles, compilerResult, /*harnessSettings*/ undefined!, compilerOptions, currentDirectory // TODO: GH#18217
|
||||
);
|
||||
// Reset compilerResult before calling into `compileDeclarationFiles` so the memory from the original compilation can be freed
|
||||
const links = compilerResult.symlinks;
|
||||
compilerResult = undefined!;
|
||||
const declFileCompilationResult = Harness.Compiler.compileDeclarationFiles(declContext, links)!;
|
||||
|
||||
return Harness.Compiler.iterateErrorBaseline(tsconfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.diagnostics, { caseSensitive, currentDirectory });
|
||||
}, baselineOpts);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export class RWCRunner extends Harness.RunnerBase {
|
||||
public enumerateTestFiles() {
|
||||
// see also: `enumerateTestFiles` in tests/webTestServer.ts
|
||||
return Harness.IO.getDirectories("internal/cases/rwc/");
|
||||
}
|
||||
|
||||
public kind(): Harness.TestRunnerKind {
|
||||
return "rwc";
|
||||
}
|
||||
|
||||
/** Setup the runner's tests so that they are ready to be executed by the harness
|
||||
* The first test should be a describe/it block that sets up the harness's compiler instance appropriately
|
||||
*/
|
||||
public initializeTests(): void {
|
||||
// Read in and evaluate the test list
|
||||
for (const test of this.tests && this.tests.length ? this.tests : this.getTestFiles()) {
|
||||
this.runTest(typeof test === "string" ? test : test.file);
|
||||
}
|
||||
}
|
||||
|
||||
private runTest(jsonFileName: string) {
|
||||
runRWCTest(jsonFileName);
|
||||
}
|
||||
}
|
||||
@ -14,7 +14,6 @@
|
||||
{ "path": "../typingsInstallerCore" },
|
||||
{ "path": "../deprecatedCompat" },
|
||||
{ "path": "../harness" },
|
||||
{ "path": "../loggedIO" }
|
||||
],
|
||||
"include": ["**/*"]
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
{ "path": "./executeCommandLine" },
|
||||
{ "path": "./harness" },
|
||||
{ "path": "./jsTyping" },
|
||||
{ "path": "./loggedIO" },
|
||||
{ "path": "./server" },
|
||||
{ "path": "./services" },
|
||||
{ "path": "./testRunner" },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user