Remove old test262 and dt runner infra (#53125)

This commit is contained in:
Jake Bailey
2023-03-07 11:59:47 -08:00
committed by GitHub
parent 0e34f187c8
commit a6be79d535
12 changed files with 10 additions and 649 deletions

View File

@@ -2,7 +2,7 @@
"extends": "../.eslintrc.json",
"parserOptions": {
"tsconfigRootDir": "src",
"project": "./tsconfig-base.json"
"project": "./tsconfig-eslint.json"
},
"rules": {
"@typescript-eslint/no-unnecessary-type-assertion": "error",

View File

@@ -610,7 +610,7 @@ export namespace Compiler {
// if lib.d.ts is explicitly included in input files and there are some errors in it (i.e. because of duplicate identifiers)
// then they will be added twice thus triggering 'total errors' assertion with condition
// Similarly for tsconfig, which may be in the input files and contain errors.
// 'totalErrorsReportedInNonLibraryNonTsconfigFiles + numLibraryDiagnostics + numTsconfigDiagnostics + numTest262HarnessDiagnostics, diagnostics.length
// 'totalErrorsReportedInNonLibraryNonTsconfigFiles + numLibraryDiagnostics + numTsconfigDiagnostics, diagnostics.length
if (!error.file || !isDefaultLibraryFile(error.file.fileName) && !vpath.isTsConfigFile(error.file.fileName)) {
totalErrorsReportedInNonLibraryNonTsconfigFiles++;
@@ -719,13 +719,8 @@ export namespace Compiler {
return !!diagnostic.file && (vpath.isTsConfigFile(diagnostic.file.fileName));
});
const numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => {
// Count an error generated from tests262-harness folder.This should only apply for test262
return !!diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0;
});
// Verify we didn't miss any errors in total
assert.equal(totalErrorsReportedInNonLibraryNonTsconfigFiles + numLibraryDiagnostics + numTsconfigDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors");
assert.equal(totalErrorsReportedInNonLibraryNonTsconfigFiles + numLibraryDiagnostics + numTsconfigDiagnostics, diagnostics.length, "total number of errors");
}
export function doErrorBaseline(baselinePath: string, inputFiles: readonly TestFile[], errors: readonly ts.Diagnostic[], pretty?: boolean) {

View File

@@ -5,7 +5,7 @@ import {
} from "./_namespaces/Harness";
import * as ts from "./_namespaces/ts";
export type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "dt";
export type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc";
export type CompilerTestKind = "conformance" | "compiler";
export type FourslashTestKind = "fourslash" | "fourslash-shims" | "fourslash-shims-pp" | "fourslash-server";

View File

@@ -8,8 +8,6 @@ export { Parallel };
export * from "../fourslashRunner";
export * from "../compilerRunner";
export * from "../externalCompileRunner";
export * from "../test262Runner";
export * from "../runner";
// If running as emitted CJS, don't start executing the tests here; instead start in runner.ts.

View File

@@ -18,7 +18,6 @@ import * as vpath from "./_namespaces/vpath";
export const enum CompilerTestType {
Conformance,
Regressions,
Test262
}
interface CompilerFileBasedTest extends FileBasedTest {
@@ -41,9 +40,6 @@ export class CompilerBaselineRunner extends RunnerBase {
else if (testType === CompilerTestType.Regressions) {
this.testSuiteName = "compiler";
}
else if (testType === CompilerTestType.Test262) {
this.testSuiteName = "test262";
}
else {
this.testSuiteName = "compiler"; // default to this for historical reasons
}

View File

@@ -1,132 +0,0 @@
import * as del from "del";
import * as fs from "fs";
import * as path from "path";
import {
Baseline,
IO,
isWorker,
RunnerBase,
TestRunnerKind,
} from "./_namespaces/Harness";
import * as ts from "./_namespaces/ts";
interface ExecResult {
stdout: Buffer;
stderr: Buffer;
status: number | null;
}
interface UserConfig {
types: string[];
cloneUrl: string;
branch?: string;
path?: string;
}
abstract class ExternalCompileRunnerBase extends RunnerBase {
abstract testDir: string;
abstract report(result: ExecResult): string | null;
enumerateTestFiles() {
return IO.getDirectories(this.testDir);
}
/** 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
*/
initializeTests(): void {
// Read in and evaluate the test list
const testList = this.tests && this.tests.length ? this.tests : this.getTestFiles();
// eslint-disable-next-line @typescript-eslint/no-this-alias
const cls = this;
describe(`${this.kind()} code samples`, function (this: Mocha.Suite) {
this.timeout(600_000); // 10 minutes
for (const test of testList) {
cls.runTest(typeof test === "string" ? test : test.file);
}
});
}
private runTest(directoryName: string) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const cls = this;
const timeout = 600_000; // 10 minutes
describe(directoryName, function (this: Mocha.Suite) {
this.timeout(timeout);
const cp: typeof import("child_process") = require("child_process");
it("should build successfully", () => {
let cwd = path.join(IO.getWorkspaceRoot(), cls.testDir, directoryName);
const originalCwd = cwd;
const stdio = isWorker ? "pipe" : "inherit";
let types: string[] | undefined;
if (fs.existsSync(path.join(cwd, "test.json"))) {
const config = JSON.parse(fs.readFileSync(path.join(cwd, "test.json"), { encoding: "utf8" })) as UserConfig;
ts.Debug.assert(!!config.types, "Bad format from test.json: Types field must be present.");
ts.Debug.assert(!!config.cloneUrl, "Bad format from test.json: cloneUrl field must be present.");
const submoduleDir = path.join(cwd, directoryName);
if (!fs.existsSync(submoduleDir)) {
exec("git", ["--work-tree", submoduleDir, "clone", "-b", config.branch || "master", config.cloneUrl, path.join(submoduleDir, ".git")], { cwd });
}
else {
exec("git", ["--git-dir", path.join(submoduleDir, ".git"), "--work-tree", submoduleDir, "checkout", config.branch || "master"], { cwd: submoduleDir });
exec("git", ["--git-dir", path.join(submoduleDir, ".git"), "--work-tree", submoduleDir, "reset", "HEAD", "--hard"], { cwd: submoduleDir });
exec("git", ["--git-dir", path.join(submoduleDir, ".git"), "--work-tree", submoduleDir, "clean", "-f"], { cwd: submoduleDir });
exec("git", ["--git-dir", path.join(submoduleDir, ".git"), "--work-tree", submoduleDir, "pull", "-f"], { cwd: submoduleDir });
}
types = config.types;
cwd = config.path ? path.join(cwd, config.path) : submoduleDir;
}
const npmVersionText = exec("npm", ["--version"], { cwd, stdio: "pipe" })?.trim();
const npmVersion = npmVersionText ? ts.Version.tryParse(npmVersionText.trim()) : undefined;
const isV7OrLater = !!npmVersion && npmVersion.major >= 7;
if (fs.existsSync(path.join(cwd, "package.json"))) {
if (fs.existsSync(path.join(cwd, "package-lock.json"))) {
fs.unlinkSync(path.join(cwd, "package-lock.json"));
}
if (fs.existsSync(path.join(cwd, "node_modules"))) {
del.sync(path.join(cwd, "node_modules"), { force: true });
}
exec("npm", ["i", "--ignore-scripts", ...(isV7OrLater ? ["--legacy-peer-deps"] : [])], { cwd, timeout: timeout / 2 }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
}
const args = [path.join(IO.getWorkspaceRoot(), "built/local/tsc.js")];
if (types) {
args.push("--types", types.join(","));
// Also actually install those types (for, eg, the js projects which need node)
if (types.length) {
exec("npm", ["i", ...types.map(t => `@types/${t}`), "--no-save", "--ignore-scripts", ...(isV7OrLater ? ["--legacy-peer-deps"] : [])], { cwd: originalCwd, timeout: timeout / 2 }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
}
}
args.push("--noEmit");
Baseline.runBaseline(`${cls.kind()}/${directoryName}.log`, cls.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true })));
function exec(command: string, args: string[], options: { cwd: string, timeout?: number, stdio?: import("child_process").StdioOptions }): string | undefined {
const res = cp.spawnSync(isWorker ? `${command} 2>&1` : command, args, { shell: true, stdio, ...options });
if (res.status !== 0) {
throw new Error(`${command} ${args.join(" ")} for ${directoryName} failed: ${res.stdout && res.stdout.toString()}`);
}
return options.stdio === "pipe" ? res.stdout.toString("utf8") : undefined;
}
});
});
}
}
export class DefinitelyTypedRunner extends ExternalCompileRunnerBase {
readonly testDir = "../DefinitelyTyped/types/";
override workingDirectory = this.testDir;
kind(): TestRunnerKind {
return "dt";
}
report(result: ExecResult) {
// eslint-disable-next-line no-null/no-null
return !result.stdout.length && !result.stderr.length ? null : `Exit Code: ${result.status}
Standard output:
${result.stdout.toString().replace(/\r\n/g, "\n")}
Standard error:
${result.stderr.toString().replace(/\r\n/g, "\n")}`;
}
}

View File

@@ -2,7 +2,6 @@ import * as FourSlash from "./_namespaces/FourSlash";
import {
CompilerBaselineRunner,
CompilerTestType,
DefinitelyTypedRunner,
FourSlashRunner,
GeneratedFourslashRunner,
IO,
@@ -11,7 +10,6 @@ import {
setLightMode,
setShardId,
setShards,
Test262BaselineRunner,
TestRunnerKind,
} from "./_namespaces/Harness";
import * as project from "./_namespaces/project";
@@ -76,10 +74,6 @@ export function createRunner(kind: TestRunnerKind): RunnerBase {
return new project.ProjectRunner();
case "rwc":
return new RWC.RWCRunner();
case "test262":
return new Test262BaselineRunner();
case "dt":
return new DefinitelyTypedRunner();
}
return ts.Debug.fail(`Unknown runner kind ${kind}`);
}
@@ -214,12 +208,6 @@ function handleTestConfig() {
case "rwc":
runners.push(new RWC.RWCRunner());
break;
case "test262":
runners.push(new Test262BaselineRunner());
break;
case "dt":
runners.push(new DefinitelyTypedRunner());
break;
}
}
}

View File

@@ -1,120 +0,0 @@
import * as compiler from "./_namespaces/compiler";
import {
Baseline,
Compiler,
IO,
RunnerBase,
TestCaseParser,
TestRunnerKind,
} from "./_namespaces/Harness";
import * as ts from "./_namespaces/ts";
import * as Utils from "./_namespaces/Utils";
// In harness baselines, null is different than undefined. See `generateActual` in `harness.ts`.
export class Test262BaselineRunner extends RunnerBase {
private static readonly basePath = "internal/cases/test262";
private static readonly helpersFilePath = "tests/cases/test262-harness/helpers.d.ts";
private static readonly helperFile: Compiler.TestFile = {
unitName: Test262BaselineRunner.helpersFilePath,
content: IO.readFile(Test262BaselineRunner.helpersFilePath)!,
};
private static readonly testFileExtensionRegex = /\.js$/;
private static readonly options: ts.CompilerOptions = {
allowNonTsExtensions: true,
target: ts.ScriptTarget.Latest,
module: ts.ModuleKind.CommonJS
};
private static readonly baselineOptions: Baseline.BaselineOptions = {
Subfolder: "test262",
Baselinefolder: "internal/baselines"
};
private static getTestFilePath(filename: string): string {
return Test262BaselineRunner.basePath + "/" + filename;
}
private runTest(filePath: string) {
describe("test262 test for " + filePath, () => {
// Mocha holds onto the closure environment of the describe callback even after the test is done.
// Everything declared here should be cleared out in the "after" callback.
let testState: {
filename: string;
compilerResult: compiler.CompilationResult;
inputFiles: Compiler.TestFile[];
};
before(() => {
const content = IO.readFile(filePath)!;
const testFilename = ts.removeFileExtension(filePath).replace(/\//g, "_") + ".test";
const testCaseContent = TestCaseParser.makeUnitsFromTest(content, testFilename);
const inputFiles: Compiler.TestFile[] = testCaseContent.testUnitData.map(unit => {
const unitName = Test262BaselineRunner.getTestFilePath(unit.name);
return { unitName, content: unit.content };
});
// Emit the results
testState = {
filename: testFilename,
inputFiles,
compilerResult: undefined!, // TODO: GH#18217
};
testState.compilerResult = Compiler.compileFiles(
[Test262BaselineRunner.helperFile].concat(inputFiles),
/*otherFiles*/ [],
/* harnessOptions */ undefined,
Test262BaselineRunner.options,
/* currentDirectory */ undefined);
});
after(() => {
testState = undefined!;
});
it("has the expected emitted code", () => {
const files = ts.arrayFrom(testState.compilerResult.js.values()).filter(f => f.file !== Test262BaselineRunner.helpersFilePath);
Baseline.runBaseline(testState.filename + ".output.js", Compiler.collateOutputs(files), Test262BaselineRunner.baselineOptions);
});
it("has the expected errors", () => {
const errors = testState.compilerResult.diagnostics;
// eslint-disable-next-line no-null/no-null
const baseline = errors.length === 0 ? null : Compiler.getErrorBaseline(testState.inputFiles, errors);
Baseline.runBaseline(testState.filename + ".errors.txt", baseline, Test262BaselineRunner.baselineOptions);
});
it("satisfies invariants", () => {
const sourceFile = testState.compilerResult.program!.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
Utils.assertInvariants(sourceFile, /*parent:*/ undefined);
});
it("has the expected AST", () => {
const sourceFile = testState.compilerResult.program!.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename))!;
Baseline.runBaseline(testState.filename + ".AST.txt", Utils.sourceFileToJSON(sourceFile), Test262BaselineRunner.baselineOptions);
});
});
}
public kind(): TestRunnerKind {
return "test262";
}
public enumerateTestFiles() {
// see also: `enumerateTestFiles` in tests/webTestServer.ts
return ts.map(this.enumerateFiles(Test262BaselineRunner.basePath, Test262BaselineRunner.testFileExtensionRegex, { recursive: true }), ts.normalizePath);
}
public initializeTests() {
// this will set up a series of describe/it blocks to run between the setup and cleanup phases
if (this.tests.length === 0) {
const testFiles = this.getTestFiles();
testFiles.forEach(fn => {
this.runTest(fn);
});
}
else {
this.tests.forEach(test => this.runTest(typeof test === "string" ? test : test.file));
}
}
}

6
src/tsconfig-eslint.json Normal file
View File

@@ -0,0 +1,6 @@
{
"extends": "./tsconfig-base",
"compilerOptions": {
"types": ["node", "mocha", "chai"]
}
}