Merge pull request #5690 from Microsoft/harnessCleanup2_WIP

cleanup harness code (part 2)
This commit is contained in:
Vladimir Matveev
2015-11-16 16:53:28 -08:00
13 changed files with 1089 additions and 1214 deletions

View File

@@ -55,7 +55,6 @@ class CompilerBaselineRunner extends RunnerBase {
let rootDir: string;
let result: Harness.Compiler.CompilerResult;
let program: ts.Program;
let options: ts.CompilerOptions;
// equivalent to the files that will be passed on the command line
let toBeCompiled: Harness.Compiler.TestFile[];
@@ -89,12 +88,11 @@ class CompilerBaselineRunner extends RunnerBase {
});
}
const output = Harness.Compiler.HarnessCompiler.compileFiles(
const output = Harness.Compiler.compileFiles(
toBeCompiled, otherFiles, harnessSettings, /* options */ undefined, /* currentDirectory */ undefined);
options = output.options;
result = output.result;
program = output.program;
});
after(() => {
@@ -108,7 +106,6 @@ class CompilerBaselineRunner extends RunnerBase {
lastUnit = undefined;
rootDir = undefined;
result = undefined;
program = undefined;
options = undefined;
toBeCompiled = undefined;
otherFiles = undefined;
@@ -181,7 +178,7 @@ class CompilerBaselineRunner extends RunnerBase {
}
const declFileCompilationResult =
Harness.Compiler.HarnessCompiler.compileDeclarationFiles(
Harness.Compiler.compileDeclarationFiles(
toBeCompiled, otherFiles, result, harnessSettings, options, /*currentDirectory*/ undefined);
if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) {
@@ -253,6 +250,7 @@ class CompilerBaselineRunner extends RunnerBase {
// These types are equivalent, but depend on what order the compiler observed
// certain parts of the program.
const program = result.program;
const allFiles = toBeCompiled.concat(otherFiles).filter(file => !!program.getSourceFile(file.unitName));
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true);

File diff suppressed because it is too large Load Diff

View File

@@ -58,56 +58,6 @@ class FourSlashRunner extends RunnerBase {
}
});
});
describe("Generate Tao XML", () => {
const invalidReasons: any = {};
FourSlash.xmlData.forEach(xml => {
if (xml.invalidReason !== null) {
invalidReasons[xml.invalidReason] = (invalidReasons[xml.invalidReason] || 0) + 1;
}
});
const invalidReport: { reason: string; count: number }[] = [];
for (const reason in invalidReasons) {
if (invalidReasons.hasOwnProperty(reason)) {
invalidReport.push({ reason: reason, count: invalidReasons[reason] });
}
}
invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1);
const lines: string[] = [];
lines.push("<!-- Blocked Test Report");
invalidReport.forEach((reasonAndCount) => {
lines.push(reasonAndCount.count + " tests blocked by " + reasonAndCount.reason);
});
lines.push("-->");
lines.push("<TaoTest xmlns=\"http://microsoft.com/schemas/VSLanguages/TAO\">");
lines.push(" <InitTest>");
lines.push(" <StartTarget />");
lines.push(" </InitTest>");
lines.push(" <ScenarioList>");
FourSlash.xmlData.forEach(xml => {
if (xml.invalidReason !== null) {
lines.push("<!-- Skipped " + xml.originalName + ", reason: " + xml.invalidReason + " -->");
}
else {
lines.push(" <Scenario Name=\"" + xml.originalName + "\">");
xml.actions.forEach(action => {
lines.push(" " + action);
});
lines.push(" </Scenario>");
}
});
lines.push(" </ScenarioList>");
lines.push(" <CleanupScenario>");
lines.push(" <CloseAllDocuments />");
lines.push(" <CleanupCreatedFiles />");
lines.push(" </CleanupScenario>");
lines.push(" <CleanupTest>");
lines.push(" <CloseTarget />");
lines.push(" </CleanupTest>");
lines.push("</TaoTest>");
Harness.IO.writeFile("built/local/fourslash.xml", lines.join("\r\n"));
});
});
}
}

View File

@@ -767,26 +767,9 @@ namespace Harness {
}
namespace Harness {
let tcServicesFileName = "typescriptServices.js";
export let libFolder: string;
switch (Utils.getExecutionEnvironment()) {
case Utils.ExecutionEnvironment.CScript:
libFolder = "built/local/";
tcServicesFileName = "built/local/typescriptServices.js";
break;
case Utils.ExecutionEnvironment.Node:
libFolder = "built/local/";
tcServicesFileName = "built/local/typescriptServices.js";
break;
case Utils.ExecutionEnvironment.Browser:
libFolder = "built/local/";
tcServicesFileName = "built/local/typescriptServices.js";
break;
default:
throw new Error("Unknown context");
}
export let tcServicesFile = IO.readFile(tcServicesFileName);
export const libFolder = "built/local/";
const tcServicesFileName = ts.combinePaths(libFolder, "typescriptServices.js");
export const tcServicesFile = IO.readFile(tcServicesFileName);
export interface SourceMapEmitterCallback {
(emittedFile: string, emittedLine: number, emittedColumn: number, sourceFile: string, sourceLine: number, sourceColumn: number, sourceName: string): void;
@@ -827,57 +810,14 @@ namespace Harness {
}
}
export interface IEmitterIOHost {
writeFile(path: string, contents: string, writeByteOrderMark: boolean): void;
resolvePath(path: string): string;
}
/** Mimics having multiple files, later concatenated to a single file. */
export class EmitterIOHost implements IEmitterIOHost {
private fileCollection: any = {};
/** create file gets the whole path to create, so this works as expected with the --out parameter */
public writeFile(s: string, contents: string, writeByteOrderMark: boolean): void {
let writer: ITextWriter;
if (this.fileCollection[s]) {
writer = <ITextWriter>this.fileCollection[s];
}
else {
writer = new Harness.Compiler.WriterAggregator();
this.fileCollection[s] = writer;
}
writer.Write(contents);
writer.Close();
}
public resolvePath(s: string) { return s; }
public reset() { this.fileCollection = {}; }
public toArray(): { fileName: string; file: WriterAggregator; }[] {
const result: { fileName: string; file: WriterAggregator; }[] = [];
for (const p in this.fileCollection) {
if (this.fileCollection.hasOwnProperty(p)) {
const current = <Harness.Compiler.WriterAggregator>this.fileCollection[p];
if (current.lines.length > 0) {
if (p.indexOf(".d.ts") !== -1) { current.lines.unshift(["////[", Path.getFileName(p), "]"].join("")); }
result.push({ fileName: p, file: this.fileCollection[p] });
}
}
}
return result;
}
}
export function createSourceFileAndAssertInvariants(
fileName: string,
sourceText: string,
languageVersion: ts.ScriptTarget) {
// We'll only assert inletiants outside of light mode.
// We'll only assert invariants outside of light mode.
const shouldAssertInvariants = !Harness.lightMode;
// Only set the parent nodes if we're asserting inletiants. We don't need them otherwise.
// Only set the parent nodes if we're asserting invariants. We don't need them otherwise.
const result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ shouldAssertInvariants);
if (shouldAssertInvariants) {
@@ -890,12 +830,12 @@ namespace Harness {
const carriageReturnLineFeed = "\r\n";
const lineFeed = "\n";
export let defaultLibFileName = "lib.d.ts";
export let defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
export let defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.es6.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
export const defaultLibFileName = "lib.d.ts";
export const defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
export const defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.es6.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
// Cache these between executions so we don't have to re-parse them for every test
export let fourslashFileName = "fourslash.ts";
export const fourslashFileName = "fourslash.ts";
export let fourslashSourceFile: ts.SourceFile;
export function getCanonicalFileName(fileName: string): string {
@@ -903,7 +843,7 @@ namespace Harness {
}
export function createCompilerHost(
inputFiles: TestFileWithPath[],
inputFiles: TestFile[],
writeFile: (fn: string, contents: string, writeByteOrderMark: boolean) => void,
scriptTarget: ts.ScriptTarget,
useCaseSensitiveFileNames: boolean,
@@ -915,16 +855,14 @@ namespace Harness {
const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
const fileMap: ts.FileMap<ts.SourceFile> = ts.createFileMap<ts.SourceFile>();
// Register input files
function register(file: TestFileWithPath) {
for (const file of inputFiles) {
if (file.content !== undefined) {
const fileName = ts.normalizePath(file.unitName);
const sourceFile = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget);
fileMap.set(file.path, sourceFile);
const path = ts.toPath(file.unitName, currentDirectory, getCanonicalFileName);
fileMap.set(path, sourceFile);
}
};
inputFiles.forEach(register);
}
function getSourceFile(fn: string, languageVersion: ts.ScriptTarget) {
fn = ts.normalizePath(fn);
@@ -1031,147 +969,135 @@ namespace Harness {
unitName: string;
content: string;
}
export interface TestFileWithPath extends TestFile {
path: ts.Path;
}
export interface CompilationOutput {
result: CompilerResult;
program: ts.Program;
options: ts.CompilerOptions & HarnessOptions;
}
export namespace HarnessCompiler {
export function compileFiles(
inputFiles: TestFile[],
otherFiles: TestFile[],
harnessSettings: TestCaseParser.CompilerSettings,
compilerOptions: ts.CompilerOptions,
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
currentDirectory: string): CompilationOutput {
export function compileFiles(
inputFiles: TestFile[],
otherFiles: TestFile[],
harnessSettings: TestCaseParser.CompilerSettings,
compilerOptions: ts.CompilerOptions,
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
currentDirectory: string): CompilationOutput {
const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.clone(compilerOptions) : { noResolve: false };
options.target = options.target || ts.ScriptTarget.ES3;
options.module = options.module || ts.ModuleKind.None;
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
options.noErrorTruncation = true;
options.skipDefaultLibCheck = true;
const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.clone(compilerOptions) : { noResolve: false };
options.target = options.target || ts.ScriptTarget.ES3;
options.module = options.module || ts.ModuleKind.None;
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
options.noErrorTruncation = true;
options.skipDefaultLibCheck = true;
const newLine = "\r\n";
currentDirectory = currentDirectory || Harness.IO.getCurrentDirectory();
currentDirectory = currentDirectory || Harness.IO.getCurrentDirectory();
// Parse settings
let useCaseSensitiveFileNames = Harness.IO.useCaseSensitiveFileNames();
if (harnessSettings) {
setCompilerOptionsFromHarnessSetting(harnessSettings, options);
}
if (options.useCaseSensitiveFileNames !== undefined) {
useCaseSensitiveFileNames = options.useCaseSensitiveFileNames;
}
const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
const inputFilesWithPath = inputFiles.map(f => {
return { unitName: f.unitName, content: f.content, path: ts.toPath(f.unitName, currentDirectory, getCanonicalFileName) };
});
const otherFilesWithPath = otherFiles.map(f => {
return { unitName: f.unitName, content: f.content, path: ts.toPath(f.unitName, currentDirectory, getCanonicalFileName) };
});
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
// Treat them as library files, so include them in build, but not in baselines.
const includeBuiltFiles: TestFileWithPath[] = [];
if (options.includeBuiltFile) {
const builtFileName = libFolder + options.includeBuiltFile;
const builtFile: TestFileWithPath = {
unitName: builtFileName,
content: normalizeLineEndings(IO.readFile(builtFileName), newLine),
path: ts.toPath(builtFileName, currentDirectory, getCanonicalFileName)
};
includeBuiltFiles.push(builtFile);
}
const fileOutputs: GeneratedFile[] = [];
const programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName);
const compilerHost = createCompilerHost(
inputFilesWithPath.concat(includeBuiltFiles).concat(otherFilesWithPath),
(fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }),
options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine);
const program = ts.createProgram(programFiles, options, compilerHost);
const emitResult = program.emit();
const errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
const result = new CompilerResult(fileOutputs, errors, program, Harness.IO.getCurrentDirectory(), emitResult.sourceMaps);
return { result, program, options };
// Parse settings
let useCaseSensitiveFileNames = Harness.IO.useCaseSensitiveFileNames();
if (harnessSettings) {
setCompilerOptionsFromHarnessSetting(harnessSettings, options);
}
if (options.useCaseSensitiveFileNames !== undefined) {
useCaseSensitiveFileNames = options.useCaseSensitiveFileNames;
}
export function compileDeclarationFiles(inputFiles: TestFile[],
otherFiles: TestFile[],
result: CompilerResult,
harnessSettings: TestCaseParser.CompilerSettings & HarnessOptions,
options: ts.CompilerOptions,
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
currentDirectory: string) {
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
const programFiles: TestFile[] = inputFiles.slice();
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
// Treat them as library files, so include them in build, but not in baselines.
if (options.includeBuiltFile) {
const builtFileName = ts.combinePaths(libFolder, options.includeBuiltFile);
const builtFile: TestFile = {
unitName: builtFileName,
content: normalizeLineEndings(IO.readFile(builtFileName), Harness.IO.newLine()),
};
programFiles.push(builtFile);
}
const fileOutputs: GeneratedFile[] = [];
const programFileNames = programFiles.map(file => file.unitName);
const compilerHost = createCompilerHost(
programFiles.concat(otherFiles),
(fileName, code, writeByteOrderMark) => fileOutputs.push({ fileName, code, writeByteOrderMark }),
options.target,
useCaseSensitiveFileNames,
currentDirectory,
options.newLine);
const program = ts.createProgram(programFileNames, options, compilerHost);
const emitResult = program.emit();
const errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
const result = new CompilerResult(fileOutputs, errors, program, Harness.IO.getCurrentDirectory(), emitResult.sourceMaps);
return { result, options };
}
export function compileDeclarationFiles(inputFiles: TestFile[],
otherFiles: TestFile[],
result: CompilerResult,
harnessSettings: TestCaseParser.CompilerSettings & HarnessOptions,
options: ts.CompilerOptions,
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
currentDirectory: string) {
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
}
const declInputFiles: TestFile[] = [];
const declOtherFiles: TestFile[] = [];
// if the .d.ts is non-empty, confirm it compiles correctly as well
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
const output = compileFiles(declInputFiles, declOtherFiles, harnessSettings, options, currentDirectory);
return { declInputFiles, declOtherFiles, declResult: output.result };
}
function addDtsFile(file: TestFile, dtsFiles: TestFile[]) {
if (isDTS(file.unitName)) {
dtsFiles.push(file);
}
const declInputFiles: TestFile[] = [];
const declOtherFiles: TestFile[] = [];
// if the .d.ts is non-empty, confirm it compiles correctly as well
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
const output = this.compileFiles(declInputFiles, declOtherFiles, harnessSettings, options, currentDirectory);
return { declInputFiles, declOtherFiles, declResult: output.result };
}
function addDtsFile(file: TestFile, dtsFiles: TestFile[]) {
if (isDTS(file.unitName)) {
dtsFiles.push(file);
}
else if (isTS(file.unitName)) {
const declFile = findResultCodeFile(file.unitName);
if (declFile && !findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
}
}
function findResultCodeFile(fileName: string) {
const sourceFile = result.program.getSourceFile(fileName);
assert(sourceFile, "Program has no source file with name '" + fileName + "'");
// Is this file going to be emitted separately
let sourceFileName: string;
const outFile = options.outFile || options.out;
if (ts.isExternalModule(sourceFile) || !outFile) {
if (options.outDir) {
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram);
sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), "");
sourceFileName = ts.combinePaths(options.outDir, sourceFilePath);
}
else {
sourceFileName = sourceFile.fileName;
}
}
else {
// Goes to single --out file
sourceFileName = outFile;
}
const dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
}
function findUnit(fileName: string, units: TestFile[]) {
return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined);
else if (isTS(file.unitName)) {
const declFile = findResultCodeFile(file.unitName);
if (declFile && !findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
}
}
}
function findResultCodeFile(fileName: string) {
const sourceFile = result.program.getSourceFile(fileName);
assert(sourceFile, "Program has no source file with name '" + fileName + "'");
// Is this file going to be emitted separately
let sourceFileName: string;
const outFile = options.outFile || options.out;
if (ts.isExternalModule(sourceFile) || !outFile) {
if (options.outDir) {
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram);
sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), "");
sourceFileName = ts.combinePaths(options.outDir, sourceFilePath);
}
else {
sourceFileName = sourceFile.fileName;
}
}
else {
// Goes to single --out file
sourceFileName = outFile;
}
const dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
}
function findUnit(fileName: string, units: TestFile[]) {
return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined);
}
}
function normalizeLineEndings(text: string, lineEnding: string): string {
@@ -1388,7 +1314,7 @@ namespace Harness {
constructor(fileResults: GeneratedFile[], errors: ts.Diagnostic[], public program: ts.Program,
public currentDirectoryForProgram: string, private sourceMapData: ts.SourceMapData[]) {
fileResults.forEach(emittedFile => {
for (const emittedFile of fileResults) {
if (isDTS(emittedFile.fileName)) {
// .d.ts file, add to declFiles emit
this.declFilesCode.push(emittedFile);
@@ -1403,7 +1329,7 @@ namespace Harness {
else {
throw new Error("Unrecognized file extension for file " + emittedFile.fileName);
}
});
}
this.errors = errors;
}

View File

@@ -7,7 +7,7 @@ namespace Harness.LanguageService {
export class ScriptInfo {
public version: number = 1;
public editRanges: { length: number; textChangeRange: ts.TextChangeRange; }[] = [];
public lineMap: number[] = undefined;
private lineMap: number[] = undefined;
constructor(public fileName: string, public content: string) {
this.setContent(content);
@@ -15,7 +15,11 @@ namespace Harness.LanguageService {
private setContent(content: string): void {
this.content = content;
this.lineMap = ts.computeLineStarts(content);
this.lineMap = undefined;
}
public getLineMap(): number[] {
return this.lineMap || (this.lineMap = ts.computeLineStarts(this.content));
}
public updateContent(content: string): void {
@@ -164,7 +168,7 @@ namespace Harness.LanguageService {
const script: ScriptInfo = this.fileNameToScript[fileName];
assert.isNotNull(script);
return ts.computeLineAndCharacterOfPosition(script.lineMap, position);
return ts.computeLineAndCharacterOfPosition(script.getLineMap(), position);
}
}

View File

@@ -126,7 +126,7 @@ namespace RWC {
// Emit the results
compilerOptions = null;
const output = Harness.Compiler.HarnessCompiler.compileFiles(
const output = Harness.Compiler.compileFiles(
inputFiles,
otherFiles,
/* harnessOptions */ undefined,
@@ -202,7 +202,7 @@ namespace RWC {
it("has the expected errors in generated declaration files", () => {
if (compilerOptions.declaration && !compilerResult.errors.length) {
Harness.Baseline.runBaseline("has the expected errors in generated declaration files", baseName + ".dts.errors.txt", () => {
const declFileCompilationResult = Harness.Compiler.HarnessCompiler.compileDeclarationFiles(
const declFileCompilationResult = Harness.Compiler.compileDeclarationFiles(
inputFiles, otherFiles, compilerResult, /*harnessSettings*/ undefined, compilerOptions, currentDirectory);
if (declFileCompilationResult.declResult.errors.length === 0) {

View File

@@ -32,7 +32,6 @@ class Test262BaselineRunner extends RunnerBase {
filename: string;
compilerResult: Harness.Compiler.CompilerResult;
inputFiles: Harness.Compiler.TestFile[];
program: ts.Program;
};
before(() => {
@@ -50,10 +49,9 @@ class Test262BaselineRunner extends RunnerBase {
filename: testFilename,
inputFiles: inputFiles,
compilerResult: undefined,
program: undefined,
};
const output = Harness.Compiler.HarnessCompiler.compileFiles(
const output = Harness.Compiler.compileFiles(
[Test262BaselineRunner.helperFile].concat(inputFiles),
/*otherFiles*/ [],
/* harnessOptions */ undefined,
@@ -61,7 +59,6 @@ class Test262BaselineRunner extends RunnerBase {
/* currentDirectory */ undefined
);
testState.compilerResult = output.result;
testState.program = output.program;
});
after(() => {
@@ -86,14 +83,14 @@ class Test262BaselineRunner extends RunnerBase {
}, false, Test262BaselineRunner.baselineOptions);
});
it("satisfies inletiants", () => {
const sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
it("satisfies invariants", () => {
const sourceFile = testState.compilerResult.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
Utils.assertInvariants(sourceFile, /*parent:*/ undefined);
});
it("has the expected AST", () => {
Harness.Baseline.runBaseline("has the expected AST", testState.filename + ".AST.txt", () => {
const sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
const sourceFile = testState.compilerResult.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
return Utils.sourceFileToJSON(sourceFile);
}, false, Test262BaselineRunner.baselineOptions);
});