-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Batch enumerateFiles into a single web request #23972
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,10 @@ const enum CompilerTestType { | |
Test262 | ||
} | ||
|
||
interface CompilerFileBasedTest extends Harness.FileBasedTest { | ||
payload?: Harness.TestCaseParser.TestCaseContent; | ||
} | ||
|
||
class CompilerBaselineRunner extends RunnerBase { | ||
private basePath = "tests/cases"; | ||
private testSuiteName: TestRunnerKind; | ||
|
@@ -42,7 +46,8 @@ class CompilerBaselineRunner extends RunnerBase { | |
} | ||
|
||
public enumerateTestFiles() { | ||
return this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true }); | ||
// see also: `enumerateTestFiles` in tests/webTestServer.ts | ||
return this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true }).map(CompilerTest.getConfigurations); | ||
} | ||
|
||
public initializeTests() { | ||
|
@@ -52,24 +57,32 @@ class CompilerBaselineRunner extends RunnerBase { | |
}); | ||
|
||
// this will set up a series of describe/it blocks to run between the setup and cleanup phases | ||
const files = this.tests.length > 0 ? this.tests : this.enumerateTestFiles(); | ||
files.forEach(file => { this.checkTestCodeOutput(vpath.normalizeSeparators(file)); }); | ||
const files = this.tests.length > 0 ? this.tests : Harness.IO.enumerateTestFiles(this); | ||
files.forEach(test => { | ||
const file = typeof test === "string" ? test : test.file; | ||
this.checkTestCodeOutput(vpath.normalizeSeparators(file), typeof test === "string" ? CompilerTest.getConfigurations(test) : test); | ||
}); | ||
}); | ||
} | ||
|
||
public checkTestCodeOutput(fileName: string) { | ||
for (const { name, payload } of CompilerTest.getConfigurations(fileName)) { | ||
describe(`${this.testSuiteName} tests for ${fileName}${name ? ` (${name})` : ``}`, () => { | ||
this.runSuite(fileName, payload); | ||
public checkTestCodeOutput(fileName: string, test?: CompilerFileBasedTest) { | ||
if (test && test.configurations) { | ||
test.configurations.forEach(configuration => { | ||
describe(`${this.testSuiteName} tests for ${fileName}${configuration && configuration.name ? ` (${configuration.name})` : ``}`, () => { | ||
this.runSuite(fileName, test, configuration); | ||
}); | ||
}); | ||
} | ||
describe(`${this.testSuiteName} tests for ${fileName}}`, () => { | ||
this.runSuite(fileName, test); | ||
}); | ||
} | ||
|
||
private runSuite(fileName: string, testCaseContent: Harness.TestCaseParser.TestCaseContent) { | ||
private runSuite(fileName: string, test?: CompilerFileBasedTest, configuration?: Harness.FileBasedTestConfiguration) { | ||
// 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 compilerTest: CompilerTest | undefined; | ||
before(() => { compilerTest = new CompilerTest(fileName, testCaseContent); }); | ||
before(() => { compilerTest = new CompilerTest(fileName, test && test.payload, configuration && configuration.settings); }); | ||
it(`Correct errors for ${fileName}`, () => { compilerTest.verifyDiagnostics(); }); | ||
it(`Correct module resolution tracing for ${fileName}`, () => { compilerTest.verifyModuleResolution(); }); | ||
it(`Correct sourcemap content for ${fileName}`, () => { compilerTest.verifySourceMapRecord(); }); | ||
|
@@ -97,11 +110,6 @@ class CompilerBaselineRunner extends RunnerBase { | |
} | ||
} | ||
|
||
interface CompilerTestConfiguration { | ||
name: string; | ||
payload: Harness.TestCaseParser.TestCaseContent; | ||
} | ||
|
||
class CompilerTest { | ||
private fileName: string; | ||
private justName: string; | ||
|
@@ -116,10 +124,20 @@ class CompilerTest { | |
// equivalent to other files on the file system not directly passed to the compiler (ie things that are referenced by other files) | ||
private otherFiles: Harness.Compiler.TestFile[]; | ||
|
||
constructor(fileName: string, testCaseContent: Harness.TestCaseParser.TestCaseContent) { | ||
constructor(fileName: string, testCaseContent?: Harness.TestCaseParser.TestCaseContent, configurationOverrides?: Harness.TestCaseParser.CompilerSettings) { | ||
this.fileName = fileName; | ||
this.justName = vpath.basename(fileName); | ||
|
||
const rootDir = fileName.indexOf("conformance") === -1 ? "tests/cases/compiler/" : ts.getDirectoryPath(fileName) + "/"; | ||
|
||
if (testCaseContent === undefined) { | ||
testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(Harness.IO.readFile(fileName), fileName, rootDir); | ||
} | ||
|
||
if (configurationOverrides) { | ||
testCaseContent = { ...testCaseContent, settings: { ...testCaseContent.settings, ...configurationOverrides } }; | ||
} | ||
|
||
const units = testCaseContent.testUnitData; | ||
this.harnessSettings = testCaseContent.settings; | ||
let tsConfigOptions: ts.CompilerOptions; | ||
|
@@ -174,32 +192,38 @@ class CompilerTest { | |
this.options = this.result.options; | ||
} | ||
|
||
public static getConfigurations(fileName: string) { | ||
const content = Harness.IO.readFile(fileName); | ||
const rootDir = fileName.indexOf("conformance") === -1 ? "tests/cases/compiler/" : ts.getDirectoryPath(fileName) + "/"; | ||
const testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName, rootDir); | ||
const configurations: CompilerTestConfiguration[] = []; | ||
const scriptTargets = this._split(testCaseContent.settings.target); | ||
const moduleKinds = this._split(testCaseContent.settings.module); | ||
public static getConfigurations(file: string): CompilerFileBasedTest { | ||
// also see `parseCompilerTestConfigurations` in tests/webTestServer.ts | ||
const content = Harness.IO.readFile(file); | ||
const rootDir = file.indexOf("conformance") === -1 ? "tests/cases/compiler/" : ts.getDirectoryPath(file) + "/"; | ||
const payload = Harness.TestCaseParser.makeUnitsFromTest(content, file, rootDir); | ||
const settings = Harness.TestCaseParser.extractCompilerSettings(content); | ||
const scriptTargets = CompilerTest._split(settings.target); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While we chose to make |
||
const moduleKinds = CompilerTest._split(settings.module); | ||
if (scriptTargets.length <= 1 && moduleKinds.length <= 1) { | ||
return { file, payload }; | ||
} | ||
|
||
const configurations: Harness.FileBasedTestConfiguration[] = []; | ||
for (const scriptTarget of scriptTargets) { | ||
for (const moduleKind of moduleKinds) { | ||
const settings: Record<string, any> = {}; | ||
let name = ""; | ||
if (moduleKinds.length > 1) { | ||
settings.module = moduleKind; | ||
name += `@module: ${moduleKind || "none"}`; | ||
} | ||
if (scriptTargets.length > 1) { | ||
settings.target = scriptTarget; | ||
if (name) name += ", "; | ||
name += `@target: ${scriptTarget || "none"}`; | ||
} | ||
|
||
const settings = { ...testCaseContent.settings }; | ||
if (scriptTarget) settings.target = scriptTarget; | ||
if (moduleKind) settings.module = moduleKind; | ||
configurations.push({ name, payload: { ...testCaseContent, settings } }); | ||
configurations.push({ name, settings }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the name is derived from the settings, why not compute it at its use? |
||
} | ||
} | ||
|
||
return configurations; | ||
return { file, payload, configurations }; | ||
} | ||
|
||
public verifyDiagnostics() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ class FourSlashRunner extends RunnerBase { | |
} | ||
|
||
public enumerateTestFiles() { | ||
// see also: `enumerateTestFiles` in tests/webTestServer.ts | ||
return this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false }); | ||
} | ||
|
||
|
@@ -45,22 +46,23 @@ class FourSlashRunner extends RunnerBase { | |
|
||
public initializeTests() { | ||
if (this.tests.length === 0) { | ||
this.tests = this.enumerateTestFiles(); | ||
this.tests = Harness.IO.enumerateTestFiles(this); | ||
} | ||
|
||
describe(this.testSuiteName + " tests", () => { | ||
this.tests.forEach((fn: string) => { | ||
describe(fn, () => { | ||
fn = ts.normalizeSlashes(fn); | ||
const justName = fn.replace(/^.*[\\\/]/, ""); | ||
this.tests.forEach(test => { | ||
const file = typeof test === "string" ? test : test.file; | ||
describe(file, () => { | ||
let fn = ts.normalizeSlashes(file); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Took me a minute to realize this meant There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, but in general I am just trying to preserve as much of the original source here as I can. |
||
const justName = fn.replace(/^.*[\\\/]/, ""); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possibly, but that source is unchanged from the original (aside from indentation). |
||
|
||
// Convert to relative path | ||
const testIndex = fn.indexOf("tests/"); | ||
if (testIndex >= 0) fn = fn.substr(testIndex); | ||
// Convert to relative path | ||
const testIndex = fn.indexOf("tests/"); | ||
if (testIndex >= 0) fn = fn.substr(testIndex); | ||
|
||
if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) { | ||
it(this.testSuiteName + " test " + justName + " runs correctly", () => { | ||
FourSlash.runFourSlashTest(this.basePath, this.testType, fn); | ||
if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we somehow got an empty name we don't run the test -- maybe this should be an assert instead of an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possibly, but that source is unchanged from the original (aside from indentation). |
||
it(this.testSuiteName + " test " + justName + " runs correctly", () => { | ||
FourSlash.runFourSlashTest(this.basePath, this.testType, fn); | ||
}); | ||
} | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
ts.contains
useful hereThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ts.contains
is for arrays.file
is a string.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry,
ts.stringContains