diff --git a/src/testRunner/unittests/helpers/baseline.ts b/src/testRunner/unittests/helpers/baseline.ts new file mode 100644 index 0000000000000..e3075686be24d --- /dev/null +++ b/src/testRunner/unittests/helpers/baseline.ts @@ -0,0 +1,370 @@ +import * as fakes from "../../_namespaces/fakes"; +import * as Harness from "../../_namespaces/Harness"; +import * as ts from "../../_namespaces/ts"; +import { TscCompileSystem } from "./tsc"; +import { TestServerHost } from "./virtualFileSystemWithWatch"; + +export type CommandLineProgram = [ts.Program, ts.BuilderProgram?]; +export interface CommandLineCallbacks { + cb: ts.ExecuteCommandLineCallbacks; + getPrograms: () => readonly CommandLineProgram[]; +} + +function isAnyProgram(program: ts.Program | ts.BuilderProgram | ts.ParsedCommandLine): program is ts.Program | ts.BuilderProgram { + return !!(program as ts.Program | ts.BuilderProgram).getCompilerOptions; +} +export function commandLineCallbacks( + sys: TscCompileSystem | TestServerHost, + originalReadCall?: ts.System["readFile"], +): CommandLineCallbacks { + let programs: CommandLineProgram[] | undefined; + + return { + cb: program => { + if (isAnyProgram(program)) { + baselineBuildInfo(program.getCompilerOptions(), sys, originalReadCall); + (programs || (programs = [])).push(ts.isBuilderProgram(program) ? + [program.getProgram(), program] : + [program] + ); + } + else { + baselineBuildInfo(program.options, sys, originalReadCall); + } + }, + getPrograms: () => { + const result = programs || ts.emptyArray; + programs = undefined; + return result; + } + }; +} + +export function baselinePrograms(baseline: string[], getPrograms: () => readonly CommandLineProgram[], oldPrograms: readonly (CommandLineProgram | undefined)[], baselineDependencies: boolean | undefined) { + const programs = getPrograms(); + for (let i = 0; i < programs.length; i++) { + baselineProgram(baseline, programs[i], oldPrograms[i], baselineDependencies); + } + return programs; +} + +function baselineProgram(baseline: string[], [program, builderProgram]: CommandLineProgram, oldProgram: CommandLineProgram | undefined, baselineDependencies: boolean | undefined) { + if (program !== oldProgram?.[0]) { + const options = program.getCompilerOptions(); + baseline.push(`Program root files: ${JSON.stringify(program.getRootFileNames())}`); + baseline.push(`Program options: ${JSON.stringify(options)}`); + baseline.push(`Program structureReused: ${(ts as any).StructureIsReused[program.structureIsReused]}`); + baseline.push("Program files::"); + for (const file of program.getSourceFiles()) { + baseline.push(file.fileName); + } + } + else { + baseline.push(`Program: Same as old program`); + } + baseline.push(""); + + if (!builderProgram) return; + if (builderProgram !== oldProgram?.[1]) { + const state = builderProgram.getState(); + const internalState = state as unknown as ts.BuilderProgramState; + if (state.semanticDiagnosticsPerFile?.size) { + baseline.push("Semantic diagnostics in builder refreshed for::"); + for (const file of program.getSourceFiles()) { + if (!internalState.semanticDiagnosticsFromOldState || !internalState.semanticDiagnosticsFromOldState.has(file.resolvedPath)) { + baseline.push(file.fileName); + } + } + } + else { + baseline.push("No cached semantic diagnostics in the builder::"); + } + if (internalState) { + baseline.push(""); + if (internalState.hasCalledUpdateShapeSignature?.size) { + baseline.push("Shape signatures in builder refreshed for::"); + internalState.hasCalledUpdateShapeSignature.forEach((path: ts.Path) => { + const info = state.fileInfos.get(path); + if (info?.version === info?.signature || !info?.signature) { + baseline.push(path + " (used version)"); + } + else if (internalState.filesChangingSignature?.has(path)) { + baseline.push(path + " (computed .d.ts during emit)"); + } + else { + baseline.push(path + " (computed .d.ts)"); + } + }); + } + else { + baseline.push("No shapes updated in the builder::"); + } + } + baseline.push(""); + if (!baselineDependencies) return; + baseline.push("Dependencies for::"); + for (const file of builderProgram.getSourceFiles()) { + baseline.push(`${file.fileName}:`); + for (const depenedency of builderProgram.getAllDependencies(file)) { + baseline.push(` ${depenedency}`); + } + } + } + else { + baseline.push(`BuilderProgram: Same as old builder program`); + } + baseline.push(""); +} + +export function generateSourceMapBaselineFiles(sys: ts.System & { writtenFiles: ts.ReadonlyCollection; }) { + const mapFileNames = ts.mapDefinedIterator(sys.writtenFiles.keys(), f => f.endsWith(".map") ? f : undefined); + for (const mapFile of mapFileNames) { + const text = Harness.SourceMapRecorder.getSourceMapRecordWithSystem(sys, mapFile); + sys.writeFile(`${mapFile}.baseline.txt`, text); + } +} + +function generateBundleFileSectionInfo(sys: ts.System, originalReadCall: ts.System["readFile"], baselineRecorder: Harness.Compiler.WriterAggregator, bundleFileInfo: ts.BundleFileInfo | undefined, outFile: string | undefined) { + if (!ts.length(bundleFileInfo && bundleFileInfo.sections) && !outFile) return; // Nothing to baseline + + const content = outFile && sys.fileExists(outFile) ? originalReadCall.call(sys, outFile, "utf8")! : ""; + baselineRecorder.WriteLine("======================================================================"); + baselineRecorder.WriteLine(`File:: ${outFile}`); + for (const section of bundleFileInfo ? bundleFileInfo.sections : ts.emptyArray) { + baselineRecorder.WriteLine("----------------------------------------------------------------------"); + writeSectionHeader(section); + if (section.kind !== ts.BundleFileSectionKind.Prepend) { + writeTextOfSection(section.pos, section.end); + } + else if (section.texts.length > 0) { + ts.Debug.assert(section.pos === ts.first(section.texts).pos); + ts.Debug.assert(section.end === ts.last(section.texts).end); + for (const text of section.texts) { + baselineRecorder.WriteLine(">>--------------------------------------------------------------------"); + writeSectionHeader(text); + writeTextOfSection(text.pos, text.end); + } + } + else { + ts.Debug.assert(section.pos === section.end); + } + } + baselineRecorder.WriteLine("======================================================================"); + + function writeTextOfSection(pos: number, end: number) { + const textLines = content.substring(pos, end).split(/\r?\n/); + for (const line of textLines) { + baselineRecorder.WriteLine(line); + } + } + + function writeSectionHeader(section: ts.BundleFileSection) { + baselineRecorder.WriteLine(`${section.kind}: (${section.pos}-${section.end})${section.data ? ":: " + section.data : ""}${section.kind === ts.BundleFileSectionKind.Prepend ? " texts:: " + section.texts.length : ""}`); + } +} + +export type ReadableProgramBuildInfoDiagnostic = string | [string, readonly ts.ReusableDiagnostic[]]; +export type ReadableBuilderFileEmit = string & { __readableBuilderFileEmit: any; }; +export type ReadableProgramBuilderInfoFilePendingEmit = [original: string | [string], emitKind: ReadableBuilderFileEmit]; +export type ReadableProgramBuildInfoEmitSignature = string | [string, ts.EmitSignature | []]; +export type ReadableProgramBuildInfoFileInfo = Omit & { + impliedFormat: string | undefined; + original: T | undefined; +}; +export type ReadableProgramBuildInfoRoot = + [original: ts.ProgramBuildInfoFileId, readable: string] | + [orginal: ts.ProgramBuildInfoRootStartEnd, readable: readonly string[]]; +export type ReadableProgramMultiFileEmitBuildInfo = Omit & { + fileNamesList: readonly (readonly string[])[] | undefined; + fileInfos: ts.MapLike>; + root: readonly ReadableProgramBuildInfoRoot[]; + referencedMap: ts.MapLike | undefined; + exportedModulesMap: ts.MapLike | undefined; + semanticDiagnosticsPerFile: readonly ReadableProgramBuildInfoDiagnostic[] | undefined; + affectedFilesPendingEmit: readonly ReadableProgramBuilderInfoFilePendingEmit[] | undefined; + changeFileSet: readonly string[] | undefined; + emitSignatures: readonly ReadableProgramBuildInfoEmitSignature[] | undefined; +}; +export type ReadableProgramBuildInfoBundlePendingEmit = [emitKind: ReadableBuilderFileEmit, original: ts.ProgramBuildInfoBundlePendingEmit]; +export type ReadableProgramBundleEmitBuildInfo = Omit & { + fileInfos: ts.MapLike>; + root: readonly ReadableProgramBuildInfoRoot[]; + pendingEmit: ReadableProgramBuildInfoBundlePendingEmit | undefined; +}; + +export type ReadableProgramBuildInfo = ReadableProgramMultiFileEmitBuildInfo | ReadableProgramBundleEmitBuildInfo; + +export function isReadableProgramBundleEmitBuildInfo(info: ReadableProgramBuildInfo | undefined): info is ReadableProgramBundleEmitBuildInfo { + return !!info && !!ts.outFile(info.options || {}); +} +export type ReadableBuildInfo = Omit & { program: ReadableProgramBuildInfo | undefined; size: number; }; +function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string, buildInfo: ts.BuildInfo) { + let program: ReadableProgramBuildInfo | undefined; + let fileNamesList: string[][] | undefined; + if (buildInfo.program && ts.isProgramBundleEmitBuildInfo(buildInfo.program)) { + const fileInfos: ReadableProgramBundleEmitBuildInfo["fileInfos"] = {}; + buildInfo.program?.fileInfos?.forEach((fileInfo, index) => + fileInfos[toFileName(index + 1 as ts.ProgramBuildInfoFileId)] = ts.isString(fileInfo) ? + fileInfo : + toReadableFileInfo(fileInfo, ts.identity) + ); + const pendingEmit = buildInfo.program.pendingEmit; + program = { + ...buildInfo.program, + fileInfos, + root: buildInfo.program.root.map(toReadableProgramBuildInfoRoot), + pendingEmit: pendingEmit === undefined ? + undefined : + [ + toReadableBuilderFileEmit(ts.toProgramEmitPending(pendingEmit, buildInfo.program.options)), + pendingEmit + ], + }; + } + else if (buildInfo.program) { + const fileInfos: ReadableProgramMultiFileEmitBuildInfo["fileInfos"] = {}; + buildInfo.program?.fileInfos?.forEach((fileInfo, index) => fileInfos[toFileName(index + 1 as ts.ProgramBuildInfoFileId)] = toReadableFileInfo(fileInfo, ts.toBuilderStateFileInfoForMultiEmit)); + fileNamesList = buildInfo.program.fileIdsList?.map(fileIdsListId => fileIdsListId.map(toFileName)); + const fullEmitForOptions = buildInfo.program.affectedFilesPendingEmit ? ts.getBuilderFileEmit(buildInfo.program.options || {}) : undefined; + program = buildInfo.program && { + fileNames: buildInfo.program.fileNames, + fileNamesList, + fileInfos: buildInfo.program.fileInfos ? fileInfos : undefined!, + root: buildInfo.program.root.map(toReadableProgramBuildInfoRoot), + options: buildInfo.program.options, + referencedMap: toMapOfReferencedSet(buildInfo.program.referencedMap), + exportedModulesMap: toMapOfReferencedSet(buildInfo.program.exportedModulesMap), + semanticDiagnosticsPerFile: buildInfo.program.semanticDiagnosticsPerFile?.map(d => + ts.isNumber(d) ? + toFileName(d) : + [toFileName(d[0]), d[1]] + ), + affectedFilesPendingEmit: buildInfo.program.affectedFilesPendingEmit?.map(value => toReadableProgramBuilderInfoFilePendingEmit(value, fullEmitForOptions!)), + changeFileSet: buildInfo.program.changeFileSet?.map(toFileName), + emitSignatures: buildInfo.program.emitSignatures?.map(s => + ts.isNumber(s) ? + toFileName(s) : + [toFileName(s[0]), s[1]] + ), + latestChangedDtsFile: buildInfo.program.latestChangedDtsFile, + }; + } + const version = buildInfo.version === ts.version ? fakes.version : buildInfo.version; + const result: ReadableBuildInfo = { + // Baseline fixed order for bundle + bundle: buildInfo.bundle && { + ...buildInfo.bundle, + js: buildInfo.bundle.js && { + sections: buildInfo.bundle.js.sections, + hash: buildInfo.bundle.js.hash, + mapHash: buildInfo.bundle.js.mapHash, + sources: buildInfo.bundle.js.sources, + }, + dts: buildInfo.bundle.dts && { + sections: buildInfo.bundle.dts.sections, + hash: buildInfo.bundle.dts.hash, + mapHash: buildInfo.bundle.dts.mapHash, + sources: buildInfo.bundle.dts.sources, + }, + }, + program, + version, + size: ts.getBuildInfoText({ ...buildInfo, version }).length, + }; + // For now its just JSON.stringify + sys.writeFile(`${buildInfoPath}.readable.baseline.txt`, JSON.stringify(result, /*replacer*/ undefined, 2)); + + function toFileName(fileId: ts.ProgramBuildInfoFileId) { + return buildInfo.program!.fileNames[fileId - 1]; + } + + function toFileNames(fileIdsListId: ts.ProgramBuildInfoFileIdListId) { + return fileNamesList![fileIdsListId - 1]; + } + + function toReadableFileInfo(original: T, toFileInfo: (fileInfo: T) => ts.BuilderState.FileInfo): ReadableProgramBuildInfoFileInfo { + const info = toFileInfo(original); + return { + original: ts.isString(original) ? undefined : original, + ...info, + impliedFormat: info.impliedFormat && ts.getNameOfCompilerOptionValue(info.impliedFormat, ts.moduleOptionDeclaration.type), + }; + } + + function toReadableProgramBuildInfoRoot(original: ts.ProgramBuildInfoRoot): ReadableProgramBuildInfoRoot { + if (!ts.isArray(original)) return [original, toFileName(original)]; + const readable: string[] = []; + for (let index = original[0]; index <= original[1]; index++) readable.push(toFileName(index)); + return [original, readable]; + } + + function toMapOfReferencedSet(referenceMap: ts.ProgramBuildInfoReferencedMap | undefined): ts.MapLike | undefined { + if (!referenceMap) return undefined; + const result: ts.MapLike = {}; + for (const [fileNamesKey, fileNamesListKey] of referenceMap) { + result[toFileName(fileNamesKey)] = toFileNames(fileNamesListKey); + } + return result; + } + + function toReadableProgramBuilderInfoFilePendingEmit(value: ts.ProgramBuilderInfoFilePendingEmit, fullEmitForOptions: ts.BuilderFileEmit): ReadableProgramBuilderInfoFilePendingEmit { + return [ + ts.isNumber(value) ? toFileName(value) : [toFileName(value[0])], + toReadableBuilderFileEmit(ts.toBuilderFileEmit(value, fullEmitForOptions)), + ]; + } + + function toReadableBuilderFileEmit(emit: ts.BuilderFileEmit | undefined): ReadableBuilderFileEmit { + let result = ""; + if (emit) { + if (emit & ts.BuilderFileEmit.Js) addFlags("Js"); + if (emit & ts.BuilderFileEmit.JsMap) addFlags("JsMap"); + if (emit & ts.BuilderFileEmit.JsInlineMap) addFlags("JsInlineMap"); + if (emit & ts.BuilderFileEmit.Dts) addFlags("Dts"); + if (emit & ts.BuilderFileEmit.DtsMap) addFlags("DtsMap"); + } + return (result || "None") as ReadableBuilderFileEmit; + function addFlags(flag: string) { + result = result ? `${result} | ${flag}` : flag; + } + } +} + +export function toPathWithSystem(sys: ts.System, fileName: string): ts.Path { + return ts.toPath(fileName, sys.getCurrentDirectory(), ts.createGetCanonicalFileName(sys.useCaseSensitiveFileNames)); +} + +export function baselineBuildInfo( + options: ts.CompilerOptions, + sys: TscCompileSystem | TestServerHost, + originalReadCall?: ts.System["readFile"], +) { + const buildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(options); + if (!buildInfoPath || !sys.writtenFiles!.has(toPathWithSystem(sys, buildInfoPath))) return; + if (!sys.fileExists(buildInfoPath)) return; + + const buildInfo = ts.getBuildInfo(buildInfoPath, (originalReadCall || sys.readFile).call(sys, buildInfoPath, "utf8")!); + if (!buildInfo) return sys.writeFile(`${buildInfoPath}.baseline.txt`, "Error reading valid buildinfo file"); + generateBuildInfoProgramBaseline(sys, buildInfoPath, buildInfo); + + if (!ts.outFile(options)) return; + const { jsFilePath, declarationFilePath } = ts.getOutputPathsForBundle(options, /*forceDtsPaths*/ false); + const bundle = buildInfo.bundle; + if (!bundle || (!ts.length(bundle.js && bundle.js.sections) && !ts.length(bundle.dts && bundle.dts.sections))) return; + + // Write the baselines: + const baselineRecorder = new Harness.Compiler.WriterAggregator(); + generateBundleFileSectionInfo(sys, originalReadCall || sys.readFile, baselineRecorder, bundle.js, jsFilePath); + generateBundleFileSectionInfo(sys, originalReadCall || sys.readFile, baselineRecorder, bundle.dts, declarationFilePath); + baselineRecorder.Close(); + const text = baselineRecorder.lines.join("\r\n"); + sys.writeFile(`${buildInfoPath}.baseline.txt`, text); +} + +export function tscBaselineName(scenario: string, subScenario: string, commandLineArgs: readonly string[], isWatch?: boolean, suffix?: string) { + return `${ts.isBuild(commandLineArgs) ? "tsbuild" : "tsc"}${isWatch ? "Watch" : ""}/${scenario}/${subScenario.split(" ").join("-")}${suffix ? suffix : ""}.js`; +} \ No newline at end of file diff --git a/src/testRunner/unittests/helpers/contents.ts b/src/testRunner/unittests/helpers/contents.ts new file mode 100644 index 0000000000000..2b81a284a55f9 --- /dev/null +++ b/src/testRunner/unittests/helpers/contents.ts @@ -0,0 +1,21 @@ +import * as ts from "../../_namespaces/ts"; +import { libFile } from "./virtualFileSystemWithWatch"; + +export function compilerOptionsToConfigJson(options: ts.CompilerOptions) { + return ts.optionMapToObject(ts.serializeCompilerOptions(options)); +} + +export const libContent = `${libFile.content} +interface ReadonlyArray {} +declare const console: { log(msg: any): void; };`; + +export const symbolLibContent = ` +interface SymbolConstructor { + readonly species: symbol; + readonly toStringTag: symbol; +} +declare var Symbol: SymbolConstructor; +interface Symbol { + readonly [Symbol.toStringTag]: string; +} +`; diff --git a/src/testRunner/unittests/helpers/solutionBuilder.ts b/src/testRunner/unittests/helpers/solutionBuilder.ts new file mode 100644 index 0000000000000..018594d044d6d --- /dev/null +++ b/src/testRunner/unittests/helpers/solutionBuilder.ts @@ -0,0 +1,63 @@ +import * as fakes from "../../_namespaces/fakes"; +import * as ts from "../../_namespaces/ts"; +import { commandLineCallbacks } from "./baseline"; +import { + makeSystemReadyForBaseline, + TscCompileSystem, +} from "./tsc"; +import { + changeToHostTrackingWrittenFiles, + createWatchedSystem, + FileOrFolderOrSymLink, + FileOrFolderOrSymLinkMap, + TestServerHost, + TestServerHostCreationParameters, +} from "./virtualFileSystemWithWatch"; + +export function createSolutionBuilderHostForBaseline( + sys: TscCompileSystem | TestServerHost, + versionToWrite?: string, + originalRead?: (TscCompileSystem | TestServerHost)["readFile"] +) { + if (sys instanceof fakes.System) makeSystemReadyForBaseline(sys, versionToWrite); + const { cb } = commandLineCallbacks(sys, originalRead); + const host = ts.createSolutionBuilderHost(sys, + /*createProgram*/ undefined, + ts.createDiagnosticReporter(sys, /*pretty*/ true), + ts.createBuilderStatusReporter(sys, /*pretty*/ true) + ); + host.afterProgramEmitAndDiagnostics = cb; + host.afterEmitBundle = cb; + return host; +} + +export function createSolutionBuilder(system: TestServerHost, rootNames: readonly string[], originalRead?: TestServerHost["readFile"]) { + const host = createSolutionBuilderHostForBaseline(system, /*versionToWrite*/ undefined, originalRead); + return ts.createSolutionBuilder(host, rootNames, {}); +} + +export function ensureErrorFreeBuild(host: TestServerHost, rootNames: readonly string[]) { + // ts build should succeed + solutionBuildWithBaseline(host, rootNames); + assert.equal(host.getOutput().length, 0, JSON.stringify(host.getOutput(), /*replacer*/ undefined, " ")); +} + +export function solutionBuildWithBaseline(sys: TestServerHost, solutionRoots: readonly string[], originalRead?: TestServerHost["readFile"]) { + const originalReadFile = sys.readFile; + const originalWrite = sys.write; + const originalWriteFile = sys.writeFile; + ts.Debug.assert(sys.writtenFiles === undefined); + const solutionBuilder = createSolutionBuilder(changeToHostTrackingWrittenFiles( + fakes.patchHostForBuildInfoReadWrite(sys) + ), solutionRoots, originalRead); + solutionBuilder.build(); + sys.readFile = originalReadFile; + sys.write = originalWrite; + sys.writeFile = originalWriteFile; + sys.writtenFiles = undefined; + return sys; +} + +export function createSystemWithSolutionBuild(solutionRoots: readonly string[], files: FileOrFolderOrSymLinkMap | readonly FileOrFolderOrSymLink[], params?: TestServerHostCreationParameters) { + return solutionBuildWithBaseline(createWatchedSystem(files, params), solutionRoots); +} \ No newline at end of file diff --git a/src/testRunner/unittests/helpers/tsc.ts b/src/testRunner/unittests/helpers/tsc.ts new file mode 100644 index 0000000000000..ce21213a4dc5f --- /dev/null +++ b/src/testRunner/unittests/helpers/tsc.ts @@ -0,0 +1,545 @@ +import * as fakes from "../../_namespaces/fakes"; +import * as Harness from "../../_namespaces/Harness"; +import * as ts from "../../_namespaces/ts"; +import * as vfs from "../../_namespaces/vfs"; +import { + baselinePrograms, + CommandLineCallbacks, + commandLineCallbacks, + CommandLineProgram, + generateSourceMapBaselineFiles, + isReadableProgramBundleEmitBuildInfo, + ReadableBuildInfo, + ReadableProgramBuildInfoFileInfo, + ReadableProgramMultiFileEmitBuildInfo, + toPathWithSystem, + tscBaselineName, +} from "./baseline"; + +export interface DtsSignatureData { + signature: string | undefined; + exportedModules: string[] | undefined; +} + +export type TscCompileSystem = fakes.System & { + writtenFiles: Set; + baseLine(): { file: string; text: string; }; + dtsSignaures?: Map>; + storeFilesChangingSignatureDuringEmit?: boolean; +}; + +export const noChangeRun: TestTscEdit = { + caption: "no-change-run", + edit: ts.noop +}; +export const noChangeOnlyRuns = [noChangeRun]; + +export interface TestTscCompile extends TestTscCompileLikeBase { + baselineSourceMap?: boolean; + baselineReadFileCalls?: boolean; + baselinePrograms?: boolean; + baselineDependencies?: boolean; +} + +export interface TestTscCompileLikeBase extends VerifyTscCompileLike { + diffWithInitial?: boolean; + modifyFs?: (fs: vfs.FileSystem) => void; + computeDtsSignatures?: boolean; + environmentVariables?: Record; +} + +export interface TestTscCompileLike extends TestTscCompileLikeBase { + compile: (sys: TscCompileSystem) => void; + additionalBaseline?: (sys: TscCompileSystem) => void; +} +/** + * Initialize FS, run compile function and save baseline + */ +export function testTscCompileLike(input: TestTscCompileLike) { + const initialFs = input.fs(); + const inputFs = initialFs.shadow(); + const { + scenario, subScenario, diffWithInitial, + commandLineArgs, modifyFs, + environmentVariables, + compile: worker, additionalBaseline, + } = input; + if (modifyFs) modifyFs(inputFs); + inputFs.makeReadonly(); + const fs = inputFs.shadow(); + + // Create system + const sys = new fakes.System(fs, { executingFilePath: "/lib/tsc", env: environmentVariables }) as TscCompileSystem; + sys.storeFilesChangingSignatureDuringEmit = true; + sys.write(`${sys.getExecutingFilePath()} ${commandLineArgs.join(" ")}\n`); + sys.exit = exitCode => sys.exitCode = exitCode; + worker(sys); + sys.write(`exitCode:: ExitStatus.${ts.ExitStatus[sys.exitCode as ts.ExitStatus]}\n`); + additionalBaseline?.(sys); + fs.makeReadonly(); + sys.baseLine = () => { + const baseFsPatch = diffWithInitial ? + inputFs.diff(initialFs, { includeChangedFileWithSameContent: true }) : + inputFs.diff(/*base*/ undefined, { baseIsNotShadowRoot: true }); + const patch = fs.diff(inputFs, { includeChangedFileWithSameContent: true }); + return { + file: tscBaselineName(scenario, subScenario, commandLineArgs), + text: `Input:: +${baseFsPatch ? vfs.formatPatch(baseFsPatch) : ""} + +Output:: +${sys.output.join("")} + +${patch ? vfs.formatPatch(patch) : ""}` + }; + }; + return sys; +} + +export function makeSystemReadyForBaseline(sys: TscCompileSystem, versionToWrite?: string) { + if (versionToWrite) { + fakes.patchHostForBuildInfoWrite(sys, versionToWrite); + } + else { + fakes.patchHostForBuildInfoReadWrite(sys); + } + const writtenFiles = sys.writtenFiles = new Set(); + const originalWriteFile = sys.writeFile; + sys.writeFile = (fileName, content, writeByteOrderMark) => { + const path = toPathWithSystem(sys, fileName); + // When buildinfo is same for two projects, + // it gives error and doesnt write buildinfo but because buildInfo is written for one project, + // readable baseline will be written two times for those two projects with same contents and is ok + ts.Debug.assert(!writtenFiles.has(path) || ts.endsWith(path, "baseline.txt")); + writtenFiles.add(path); + return originalWriteFile.call(sys, fileName, content, writeByteOrderMark); + }; +} + +/** + * Initialize Fs, execute command line and save baseline + */ +export function testTscCompile(input: TestTscCompile) { + let actualReadFileMap: ts.MapLike | undefined; + let getPrograms: CommandLineCallbacks["getPrograms"] | undefined; + return testTscCompileLike({ + ...input, + compile: commandLineCompile, + additionalBaseline + }); + + function commandLineCompile(sys: TscCompileSystem) { + makeSystemReadyForBaseline(sys); + actualReadFileMap = {}; + const originalReadFile = sys.readFile; + sys.readFile = path => { + // Dont record libs + if (path.startsWith("/src/")) { + actualReadFileMap![path] = (ts.getProperty(actualReadFileMap!, path) || 0) + 1; + } + return originalReadFile.call(sys, path); + }; + + const result = commandLineCallbacks(sys, originalReadFile); + ts.executeCommandLine( + sys, + result.cb, + input.commandLineArgs, + ); + sys.readFile = originalReadFile; + getPrograms = result.getPrograms; + } + + function additionalBaseline(sys: TscCompileSystem) { + const { baselineSourceMap, baselineReadFileCalls, baselinePrograms: shouldBaselinePrograms, baselineDependencies } = input; + if (input.computeDtsSignatures) storeDtsSignatures(sys, getPrograms!()); + if (shouldBaselinePrograms) { + const baseline: string[] = []; + baselinePrograms(baseline, getPrograms!, ts.emptyArray, baselineDependencies); + sys.write(baseline.join("\n")); + } + if (baselineReadFileCalls) { + sys.write(`readFiles:: ${JSON.stringify(actualReadFileMap, /*replacer*/ undefined, " ")} `); + } + if (baselineSourceMap) generateSourceMapBaselineFiles(sys); + actualReadFileMap = undefined; + getPrograms = undefined; + } +} + +function storeDtsSignatures(sys: TscCompileSystem, programs: readonly CommandLineProgram[]) { + for (const [program, builderProgram] of programs) { + if (!builderProgram) continue; + const buildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(program.getCompilerOptions()); + if (!buildInfoPath) continue; + sys.dtsSignaures ??= new Map(); + const dtsSignatureData = new Map(); + sys.dtsSignaures.set(`${toPathWithSystem(sys, buildInfoPath)}.readable.baseline.txt` as ts.Path, dtsSignatureData); + const state = builderProgram.getState(); + state.hasCalledUpdateShapeSignature?.forEach(resolvedPath => { + const file = program.getSourceFileByPath(resolvedPath); + if (!file || file.isDeclarationFile) return; + // Compute dts and exported map and store it + ts.BuilderState.computeDtsSignature( + program, + file, + /*cancellationToken*/ undefined, + sys, + (signature, sourceFiles) => { + const exportedModules = ts.BuilderState.getExportedModules(state.exportedModulesMap && sourceFiles[0].exportedModulesFromDeclarationEmit); + dtsSignatureData.set(relativeToBuildInfo(resolvedPath), { signature, exportedModules: exportedModules && ts.arrayFrom(exportedModules.keys(), relativeToBuildInfo) }); + }, + ); + }); + + function relativeToBuildInfo(path: string) { + const currentDirectory = program.getCurrentDirectory(); + const getCanonicalFileName = ts.createGetCanonicalFileName(program.useCaseSensitiveFileNames()); + const buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(buildInfoPath!, currentDirectory)); + return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(buildInfoDirectory, path, getCanonicalFileName)); + } + } +} + +export function verifyTscBaseline(sys: () => { baseLine: TscCompileSystem["baseLine"]; }) { + it(`Generates files matching the baseline`, () => { + const { file, text } = sys().baseLine(); + Harness.Baseline.runBaseline(file, text); + }); +} +export interface VerifyTscCompileLike { + scenario: string; + subScenario: string; + commandLineArgs: readonly string[]; + fs: () => vfs.FileSystem; +} + +/** + * Verify by baselining after initializing FS and custom compile + */ +export function verifyTscCompileLike(verifier: (input: T) => { baseLine: TscCompileSystem["baseLine"]; }, input: T) { + describe(`tsc ${input.commandLineArgs.join(" ")} ${input.scenario}:: ${input.subScenario}`, () => { + describe(input.scenario, () => { + describe(input.subScenario, () => { + verifyTscBaseline(() => verifier({ + ...input, + fs: () => input.fs().makeReadonly() + })); + }); + }); + }); +} + +interface VerifyTscEditDiscrepanciesInput { + index: number; + edits: readonly TestTscEdit[]; + scenario: TestTscCompile["scenario"]; + baselines: string[] | undefined; + commandLineArgs: TestTscCompile["commandLineArgs"]; + modifyFs: TestTscCompile["modifyFs"]; + baseFs: vfs.FileSystem; + newSys: TscCompileSystem; + environmentVariables: TestTscCompile["environmentVariables"]; +} +function verifyTscEditDiscrepancies({ + index, edits, scenario, commandLineArgs, environmentVariables, + baselines, + modifyFs, baseFs, newSys +}: VerifyTscEditDiscrepanciesInput): string[] | undefined { + const { caption, discrepancyExplanation } = edits[index]; + const sys = testTscCompile({ + scenario, + subScenario: caption, + fs: () => baseFs.makeReadonly(), + commandLineArgs: edits[index].commandLineArgs || commandLineArgs, + modifyFs: fs => { + if (modifyFs) modifyFs(fs); + for (let i = 0; i <= index; i++) { + edits[i].edit(fs); + } + }, + environmentVariables, + computeDtsSignatures: true, + }); + let headerAdded = false; + for (const outputFile of sys.writtenFiles.keys()) { + const cleanBuildText = sys.readFile(outputFile); + const incrementalBuildText = newSys.readFile(outputFile); + if (ts.isBuildInfoFile(outputFile)) { + // Check only presence and absence and not text as we will do that for readable baseline + if (!sys.fileExists(`${outputFile}.readable.baseline.txt`)) addBaseline(`Readable baseline not present in clean build:: File:: ${outputFile}`); + if (!newSys.fileExists(`${outputFile}.readable.baseline.txt`)) addBaseline(`Readable baseline not present in incremental build:: File:: ${outputFile}`); + verifyPresenceAbsence(incrementalBuildText, cleanBuildText, `Incremental and clean tsbuildinfo file presence differs:: File:: ${outputFile}`); + } + else if (!ts.fileExtensionIs(outputFile, ".tsbuildinfo.readable.baseline.txt")) { + verifyTextEqual(incrementalBuildText, cleanBuildText, `File: ${outputFile}`); + } + else if (incrementalBuildText !== cleanBuildText) { + // Verify build info without affectedFilesPendingEmit + const { buildInfo: incrementalBuildInfo, readableBuildInfo: incrementalReadableBuildInfo } = getBuildInfoForIncrementalCorrectnessCheck(incrementalBuildText); + const { buildInfo: cleanBuildInfo, readableBuildInfo: cleanReadableBuildInfo } = getBuildInfoForIncrementalCorrectnessCheck(cleanBuildText); + const dtsSignaures = sys.dtsSignaures?.get(outputFile); + verifyTextEqual(incrementalBuildInfo, cleanBuildInfo, `TsBuild info text without affectedFilesPendingEmit:: ${outputFile}::`); + // Verify file info sigantures + verifyMapLike( + incrementalReadableBuildInfo?.program?.fileInfos as ReadableProgramMultiFileEmitBuildInfo["fileInfos"], + cleanReadableBuildInfo?.program?.fileInfos as ReadableProgramMultiFileEmitBuildInfo["fileInfos"], + (key, incrementalFileInfo, cleanFileInfo) => { + const dtsForKey = dtsSignaures?.get(key); + if (!incrementalFileInfo || !cleanFileInfo || incrementalFileInfo.signature !== cleanFileInfo.signature && (!dtsForKey || incrementalFileInfo.signature !== dtsForKey.signature)) { + return [ + `Incremental signature is neither dts signature nor file version for File:: ${key}`, + `Incremental:: ${JSON.stringify(incrementalFileInfo, /*replacer*/ undefined, 2)}`, + `Clean:: ${JSON.stringify(cleanFileInfo, /*replacer*/ undefined, 2)}`, + `Dts Signature:: $${JSON.stringify(dtsForKey?.signature)}` + ]; + } + }, + `FileInfos:: File:: ${outputFile}` + ); + if (!isReadableProgramBundleEmitBuildInfo(incrementalReadableBuildInfo?.program)) { + ts.Debug.assert(!isReadableProgramBundleEmitBuildInfo(cleanReadableBuildInfo?.program)); + // Verify exportedModulesMap + verifyMapLike( + incrementalReadableBuildInfo?.program?.exportedModulesMap, + cleanReadableBuildInfo?.program?.exportedModulesMap, + (key, incrementalReferenceSet, cleanReferenceSet) => { + const dtsForKey = dtsSignaures?.get(key); + if (!ts.arrayIsEqualTo(incrementalReferenceSet, cleanReferenceSet) && + (!dtsForKey || !ts.arrayIsEqualTo(incrementalReferenceSet, dtsForKey.exportedModules))) { + return [ + `Incremental Reference set is neither from dts nor files reference map for File:: ${key}::`, + `Incremental:: ${JSON.stringify(incrementalReferenceSet, /*replacer*/ undefined, 2)}`, + `Clean:: ${JSON.stringify(cleanReferenceSet, /*replacer*/ undefined, 2)}`, + `DtsExportsMap:: ${JSON.stringify(dtsForKey?.exportedModules, /*replacer*/ undefined, 2)}` + ]; + } + }, + `exportedModulesMap:: File:: ${outputFile}` + ); + // Verify that incrementally pending affected file emit are in clean build since clean build can contain more files compared to incremental depending of noEmitOnError option + if (incrementalReadableBuildInfo?.program?.affectedFilesPendingEmit) { + if (cleanReadableBuildInfo?.program?.affectedFilesPendingEmit === undefined) { + addBaseline( + `Incremental build contains affectedFilesPendingEmit, clean build does not have it: ${outputFile}::`, + `Incremental buildInfoText:: ${incrementalBuildText}`, + `Clean buildInfoText:: ${cleanBuildText}` + ); + } + let expectedIndex = 0; + incrementalReadableBuildInfo.program.affectedFilesPendingEmit.forEach(([actualFileOrArray]) => { + const actualFile = ts.isString(actualFileOrArray) ? actualFileOrArray : actualFileOrArray[0]; + expectedIndex = ts.findIndex( + (cleanReadableBuildInfo!.program! as ReadableProgramMultiFileEmitBuildInfo).affectedFilesPendingEmit, + ([expectedFileOrArray]) => actualFile === (ts.isString(expectedFileOrArray) ? expectedFileOrArray : expectedFileOrArray[0]), + expectedIndex + ); + if (expectedIndex === -1) { + addBaseline( + `Incremental build contains ${actualFile} file as pending emit, clean build does not have it: ${outputFile}::`, + `Incremental buildInfoText:: ${incrementalBuildText}`, + `Clean buildInfoText:: ${cleanBuildText}` + ); + } + expectedIndex++; + }); + } + } + } + } + if (!headerAdded && discrepancyExplanation) addBaseline("*** Supplied discrepancy explanation but didnt file any difference"); + return baselines; + + function verifyTextEqual(incrementalText: string | undefined, cleanText: string | undefined, message: string) { + if (incrementalText !== cleanText) writeNotEqual(incrementalText, cleanText, message); + } + + function verifyMapLike( + incremental: ts.MapLike | undefined, + clean: ts.MapLike | undefined, + verifyValue: (key: string, incrementalValue: T | undefined, cleanValue: T | undefined) => string[] | undefined, + message: string, + ) { + verifyPresenceAbsence(incremental, clean, `Incremental and clean do not match:: ${message}`); + if (!incremental || !clean) return; + const incrementalMap = new Map(Object.entries(incremental)); + const cleanMap = new Map(Object.entries(clean)); + cleanMap.forEach((cleanValue, key) => { + const result = verifyValue(key, incrementalMap.get(key), cleanValue); + if (result) addBaseline(...result); + }); + incrementalMap.forEach((incremetnalValue, key) => { + if (cleanMap.has(key)) return; + // This is value only in incremental Map + const result = verifyValue(key, incremetnalValue, /*cleanValue*/ undefined); + if (result) addBaseline(...result); + }); + } + + function verifyPresenceAbsence(actual: T | undefined, expected: T | undefined, message: string) { + if (expected === undefined) { + if (actual === undefined) return; + } + else { + if (actual !== undefined) return; + } + writeNotEqual(actual, expected, message); + } + + function writeNotEqual(actual: T | undefined, expected: T | undefined, message: string) { + addBaseline( + message, + "CleanBuild:", + ts.isString(expected) ? expected : JSON.stringify(expected), + "IncrementalBuild:", + ts.isString(actual) ? actual : JSON.stringify(actual), + ); + } + + function addBaseline(...text: string[]) { + if (!baselines || !headerAdded) { + (baselines ||= []).push(`${index}:: ${caption}`, ...(discrepancyExplanation?.()|| ["*** Needs explanation"])); + headerAdded = true; + } + baselines.push(...text); + } +} + +function getBuildInfoForIncrementalCorrectnessCheck(text: string | undefined): { + buildInfo: string | undefined; + readableBuildInfo?: ReadableBuildInfo; +} { + if (!text) return { buildInfo: text }; + const readableBuildInfo = JSON.parse(text) as ReadableBuildInfo; + let sanitizedFileInfos: ts.MapLike | ReadableProgramBuildInfoFileInfo, "signature" | "original"> & { signature: undefined; original: undefined; }> | undefined; + if (readableBuildInfo.program?.fileInfos) { + sanitizedFileInfos = {}; + for (const id in readableBuildInfo.program.fileInfos) { + if (ts.hasProperty(readableBuildInfo.program.fileInfos, id)) { + const info = readableBuildInfo.program.fileInfos[id]; + sanitizedFileInfos[id] = ts.isString(info) ? info : { ...info, signature: undefined, original: undefined }; + } + } + } + return { + buildInfo: JSON.stringify({ + ...readableBuildInfo, + program: readableBuildInfo.program && { + ...readableBuildInfo.program, + fileNames: undefined, + fileNamesList: undefined, + fileInfos: sanitizedFileInfos, + // Ignore noEmit since that shouldnt be reason to emit the tsbuild info and presence of it in the buildinfo file does not matter + options: { ...readableBuildInfo.program.options, noEmit: undefined }, + exportedModulesMap: undefined, + affectedFilesPendingEmit: undefined, + latestChangedDtsFile: readableBuildInfo.program.latestChangedDtsFile ? "FakeFileName" : undefined, + }, + size: undefined, // Size doesnt need to be equal + }, /*replacer*/ undefined, 2), + readableBuildInfo, + }; +} + +export interface TestTscEdit { + edit: (fs: vfs.FileSystem) => void; + caption: string; + commandLineArgs?: readonly string[]; + /** An array of lines to be printed in order when a discrepancy is detected */ + discrepancyExplanation?: () => readonly string[]; +} + +export interface VerifyTscWithEditsInput extends TestTscCompile { + edits?: readonly TestTscEdit[]; +} + +/** + * Verify non watch tsc invokcation after each edit + */ +export function verifyTsc({ + subScenario, fs, scenario, commandLineArgs, environmentVariables, + baselineSourceMap, modifyFs, baselineReadFileCalls, baselinePrograms, + edits +}: VerifyTscWithEditsInput) { + describe(`tsc ${commandLineArgs.join(" ")} ${scenario}:: ${subScenario}`, () => { + let sys: TscCompileSystem; + let baseFs: vfs.FileSystem; + let editsSys: TscCompileSystem[] | undefined; + before(() => { + baseFs = fs().makeReadonly(); + sys = testTscCompile({ + scenario, + subScenario, + fs: () => baseFs, + commandLineArgs, + modifyFs, + baselineSourceMap, + baselineReadFileCalls, + baselinePrograms, + environmentVariables, + }); + edits?.forEach(( + { edit, caption, commandLineArgs: editCommandLineArgs }, + index + ) => { + (editsSys || (editsSys = [])).push(testTscCompile({ + scenario, + subScenario: caption, + diffWithInitial: true, + fs: () => index === 0 ? sys.vfs : editsSys![index - 1].vfs, + commandLineArgs: editCommandLineArgs || commandLineArgs, + modifyFs: edit, + baselineSourceMap, + baselineReadFileCalls, + baselinePrograms, + environmentVariables, + })); + }); + }); + after(() => { + baseFs = undefined!; + sys = undefined!; + editsSys = undefined!; + }); + verifyTscBaseline(() => ({ + baseLine: () => { + const { file, text } = sys.baseLine(); + const texts: string[] = [text]; + editsSys?.forEach((sys, index) => { + const incrementalScenario = edits![index]; + texts.push(""); + texts.push(`Change:: ${incrementalScenario.caption}`); + texts.push(sys.baseLine().text); + }); + return { + file, + text: `currentDirectory:: ${sys.getCurrentDirectory()} useCaseSensitiveFileNames: ${sys.useCaseSensitiveFileNames}\r\n` + + texts.join("\r\n"), + }; + } + })); + if (edits?.length) { + it("tsc invocation after edit and clean build correctness", () => { + let baselines: string[] | undefined; + for (let index = 0; index < edits.length; index++) { + baselines = verifyTscEditDiscrepancies({ + index, + edits, + scenario, + baselines, + baseFs, + newSys: editsSys![index], + commandLineArgs, + modifyFs, + environmentVariables, + }); + } + Harness.Baseline.runBaseline( + tscBaselineName(scenario, subScenario, commandLineArgs, /*isWatch*/ undefined, "-discrepancies"), + baselines ? baselines.join("\r\n") : null // eslint-disable-line no-null/no-null + ); + }); + } + }); +} + diff --git a/src/testRunner/unittests/tscWatch/helpers.ts b/src/testRunner/unittests/helpers/tscWatch.ts similarity index 82% rename from src/testRunner/unittests/tscWatch/helpers.ts rename to src/testRunner/unittests/helpers/tscWatch.ts index e864b976277ba..4b8a3a6076866 100644 --- a/src/testRunner/unittests/tscWatch/helpers.ts +++ b/src/testRunner/unittests/helpers/tscWatch.ts @@ -6,19 +6,15 @@ import { CommandLineCallbacks, commandLineCallbacks, CommandLineProgram, - createSolutionBuilderHostForBaseline, generateSourceMapBaselineFiles, -} from "../tsc/helpers"; + tscBaselineName, +} from "./baseline"; import { changeToHostTrackingWrittenFiles, - createWatchedSystem, File, - FileOrFolderOrSymLink, - FileOrFolderOrSymLinkMap, TestServerHost, - TestServerHostCreationParameters, TestServerHostTrackingWrittenFiles, -} from "../virtualFileSystemWithWatch"; +} from "./virtualFileSystemWithWatch"; export const commonFile1: File = { path: "/a/b/commonFile1.ts", @@ -249,10 +245,10 @@ export function runWatchBaseline { if (arg.charCodeAt(0) !== ts.CharacterCodes.minus) return false; const option = arg.slice(arg.charCodeAt(1) === ts.CharacterCodes.minus ? 2 : 1).toLowerCase(); @@ -296,34 +292,3 @@ export function verifyTscWatch(input: VerifyTscWatch) { } }); } - -export function createSolutionBuilder(system: TestServerHost, rootNames: readonly string[], originalRead?: TestServerHost["readFile"]) { - const host = createSolutionBuilderHostForBaseline(system, /*versionToWrite*/ undefined, originalRead); - return ts.createSolutionBuilder(host, rootNames, {}); -} - -export function ensureErrorFreeBuild(host: TestServerHost, rootNames: readonly string[]) { - // ts build should succeed - solutionBuildWithBaseline(host, rootNames); - assert.equal(host.getOutput().length, 0, JSON.stringify(host.getOutput(), /*replacer*/ undefined, " ")); -} - -export function solutionBuildWithBaseline(sys: TestServerHost, solutionRoots: readonly string[], originalRead?: TestServerHost["readFile"]) { - const originalReadFile = sys.readFile; - const originalWrite = sys.write; - const originalWriteFile = sys.writeFile; - ts.Debug.assert(sys.writtenFiles === undefined); - const solutionBuilder = createSolutionBuilder(changeToHostTrackingWrittenFiles( - patchHostForBuildInfoReadWrite(sys) - ), solutionRoots, originalRead); - solutionBuilder.build(); - sys.readFile = originalReadFile; - sys.write = originalWrite; - sys.writeFile = originalWriteFile; - sys.writtenFiles = undefined; - return sys; -} - -export function createSystemWithSolutionBuild(solutionRoots: readonly string[], files: FileOrFolderOrSymLinkMap | readonly FileOrFolderOrSymLink[], params?: TestServerHostCreationParameters) { - return solutionBuildWithBaseline(createWatchedSystem(files, params), solutionRoots); -} diff --git a/src/testRunner/unittests/tsserver/helpers.ts b/src/testRunner/unittests/helpers/tsserver.ts similarity index 97% rename from src/testRunner/unittests/tsserver/helpers.ts rename to src/testRunner/unittests/helpers/tsserver.ts index 4a4116a7cd9a1..00141c1b569ba 100644 --- a/src/testRunner/unittests/tsserver/helpers.ts +++ b/src/testRunner/unittests/helpers/tsserver.ts @@ -1,6 +1,6 @@ import * as Harness from "../../_namespaces/Harness"; import * as ts from "../../_namespaces/ts"; -import { ensureErrorFreeBuild } from "../tscWatch/helpers"; +import { ensureErrorFreeBuild } from "./solutionBuilder"; import { changeToHostTrackingWrittenFiles, createServerHost, @@ -9,7 +9,7 @@ import { libFile, TestServerHost, TestServerHostTrackingWrittenFiles, -} from "../virtualFileSystemWithWatch"; +} from "./virtualFileSystemWithWatch"; export const customTypesMap = { path: "/typesMap.json" as ts.Path, diff --git a/src/testRunner/unittests/helpers/vfs.ts b/src/testRunner/unittests/helpers/vfs.ts new file mode 100644 index 0000000000000..cf91b51d499fb --- /dev/null +++ b/src/testRunner/unittests/helpers/vfs.ts @@ -0,0 +1,135 @@ +import * as Harness from "../../_namespaces/Harness"; +import * as vfs from "../../_namespaces/vfs"; +import * as vpath from "../../_namespaces/vpath"; +import { libContent } from "./contents"; + +/** + * Load project from disk into /src folder + */ + +export function loadProjectFromDisk( + root: string, + libContentToAppend?: string +): vfs.FileSystem { + const resolver = vfs.createResolver(Harness.IO); + const fs = new vfs.FileSystem(/*ignoreCase*/ true, { + files: { + ["/src"]: new vfs.Mount(vpath.resolve(Harness.IO.getWorkspaceRoot(), root), resolver) + }, + cwd: "/", + meta: { defaultLibLocation: "/lib" }, + }); + addLibAndMakeReadonly(fs, libContentToAppend); + return fs; +} +/** + * All the files must be in /src + */ + +export function loadProjectFromFiles( + files: vfs.FileSet, + libContentToAppend?: string +): vfs.FileSystem { + const fs = new vfs.FileSystem(/*ignoreCase*/ true, { + files, + cwd: "/", + meta: { defaultLibLocation: "/lib" }, + }); + addLibAndMakeReadonly(fs, libContentToAppend); + return fs; +} +function addLibAndMakeReadonly(fs: vfs.FileSystem, libContentToAppend?: string) { + fs.mkdirSync("/lib"); + fs.writeFileSync("/lib/lib.d.ts", libContentToAppend ? `${libContent}${libContentToAppend}` : libContent); + fs.makeReadonly(); +} + +export function replaceText(fs: vfs.FileSystem, path: string, oldText: string, newText: string) { + if (!fs.statSync(path).isFile()) { + throw new Error(`File ${path} does not exist`); + } + const old = fs.readFileSync(path, "utf-8"); + if (old.indexOf(oldText) < 0) { + throw new Error(`Text "${oldText}" does not exist in file ${path}`); + } + const newContent = old.replace(oldText, newText); + fs.writeFileSync(path, newContent, "utf-8"); +} + +export function prependText(fs: vfs.FileSystem, path: string, additionalContent: string) { + if (!fs.statSync(path).isFile()) { + throw new Error(`File ${path} does not exist`); + } + const old = fs.readFileSync(path, "utf-8"); + fs.writeFileSync(path, `${additionalContent}${old}`, "utf-8"); +} + +export function appendText(fs: vfs.FileSystem, path: string, additionalContent: string) { + if (!fs.statSync(path).isFile()) { + throw new Error(`File ${path} does not exist`); + } + const old = fs.readFileSync(path, "utf-8"); + fs.writeFileSync(path, `${old}${additionalContent}`); +} + +export function enableStrict(fs: vfs.FileSystem, path: string) { + replaceText(fs, path, `"strict": false`, `"strict": true`); +} + +export function addTestPrologue(fs: vfs.FileSystem, path: string, prologue: string) { + prependText(fs, path, `${prologue} +`); +} + +export function addShebang(fs: vfs.FileSystem, project: string, file: string) { + prependText(fs, `src/${project}/${file}.ts`, `#!someshebang ${project} ${file} +`); +} + +export function restContent(project: string, file: string) { + return `function for${project}${file}Rest() { +const { b, ...rest } = { a: 10, b: 30, yy: 30 }; +}`; +} +function nonrestContent(project: string, file: string) { + return `function for${project}${file}Rest() { }`; +} + +export function addRest(fs: vfs.FileSystem, project: string, file: string) { + appendText(fs, `src/${project}/${file}.ts`, restContent(project, file)); +} + +export function removeRest(fs: vfs.FileSystem, project: string, file: string) { + replaceText(fs, `src/${project}/${file}.ts`, restContent(project, file), nonrestContent(project, file)); +} + +export function addStubFoo(fs: vfs.FileSystem, project: string, file: string) { + appendText(fs, `src/${project}/${file}.ts`, nonrestContent(project, file)); +} + +export function changeStubToRest(fs: vfs.FileSystem, project: string, file: string) { + replaceText(fs, `src/${project}/${file}.ts`, nonrestContent(project, file), restContent(project, file)); +} + +export function addSpread(fs: vfs.FileSystem, project: string, file: string) { + const path = `src/${project}/${file}.ts`; + const content = fs.readFileSync(path, "utf8"); + fs.writeFileSync(path, `${content} +function ${project}${file}Spread(...b: number[]) { } +const ${project}${file}_ar = [20, 30]; +${project}${file}Spread(10, ...${project}${file}_ar);`); + + replaceText(fs, `src/${project}/tsconfig.json`, `"strict": false,`, `"strict": false, + "downlevelIteration": true,`); +} + +export function getTripleSlashRef(project: string) { + return `/src/${project}/tripleRef.d.ts`; +} + +export function addTripleSlashRef(fs: vfs.FileSystem, project: string, file: string) { + fs.writeFileSync(getTripleSlashRef(project), `declare class ${project}${file} { }`); + prependText(fs, `src/${project}/${file}.ts`, `/// +const ${file}Const = new ${project}${file}(); +`); +} diff --git a/src/testRunner/unittests/virtualFileSystemWithWatch.ts b/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts similarity index 97% rename from src/testRunner/unittests/virtualFileSystemWithWatch.ts rename to src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts index 3873a36051c85..6ee669a78d0f6 100644 --- a/src/testRunner/unittests/virtualFileSystemWithWatch.ts +++ b/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts @@ -1,4 +1,4 @@ -import * as Harness from "../_namespaces/Harness"; +import * as Harness from "../../_namespaces/Harness"; import { clear, clone, @@ -42,8 +42,8 @@ import { SortedArray, sys, toPath, -} from "../_namespaces/ts"; -import { timeIncrements } from "../_namespaces/vfs"; +} from "../../_namespaces/ts"; +import { timeIncrements } from "../../_namespaces/vfs"; export const libFile: File = { path: "/a/lib/lib.d.ts", diff --git a/src/testRunner/unittests/reuseProgramStructure.ts b/src/testRunner/unittests/reuseProgramStructure.ts index e987263cd81c3..8c03d4b0b447d 100644 --- a/src/testRunner/unittests/reuseProgramStructure.ts +++ b/src/testRunner/unittests/reuseProgramStructure.ts @@ -16,7 +16,7 @@ import { createWatchedSystem, File, libFile, -} from "./virtualFileSystemWithWatch"; +} from "./helpers/virtualFileSystemWithWatch"; describe("unittests:: Reuse program structure:: General", () => { function baselineCache(baselines: string[], cacheType: string, cache: ts.ModeAwareCache | undefined) { diff --git a/src/testRunner/unittests/services/convertToAsyncFunction.ts b/src/testRunner/unittests/services/convertToAsyncFunction.ts index dc4ce581a8481..00b46896aaaa2 100644 --- a/src/testRunner/unittests/services/convertToAsyncFunction.ts +++ b/src/testRunner/unittests/services/convertToAsyncFunction.ts @@ -1,10 +1,10 @@ import * as Harness from "../../_namespaces/Harness"; import * as ts from "../../_namespaces/ts"; -import { createProjectService } from "../tsserver/helpers"; +import { createProjectService } from "../helpers/tsserver"; import { createServerHost, File, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; import { extractTest, newLineCharacter, diff --git a/src/testRunner/unittests/services/extract/helpers.ts b/src/testRunner/unittests/services/extract/helpers.ts index 74900ca0f1a71..cc139c3f42a2c 100644 --- a/src/testRunner/unittests/services/extract/helpers.ts +++ b/src/testRunner/unittests/services/extract/helpers.ts @@ -1,10 +1,10 @@ import * as Harness from "../../../_namespaces/Harness"; import * as ts from "../../../_namespaces/ts"; -import { createProjectService } from "../../tsserver/helpers"; +import { createProjectService } from "../../helpers/tsserver"; import { createServerHost, libFile, -} from "../../virtualFileSystemWithWatch"; +} from "../../helpers/virtualFileSystemWithWatch"; interface Range { pos: number; diff --git a/src/testRunner/unittests/services/findAllReferences.ts b/src/testRunner/unittests/services/findAllReferences.ts index ec1ea57921d81..85b1b4b05fcaa 100644 --- a/src/testRunner/unittests/services/findAllReferences.ts +++ b/src/testRunner/unittests/services/findAllReferences.ts @@ -1,6 +1,6 @@ import { protocol } from "../../_namespaces/ts.server"; -import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession } from "../tsserver/helpers"; -import { createServerHost, File } from "../virtualFileSystemWithWatch"; +import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession } from "../helpers/tsserver"; +import { createServerHost, File } from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: services:: findAllReferences", () => { it("does not try to open a file in a project that was updated and no longer has the file", () => { diff --git a/src/testRunner/unittests/services/languageService.ts b/src/testRunner/unittests/services/languageService.ts index a3671c1c9f3cb..f34256c4fccbe 100644 --- a/src/testRunner/unittests/services/languageService.ts +++ b/src/testRunner/unittests/services/languageService.ts @@ -5,7 +5,7 @@ import { createServerHost, File, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: services:: languageService", () => { const files: {[index: string]: string} = { diff --git a/src/testRunner/unittests/services/organizeImports.ts b/src/testRunner/unittests/services/organizeImports.ts index 3d89460349688..9794bd1d68746 100644 --- a/src/testRunner/unittests/services/organizeImports.ts +++ b/src/testRunner/unittests/services/organizeImports.ts @@ -1,10 +1,10 @@ import * as Harness from "../../_namespaces/Harness"; import * as ts from "../../_namespaces/ts"; -import { createProjectService } from "../tsserver/helpers"; +import { createProjectService } from "../helpers/tsserver"; import { createServerHost, File, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; import { newLineCharacter } from "./extract/helpers"; describe("unittests:: services:: organizeImports", () => { diff --git a/src/testRunner/unittests/tsbuild/amdModulesWithOut.ts b/src/testRunner/unittests/tsbuild/amdModulesWithOut.ts index a7378110ba88c..848b58933edef 100644 --- a/src/testRunner/unittests/tsbuild/amdModulesWithOut.ts +++ b/src/testRunner/unittests/tsbuild/amdModulesWithOut.ts @@ -1,5 +1,8 @@ import * as ts from "../../_namespaces/ts"; import * as vfs from "../../_namespaces/vfs"; +import { + verifyTsc, +} from "../helpers/tsc"; import { addRest, addShebang, @@ -10,9 +13,8 @@ import { enableStrict, loadProjectFromDisk, removeRest, - replaceText, - verifyTsc, -} from "../tsc/helpers"; + replaceText +} from "../helpers/vfs"; describe("unittests:: tsbuild:: outFile:: on amd modules with --out", () => { let outFileFs: vfs.FileSystem; diff --git a/src/testRunner/unittests/tsbuild/clean.ts b/src/testRunner/unittests/tsbuild/clean.ts index 0778e4ef60fdf..6b181ac59b381 100644 --- a/src/testRunner/unittests/tsbuild/clean.ts +++ b/src/testRunner/unittests/tsbuild/clean.ts @@ -1,7 +1,7 @@ import { - loadProjectFromFiles, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsbuild - clean", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tsbuild/commandLine.ts b/src/testRunner/unittests/tsbuild/commandLine.ts index 7e4f45752fcf4..5fc995c80aab2 100644 --- a/src/testRunner/unittests/tsbuild/commandLine.ts +++ b/src/testRunner/unittests/tsbuild/commandLine.ts @@ -1,13 +1,14 @@ import * as ts from "../../_namespaces/ts"; +import { compilerOptionsToConfigJson } from "../helpers/contents"; import { - appendText, - compilerOptionsToConfigJson, - loadProjectFromFiles, noChangeRun, - replaceText, TestTscEdit, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { + appendText, + loadProjectFromFiles, replaceText +} from "../helpers/vfs"; describe("unittests:: tsbuild:: commandLine::", () => { describe("different options::", () => { diff --git a/src/testRunner/unittests/tsbuild/configFileErrors.ts b/src/testRunner/unittests/tsbuild/configFileErrors.ts index 2280f363ef78c..63d9c2bb70dd2 100644 --- a/src/testRunner/unittests/tsbuild/configFileErrors.ts +++ b/src/testRunner/unittests/tsbuild/configFileErrors.ts @@ -1,12 +1,13 @@ import { dedent } from "../../_namespaces/Utils"; import { - appendText, - loadProjectFromDisk, - loadProjectFromFiles, noChangeRun, - replaceText, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { + appendText, + loadProjectFromDisk, + loadProjectFromFiles, replaceText +} from "../helpers/vfs"; describe("unittests:: tsbuild:: configFileErrors:: when tsconfig extends the missing file", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tsbuild/configFileExtends.ts b/src/testRunner/unittests/tsbuild/configFileExtends.ts index 3fcd12acf0c02..0344e78889721 100644 --- a/src/testRunner/unittests/tsbuild/configFileExtends.ts +++ b/src/testRunner/unittests/tsbuild/configFileExtends.ts @@ -1,7 +1,7 @@ import { - loadProjectFromFiles, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsbuild:: configFileExtends:: when tsconfig extends another config", () => { function getConfigExtendsWithIncludeFs() { diff --git a/src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts b/src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts index 4d1a553f8e402..7936c58b6672e 100644 --- a/src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts +++ b/src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts @@ -1,10 +1,11 @@ import { - loadProjectFromDisk, - loadProjectFromFiles, noChangeOnlyRuns, - replaceText, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { + loadProjectFromDisk, + loadProjectFromFiles, replaceText +} from "../helpers/vfs"; describe("unittests:: tsbuild:: when containerOnly project is referenced", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tsbuild/declarationEmit.ts b/src/testRunner/unittests/tsbuild/declarationEmit.ts index 9f5b70fba3040..30c28dafd7c6f 100644 --- a/src/testRunner/unittests/tsbuild/declarationEmit.ts +++ b/src/testRunner/unittests/tsbuild/declarationEmit.ts @@ -1,9 +1,9 @@ import * as Utils from "../../_namespaces/Utils"; import * as vfs from "../../_namespaces/vfs"; import { - loadProjectFromFiles, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsbuild:: declarationEmit", () => { function getFiles(): vfs.FileSet { diff --git a/src/testRunner/unittests/tsbuild/demo.ts b/src/testRunner/unittests/tsbuild/demo.ts index dfc7868fe54e4..c05cff7be93d1 100644 --- a/src/testRunner/unittests/tsbuild/demo.ts +++ b/src/testRunner/unittests/tsbuild/demo.ts @@ -1,10 +1,12 @@ import * as vfs from "../../_namespaces/vfs"; +import { + verifyTsc, +} from "../helpers/tsc"; import { loadProjectFromDisk, prependText, - replaceText, - verifyTsc, -} from "../tsc/helpers"; + replaceText +} from "../helpers/vfs"; describe("unittests:: tsbuild:: on demo project", () => { let projFs: vfs.FileSystem; diff --git a/src/testRunner/unittests/tsbuild/emitDeclarationOnly.ts b/src/testRunner/unittests/tsbuild/emitDeclarationOnly.ts index 90feed378e6d1..5c4324e80a360 100644 --- a/src/testRunner/unittests/tsbuild/emitDeclarationOnly.ts +++ b/src/testRunner/unittests/tsbuild/emitDeclarationOnly.ts @@ -1,9 +1,11 @@ import * as vfs from "../../_namespaces/vfs"; import { - loadProjectFromDisk, - replaceText, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { + loadProjectFromDisk, + replaceText +} from "../helpers/vfs"; describe("unittests:: tsbuild:: on project with emitDeclarationOnly set to true", () => { let projFs: vfs.FileSystem; diff --git a/src/testRunner/unittests/tsbuild/emptyFiles.ts b/src/testRunner/unittests/tsbuild/emptyFiles.ts index b86584263bb53..0c97fb04c10c8 100644 --- a/src/testRunner/unittests/tsbuild/emptyFiles.ts +++ b/src/testRunner/unittests/tsbuild/emptyFiles.ts @@ -1,8 +1,8 @@ import * as vfs from "../../_namespaces/vfs"; import { - loadProjectFromDisk, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromDisk } from "../helpers/vfs"; describe("unittests:: tsbuild - empty files option in tsconfig", () => { let projFs: vfs.FileSystem; diff --git a/src/testRunner/unittests/tsbuild/exitCodeOnBogusFile.ts b/src/testRunner/unittests/tsbuild/exitCodeOnBogusFile.ts index 19459648351a2..7bdf03df92d98 100644 --- a/src/testRunner/unittests/tsbuild/exitCodeOnBogusFile.ts +++ b/src/testRunner/unittests/tsbuild/exitCodeOnBogusFile.ts @@ -1,7 +1,7 @@ import { - loadProjectFromFiles, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; // https://github.com/microsoft/TypeScript/issues/33849 describe("unittests:: tsbuild:: exitCodeOnBogusFile:: test exit code", () => { diff --git a/src/testRunner/unittests/tsbuild/fileDelete.ts b/src/testRunner/unittests/tsbuild/fileDelete.ts index 49a663a59e873..e8768911cad33 100644 --- a/src/testRunner/unittests/tsbuild/fileDelete.ts +++ b/src/testRunner/unittests/tsbuild/fileDelete.ts @@ -2,11 +2,11 @@ import * as ts from "../../_namespaces/ts"; import { dedent } from "../../_namespaces/Utils"; +import { compilerOptionsToConfigJson } from "../helpers/contents"; import { - compilerOptionsToConfigJson, - loadProjectFromFiles, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsbuild:: fileDelete::", () => { function fs(childOptions: ts.CompilerOptions, mainOptions?: ts.CompilerOptions) { diff --git a/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts b/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts index af4b4ef9651bc..2c120f994aefe 100644 --- a/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts +++ b/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts @@ -1,10 +1,12 @@ import * as vfs from "../../_namespaces/vfs"; +import { + verifyTsc, +} from "../helpers/tsc"; import { appendText, loadProjectFromDisk, - replaceText, - verifyTsc, -} from "../tsc/helpers"; + replaceText +} from "../helpers/vfs"; describe("unittests:: tsbuild:: inferredTypeFromTransitiveModule::", () => { let projFs: vfs.FileSystem; diff --git a/src/testRunner/unittests/tsbuild/javascriptProjectEmit.ts b/src/testRunner/unittests/tsbuild/javascriptProjectEmit.ts index e5774c016d7bc..d07751ec262d8 100644 --- a/src/testRunner/unittests/tsbuild/javascriptProjectEmit.ts +++ b/src/testRunner/unittests/tsbuild/javascriptProjectEmit.ts @@ -1,10 +1,12 @@ import * as Utils from "../../_namespaces/Utils"; +import { symbolLibContent } from "../helpers/contents"; import { - loadProjectFromFiles, - replaceText, - symbolLibContent, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { + loadProjectFromFiles, + replaceText +} from "../helpers/vfs"; describe("unittests:: tsbuild:: javascriptProjectEmit::", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts b/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts index 09ab2b3d12d11..bee588739366e 100644 --- a/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts +++ b/src/testRunner/unittests/tsbuild/lateBoundSymbol.ts @@ -1,9 +1,11 @@ +import { + verifyTsc, +} from "../helpers/tsc"; import { appendText, loadProjectFromDisk, - replaceText, - verifyTsc, -} from "../tsc/helpers"; + replaceText +} from "../helpers/vfs"; describe("unittests:: tsbuild:: lateBoundSymbol:: interface is merged and contains late bound member", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tsbuild/moduleResolution.ts b/src/testRunner/unittests/tsbuild/moduleResolution.ts index 5adab8bcf3df8..e6e718526c94d 100644 --- a/src/testRunner/unittests/tsbuild/moduleResolution.ts +++ b/src/testRunner/unittests/tsbuild/moduleResolution.ts @@ -1,15 +1,15 @@ import * as ts from "../../_namespaces/ts"; import * as Utils from "../../_namespaces/Utils"; import { - loadProjectFromFiles, noChangeOnlyRuns, verifyTsc, -} from "../tsc/helpers"; -import { verifyTscWatch } from "../tscWatch/helpers"; +} from "../helpers/tsc"; +import { verifyTscWatch } from "../helpers/tscWatch"; +import { loadProjectFromFiles } from "../helpers/vfs"; import { createWatchedSystem, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsbuild:: moduleResolution:: handles the modules and options from referenced project correctly", () => { function sys(optionsToExtend?: ts.CompilerOptions) { diff --git a/src/testRunner/unittests/tsbuild/moduleSpecifiers.ts b/src/testRunner/unittests/tsbuild/moduleSpecifiers.ts index 232db698d2c71..b42439f099569 100644 --- a/src/testRunner/unittests/tsbuild/moduleSpecifiers.ts +++ b/src/testRunner/unittests/tsbuild/moduleSpecifiers.ts @@ -1,10 +1,10 @@ import * as Utils from "../../_namespaces/Utils"; +import { symbolLibContent } from "../helpers/contents"; import { - loadProjectFromFiles, - symbolLibContent, verifyTsc, -} from "../tsc/helpers"; -import { libFile } from "../virtualFileSystemWithWatch"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; +import { libFile } from "../helpers/virtualFileSystemWithWatch"; // https://github.com/microsoft/TypeScript/issues/31696 describe("unittests:: tsbuild:: moduleSpecifiers:: synthesized module specifiers to referenced projects resolve correctly", () => { diff --git a/src/testRunner/unittests/tsbuild/noEmit.ts b/src/testRunner/unittests/tsbuild/noEmit.ts index 21510ba5960eb..3f0e6f278d949 100644 --- a/src/testRunner/unittests/tsbuild/noEmit.ts +++ b/src/testRunner/unittests/tsbuild/noEmit.ts @@ -1,8 +1,8 @@ import { - loadProjectFromFiles, noChangeRun, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsbuild:: noEmit", () => { function verifyNoEmitWorker(subScenario: string, aTsContent: string, commandLineArgs: readonly string[]) { diff --git a/src/testRunner/unittests/tsbuild/noEmitOnError.ts b/src/testRunner/unittests/tsbuild/noEmitOnError.ts index 55a2ce5cfcef6..10fb8ebd0e8d9 100644 --- a/src/testRunner/unittests/tsbuild/noEmitOnError.ts +++ b/src/testRunner/unittests/tsbuild/noEmitOnError.ts @@ -1,9 +1,9 @@ import * as vfs from "../../_namespaces/vfs"; import { - loadProjectFromDisk, noChangeRun, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromDisk } from "../helpers/vfs"; describe("unittests:: tsbuild - with noEmitOnError", () => { let projFs: vfs.FileSystem; diff --git a/src/testRunner/unittests/tsbuild/outFile.ts b/src/testRunner/unittests/tsbuild/outFile.ts index 3e19b3c9848b0..1c5a46885fee4 100644 --- a/src/testRunner/unittests/tsbuild/outFile.ts +++ b/src/testRunner/unittests/tsbuild/outFile.ts @@ -1,6 +1,15 @@ import * as fakes from "../../_namespaces/fakes"; import * as ts from "../../_namespaces/ts"; import * as vfs from "../../_namespaces/vfs"; +import { createSolutionBuilderHostForBaseline } from "../helpers/solutionBuilder"; +import { + noChangeOnlyRuns, + testTscCompileLike, + TestTscEdit, + TscCompileSystem, + verifyTsc, + verifyTscCompileLike, +} from "../helpers/tsc"; import { addRest, addShebang, @@ -9,20 +18,11 @@ import { addTestPrologue, addTripleSlashRef, appendText, - changeStubToRest, - createSolutionBuilderHostForBaseline, - enableStrict, - loadProjectFromDisk, - noChangeOnlyRuns, - prependText, + changeStubToRest, enableStrict, + loadProjectFromDisk, prependText, removeRest, - replaceText, - testTscCompileLike, - TestTscEdit, - TscCompileSystem, - verifyTsc, - verifyTscCompileLike, -} from "../tsc/helpers"; + replaceText +} from "../helpers/vfs"; describe("unittests:: tsbuild:: outFile::", () => { let outFileFs: vfs.FileSystem; diff --git a/src/testRunner/unittests/tsbuild/outputPaths.ts b/src/testRunner/unittests/tsbuild/outputPaths.ts index 9623743ed4de3..15686987c2239 100644 --- a/src/testRunner/unittests/tsbuild/outputPaths.ts +++ b/src/testRunner/unittests/tsbuild/outputPaths.ts @@ -1,13 +1,13 @@ import * as fakes from "../../_namespaces/fakes"; import * as ts from "../../_namespaces/ts"; import { - loadProjectFromFiles, noChangeRun, TestTscEdit, TscCompileSystem, verifyTsc, VerifyTscWithEditsInput, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsbuild - output file paths", () => { const noChangeProject: TestTscEdit = { diff --git a/src/testRunner/unittests/tsbuild/publicApi.ts b/src/testRunner/unittests/tsbuild/publicApi.ts index ec5ffbde54ecf..0359a62a7a42a 100644 --- a/src/testRunner/unittests/tsbuild/publicApi.ts +++ b/src/testRunner/unittests/tsbuild/publicApi.ts @@ -4,11 +4,13 @@ import * as vfs from "../../_namespaces/vfs"; import { baselinePrograms, commandLineCallbacks, - loadProjectFromFiles, toPathWithSystem, +} from "../helpers/baseline"; +import { TscCompileSystem, verifyTscBaseline, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsbuild:: Public API with custom transformers when passed to build", () => { let sys: TscCompileSystem; diff --git a/src/testRunner/unittests/tsbuild/referencesWithRootDirInParent.ts b/src/testRunner/unittests/tsbuild/referencesWithRootDirInParent.ts index 5ceaa6ac3ea37..63d2fbaa35286 100644 --- a/src/testRunner/unittests/tsbuild/referencesWithRootDirInParent.ts +++ b/src/testRunner/unittests/tsbuild/referencesWithRootDirInParent.ts @@ -1,9 +1,11 @@ import * as vfs from "../../_namespaces/vfs"; import { - loadProjectFromDisk, - replaceText, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { + loadProjectFromDisk, + replaceText +} from "../helpers/vfs"; describe("unittests:: tsbuild:: with rootDir of project reference in parentDirectory", () => { let projFs: vfs.FileSystem; diff --git a/src/testRunner/unittests/tsbuild/resolveJsonModule.ts b/src/testRunner/unittests/tsbuild/resolveJsonModule.ts index 6649bbf488a88..7275c671f83ad 100644 --- a/src/testRunner/unittests/tsbuild/resolveJsonModule.ts +++ b/src/testRunner/unittests/tsbuild/resolveJsonModule.ts @@ -1,10 +1,9 @@ import * as vfs from "../../_namespaces/vfs"; import { - loadProjectFromDisk, noChangeOnlyRuns, - replaceText, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromDisk, replaceText } from "../helpers/vfs"; describe("unittests:: tsbuild:: with resolveJsonModule option on project resolveJsonModuleAndComposite", () => { let projFs: vfs.FileSystem; diff --git a/src/testRunner/unittests/tsbuild/roots.ts b/src/testRunner/unittests/tsbuild/roots.ts index f8ef49ad2c857..6d824635fc08d 100644 --- a/src/testRunner/unittests/tsbuild/roots.ts +++ b/src/testRunner/unittests/tsbuild/roots.ts @@ -1,8 +1,8 @@ import { dedent } from "../../_namespaces/Utils"; import { - loadProjectFromFiles, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsbuild:: roots::", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tsbuild/sample.ts b/src/testRunner/unittests/tsbuild/sample.ts index 879d500330a53..49815d6375066 100644 --- a/src/testRunner/unittests/tsbuild/sample.ts +++ b/src/testRunner/unittests/tsbuild/sample.ts @@ -2,22 +2,22 @@ import * as fakes from "../../_namespaces/fakes"; import * as Harness from "../../_namespaces/Harness"; import * as ts from "../../_namespaces/ts"; import * as vfs from "../../_namespaces/vfs"; +import { libContent } from "../helpers/contents"; +import { createSolutionBuilderHostForBaseline } from "../helpers/solutionBuilder"; import { - appendText, - createSolutionBuilderHostForBaseline, - libContent, - loadProjectFromDisk, - loadProjectFromFiles, noChangeOnlyRuns, noChangeRun, - prependText, - replaceText, testTscCompileLike, TestTscEdit, TscCompileSystem, verifyTsc, verifyTscCompileLike, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { + appendText, loadProjectFromDisk, + loadProjectFromFiles, prependText, + replaceText +} from "../helpers/vfs"; import { changeToHostTrackingWrittenFiles, createWatchedSystem, @@ -25,7 +25,7 @@ import { getTsBuildProjectFilePath, libFile, TestServerHost, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsbuild:: on 'sample1' project", () => { let projFs: vfs.FileSystem; diff --git a/src/testRunner/unittests/tsbuild/transitiveReferences.ts b/src/testRunner/unittests/tsbuild/transitiveReferences.ts index a49d83c21a12d..37693c8eb5d5a 100644 --- a/src/testRunner/unittests/tsbuild/transitiveReferences.ts +++ b/src/testRunner/unittests/tsbuild/transitiveReferences.ts @@ -1,8 +1,8 @@ import * as vfs from "../../_namespaces/vfs"; import { - loadProjectFromDisk, verifyTsc, -} from "../tsc/helpers"; +} from "../helpers/tsc"; +import { loadProjectFromDisk } from "../helpers/vfs"; describe("unittests:: tsbuild:: when project reference is referenced transitively", () => { let projFs: vfs.FileSystem; diff --git a/src/testRunner/unittests/tsbuildWatch/configFileErrors.ts b/src/testRunner/unittests/tsbuildWatch/configFileErrors.ts index 03b91c2a39b63..4059cfce11477 100644 --- a/src/testRunner/unittests/tsbuildWatch/configFileErrors.ts +++ b/src/testRunner/unittests/tsbuildWatch/configFileErrors.ts @@ -1,9 +1,9 @@ import { dedent } from "../../_namespaces/Utils"; -import { verifyTscWatch } from "../tscWatch/helpers"; +import { verifyTscWatch } from "../helpers/tscWatch"; import { createWatchedSystem, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsbuildWatch:: watchMode:: configFileErrors:: reports syntax errors in config file", () => { verifyTscWatch({ diff --git a/src/testRunner/unittests/tsbuildWatch/demo.ts b/src/testRunner/unittests/tsbuildWatch/demo.ts index 8655b4c57d8c1..03b36bcd39cb4 100644 --- a/src/testRunner/unittests/tsbuildWatch/demo.ts +++ b/src/testRunner/unittests/tsbuildWatch/demo.ts @@ -1,11 +1,11 @@ -import { libContent } from "../tsc/helpers"; -import { verifyTscWatch } from "../tscWatch/helpers"; +import { libContent } from "../helpers/contents"; +import { verifyTscWatch } from "../helpers/tscWatch"; import { createWatchedSystem, File, getTsBuildProjectFile, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsbuildWatch:: watchMode:: with demo project", () => { const projectLocation = `/user/username/projects/demo`; diff --git a/src/testRunner/unittests/tsbuildWatch/moduleResolution.ts b/src/testRunner/unittests/tsbuildWatch/moduleResolution.ts index ef4541352f3a4..141494295eb71 100644 --- a/src/testRunner/unittests/tsbuildWatch/moduleResolution.ts +++ b/src/testRunner/unittests/tsbuildWatch/moduleResolution.ts @@ -1,9 +1,9 @@ import { dedent } from "../../_namespaces/Utils"; -import { verifyTscWatch } from "../tscWatch/helpers"; +import { verifyTscWatch } from "../helpers/tscWatch"; import { createWatchedSystem, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsbuildWatch:: watchMode:: moduleResolution", () => { verifyTscWatch({ diff --git a/src/testRunner/unittests/tsbuildWatch/noEmit.ts b/src/testRunner/unittests/tsbuildWatch/noEmit.ts index c980e67d230c0..68ebaa759e024 100644 --- a/src/testRunner/unittests/tsbuildWatch/noEmit.ts +++ b/src/testRunner/unittests/tsbuildWatch/noEmit.ts @@ -1,9 +1,9 @@ -import { libContent } from "../tsc/helpers"; -import { verifyTscWatch } from "../tscWatch/helpers"; +import { libContent } from "../helpers/contents"; +import { verifyTscWatch } from "../helpers/tscWatch"; import { createWatchedSystem, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsbuildWatch:: watchMode:: with noEmit", () => { verifyTscWatch({ diff --git a/src/testRunner/unittests/tsbuildWatch/noEmitOnError.ts b/src/testRunner/unittests/tsbuildWatch/noEmitOnError.ts index 516ef2d6cc14e..5a08e0cdbbdc2 100644 --- a/src/testRunner/unittests/tsbuildWatch/noEmitOnError.ts +++ b/src/testRunner/unittests/tsbuildWatch/noEmitOnError.ts @@ -1,13 +1,13 @@ -import { libContent } from "../tsc/helpers"; +import { libContent } from "../helpers/contents"; import { TscWatchCompileChange, verifyTscWatch, -} from "../tscWatch/helpers"; +} from "../helpers/tscWatch"; import { createWatchedSystem, getTsBuildProjectFile, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsbuildWatch:: watchMode:: with noEmitOnError", () => { function change(caption: string, content: string): TscWatchCompileChange { diff --git a/src/testRunner/unittests/tsbuildWatch/programUpdates.ts b/src/testRunner/unittests/tsbuildWatch/programUpdates.ts index 608e27ce7cc4c..0352a1b571147 100644 --- a/src/testRunner/unittests/tsbuildWatch/programUpdates.ts +++ b/src/testRunner/unittests/tsbuildWatch/programUpdates.ts @@ -8,14 +8,14 @@ import { runWatchBaseline, TscWatchCompileChange, verifyTscWatch, -} from "../tscWatch/helpers"; +} from "../helpers/tscWatch"; import { createWatchedSystem, File, getTsBuildProjectFile, getTsBuildProjectFilePath, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsbuildWatch:: watchMode:: program updates", () => { const enum SubProject { diff --git a/src/testRunner/unittests/tsbuildWatch/projectsBuilding.ts b/src/testRunner/unittests/tsbuildWatch/projectsBuilding.ts index 44fc16c151845..0968b40bdef0e 100644 --- a/src/testRunner/unittests/tsbuildWatch/projectsBuilding.ts +++ b/src/testRunner/unittests/tsbuildWatch/projectsBuilding.ts @@ -3,12 +3,12 @@ import { noopChange, TscWatchCompileChange, verifyTscWatch, -} from "../tscWatch/helpers"; +} from "../helpers/tscWatch"; import { createWatchedSystem, File, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsbuildWatch:: watchMode:: projectsBuilding", () => { function pkgs(cb: (index: number) => T, count: number, startIndex?: number): T[] { diff --git a/src/testRunner/unittests/tsbuildWatch/publicApi.ts b/src/testRunner/unittests/tsbuildWatch/publicApi.ts index 4100665541792..a8b5a21152553 100644 --- a/src/testRunner/unittests/tsbuildWatch/publicApi.ts +++ b/src/testRunner/unittests/tsbuildWatch/publicApi.ts @@ -3,12 +3,12 @@ import { createBaseline, createSolutionBuilderWithWatchHostForBaseline, runWatchBaseline, -} from "../tscWatch/helpers"; +} from "../helpers/tscWatch"; import { createWatchedSystem, File, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; it("unittests:: tsbuildWatch:: watchMode:: Public API with custom transformers", () => { const solution: File = { diff --git a/src/testRunner/unittests/tsbuildWatch/reexport.ts b/src/testRunner/unittests/tsbuildWatch/reexport.ts index 4943ca8fde93e..ff1f3b1f05bed 100644 --- a/src/testRunner/unittests/tsbuildWatch/reexport.ts +++ b/src/testRunner/unittests/tsbuildWatch/reexport.ts @@ -1,10 +1,10 @@ -import { libContent } from "../tsc/helpers"; -import { verifyTscWatch } from "../tscWatch/helpers"; +import { libContent } from "../helpers/contents"; +import { verifyTscWatch } from "../helpers/tscWatch"; import { createWatchedSystem, getTsBuildProjectFile, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsbuildWatch:: watchMode:: with reexport when referenced project reexports definitions from another file", () => { verifyTscWatch({ diff --git a/src/testRunner/unittests/tsbuildWatch/watchEnvironment.ts b/src/testRunner/unittests/tsbuildWatch/watchEnvironment.ts index 792a1f9ff4850..ca887c6699db1 100644 --- a/src/testRunner/unittests/tsbuildWatch/watchEnvironment.ts +++ b/src/testRunner/unittests/tsbuildWatch/watchEnvironment.ts @@ -3,13 +3,13 @@ import { createBaseline, createSolutionBuilderWithWatchHostForBaseline, runWatchBaseline, -} from "../tscWatch/helpers"; +} from "../helpers/tscWatch"; import { createWatchedSystem, File, libFile, TestServerHost, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsbuildWatch:: watchEnvironment:: tsbuild:: watchMode:: with different watch environments", () => { it("watchFile on same file multiple times because file is part of multiple projects", () => { diff --git a/src/testRunner/unittests/tsc/cancellationToken.ts b/src/testRunner/unittests/tsc/cancellationToken.ts index 04eeb68ebbad0..dfda4549902b4 100644 --- a/src/testRunner/unittests/tsc/cancellationToken.ts +++ b/src/testRunner/unittests/tsc/cancellationToken.ts @@ -4,17 +4,17 @@ import * as Utils from "../../_namespaces/Utils"; import { baselineBuildInfo, CommandLineProgram, -} from "../tsc/helpers"; +} from "../helpers/baseline"; import { applyEdit, createBaseline, watchBaseline, -} from "../tscWatch/helpers"; +} from "../helpers/tscWatch"; import { createWatchedSystem, File, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc:: builder cancellationToken", () => { verifyCancellation(/*useBuildInfo*/ true, "when emitting buildInfo"); diff --git a/src/testRunner/unittests/tsc/composite.ts b/src/testRunner/unittests/tsc/composite.ts index 8d9a3d0994cf4..571ade2ab4235 100644 --- a/src/testRunner/unittests/tsc/composite.ts +++ b/src/testRunner/unittests/tsc/composite.ts @@ -1,9 +1,11 @@ import * as Utils from "../../_namespaces/Utils"; import { - loadProjectFromFiles, - replaceText, verifyTsc, -} from "./helpers"; +} from "../helpers/tsc"; +import { + loadProjectFromFiles, + replaceText +} from "../helpers/vfs"; describe("unittests:: tsc:: composite::", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tsc/declarationEmit.ts b/src/testRunner/unittests/tsc/declarationEmit.ts index d3b3b6f07cce5..55c5c3d3e8252 100644 --- a/src/testRunner/unittests/tsc/declarationEmit.ts +++ b/src/testRunner/unittests/tsc/declarationEmit.ts @@ -1,12 +1,12 @@ import * as ts from "../../_namespaces/ts"; import * as Utils from "../../_namespaces/Utils"; -import { verifyTscWatch } from "../tscWatch/helpers"; +import { verifyTscWatch } from "../helpers/tscWatch"; import { createWatchedSystem, FileOrFolderOrSymLink, isSymLink, libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc:: declarationEmit::", () => { interface VerifyDeclarationEmitInput { diff --git a/src/testRunner/unittests/tsc/forceConsistentCasingInFileNames.ts b/src/testRunner/unittests/tsc/forceConsistentCasingInFileNames.ts index 70c79ac8b44a3..7a1f9414ef8f6 100644 --- a/src/testRunner/unittests/tsc/forceConsistentCasingInFileNames.ts +++ b/src/testRunner/unittests/tsc/forceConsistentCasingInFileNames.ts @@ -1,8 +1,8 @@ import * as Utils from "../../_namespaces/Utils"; import { - loadProjectFromFiles, verifyTsc, -} from "./helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsc:: forceConsistentCasingInFileNames::", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tsc/helpers.ts b/src/testRunner/unittests/tsc/helpers.ts deleted file mode 100644 index dfc24ebb4cf55..0000000000000 --- a/src/testRunner/unittests/tsc/helpers.ts +++ /dev/null @@ -1,1063 +0,0 @@ -import * as fakes from "../../_namespaces/fakes"; -import * as Harness from "../../_namespaces/Harness"; -import * as ts from "../../_namespaces/ts"; -import * as vfs from "../../_namespaces/vfs"; -import * as vpath from "../../_namespaces/vpath"; -import { - libFile, - TestServerHost, -} from "../virtualFileSystemWithWatch"; - -export interface DtsSignatureData { - signature: string | undefined; - exportedModules: string[] | undefined; -} - -export type TscCompileSystem = fakes.System & { - writtenFiles: Set; - baseLine(): { file: string; text: string; }; - dtsSignaures?: Map>; - storeFilesChangingSignatureDuringEmit?: boolean; -}; - -export function compilerOptionsToConfigJson(options: ts.CompilerOptions) { - return ts.optionMapToObject(ts.serializeCompilerOptions(options)); -} - -export const noChangeRun: TestTscEdit = { - caption: "no-change-run", - edit: ts.noop -}; -export const noChangeOnlyRuns = [noChangeRun]; - -export interface TestTscCompile extends TestTscCompileLikeBase { - baselineSourceMap?: boolean; - baselineReadFileCalls?: boolean; - baselinePrograms?: boolean; - baselineDependencies?: boolean; -} - -export type CommandLineProgram = [ts.Program, ts.BuilderProgram?]; -export interface CommandLineCallbacks { - cb: ts.ExecuteCommandLineCallbacks; - getPrograms: () => readonly CommandLineProgram[]; -} - -function isAnyProgram(program: ts.Program | ts.BuilderProgram | ts.ParsedCommandLine): program is ts.Program | ts.BuilderProgram { - return !!(program as ts.Program | ts.BuilderProgram).getCompilerOptions; -} -export function commandLineCallbacks( - sys: TscCompileSystem | TestServerHost, - originalReadCall?: ts.System["readFile"], -): CommandLineCallbacks { - let programs: CommandLineProgram[] | undefined; - - return { - cb: program => { - if (isAnyProgram(program)) { - baselineBuildInfo(program.getCompilerOptions(), sys, originalReadCall); - (programs || (programs = [])).push(ts.isBuilderProgram(program) ? - [program.getProgram(), program] : - [program] - ); - } - else { - baselineBuildInfo(program.options, sys, originalReadCall); - } - }, - getPrograms: () => { - const result = programs || ts.emptyArray; - programs = undefined; - return result; - } - }; -} -export interface TestTscCompileLikeBase extends VerifyTscCompileLike { - diffWithInitial?: boolean; - modifyFs?: (fs: vfs.FileSystem) => void; - computeDtsSignatures?: boolean; - environmentVariables?: Record; -} - -export interface TestTscCompileLike extends TestTscCompileLikeBase { - compile: (sys: TscCompileSystem) => void; - additionalBaseline?: (sys: TscCompileSystem) => void; -} -/** - * Initialize FS, run compile function and save baseline - */ -export function testTscCompileLike(input: TestTscCompileLike) { - const initialFs = input.fs(); - const inputFs = initialFs.shadow(); - const { - scenario, subScenario, diffWithInitial, - commandLineArgs, modifyFs, - environmentVariables, - compile: worker, additionalBaseline, - } = input; - if (modifyFs) modifyFs(inputFs); - inputFs.makeReadonly(); - const fs = inputFs.shadow(); - - // Create system - const sys = new fakes.System(fs, { executingFilePath: "/lib/tsc", env: environmentVariables }) as TscCompileSystem; - sys.storeFilesChangingSignatureDuringEmit = true; - sys.write(`${sys.getExecutingFilePath()} ${commandLineArgs.join(" ")}\n`); - sys.exit = exitCode => sys.exitCode = exitCode; - worker(sys); - sys.write(`exitCode:: ExitStatus.${ts.ExitStatus[sys.exitCode as ts.ExitStatus]}\n`); - additionalBaseline?.(sys); - fs.makeReadonly(); - sys.baseLine = () => { - const baseFsPatch = diffWithInitial ? - inputFs.diff(initialFs, { includeChangedFileWithSameContent: true }) : - inputFs.diff(/*base*/ undefined, { baseIsNotShadowRoot: true }); - const patch = fs.diff(inputFs, { includeChangedFileWithSameContent: true }); - return { - file: `${ts.isBuild(commandLineArgs) ? "tsbuild" : "tsc"}/${scenario}/${subScenario.split(" ").join("-")}.js`, - text: `Input:: -${baseFsPatch ? vfs.formatPatch(baseFsPatch) : ""} - -Output:: -${sys.output.join("")} - -${patch ? vfs.formatPatch(patch) : ""}` - }; - }; - return sys; -} - -function makeSystemReadyForBaseline(sys: TscCompileSystem, versionToWrite?: string) { - if (versionToWrite) { - fakes.patchHostForBuildInfoWrite(sys, versionToWrite); - } - else { - fakes.patchHostForBuildInfoReadWrite(sys); - } - const writtenFiles = sys.writtenFiles = new Set(); - const originalWriteFile = sys.writeFile; - sys.writeFile = (fileName, content, writeByteOrderMark) => { - const path = toPathWithSystem(sys, fileName); - // When buildinfo is same for two projects, - // it gives error and doesnt write buildinfo but because buildInfo is written for one project, - // readable baseline will be written two times for those two projects with same contents and is ok - ts.Debug.assert(!writtenFiles.has(path) || ts.endsWith(path, "baseline.txt")); - writtenFiles.add(path); - return originalWriteFile.call(sys, fileName, content, writeByteOrderMark); - }; -} - -export function createSolutionBuilderHostForBaseline( - sys: TscCompileSystem | TestServerHost, - versionToWrite?: string, - originalRead?: (TscCompileSystem | TestServerHost)["readFile"] -) { - if (sys instanceof fakes.System) makeSystemReadyForBaseline(sys, versionToWrite); - const { cb } = commandLineCallbacks(sys, originalRead); - const host = ts.createSolutionBuilderHost(sys, - /*createProgram*/ undefined, - ts.createDiagnosticReporter(sys, /*pretty*/ true), - ts.createBuilderStatusReporter(sys, /*pretty*/ true), - ); - host.afterProgramEmitAndDiagnostics = cb; - host.afterEmitBundle = cb; - return host; -} - -/** - * Initialize Fs, execute command line and save baseline - */ -export function testTscCompile(input: TestTscCompile) { - let actualReadFileMap: ts.MapLike | undefined; - let getPrograms: CommandLineCallbacks["getPrograms"] | undefined; - return testTscCompileLike({ - ...input, - compile: commandLineCompile, - additionalBaseline - }); - - function commandLineCompile(sys: TscCompileSystem) { - makeSystemReadyForBaseline(sys); - actualReadFileMap = {}; - const originalReadFile = sys.readFile; - sys.readFile = path => { - // Dont record libs - if (path.startsWith("/src/")) { - actualReadFileMap![path] = (ts.getProperty(actualReadFileMap!, path) || 0) + 1; - } - return originalReadFile.call(sys, path); - }; - - const result = commandLineCallbacks(sys, originalReadFile); - ts.executeCommandLine( - sys, - result.cb, - input.commandLineArgs, - ); - sys.readFile = originalReadFile; - getPrograms = result.getPrograms; - } - - function additionalBaseline(sys: TscCompileSystem) { - const { baselineSourceMap, baselineReadFileCalls, baselinePrograms: shouldBaselinePrograms, baselineDependencies } = input; - if (input.computeDtsSignatures) storeDtsSignatures(sys, getPrograms!()); - if (shouldBaselinePrograms) { - const baseline: string[] = []; - baselinePrograms(baseline, getPrograms!, ts.emptyArray, baselineDependencies); - sys.write(baseline.join("\n")); - } - if (baselineReadFileCalls) { - sys.write(`readFiles:: ${JSON.stringify(actualReadFileMap, /*replacer*/ undefined, " ")} `); - } - if (baselineSourceMap) generateSourceMapBaselineFiles(sys); - actualReadFileMap = undefined; - getPrograms = undefined; - } -} - -function storeDtsSignatures(sys: TscCompileSystem, programs: readonly CommandLineProgram[]) { - for (const [program, builderProgram] of programs) { - if (!builderProgram) continue; - const buildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(program.getCompilerOptions()); - if (!buildInfoPath) continue; - sys.dtsSignaures ??= new Map(); - const dtsSignatureData = new Map(); - sys.dtsSignaures.set(`${toPathWithSystem(sys, buildInfoPath)}.readable.baseline.txt` as ts.Path, dtsSignatureData); - const state = builderProgram.getState(); - state.hasCalledUpdateShapeSignature?.forEach(resolvedPath => { - const file = program.getSourceFileByPath(resolvedPath); - if (!file || file.isDeclarationFile) return; - // Compute dts and exported map and store it - ts.BuilderState.computeDtsSignature( - program, - file, - /*cancellationToken*/ undefined, - sys, - (signature, sourceFiles) => { - const exportedModules = ts.BuilderState.getExportedModules(state.exportedModulesMap && sourceFiles[0].exportedModulesFromDeclarationEmit); - dtsSignatureData.set(relativeToBuildInfo(resolvedPath), { signature, exportedModules: exportedModules && ts.arrayFrom(exportedModules.keys(), relativeToBuildInfo) }); - }, - ); - }); - - function relativeToBuildInfo(path: string) { - const currentDirectory = program.getCurrentDirectory(); - const getCanonicalFileName = ts.createGetCanonicalFileName(program.useCaseSensitiveFileNames()); - const buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(buildInfoPath!, currentDirectory)); - return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(buildInfoDirectory, path, getCanonicalFileName)); - } - } -} - -export function baselinePrograms(baseline: string[], getPrograms: () => readonly CommandLineProgram[], oldPrograms: readonly (CommandLineProgram | undefined)[], baselineDependencies: boolean | undefined) { - const programs = getPrograms(); - for (let i = 0; i < programs.length; i++) { - baselineProgram(baseline, programs[i], oldPrograms[i], baselineDependencies); - } - return programs; -} - -function baselineProgram(baseline: string[], [program, builderProgram]: CommandLineProgram, oldProgram: CommandLineProgram | undefined, baselineDependencies: boolean | undefined) { - if (program !== oldProgram?.[0]) { - const options = program.getCompilerOptions(); - baseline.push(`Program root files: ${JSON.stringify(program.getRootFileNames())}`); - baseline.push(`Program options: ${JSON.stringify(options)}`); - baseline.push(`Program structureReused: ${(ts as any).StructureIsReused[program.structureIsReused]}`); - baseline.push("Program files::"); - for (const file of program.getSourceFiles()) { - baseline.push(file.fileName); - } - } - else { - baseline.push(`Program: Same as old program`); - } - baseline.push(""); - - if (!builderProgram) return; - if (builderProgram !== oldProgram?.[1]) { - const state = builderProgram.getState(); - const internalState = state as unknown as ts.BuilderProgramState; - if (state.semanticDiagnosticsPerFile?.size) { - baseline.push("Semantic diagnostics in builder refreshed for::"); - for (const file of program.getSourceFiles()) { - if (!internalState.semanticDiagnosticsFromOldState || !internalState.semanticDiagnosticsFromOldState.has(file.resolvedPath)) { - baseline.push(file.fileName); - } - } - } - else { - baseline.push("No cached semantic diagnostics in the builder::"); - } - if (internalState) { - baseline.push(""); - if (internalState.hasCalledUpdateShapeSignature?.size) { - baseline.push("Shape signatures in builder refreshed for::"); - internalState.hasCalledUpdateShapeSignature.forEach((path: ts.Path) => { - const info = state.fileInfos.get(path); - if (info?.version === info?.signature || !info?.signature) { - baseline.push(path + " (used version)"); - } - else if (internalState.filesChangingSignature?.has(path)) { - baseline.push(path + " (computed .d.ts during emit)"); - } - else { - baseline.push(path + " (computed .d.ts)"); - } - }); - } - else { - baseline.push("No shapes updated in the builder::"); - } - } - baseline.push(""); - if (!baselineDependencies) return; - baseline.push("Dependencies for::"); - for (const file of builderProgram.getSourceFiles()) { - baseline.push(`${file.fileName}:`); - for (const depenedency of builderProgram.getAllDependencies(file)) { - baseline.push(` ${depenedency}`); - } - } - } - else { - baseline.push(`BuilderProgram: Same as old builder program`); - } - baseline.push(""); -} - -export function verifyTscBaseline(sys: () => { baseLine: TscCompileSystem["baseLine"]; }) { - it(`Generates files matching the baseline`, () => { - const { file, text } = sys().baseLine(); - Harness.Baseline.runBaseline(file, text); - }); -} -export interface VerifyTscCompileLike { - scenario: string; - subScenario: string; - commandLineArgs: readonly string[]; - fs: () => vfs.FileSystem; -} - -/** - * Verify by baselining after initializing FS and custom compile - */ -export function verifyTscCompileLike(verifier: (input: T) => { baseLine: TscCompileSystem["baseLine"]; }, input: T) { - describe(`tsc ${input.commandLineArgs.join(" ")} ${input.scenario}:: ${input.subScenario}`, () => { - describe(input.scenario, () => { - describe(input.subScenario, () => { - verifyTscBaseline(() => verifier({ - ...input, - fs: () => input.fs().makeReadonly() - })); - }); - }); - }); -} - -export function replaceText(fs: vfs.FileSystem, path: string, oldText: string, newText: string) { - if (!fs.statSync(path).isFile()) { - throw new Error(`File ${path} does not exist`); - } - const old = fs.readFileSync(path, "utf-8"); - if (old.indexOf(oldText) < 0) { - throw new Error(`Text "${oldText}" does not exist in file ${path}`); - } - const newContent = old.replace(oldText, newText); - fs.writeFileSync(path, newContent, "utf-8"); -} - -export function prependText(fs: vfs.FileSystem, path: string, additionalContent: string) { - if (!fs.statSync(path).isFile()) { - throw new Error(`File ${path} does not exist`); - } - const old = fs.readFileSync(path, "utf-8"); - fs.writeFileSync(path, `${additionalContent}${old}`, "utf-8"); -} - -export function appendText(fs: vfs.FileSystem, path: string, additionalContent: string) { - if (!fs.statSync(path).isFile()) { - throw new Error(`File ${path} does not exist`); - } - const old = fs.readFileSync(path, "utf-8"); - fs.writeFileSync(path, `${old}${additionalContent}`); -} - -export const libContent = `${libFile.content} -interface ReadonlyArray {} -declare const console: { log(msg: any): void; };`; - -export const symbolLibContent = ` -interface SymbolConstructor { - readonly species: symbol; - readonly toStringTag: symbol; -} -declare var Symbol: SymbolConstructor; -interface Symbol { - readonly [Symbol.toStringTag]: string; -} -`; - -/** - * Load project from disk into /src folder - */ -export function loadProjectFromDisk( - root: string, - libContentToAppend?: string -): vfs.FileSystem { - const resolver = vfs.createResolver(Harness.IO); - const fs = new vfs.FileSystem(/*ignoreCase*/ true, { - files: { - ["/src"]: new vfs.Mount(vpath.resolve(Harness.IO.getWorkspaceRoot(), root), resolver) - }, - cwd: "/", - meta: { defaultLibLocation: "/lib" }, - }); - addLibAndMakeReadonly(fs, libContentToAppend); - return fs; -} - -/** - * All the files must be in /src - */ -export function loadProjectFromFiles( - files: vfs.FileSet, - libContentToAppend?: string -): vfs.FileSystem { - const fs = new vfs.FileSystem(/*ignoreCase*/ true, { - files, - cwd: "/", - meta: { defaultLibLocation: "/lib" }, - }); - addLibAndMakeReadonly(fs, libContentToAppend); - return fs; -} - -function addLibAndMakeReadonly(fs: vfs.FileSystem, libContentToAppend?: string) { - fs.mkdirSync("/lib"); - fs.writeFileSync("/lib/lib.d.ts", libContentToAppend ? `${libContent}${libContentToAppend}` : libContent); - fs.makeReadonly(); -} - -export function generateSourceMapBaselineFiles(sys: ts.System & { writtenFiles: ts.ReadonlyCollection; }) { - const mapFileNames = ts.mapDefinedIterator(sys.writtenFiles.keys(), f => f.endsWith(".map") ? f : undefined); - for (const mapFile of mapFileNames) { - const text = Harness.SourceMapRecorder.getSourceMapRecordWithSystem(sys, mapFile); - sys.writeFile(`${mapFile}.baseline.txt`, text); - } -} - -function generateBundleFileSectionInfo(sys: ts.System, originalReadCall: ts.System["readFile"], baselineRecorder: Harness.Compiler.WriterAggregator, bundleFileInfo: ts.BundleFileInfo | undefined, outFile: string | undefined) { - if (!ts.length(bundleFileInfo && bundleFileInfo.sections) && !outFile) return; // Nothing to baseline - - const content = outFile && sys.fileExists(outFile) ? originalReadCall.call(sys, outFile, "utf8")! : ""; - baselineRecorder.WriteLine("======================================================================"); - baselineRecorder.WriteLine(`File:: ${outFile}`); - for (const section of bundleFileInfo ? bundleFileInfo.sections : ts.emptyArray) { - baselineRecorder.WriteLine("----------------------------------------------------------------------"); - writeSectionHeader(section); - if (section.kind !== ts.BundleFileSectionKind.Prepend) { - writeTextOfSection(section.pos, section.end); - } - else if (section.texts.length > 0) { - ts.Debug.assert(section.pos === ts.first(section.texts).pos); - ts.Debug.assert(section.end === ts.last(section.texts).end); - for (const text of section.texts) { - baselineRecorder.WriteLine(">>--------------------------------------------------------------------"); - writeSectionHeader(text); - writeTextOfSection(text.pos, text.end); - } - } - else { - ts.Debug.assert(section.pos === section.end); - } - } - baselineRecorder.WriteLine("======================================================================"); - - function writeTextOfSection(pos: number, end: number) { - const textLines = content.substring(pos, end).split(/\r?\n/); - for (const line of textLines) { - baselineRecorder.WriteLine(line); - } - } - - function writeSectionHeader(section: ts.BundleFileSection) { - baselineRecorder.WriteLine(`${section.kind}: (${section.pos}-${section.end})${section.data ? ":: " + section.data : ""}${section.kind === ts.BundleFileSectionKind.Prepend ? " texts:: " + section.texts.length : ""}`); - } -} - -type ReadableProgramBuildInfoDiagnostic = string | [string, readonly ts.ReusableDiagnostic[]]; -type ReadableBuilderFileEmit = string & { __readableBuilderFileEmit: any; }; -type ReadableProgramBuilderInfoFilePendingEmit = [original: string | [string], emitKind: ReadableBuilderFileEmit]; -type ReadableProgramBuildInfoEmitSignature = string | [string, ts.EmitSignature | []]; -type ReadableProgramBuildInfoFileInfo = Omit & { - impliedFormat: string | undefined; - original: T | undefined; -}; -type ReadableProgramBuildInfoRoot = - [original: ts.ProgramBuildInfoFileId, readable: string] | - [orginal: ts.ProgramBuildInfoRootStartEnd, readable: readonly string[]]; -type ReadableProgramMultiFileEmitBuildInfo = Omit & { - fileNamesList: readonly (readonly string[])[] | undefined; - fileInfos: ts.MapLike>; - root: readonly ReadableProgramBuildInfoRoot[]; - referencedMap: ts.MapLike | undefined; - exportedModulesMap: ts.MapLike | undefined; - semanticDiagnosticsPerFile: readonly ReadableProgramBuildInfoDiagnostic[] | undefined; - affectedFilesPendingEmit: readonly ReadableProgramBuilderInfoFilePendingEmit[] | undefined; - changeFileSet: readonly string[] | undefined; - emitSignatures: readonly ReadableProgramBuildInfoEmitSignature[] | undefined; -}; -type ReadableProgramBuildInfoBundlePendingEmit = [emitKind: ReadableBuilderFileEmit, original: ts.ProgramBuildInfoBundlePendingEmit]; -type ReadableProgramBundleEmitBuildInfo = Omit & { - fileInfos: ts.MapLike>; - root: readonly ReadableProgramBuildInfoRoot[]; - pendingEmit: ReadableProgramBuildInfoBundlePendingEmit | undefined; -}; - -type ReadableProgramBuildInfo = ReadableProgramMultiFileEmitBuildInfo | ReadableProgramBundleEmitBuildInfo; - -function isReadableProgramBundleEmitBuildInfo(info: ReadableProgramBuildInfo | undefined): info is ReadableProgramBundleEmitBuildInfo { - return !!info && !!ts.outFile(info.options || {}); -} -type ReadableBuildInfo = Omit & { program: ReadableProgramBuildInfo | undefined; size: number; }; -function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string, buildInfo: ts.BuildInfo) { - let program: ReadableProgramBuildInfo | undefined; - let fileNamesList: string[][] | undefined; - if (buildInfo.program && ts.isProgramBundleEmitBuildInfo(buildInfo.program)) { - const fileInfos: ReadableProgramBundleEmitBuildInfo["fileInfos"] = {}; - buildInfo.program?.fileInfos?.forEach((fileInfo, index) => - fileInfos[toFileName(index + 1 as ts.ProgramBuildInfoFileId)] = ts.isString(fileInfo) ? - fileInfo : - toReadableFileInfo(fileInfo, ts.identity) - ); - const pendingEmit = buildInfo.program.pendingEmit; - program = { - ...buildInfo.program, - fileInfos, - root: buildInfo.program.root.map(toReadableProgramBuildInfoRoot), - pendingEmit: pendingEmit === undefined ? - undefined : - [ - toReadableBuilderFileEmit(ts.toProgramEmitPending(pendingEmit, buildInfo.program.options)), - pendingEmit - ], - }; - } - else if (buildInfo.program) { - const fileInfos: ReadableProgramMultiFileEmitBuildInfo["fileInfos"] = {}; - buildInfo.program?.fileInfos?.forEach((fileInfo, index) => fileInfos[toFileName(index + 1 as ts.ProgramBuildInfoFileId)] = toReadableFileInfo(fileInfo, ts.toBuilderStateFileInfoForMultiEmit)); - fileNamesList = buildInfo.program.fileIdsList?.map(fileIdsListId => fileIdsListId.map(toFileName)); - const fullEmitForOptions = buildInfo.program.affectedFilesPendingEmit ? ts.getBuilderFileEmit(buildInfo.program.options || {}) : undefined; - program = buildInfo.program && { - fileNames: buildInfo.program.fileNames, - fileNamesList, - fileInfos: buildInfo.program.fileInfos ? fileInfos : undefined!, - root: buildInfo.program.root.map(toReadableProgramBuildInfoRoot), - options: buildInfo.program.options, - referencedMap: toMapOfReferencedSet(buildInfo.program.referencedMap), - exportedModulesMap: toMapOfReferencedSet(buildInfo.program.exportedModulesMap), - semanticDiagnosticsPerFile: buildInfo.program.semanticDiagnosticsPerFile?.map(d => - ts.isNumber(d) ? - toFileName(d) : - [toFileName(d[0]), d[1]] - ), - affectedFilesPendingEmit: buildInfo.program.affectedFilesPendingEmit?.map(value => toReadableProgramBuilderInfoFilePendingEmit(value, fullEmitForOptions!)), - changeFileSet: buildInfo.program.changeFileSet?.map(toFileName), - emitSignatures: buildInfo.program.emitSignatures?.map(s => - ts.isNumber(s) ? - toFileName(s) : - [toFileName(s[0]), s[1]] - ), - latestChangedDtsFile: buildInfo.program.latestChangedDtsFile, - }; - } - const version = buildInfo.version === ts.version ? fakes.version : buildInfo.version; - const result: ReadableBuildInfo = { - // Baseline fixed order for bundle - bundle: buildInfo.bundle && { - ...buildInfo.bundle, - js: buildInfo.bundle.js && { - sections: buildInfo.bundle.js.sections, - hash: buildInfo.bundle.js.hash, - mapHash: buildInfo.bundle.js.mapHash, - sources: buildInfo.bundle.js.sources, - }, - dts: buildInfo.bundle.dts && { - sections: buildInfo.bundle.dts.sections, - hash: buildInfo.bundle.dts.hash, - mapHash: buildInfo.bundle.dts.mapHash, - sources: buildInfo.bundle.dts.sources, - }, - }, - program, - version, - size: ts.getBuildInfoText({ ...buildInfo, version }).length, - }; - // For now its just JSON.stringify - sys.writeFile(`${buildInfoPath}.readable.baseline.txt`, JSON.stringify(result, /*replacer*/ undefined, 2)); - - function toFileName(fileId: ts.ProgramBuildInfoFileId) { - return buildInfo.program!.fileNames[fileId - 1]; - } - - function toFileNames(fileIdsListId: ts.ProgramBuildInfoFileIdListId) { - return fileNamesList![fileIdsListId - 1]; - } - - function toReadableFileInfo(original: T, toFileInfo: (fileInfo: T) => ts.BuilderState.FileInfo): ReadableProgramBuildInfoFileInfo { - const info = toFileInfo(original); - return { - original: ts.isString(original) ? undefined : original, - ...info, - impliedFormat: info.impliedFormat && ts.getNameOfCompilerOptionValue(info.impliedFormat, ts.moduleOptionDeclaration.type), - }; - } - - function toReadableProgramBuildInfoRoot(original: ts.ProgramBuildInfoRoot): ReadableProgramBuildInfoRoot { - if (!ts.isArray(original)) return [original, toFileName(original)]; - const readable: string[] = []; - for (let index = original[0]; index <= original[1]; index++) readable.push(toFileName(index)); - return [original, readable]; - } - - function toMapOfReferencedSet(referenceMap: ts.ProgramBuildInfoReferencedMap | undefined): ts.MapLike | undefined { - if (!referenceMap) return undefined; - const result: ts.MapLike = {}; - for (const [fileNamesKey, fileNamesListKey] of referenceMap) { - result[toFileName(fileNamesKey)] = toFileNames(fileNamesListKey); - } - return result; - } - - function toReadableProgramBuilderInfoFilePendingEmit(value: ts.ProgramBuilderInfoFilePendingEmit, fullEmitForOptions: ts.BuilderFileEmit): ReadableProgramBuilderInfoFilePendingEmit { - return [ - ts.isNumber(value) ? toFileName(value) : [toFileName(value[0])], - toReadableBuilderFileEmit(ts.toBuilderFileEmit(value, fullEmitForOptions)), - ]; - } - - function toReadableBuilderFileEmit(emit: ts.BuilderFileEmit | undefined): ReadableBuilderFileEmit { - let result = ""; - if (emit) { - if (emit & ts.BuilderFileEmit.Js) addFlags("Js"); - if (emit & ts.BuilderFileEmit.JsMap) addFlags("JsMap"); - if (emit & ts.BuilderFileEmit.JsInlineMap) addFlags("JsInlineMap"); - if (emit & ts.BuilderFileEmit.Dts) addFlags("Dts"); - if (emit & ts.BuilderFileEmit.DtsMap) addFlags("DtsMap"); - } - return (result || "None") as ReadableBuilderFileEmit; - function addFlags(flag: string) { - result = result ? `${result} | ${flag}` : flag; - } - } -} - -export function toPathWithSystem(sys: ts.System, fileName: string): ts.Path { - return ts.toPath(fileName, sys.getCurrentDirectory(), ts.createGetCanonicalFileName(sys.useCaseSensitiveFileNames)); -} - -export function baselineBuildInfo( - options: ts.CompilerOptions, - sys: TscCompileSystem | TestServerHost, - originalReadCall?: ts.System["readFile"], -) { - const buildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(options); - if (!buildInfoPath || !sys.writtenFiles!.has(toPathWithSystem(sys, buildInfoPath))) return; - if (!sys.fileExists(buildInfoPath)) return; - - const buildInfo = ts.getBuildInfo(buildInfoPath, (originalReadCall || sys.readFile).call(sys, buildInfoPath, "utf8")!); - if (!buildInfo) return sys.writeFile(`${buildInfoPath}.baseline.txt`, "Error reading valid buildinfo file"); - generateBuildInfoProgramBaseline(sys, buildInfoPath, buildInfo); - - if (!ts.outFile(options)) return; - const { jsFilePath, declarationFilePath } = ts.getOutputPathsForBundle(options, /*forceDtsPaths*/ false); - const bundle = buildInfo.bundle; - if (!bundle || (!ts.length(bundle.js && bundle.js.sections) && !ts.length(bundle.dts && bundle.dts.sections))) return; - - // Write the baselines: - const baselineRecorder = new Harness.Compiler.WriterAggregator(); - generateBundleFileSectionInfo(sys, originalReadCall || sys.readFile, baselineRecorder, bundle.js, jsFilePath); - generateBundleFileSectionInfo(sys, originalReadCall || sys.readFile, baselineRecorder, bundle.dts, declarationFilePath); - baselineRecorder.Close(); - const text = baselineRecorder.lines.join("\r\n"); - sys.writeFile(`${buildInfoPath}.baseline.txt`, text); -} -interface VerifyTscEditDiscrepanciesInput { - index: number; - edits: readonly TestTscEdit[]; - scenario: TestTscCompile["scenario"]; - baselines: string[] | undefined; - commandLineArgs: TestTscCompile["commandLineArgs"]; - modifyFs: TestTscCompile["modifyFs"]; - baseFs: vfs.FileSystem; - newSys: TscCompileSystem; - environmentVariables: TestTscCompile["environmentVariables"]; -} -function verifyTscEditDiscrepancies({ - index, edits, scenario, commandLineArgs, environmentVariables, - baselines, - modifyFs, baseFs, newSys -}: VerifyTscEditDiscrepanciesInput): string[] | undefined { - const { caption, discrepancyExplanation } = edits[index]; - const sys = testTscCompile({ - scenario, - subScenario: caption, - fs: () => baseFs.makeReadonly(), - commandLineArgs: edits[index].commandLineArgs || commandLineArgs, - modifyFs: fs => { - if (modifyFs) modifyFs(fs); - for (let i = 0; i <= index; i++) { - edits[i].edit(fs); - } - }, - environmentVariables, - computeDtsSignatures: true, - }); - let headerAdded = false; - for (const outputFile of sys.writtenFiles.keys()) { - const cleanBuildText = sys.readFile(outputFile); - const incrementalBuildText = newSys.readFile(outputFile); - if (ts.isBuildInfoFile(outputFile)) { - // Check only presence and absence and not text as we will do that for readable baseline - if (!sys.fileExists(`${outputFile}.readable.baseline.txt`)) addBaseline(`Readable baseline not present in clean build:: File:: ${outputFile}`); - if (!newSys.fileExists(`${outputFile}.readable.baseline.txt`)) addBaseline(`Readable baseline not present in incremental build:: File:: ${outputFile}`); - verifyPresenceAbsence(incrementalBuildText, cleanBuildText, `Incremental and clean tsbuildinfo file presence differs:: File:: ${outputFile}`); - } - else if (!ts.fileExtensionIs(outputFile, ".tsbuildinfo.readable.baseline.txt")) { - verifyTextEqual(incrementalBuildText, cleanBuildText, `File: ${outputFile}`); - } - else if (incrementalBuildText !== cleanBuildText) { - // Verify build info without affectedFilesPendingEmit - const { buildInfo: incrementalBuildInfo, readableBuildInfo: incrementalReadableBuildInfo } = getBuildInfoForIncrementalCorrectnessCheck(incrementalBuildText); - const { buildInfo: cleanBuildInfo, readableBuildInfo: cleanReadableBuildInfo } = getBuildInfoForIncrementalCorrectnessCheck(cleanBuildText); - const dtsSignaures = sys.dtsSignaures?.get(outputFile); - verifyTextEqual(incrementalBuildInfo, cleanBuildInfo, `TsBuild info text without affectedFilesPendingEmit:: ${outputFile}::`); - // Verify file info sigantures - verifyMapLike( - incrementalReadableBuildInfo?.program?.fileInfos as ReadableProgramMultiFileEmitBuildInfo["fileInfos"], - cleanReadableBuildInfo?.program?.fileInfos as ReadableProgramMultiFileEmitBuildInfo["fileInfos"], - (key, incrementalFileInfo, cleanFileInfo) => { - const dtsForKey = dtsSignaures?.get(key); - if (!incrementalFileInfo || !cleanFileInfo || incrementalFileInfo.signature !== cleanFileInfo.signature && (!dtsForKey || incrementalFileInfo.signature !== dtsForKey.signature)) { - return [ - `Incremental signature is neither dts signature nor file version for File:: ${key}`, - `Incremental:: ${JSON.stringify(incrementalFileInfo, /*replacer*/ undefined, 2)}`, - `Clean:: ${JSON.stringify(cleanFileInfo, /*replacer*/ undefined, 2)}`, - `Dts Signature:: $${JSON.stringify(dtsForKey?.signature)}` - ]; - } - }, - `FileInfos:: File:: ${outputFile}` - ); - if (!isReadableProgramBundleEmitBuildInfo(incrementalReadableBuildInfo?.program)) { - ts.Debug.assert(!isReadableProgramBundleEmitBuildInfo(cleanReadableBuildInfo?.program)); - // Verify exportedModulesMap - verifyMapLike( - incrementalReadableBuildInfo?.program?.exportedModulesMap, - cleanReadableBuildInfo?.program?.exportedModulesMap, - (key, incrementalReferenceSet, cleanReferenceSet) => { - const dtsForKey = dtsSignaures?.get(key); - if (!ts.arrayIsEqualTo(incrementalReferenceSet, cleanReferenceSet) && - (!dtsForKey || !ts.arrayIsEqualTo(incrementalReferenceSet, dtsForKey.exportedModules))) { - return [ - `Incremental Reference set is neither from dts nor files reference map for File:: ${key}::`, - `Incremental:: ${JSON.stringify(incrementalReferenceSet, /*replacer*/ undefined, 2)}`, - `Clean:: ${JSON.stringify(cleanReferenceSet, /*replacer*/ undefined, 2)}`, - `DtsExportsMap:: ${JSON.stringify(dtsForKey?.exportedModules, /*replacer*/ undefined, 2)}` - ]; - } - }, - `exportedModulesMap:: File:: ${outputFile}` - ); - // Verify that incrementally pending affected file emit are in clean build since clean build can contain more files compared to incremental depending of noEmitOnError option - if (incrementalReadableBuildInfo?.program?.affectedFilesPendingEmit) { - if (cleanReadableBuildInfo?.program?.affectedFilesPendingEmit === undefined) { - addBaseline( - `Incremental build contains affectedFilesPendingEmit, clean build does not have it: ${outputFile}::`, - `Incremental buildInfoText:: ${incrementalBuildText}`, - `Clean buildInfoText:: ${cleanBuildText}` - ); - } - let expectedIndex = 0; - incrementalReadableBuildInfo.program.affectedFilesPendingEmit.forEach(([actualFileOrArray]) => { - const actualFile = ts.isString(actualFileOrArray) ? actualFileOrArray : actualFileOrArray[0]; - expectedIndex = ts.findIndex( - (cleanReadableBuildInfo!.program! as ReadableProgramMultiFileEmitBuildInfo).affectedFilesPendingEmit, - ([expectedFileOrArray]) => actualFile === (ts.isString(expectedFileOrArray) ? expectedFileOrArray : expectedFileOrArray[0]), - expectedIndex - ); - if (expectedIndex === -1) { - addBaseline( - `Incremental build contains ${actualFile} file as pending emit, clean build does not have it: ${outputFile}::`, - `Incremental buildInfoText:: ${incrementalBuildText}`, - `Clean buildInfoText:: ${cleanBuildText}` - ); - } - expectedIndex++; - }); - } - } - } - } - if (!headerAdded && discrepancyExplanation) addBaseline("*** Supplied discrepancy explanation but didnt file any difference"); - return baselines; - - function verifyTextEqual(incrementalText: string | undefined, cleanText: string | undefined, message: string) { - if (incrementalText !== cleanText) writeNotEqual(incrementalText, cleanText, message); - } - - function verifyMapLike( - incremental: ts.MapLike | undefined, - clean: ts.MapLike | undefined, - verifyValue: (key: string, incrementalValue: T | undefined, cleanValue: T | undefined) => string[] | undefined, - message: string, - ) { - verifyPresenceAbsence(incremental, clean, `Incremental and clean do not match:: ${message}`); - if (!incremental || !clean) return; - const incrementalMap = new Map(Object.entries(incremental)); - const cleanMap = new Map(Object.entries(clean)); - cleanMap.forEach((cleanValue, key) => { - const result = verifyValue(key, incrementalMap.get(key), cleanValue); - if (result) addBaseline(...result); - }); - incrementalMap.forEach((incremetnalValue, key) => { - if (cleanMap.has(key)) return; - // This is value only in incremental Map - const result = verifyValue(key, incremetnalValue, /*cleanValue*/ undefined); - if (result) addBaseline(...result); - }); - } - - function verifyPresenceAbsence(actual: T | undefined, expected: T | undefined, message: string) { - if (expected === undefined) { - if (actual === undefined) return; - } - else { - if (actual !== undefined) return; - } - writeNotEqual(actual, expected, message); - } - - function writeNotEqual(actual: T | undefined, expected: T | undefined, message: string) { - addBaseline( - message, - "CleanBuild:", - ts.isString(expected) ? expected : JSON.stringify(expected), - "IncrementalBuild:", - ts.isString(actual) ? actual : JSON.stringify(actual), - ); - } - - function addBaseline(...text: string[]) { - if (!baselines || !headerAdded) { - (baselines ||= []).push(`${index}:: ${caption}`, ...(discrepancyExplanation?.()|| ["*** Needs explanation"])); - headerAdded = true; - } - baselines.push(...text); - } -} - -function getBuildInfoForIncrementalCorrectnessCheck(text: string | undefined): { - buildInfo: string | undefined; - readableBuildInfo?: ReadableBuildInfo; -} { - if (!text) return { buildInfo: text }; - const readableBuildInfo = JSON.parse(text) as ReadableBuildInfo; - let sanitizedFileInfos: ts.MapLike | ReadableProgramBuildInfoFileInfo, "signature" | "original"> & { signature: undefined; original: undefined; }> | undefined; - if (readableBuildInfo.program?.fileInfos) { - sanitizedFileInfos = {}; - for (const id in readableBuildInfo.program.fileInfos) { - if (ts.hasProperty(readableBuildInfo.program.fileInfos, id)) { - const info = readableBuildInfo.program.fileInfos[id]; - sanitizedFileInfos[id] = ts.isString(info) ? info : { ...info, signature: undefined, original: undefined }; - } - } - } - return { - buildInfo: JSON.stringify({ - ...readableBuildInfo, - program: readableBuildInfo.program && { - ...readableBuildInfo.program, - fileNames: undefined, - fileNamesList: undefined, - fileInfos: sanitizedFileInfos, - // Ignore noEmit since that shouldnt be reason to emit the tsbuild info and presence of it in the buildinfo file does not matter - options: { ...readableBuildInfo.program.options, noEmit: undefined }, - exportedModulesMap: undefined, - affectedFilesPendingEmit: undefined, - latestChangedDtsFile: readableBuildInfo.program.latestChangedDtsFile ? "FakeFileName" : undefined, - }, - size: undefined, // Size doesnt need to be equal - }, /*replacer*/ undefined, 2), - readableBuildInfo, - }; -} - -export interface TestTscEdit { - edit: (fs: vfs.FileSystem) => void; - caption: string; - commandLineArgs?: readonly string[]; - /** An array of lines to be printed in order when a discrepancy is detected */ - discrepancyExplanation?: () => readonly string[]; -} - -export interface VerifyTscWithEditsInput extends TestTscCompile { - edits?: readonly TestTscEdit[]; -} - -/** - * Verify non watch tsc invokcation after each edit - */ -export function verifyTsc({ - subScenario, fs, scenario, commandLineArgs, environmentVariables, - baselineSourceMap, modifyFs, baselineReadFileCalls, baselinePrograms, - edits -}: VerifyTscWithEditsInput) { - describe(`tsc ${commandLineArgs.join(" ")} ${scenario}:: ${subScenario}`, () => { - let sys: TscCompileSystem; - let baseFs: vfs.FileSystem; - let editsSys: TscCompileSystem[] | undefined; - before(() => { - baseFs = fs().makeReadonly(); - sys = testTscCompile({ - scenario, - subScenario, - fs: () => baseFs, - commandLineArgs, - modifyFs, - baselineSourceMap, - baselineReadFileCalls, - baselinePrograms, - environmentVariables, - }); - edits?.forEach(( - { edit, caption, commandLineArgs: editCommandLineArgs }, - index - ) => { - (editsSys || (editsSys = [])).push(testTscCompile({ - scenario, - subScenario: caption, - diffWithInitial: true, - fs: () => index === 0 ? sys.vfs : editsSys![index - 1].vfs, - commandLineArgs: editCommandLineArgs || commandLineArgs, - modifyFs: edit, - baselineSourceMap, - baselineReadFileCalls, - baselinePrograms, - environmentVariables, - })); - }); - }); - after(() => { - baseFs = undefined!; - sys = undefined!; - editsSys = undefined!; - }); - verifyTscBaseline(() => ({ - baseLine: () => { - const { file, text } = sys.baseLine(); - const texts: string[] = [text]; - editsSys?.forEach((sys, index) => { - const incrementalScenario = edits![index]; - texts.push(""); - texts.push(`Change:: ${incrementalScenario.caption}`); - texts.push(sys.baseLine().text); - }); - return { - file, - text: `currentDirectory:: ${sys.getCurrentDirectory()} useCaseSensitiveFileNames: ${sys.useCaseSensitiveFileNames}\r\n` + - texts.join("\r\n"), - }; - } - })); - if (edits?.length) { - it("tsc invocation after edit and clean build correctness", () => { - let baselines: string[] | undefined; - for (let index = 0; index < edits.length; index++) { - baselines = verifyTscEditDiscrepancies({ - index, - edits, - scenario, - baselines, - baseFs, - newSys: editsSys![index], - commandLineArgs, - modifyFs, - environmentVariables, - }); - } - Harness.Baseline.runBaseline( - `${ts.isBuild(commandLineArgs) ? "tsbuild" : "tsc"}/${scenario}/${subScenario.split(" ").join("-")}-discrepancies.js`, - baselines ? baselines.join("\r\n") : null // eslint-disable-line no-null/no-null - ); - }); - } - }); -} - -export function enableStrict(fs: vfs.FileSystem, path: string) { - replaceText(fs, path, `"strict": false`, `"strict": true`); -} - -export function addTestPrologue(fs: vfs.FileSystem, path: string, prologue: string) { - prependText(fs, path, `${prologue} -`); -} - -export function addShebang(fs: vfs.FileSystem, project: string, file: string) { - prependText(fs, `src/${project}/${file}.ts`, `#!someshebang ${project} ${file} -`); -} - -export function restContent(project: string, file: string) { - return `function for${project}${file}Rest() { -const { b, ...rest } = { a: 10, b: 30, yy: 30 }; -}`; -} - -function nonrestContent(project: string, file: string) { - return `function for${project}${file}Rest() { }`; -} - -export function addRest(fs: vfs.FileSystem, project: string, file: string) { - appendText(fs, `src/${project}/${file}.ts`, restContent(project, file)); -} - -export function removeRest(fs: vfs.FileSystem, project: string, file: string) { - replaceText(fs, `src/${project}/${file}.ts`, restContent(project, file), nonrestContent(project, file)); -} - -export function addStubFoo(fs: vfs.FileSystem, project: string, file: string) { - appendText(fs, `src/${project}/${file}.ts`, nonrestContent(project, file)); -} - -export function changeStubToRest(fs: vfs.FileSystem, project: string, file: string) { - replaceText(fs, `src/${project}/${file}.ts`, nonrestContent(project, file), restContent(project, file)); -} - -export function addSpread(fs: vfs.FileSystem, project: string, file: string) { - const path = `src/${project}/${file}.ts`; - const content = fs.readFileSync(path, "utf8"); - fs.writeFileSync(path, `${content} -function ${project}${file}Spread(...b: number[]) { } -const ${project}${file}_ar = [20, 30]; -${project}${file}Spread(10, ...${project}${file}_ar);`); - - replaceText(fs, `src/${project}/tsconfig.json`, `"strict": false,`, `"strict": false, - "downlevelIteration": true,`); -} - -export function getTripleSlashRef(project: string) { - return `/src/${project}/tripleRef.d.ts`; -} - -export function addTripleSlashRef(fs: vfs.FileSystem, project: string, file: string) { - fs.writeFileSync(getTripleSlashRef(project), `declare class ${project}${file} { }`); - prependText(fs, `src/${project}/${file}.ts`, `/// -const ${file}Const = new ${project}${file}(); -`); -} diff --git a/src/testRunner/unittests/tsc/incremental.ts b/src/testRunner/unittests/tsc/incremental.ts index 3c3405dec550b..feb5b64419abf 100644 --- a/src/testRunner/unittests/tsc/incremental.ts +++ b/src/testRunner/unittests/tsc/incremental.ts @@ -2,18 +2,21 @@ import * as ts from "../../_namespaces/ts"; import * as Utils from "../../_namespaces/Utils"; import * as vfs from "../../_namespaces/vfs"; import { - appendText, compilerOptionsToConfigJson, - libContent, - loadProjectFromDisk, - loadProjectFromFiles, + libContent +} from "../helpers/contents"; +import { noChangeOnlyRuns, noChangeRun, - prependText, - replaceText, TestTscEdit, verifyTsc, -} from "./helpers"; +} from "../helpers/tsc"; +import { + appendText, + loadProjectFromDisk, + loadProjectFromFiles, prependText, + replaceText +} from "../helpers/vfs"; describe("unittests:: tsc:: incremental::", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tsc/listFilesOnly.ts b/src/testRunner/unittests/tsc/listFilesOnly.ts index 3bc07ece6bc3e..1ff81276d2227 100644 --- a/src/testRunner/unittests/tsc/listFilesOnly.ts +++ b/src/testRunner/unittests/tsc/listFilesOnly.ts @@ -1,9 +1,9 @@ import * as Utils from "../../_namespaces/Utils"; import { - loadProjectFromFiles, noChangeRun, verifyTsc, -} from "./helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsc:: listFilesOnly::", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tsc/projectReferences.ts b/src/testRunner/unittests/tsc/projectReferences.ts index 070d2b338920a..e6bd7ce6caf20 100644 --- a/src/testRunner/unittests/tsc/projectReferences.ts +++ b/src/testRunner/unittests/tsc/projectReferences.ts @@ -1,7 +1,7 @@ import { - loadProjectFromFiles, verifyTsc, -} from "./helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsc:: projectReferences::", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tsc/projectReferencesConfig.ts b/src/testRunner/unittests/tsc/projectReferencesConfig.ts index 17b26e892859e..ae2f4c736cc39 100644 --- a/src/testRunner/unittests/tsc/projectReferencesConfig.ts +++ b/src/testRunner/unittests/tsc/projectReferencesConfig.ts @@ -1,5 +1,6 @@ import * as ts from "../../_namespaces/ts"; -import { loadProjectFromFiles, verifyTsc } from "./helpers"; +import { verifyTsc } from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; function emptyModule() { return "export { };"; diff --git a/src/testRunner/unittests/tsc/redirect.ts b/src/testRunner/unittests/tsc/redirect.ts index 086fa782130ee..bd56f7aafdc53 100644 --- a/src/testRunner/unittests/tsc/redirect.ts +++ b/src/testRunner/unittests/tsc/redirect.ts @@ -1,7 +1,7 @@ import { - loadProjectFromFiles, verifyTsc, -} from "./helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsc:: redirect::", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tsc/runWithoutArgs.ts b/src/testRunner/unittests/tsc/runWithoutArgs.ts index cf5ea49cbc099..ee4c7a8ae0a41 100644 --- a/src/testRunner/unittests/tsc/runWithoutArgs.ts +++ b/src/testRunner/unittests/tsc/runWithoutArgs.ts @@ -1,7 +1,7 @@ import { - loadProjectFromFiles, verifyTsc, -} from "./helpers"; +} from "../helpers/tsc"; +import { loadProjectFromFiles } from "../helpers/vfs"; describe("unittests:: tsc:: runWithoutArgs::", () => { verifyTsc({ diff --git a/src/testRunner/unittests/tscWatch/consoleClearing.ts b/src/testRunner/unittests/tscWatch/consoleClearing.ts index 4c05b6f76b0b7..f48ea56bd5060 100644 --- a/src/testRunner/unittests/tscWatch/consoleClearing.ts +++ b/src/testRunner/unittests/tscWatch/consoleClearing.ts @@ -1,16 +1,16 @@ import * as ts from "../../_namespaces/ts"; -import { - createWatchedSystem, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { createBaseline, createWatchCompilerHostOfConfigFileForBaseline, runWatchBaseline, TscWatchCompileChange, verifyTscWatch, -} from "./helpers"; +} from "../helpers/tscWatch"; +import { + createWatchedSystem, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: console clearing", () => { const scenario = "consoleClearing"; diff --git a/src/testRunner/unittests/tscWatch/emit.ts b/src/testRunner/unittests/tscWatch/emit.ts index f5333a56fe31b..4cd7a3b591920 100644 --- a/src/testRunner/unittests/tscWatch/emit.ts +++ b/src/testRunner/unittests/tscWatch/emit.ts @@ -1,14 +1,14 @@ import * as ts from "../../_namespaces/ts"; +import { + TscWatchCompileChange, + verifyTscWatch, +} from "../helpers/tscWatch"; import { createWatchedSystem, File, libFile, TestServerHost, -} from "../virtualFileSystemWithWatch"; -import { - TscWatchCompileChange, - verifyTscWatch, -} from "./helpers"; +} from "../helpers/virtualFileSystemWithWatch"; const scenario = "emit"; describe("unittests:: tsc-watch:: emit with outFile or out setting", () => { diff --git a/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts b/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts index 8558bd3367dd2..926cf99ec5c4f 100644 --- a/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts +++ b/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts @@ -1,14 +1,14 @@ -import { libContent } from "../tsc/helpers"; +import { libContent } from "../helpers/contents"; +import { + TscWatchCompileChange, + verifyTscWatch, +} from "../helpers/tscWatch"; import { createWatchedSystem, File, getTsBuildProjectFile, libFile, -} from "../virtualFileSystemWithWatch"; -import { - TscWatchCompileChange, - verifyTscWatch, -} from "./helpers"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: Emit times and Error updates in builder after program changes", () => { const config: File = { diff --git a/src/testRunner/unittests/tscWatch/forceConsistentCasingInFileNames.ts b/src/testRunner/unittests/tscWatch/forceConsistentCasingInFileNames.ts index 89b7e5c293c6f..da9db45871b84 100644 --- a/src/testRunner/unittests/tscWatch/forceConsistentCasingInFileNames.ts +++ b/src/testRunner/unittests/tscWatch/forceConsistentCasingInFileNames.ts @@ -1,14 +1,14 @@ import * as Utils from "../../_namespaces/Utils"; +import { + TscWatchCompileChange, + verifyTscWatch, +} from "../helpers/tscWatch"; import { createWatchedSystem, File, libFile, SymLink, -} from "../virtualFileSystemWithWatch"; -import { - TscWatchCompileChange, - verifyTscWatch, -} from "./helpers"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: forceConsistentCasingInFileNames", () => { const loggerFile: File = { diff --git a/src/testRunner/unittests/tscWatch/incremental.ts b/src/testRunner/unittests/tscWatch/incremental.ts index bc73995f46282..4bef1da5b5d87 100644 --- a/src/testRunner/unittests/tscWatch/incremental.ts +++ b/src/testRunner/unittests/tscWatch/incremental.ts @@ -1,22 +1,20 @@ import * as Harness from "../../_namespaces/Harness"; import * as ts from "../../_namespaces/ts"; -import { - CommandLineProgram, - libContent, -} from "../tsc/helpers"; -import { - createWatchedSystem, - File, - libFile, - TestServerHost, -} from "../virtualFileSystemWithWatch"; +import { CommandLineProgram } from "../helpers/baseline"; +import { libContent } from "../helpers/contents"; import { applyEdit, createBaseline, SystemSnap, verifyTscWatch, watchBaseline, -} from "./helpers"; +} from "../helpers/tscWatch"; +import { + createWatchedSystem, + File, + libFile, + TestServerHost, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: emit file --incremental", () => { const project = "/users/username/projects/project"; diff --git a/src/testRunner/unittests/tscWatch/moduleResolution.ts b/src/testRunner/unittests/tscWatch/moduleResolution.ts index 8aabf0b435798..4837e7763be53 100644 --- a/src/testRunner/unittests/tscWatch/moduleResolution.ts +++ b/src/testRunner/unittests/tscWatch/moduleResolution.ts @@ -1,10 +1,10 @@ import * as Utils from "../../_namespaces/Utils"; +import { verifyTscWatch } from "../helpers/tscWatch"; import { createWatchedSystem, File, libFile, -} from "../virtualFileSystemWithWatch"; -import { verifyTscWatch } from "./helpers"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: moduleResolution", () => { verifyTscWatch({ diff --git a/src/testRunner/unittests/tscWatch/nodeNextWatch.ts b/src/testRunner/unittests/tscWatch/nodeNextWatch.ts index b9ab7e29666bf..38f5b340a8643 100644 --- a/src/testRunner/unittests/tscWatch/nodeNextWatch.ts +++ b/src/testRunner/unittests/tscWatch/nodeNextWatch.ts @@ -1,10 +1,10 @@ import * as Utils from "../../_namespaces/Utils"; +import { verifyTscWatch } from "../helpers/tscWatch"; import { createWatchedSystem, File, libFile, -} from "../virtualFileSystemWithWatch"; -import { verifyTscWatch } from "./helpers"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: nodeNextWatch:: emit when module emit is specified as nodenext", () => { verifyTscWatch({ diff --git a/src/testRunner/unittests/tscWatch/programUpdates.ts b/src/testRunner/unittests/tscWatch/programUpdates.ts index d267798c1488b..229aadd9e1501 100644 --- a/src/testRunner/unittests/tscWatch/programUpdates.ts +++ b/src/testRunner/unittests/tscWatch/programUpdates.ts @@ -1,16 +1,7 @@ import * as Harness from "../../_namespaces/Harness"; import * as ts from "../../_namespaces/ts"; -import { - commandLineCallbacks, - compilerOptionsToConfigJson, -} from "../tsc/helpers"; -import { - createWatchedSystem, - File, - libFile, - SymLink, - TestServerHost, -} from "../virtualFileSystemWithWatch"; +import { commandLineCallbacks } from "../helpers/baseline"; +import { compilerOptionsToConfigJson } from "../helpers/contents"; import { commonFile1, commonFile2, @@ -21,7 +12,14 @@ import { TscWatchCompileChange, verifyTscWatch, watchBaseline, -} from "./helpers"; +} from "../helpers/tscWatch"; +import { + createWatchedSystem, + File, + libFile, + SymLink, + TestServerHost, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: program updates", () => { const scenario = "programUpdates"; diff --git a/src/testRunner/unittests/tscWatch/projectsWithReferences.ts b/src/testRunner/unittests/tscWatch/projectsWithReferences.ts index a1c51072281dc..8c091768df202 100644 --- a/src/testRunner/unittests/tscWatch/projectsWithReferences.ts +++ b/src/testRunner/unittests/tscWatch/projectsWithReferences.ts @@ -1,14 +1,14 @@ +import { + createSolutionBuilder, + createSystemWithSolutionBuild, +} from "../helpers/solutionBuilder"; +import { verifyTscWatch } from "../helpers/tscWatch"; import { getTsBuildProjectFile, getTsBuildProjectFilePath, libFile, TestServerHost, -} from "../virtualFileSystemWithWatch"; -import { - createSolutionBuilder, - createSystemWithSolutionBuild, - verifyTscWatch, -} from "./helpers"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: projects with references: invoking when references are already built", () => { verifyTscWatch({ diff --git a/src/testRunner/unittests/tscWatch/resolutionCache.ts b/src/testRunner/unittests/tscWatch/resolutionCache.ts index 7a66f64780880..e40425630e63a 100644 --- a/src/testRunner/unittests/tscWatch/resolutionCache.ts +++ b/src/testRunner/unittests/tscWatch/resolutionCache.ts @@ -1,18 +1,18 @@ import * as ts from "../../_namespaces/ts"; import * as Utils from "../../_namespaces/Utils"; -import { libContent } from "../tsc/helpers"; -import { - createWatchedSystem, - File, - libFile, - SymLink, -} from "../virtualFileSystemWithWatch"; +import { libContent } from "../helpers/contents"; import { createBaseline, createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline, runWatchBaseline, verifyTscWatch, -} from "./helpers"; +} from "../helpers/tscWatch"; +import { + createWatchedSystem, + File, + libFile, + SymLink, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: resolutionCache:: tsc-watch module resolution caching", () => { const scenario = "resolutionCache"; diff --git a/src/testRunner/unittests/tscWatch/resolveJsonModuleWithIncremental.ts b/src/testRunner/unittests/tscWatch/resolveJsonModuleWithIncremental.ts index 7838b8a666043..e4a1d09ac2019 100644 --- a/src/testRunner/unittests/tscWatch/resolveJsonModuleWithIncremental.ts +++ b/src/testRunner/unittests/tscWatch/resolveJsonModuleWithIncremental.ts @@ -1,10 +1,10 @@ +import { + verifyTscWatch, +} from "../helpers/tscWatch"; import { createWatchedSystem, libFile, -} from "../virtualFileSystemWithWatch"; -import { - verifyTscWatch, -} from "./helpers"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: resolveJsonModuleWithIncremental:: emit file --incremental", () => { verifyTscWatch({ diff --git a/src/testRunner/unittests/tscWatch/sourceOfProjectReferenceRedirect.ts b/src/testRunner/unittests/tscWatch/sourceOfProjectReferenceRedirect.ts index 8510383a57c1f..e8f6810564ca4 100644 --- a/src/testRunner/unittests/tscWatch/sourceOfProjectReferenceRedirect.ts +++ b/src/testRunner/unittests/tscWatch/sourceOfProjectReferenceRedirect.ts @@ -1,5 +1,11 @@ import * as ts from "../../_namespaces/ts"; -import { libContent } from "../tsc/helpers"; +import { libContent } from "../helpers/contents"; +import { solutionBuildWithBaseline } from "../helpers/solutionBuilder"; +import { + createBaseline, + createWatchCompilerHostOfConfigFileForBaseline, + runWatchBaseline, +} from "../helpers/tscWatch"; import { createWatchedSystem, File, @@ -7,13 +13,7 @@ import { getTsBuildProjectFile, libFile, SymLink, -} from "../virtualFileSystemWithWatch"; -import { - createBaseline, - createWatchCompilerHostOfConfigFileForBaseline, - runWatchBaseline, - solutionBuildWithBaseline, -} from "./helpers"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: watchAPI:: with sourceOfProjectReferenceRedirect", () => { interface VerifyWatchInput { diff --git a/src/testRunner/unittests/tscWatch/watchApi.ts b/src/testRunner/unittests/tscWatch/watchApi.ts index c657574f27983..81274cbbf1932 100644 --- a/src/testRunner/unittests/tscWatch/watchApi.ts +++ b/src/testRunner/unittests/tscWatch/watchApi.ts @@ -1,12 +1,8 @@ import * as Harness from "../../_namespaces/Harness"; import * as ts from "../../_namespaces/ts"; import { dedent } from "../../_namespaces/Utils"; -import { commandLineCallbacks, libContent } from "../tsc/helpers"; -import { - createWatchedSystem, - File, - libFile, -} from "../virtualFileSystemWithWatch"; +import { commandLineCallbacks } from "../helpers/baseline"; +import { libContent } from "../helpers/contents"; import { applyEdit, createBaseline, @@ -15,7 +11,12 @@ import { runWatchBaseline, TscWatchSystem, watchBaseline, -} from "./helpers"; +} from "../helpers/tscWatch"; +import { + createWatchedSystem, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: watchAPI:: tsc-watch with custom module resolution", () => { it("verify that module resolution with json extension works when returned without extension", () => { diff --git a/src/testRunner/unittests/tscWatch/watchEnvironment.ts b/src/testRunner/unittests/tscWatch/watchEnvironment.ts index 3d3506b248355..79afff507cf16 100644 --- a/src/testRunner/unittests/tscWatch/watchEnvironment.ts +++ b/src/testRunner/unittests/tscWatch/watchEnvironment.ts @@ -1,4 +1,10 @@ import * as ts from "../../_namespaces/ts"; +import { + commonFile1, + commonFile2, + noopChange, + verifyTscWatch, +} from "../helpers/tscWatch"; import { createWatchedSystem, File, @@ -7,13 +13,7 @@ import { TestServerHost, Tsc_WatchDirectory, Tsc_WatchFile, -} from "../virtualFileSystemWithWatch"; -import { - commonFile1, - commonFile2, - noopChange, - verifyTscWatch, -} from "./helpers"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsc-watch:: watchEnvironment:: tsc-watch with different polling/non polling options", () => { const scenario = "watchEnvironment"; diff --git a/src/testRunner/unittests/tsserver/applyChangesToOpenFiles.ts b/src/testRunner/unittests/tsserver/applyChangesToOpenFiles.ts index a1aabbb052feb..d78e6168b0470 100644 --- a/src/testRunner/unittests/tsserver/applyChangesToOpenFiles.ts +++ b/src/testRunner/unittests/tsserver/applyChangesToOpenFiles.ts @@ -2,17 +2,17 @@ import * as ts from "../../_namespaces/ts"; import { commonFile1, commonFile2, -} from "../tscWatch/helpers"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/tscWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: applyChangesToOpenFiles", () => { function fileContentWithComment(file: File) { diff --git a/src/testRunner/unittests/tsserver/autoImportProvider.ts b/src/testRunner/unittests/tsserver/autoImportProvider.ts index 93a350505e545..f07a52f9112eb 100644 --- a/src/testRunner/unittests/tsserver/autoImportProvider.ts +++ b/src/testRunner/unittests/tsserver/autoImportProvider.ts @@ -1,14 +1,14 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; const angularFormsDts: File = { path: "/node_modules/@angular/forms/forms.d.ts", diff --git a/src/testRunner/unittests/tsserver/auxiliaryProject.ts b/src/testRunner/unittests/tsserver/auxiliaryProject.ts index 93824fd76d837..36f0e6cb45a69 100644 --- a/src/testRunner/unittests/tsserver/auxiliaryProject.ts +++ b/src/testRunner/unittests/tsserver/auxiliaryProject.ts @@ -1,14 +1,14 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; const aTs: File = { path: "/a.ts", diff --git a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts index 72e146245b7ae..6e4f6bc76e365 100644 --- a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts +++ b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts @@ -1,12 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - Folder, - libFile, - SymLink, - TestServerHost, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -16,7 +8,15 @@ import { Logger, openFilesForSession, TestProjectService, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + Folder, + libFile, + SymLink, + TestServerHost, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: CachingFileSystemInformation:: tsserverProjectSystem CachingFileSystemInformation", () => { enum CalledMapsWithSingleArg { diff --git a/src/testRunner/unittests/tsserver/cancellationToken.ts b/src/testRunner/unittests/tsserver/cancellationToken.ts index 0c0cccc0e14dd..b095bd690de59 100644 --- a/src/testRunner/unittests/tsserver/cancellationToken.ts +++ b/src/testRunner/unittests/tsserver/cancellationToken.ts @@ -1,12 +1,12 @@ import * as ts from "../../_namespaces/ts"; -import { createServerHost } from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, TestServerCancellationToken, TestSessionRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { createServerHost } from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: cancellationToken", () => { // Disable sourcemap support for the duration of the test, as sourcemapping the errors generated during this test is slow and not something we care to test diff --git a/src/testRunner/unittests/tsserver/compileOnSave.ts b/src/testRunner/unittests/tsserver/compileOnSave.ts index 9e4e773bc1bfa..9e8f783d65186 100644 --- a/src/testRunner/unittests/tsserver/compileOnSave.ts +++ b/src/testRunner/unittests/tsserver/compileOnSave.ts @@ -1,9 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -14,7 +9,12 @@ import { protocolTextSpanFromSubstring, TestSession, toExternalFiles, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: compileOnSave:: affected list", () => { describe("for configured projects", () => { diff --git a/src/testRunner/unittests/tsserver/completions.ts b/src/testRunner/unittests/tsserver/completions.ts index 9904ea91ab663..e385dad6c06e6 100644 --- a/src/testRunner/unittests/tsserver/completions.ts +++ b/src/testRunner/unittests/tsserver/completions.ts @@ -1,16 +1,16 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, TestTypingsInstaller, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: completions", () => { it("works", () => { diff --git a/src/testRunner/unittests/tsserver/completionsIncomplete.ts b/src/testRunner/unittests/tsserver/completionsIncomplete.ts index c81cb6d3ef692..ad52b6ebe3c16 100644 --- a/src/testRunner/unittests/tsserver/completionsIncomplete.ts +++ b/src/testRunner/unittests/tsserver/completionsIncomplete.ts @@ -1,14 +1,14 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; function createExportingModuleFile(path: string, exportPrefix: string, exportCount: number): File { return { diff --git a/src/testRunner/unittests/tsserver/configFileSearch.ts b/src/testRunner/unittests/tsserver/configFileSearch.ts index 69b599fce6550..17682e3042056 100644 --- a/src/testRunner/unittests/tsserver/configFileSearch.ts +++ b/src/testRunner/unittests/tsserver/configFileSearch.ts @@ -1,13 +1,13 @@ -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createProjectService, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: configFileSearch:: searching for config file", () => { it("should stop at projectRootPath if given", () => { diff --git a/src/testRunner/unittests/tsserver/configuredProjects.ts b/src/testRunner/unittests/tsserver/configuredProjects.ts index 6500685aa0b7e..bd461d7056e41 100644 --- a/src/testRunner/unittests/tsserver/configuredProjects.ts +++ b/src/testRunner/unittests/tsserver/configuredProjects.ts @@ -1,15 +1,9 @@ import * as ts from "../../_namespaces/ts"; +import { ensureErrorFreeBuild } from "../helpers/solutionBuilder"; import { commonFile1, commonFile2, - ensureErrorFreeBuild, -} from "../tscWatch/helpers"; -import { - createServerHost, - File, - libFile, - SymLink, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/tscWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -19,7 +13,13 @@ import { logInferredProjectsOrphanStatus, openFilesForSession, verifyGetErrRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, + SymLink, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: ConfiguredProjects", () => { it("create configured project without file list", () => { diff --git a/src/testRunner/unittests/tsserver/declarationFileMaps.ts b/src/testRunner/unittests/tsserver/declarationFileMaps.ts index ae2966edaf159..1539380be3728 100644 --- a/src/testRunner/unittests/tsserver/declarationFileMaps.ts +++ b/src/testRunner/unittests/tsserver/declarationFileMaps.ts @@ -1,8 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, closeFilesForSession, @@ -11,7 +7,11 @@ import { openFilesForSession, protocolFileLocationFromSubstring, TestSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; function checkDeclarationFiles(file: File, session: TestSession): void { openFilesForSession([file], session); diff --git a/src/testRunner/unittests/tsserver/documentRegistry.ts b/src/testRunner/unittests/tsserver/documentRegistry.ts index 1377b9f7fdfcb..f3b679bb7367f 100644 --- a/src/testRunner/unittests/tsserver/documentRegistry.ts +++ b/src/testRunner/unittests/tsserver/documentRegistry.ts @@ -1,15 +1,15 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createProjectService, TestProjectService, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: documentRegistry:: document registry in project service", () => { const importModuleContent = `import {a} from "./module1"`; diff --git a/src/testRunner/unittests/tsserver/duplicatePackages.ts b/src/testRunner/unittests/tsserver/duplicatePackages.ts index dbaa4888f346d..3d4f31cba11e1 100644 --- a/src/testRunner/unittests/tsserver/duplicatePackages.ts +++ b/src/testRunner/unittests/tsserver/duplicatePackages.ts @@ -1,14 +1,14 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: duplicate packages", () => { // Tests that 'moduleSpecifiers.ts' will import from the redirecting file, and not from the file it redirects to, if that can provide a global module specifier. diff --git a/src/testRunner/unittests/tsserver/dynamicFiles.ts b/src/testRunner/unittests/tsserver/dynamicFiles.ts index 69ab05ba990f3..4d1c79c582891 100644 --- a/src/testRunner/unittests/tsserver/dynamicFiles.ts +++ b/src/testRunner/unittests/tsserver/dynamicFiles.ts @@ -1,9 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -13,7 +8,12 @@ import { protocolFileLocationFromSubstring, setCompilerOptionsForInferredProjectsRequestForSession, verifyDynamic, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; function verifyPathRecognizedAsDynamic(subscenario: string, path: string) { it(subscenario, () => { diff --git a/src/testRunner/unittests/tsserver/events/largeFileReferenced.ts b/src/testRunner/unittests/tsserver/events/largeFileReferenced.ts index ca17216af173f..c62579832b33e 100644 --- a/src/testRunner/unittests/tsserver/events/largeFileReferenced.ts +++ b/src/testRunner/unittests/tsserver/events/largeFileReferenced.ts @@ -1,15 +1,15 @@ import * as ts from "../../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "../helpers"; +} from "../../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: events:: LargeFileReferencedEvent with large file", () => { function getFileType(useLargeTsFile: boolean) { diff --git a/src/testRunner/unittests/tsserver/events/projectLanguageServiceState.ts b/src/testRunner/unittests/tsserver/events/projectLanguageServiceState.ts index eb6f106d6f57d..6ce697771b67a 100644 --- a/src/testRunner/unittests/tsserver/events/projectLanguageServiceState.ts +++ b/src/testRunner/unittests/tsserver/events/projectLanguageServiceState.ts @@ -1,16 +1,16 @@ import * as ts from "../../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createProjectService, createSession, openFilesForSession, -} from "../helpers"; +} from "../../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: events:: ProjectLanguageServiceStateEvent", () => { it("language service disabled events are triggered", () => { diff --git a/src/testRunner/unittests/tsserver/events/projectLoading.ts b/src/testRunner/unittests/tsserver/events/projectLoading.ts index 75adbb0507cb0..90781f75c8bba 100644 --- a/src/testRunner/unittests/tsserver/events/projectLoading.ts +++ b/src/testRunner/unittests/tsserver/events/projectLoading.ts @@ -1,10 +1,4 @@ import * as ts from "../../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, - TestServerHost, -} from "../../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -15,7 +9,13 @@ import { protocolLocationFromSubstring, TestSession, toExternalFiles, -} from "../helpers"; +} from "../../helpers/tsserver"; +import { + createServerHost, + File, + libFile, + TestServerHost, +} from "../../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: events:: ProjectLoadingStart and ProjectLoadingFinish events", () => { const aTs: File = { diff --git a/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts b/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts index 94b5d602c2922..19be7628c980b 100644 --- a/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts +++ b/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts @@ -1,10 +1,4 @@ import * as ts from "../../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, - TestServerHost, -} from "../../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -12,7 +6,13 @@ import { createSessionWithCustomEventHandler, openFilesForSession, TestSession, -} from "../helpers"; +} from "../../helpers/tsserver"; +import { + createServerHost, + File, + libFile, + TestServerHost, +} from "../../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: events:: ProjectsUpdatedInBackground", () => { function verifyProjectsUpdatedInBackgroundEvent(scenario: string, createSession: (host: TestServerHost) => TestSession) { diff --git a/src/testRunner/unittests/tsserver/exportMapCache.ts b/src/testRunner/unittests/tsserver/exportMapCache.ts index c8692f996c429..601be84a76f4a 100644 --- a/src/testRunner/unittests/tsserver/exportMapCache.ts +++ b/src/testRunner/unittests/tsserver/exportMapCache.ts @@ -1,14 +1,14 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; const packageJson: File = { path: "/package.json", diff --git a/src/testRunner/unittests/tsserver/externalProjects.ts b/src/testRunner/unittests/tsserver/externalProjects.ts index edca714e0775b..ff20e0c081fb1 100644 --- a/src/testRunner/unittests/tsserver/externalProjects.ts +++ b/src/testRunner/unittests/tsserver/externalProjects.ts @@ -1,10 +1,5 @@ import * as Harness from "../../_namespaces/Harness"; import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -18,7 +13,12 @@ import { toExternalFile, toExternalFiles, verifyDynamic, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: externalProjects", () => { describe("can handle tsconfig file name with difference casing", () => { diff --git a/src/testRunner/unittests/tsserver/forceConsistentCasingInFileNames.ts b/src/testRunner/unittests/tsserver/forceConsistentCasingInFileNames.ts index 680ea481b15c6..6dbfe687f421e 100644 --- a/src/testRunner/unittests/tsserver/forceConsistentCasingInFileNames.ts +++ b/src/testRunner/unittests/tsserver/forceConsistentCasingInFileNames.ts @@ -1,9 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, closeFilesForSession, @@ -12,7 +7,12 @@ import { openFilesForSession, protocolTextSpanFromSubstring, verifyGetErrRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: forceConsistentCasingInFileNames", () => { it("works when extends is specified with a case insensitive file system", () => { diff --git a/src/testRunner/unittests/tsserver/formatSettings.ts b/src/testRunner/unittests/tsserver/formatSettings.ts index 92a6b67d5d4f8..2978804b91d8a 100644 --- a/src/testRunner/unittests/tsserver/formatSettings.ts +++ b/src/testRunner/unittests/tsserver/formatSettings.ts @@ -1,6 +1,6 @@ import * as ts from "../../_namespaces/ts"; -import { createServerHost } from "../virtualFileSystemWithWatch"; -import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession } from "./helpers"; +import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession } from "../helpers/tsserver"; +import { createServerHost } from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: formatSettings", () => { it("can be set globally", () => { diff --git a/src/testRunner/unittests/tsserver/getApplicableRefactors.ts b/src/testRunner/unittests/tsserver/getApplicableRefactors.ts index a383a414dc70f..793ee5cfd0979 100644 --- a/src/testRunner/unittests/tsserver/getApplicableRefactors.ts +++ b/src/testRunner/unittests/tsserver/getApplicableRefactors.ts @@ -1,14 +1,14 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: getApplicableRefactors", () => { it("works when taking position", () => { diff --git a/src/testRunner/unittests/tsserver/getEditsForFileRename.ts b/src/testRunner/unittests/tsserver/getEditsForFileRename.ts index 41a0cc6d4cb59..e9e717cce003b 100644 --- a/src/testRunner/unittests/tsserver/getEditsForFileRename.ts +++ b/src/testRunner/unittests/tsserver/getEditsForFileRename.ts @@ -1,15 +1,15 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, textSpanFromSubstring, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: getEditsForFileRename", () => { it("works for host implementing 'resolveModuleNames' and 'getResolvedModuleWithFailedLookupLocationsFromCache'", () => { diff --git a/src/testRunner/unittests/tsserver/getExportReferences.ts b/src/testRunner/unittests/tsserver/getExportReferences.ts index 08b03e9bf54f2..1219a07c2f3b1 100644 --- a/src/testRunner/unittests/tsserver/getExportReferences.ts +++ b/src/testRunner/unittests/tsserver/getExportReferences.ts @@ -1,15 +1,15 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, protocolFileLocationFromSubstring, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: getExportReferences", () => { function makeSampleSession() { diff --git a/src/testRunner/unittests/tsserver/getFileReferences.ts b/src/testRunner/unittests/tsserver/getFileReferences.ts index b6092d2524352..147f9091c3f1d 100644 --- a/src/testRunner/unittests/tsserver/getFileReferences.ts +++ b/src/testRunner/unittests/tsserver/getFileReferences.ts @@ -1,14 +1,14 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: getFileReferences", () => { const importA = `import "./a";`; diff --git a/src/testRunner/unittests/tsserver/importHelpers.ts b/src/testRunner/unittests/tsserver/importHelpers.ts index 53db8b79a9fa8..cad9e1c491552 100644 --- a/src/testRunner/unittests/tsserver/importHelpers.ts +++ b/src/testRunner/unittests/tsserver/importHelpers.ts @@ -1,11 +1,11 @@ -import { createServerHost } from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openExternalProjectForSession, toExternalFile, -} from "./helpers"; +} from "../helpers/tsserver"; +import { createServerHost } from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: importHelpers", () => { it("should not crash in tsserver", () => { diff --git a/src/testRunner/unittests/tsserver/inconsistentErrorInEditor.ts b/src/testRunner/unittests/tsserver/inconsistentErrorInEditor.ts index 3901de75ab78b..fdee92a017186 100644 --- a/src/testRunner/unittests/tsserver/inconsistentErrorInEditor.ts +++ b/src/testRunner/unittests/tsserver/inconsistentErrorInEditor.ts @@ -1,13 +1,13 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, verifyGetErrRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: inconsistentErrorInEditor", () => { it("should not error", () => { const host = createServerHost([]); diff --git a/src/testRunner/unittests/tsserver/inferredProjects.ts b/src/testRunner/unittests/tsserver/inferredProjects.ts index 7b41d3b9d8b80..abe55289e5222 100644 --- a/src/testRunner/unittests/tsserver/inferredProjects.ts +++ b/src/testRunner/unittests/tsserver/inferredProjects.ts @@ -1,10 +1,5 @@ import * as ts from "../../_namespaces/ts"; -import { commonFile1 } from "../tscWatch/helpers"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; +import { commonFile1 } from "../helpers/tscWatch"; import { baselineTsserverLogs, closeFilesForSession, @@ -14,7 +9,12 @@ import { logInferredProjectsOrphanStatus, openFilesForSession, setCompilerOptionsForInferredProjectsRequestForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: inferredProjects", () => { it("create inferred project", () => { diff --git a/src/testRunner/unittests/tsserver/inlayHints.ts b/src/testRunner/unittests/tsserver/inlayHints.ts index eed873c432fe6..375393932892b 100644 --- a/src/testRunner/unittests/tsserver/inlayHints.ts +++ b/src/testRunner/unittests/tsserver/inlayHints.ts @@ -2,18 +2,18 @@ import * as ts from "../../_namespaces/ts"; import { commonFile1, commonFile2, -} from "../tscWatch/helpers"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/tscWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, TestSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: inlayHints", () => { const configFile: File = { diff --git a/src/testRunner/unittests/tsserver/jsdocTag.ts b/src/testRunner/unittests/tsserver/jsdocTag.ts index 97b8d41f7ca73..1c1ffd51a1003 100644 --- a/src/testRunner/unittests/tsserver/jsdocTag.ts +++ b/src/testRunner/unittests/tsserver/jsdocTag.ts @@ -1,14 +1,14 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: jsdocTag:: jsdoc @link ", () => { const config: File = { diff --git a/src/testRunner/unittests/tsserver/languageService.ts b/src/testRunner/unittests/tsserver/languageService.ts index cf1043cb69969..ae95669213adb 100644 --- a/src/testRunner/unittests/tsserver/languageService.ts +++ b/src/testRunner/unittests/tsserver/languageService.ts @@ -1,6 +1,6 @@ import * as Utils from "../../_namespaces/Utils"; -import { createServerHost } from "../virtualFileSystemWithWatch"; -import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createProjectService, logDiagnostics } from "./helpers"; +import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createProjectService, logDiagnostics } from "../helpers/tsserver"; +import { createServerHost } from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: languageService", () => { it("should work correctly on case-sensitive file systems", () => { diff --git a/src/testRunner/unittests/tsserver/maxNodeModuleJsDepth.ts b/src/testRunner/unittests/tsserver/maxNodeModuleJsDepth.ts index 842d79e1ae0ae..02b722bf0165d 100644 --- a/src/testRunner/unittests/tsserver/maxNodeModuleJsDepth.ts +++ b/src/testRunner/unittests/tsserver/maxNodeModuleJsDepth.ts @@ -1,9 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, closeFilesForSession, @@ -11,7 +6,12 @@ import { createSession, openFilesForSession, setCompilerOptionsForInferredProjectsRequestForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: maxNodeModuleJsDepth for inferred projects", () => { it("should be set to 2 if the project has js root files", () => { diff --git a/src/testRunner/unittests/tsserver/metadataInResponse.ts b/src/testRunner/unittests/tsserver/metadataInResponse.ts index 2c7ee05b8cc04..e69b1ab1f198c 100644 --- a/src/testRunner/unittests/tsserver/metadataInResponse.ts +++ b/src/testRunner/unittests/tsserver/metadataInResponse.ts @@ -1,15 +1,15 @@ import * as Harness from "../../_namespaces/Harness"; import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: with metadataInResponse::", () => { const metadata = "Extra Info"; diff --git a/src/testRunner/unittests/tsserver/moduleResolution.ts b/src/testRunner/unittests/tsserver/moduleResolution.ts index d03488e35e4a4..7dca1d93bfcbe 100644 --- a/src/testRunner/unittests/tsserver/moduleResolution.ts +++ b/src/testRunner/unittests/tsserver/moduleResolution.ts @@ -1,16 +1,16 @@ import * as Utils from "../../_namespaces/Utils"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, verifyGetErrRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: moduleResolution", () => { describe("package json file is edited", () => { diff --git a/src/testRunner/unittests/tsserver/moduleSpecifierCache.ts b/src/testRunner/unittests/tsserver/moduleSpecifierCache.ts index 398ebd7ef5b1a..5e06f62d75a52 100644 --- a/src/testRunner/unittests/tsserver/moduleSpecifierCache.ts +++ b/src/testRunner/unittests/tsserver/moduleSpecifierCache.ts @@ -1,15 +1,15 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - SymLink, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + SymLink, +} from "../helpers/virtualFileSystemWithWatch"; const packageJson: File = { path: "/package.json", diff --git a/src/testRunner/unittests/tsserver/navTo.ts b/src/testRunner/unittests/tsserver/navTo.ts index ffd6f07d6d7ce..db9303a635ee2 100644 --- a/src/testRunner/unittests/tsserver/navTo.ts +++ b/src/testRunner/unittests/tsserver/navTo.ts @@ -1,15 +1,15 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: navigate-to for javascript project", () => { it("should not include type symbols", () => { diff --git a/src/testRunner/unittests/tsserver/occurences.ts b/src/testRunner/unittests/tsserver/occurences.ts index 07fe3c34c33d6..e9eb1552bf3e3 100644 --- a/src/testRunner/unittests/tsserver/occurences.ts +++ b/src/testRunner/unittests/tsserver/occurences.ts @@ -1,14 +1,14 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: occurrence highlight on string", () => { it("should be marked if only on string values", () => { diff --git a/src/testRunner/unittests/tsserver/openFile.ts b/src/testRunner/unittests/tsserver/openFile.ts index 59b036e6c9969..3d3c9c1929a85 100644 --- a/src/testRunner/unittests/tsserver/openFile.ts +++ b/src/testRunner/unittests/tsserver/openFile.ts @@ -1,9 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, closeFilesForSession, @@ -15,7 +10,12 @@ import { TestSession, toExternalFile, verifyGetErrRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: Open-file", () => { it("can be reloaded with empty content", () => { diff --git a/src/testRunner/unittests/tsserver/packageJsonInfo.ts b/src/testRunner/unittests/tsserver/packageJsonInfo.ts index 0b25c9f4415c3..1f7e4a740c5f1 100644 --- a/src/testRunner/unittests/tsserver/packageJsonInfo.ts +++ b/src/testRunner/unittests/tsserver/packageJsonInfo.ts @@ -1,14 +1,14 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; const tsConfig: File = { path: "/tsconfig.json", diff --git a/src/testRunner/unittests/tsserver/partialSemanticServer.ts b/src/testRunner/unittests/tsserver/partialSemanticServer.ts index ef1a7c2ad752c..ed8d7a988dad4 100644 --- a/src/testRunner/unittests/tsserver/partialSemanticServer.ts +++ b/src/testRunner/unittests/tsserver/partialSemanticServer.ts @@ -1,9 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, closeFilesForSession, @@ -12,7 +7,12 @@ import { openFilesForSession, protocolFileLocationFromSubstring, verifyGetErrRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: Semantic operations on partialSemanticServer", () => { function setup() { diff --git a/src/testRunner/unittests/tsserver/plugins.ts b/src/testRunner/unittests/tsserver/plugins.ts index a003eb1e5ce4a..df0befc74e0d1 100644 --- a/src/testRunner/unittests/tsserver/plugins.ts +++ b/src/testRunner/unittests/tsserver/plugins.ts @@ -1,17 +1,17 @@ import * as Harness from "../../_namespaces/Harness"; import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, TestSessionOptions, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: plugins:: loading", () => { const testProtocolCommand = "testProtocolCommand"; diff --git a/src/testRunner/unittests/tsserver/projectErrors.ts b/src/testRunner/unittests/tsserver/projectErrors.ts index e844c34343e0a..20f38c4ab8fc4 100644 --- a/src/testRunner/unittests/tsserver/projectErrors.ts +++ b/src/testRunner/unittests/tsserver/projectErrors.ts @@ -1,10 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - Folder, - libFile, -} from "../virtualFileSystemWithWatch"; import { appendAllScriptInfos, baselineTsserverLogs, @@ -19,7 +13,13 @@ import { toExternalFiles, verifyGetErrRequest, verifyGetErrScenario, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + Folder, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: projectErrors::", () => { it("external project - diagnostics for missing files", () => { diff --git a/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts b/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts index 42136c51421e7..e9f24f00bf8b0 100644 --- a/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts +++ b/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts @@ -1,17 +1,17 @@ import * as ts from "../../_namespaces/ts"; -import { ensureErrorFreeBuild } from "../tscWatch/helpers"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; +import { ensureErrorFreeBuild } from "../helpers/solutionBuilder"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, protocolToLocation, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: with project references and compile on save", () => { const dependecyLocation = `/user/username/projects/myproject/dependency`; diff --git a/src/testRunner/unittests/tsserver/projectReferenceErrors.ts b/src/testRunner/unittests/tsserver/projectReferenceErrors.ts index a590f7906ea3c..9b92d6c7cf0f7 100644 --- a/src/testRunner/unittests/tsserver/projectReferenceErrors.ts +++ b/src/testRunner/unittests/tsserver/projectReferenceErrors.ts @@ -1,8 +1,8 @@ -import { File } from "../virtualFileSystemWithWatch"; import { GetErrForProjectDiagnostics, verifyGetErrScenario, -} from "./helpers"; +} from "../helpers/tsserver"; +import { File } from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: with project references and error reporting", () => { const dependecyLocation = `/user/username/projects/myproject/dependency`; diff --git a/src/testRunner/unittests/tsserver/projectReferences.ts b/src/testRunner/unittests/tsserver/projectReferences.ts index 0c4761de5d90b..e9d07963f0cab 100644 --- a/src/testRunner/unittests/tsserver/projectReferences.ts +++ b/src/testRunner/unittests/tsserver/projectReferences.ts @@ -1,13 +1,5 @@ import * as ts from "../../_namespaces/ts"; -import { solutionBuildWithBaseline } from "../tscWatch/helpers"; -import { - createServerHost, - File, - getTsBuildProjectFile, - getTsBuildProjectFilePath, - libFile, - SymLink, -} from "../virtualFileSystemWithWatch"; +import { solutionBuildWithBaseline } from "../helpers/solutionBuilder"; import { baselineTsserverLogs, createHostWithSolutionBuild, @@ -18,7 +10,15 @@ import { protocolFileLocationFromSubstring, protocolLocationFromSubstring, verifyGetErrRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + getTsBuildProjectFile, + getTsBuildProjectFilePath, + libFile, + SymLink, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: with project references and tsbuild", () => { describe("with container project", () => { diff --git a/src/testRunner/unittests/tsserver/projectReferencesSourcemap.ts b/src/testRunner/unittests/tsserver/projectReferencesSourcemap.ts index f9926640e6f54..d4b0637994224 100644 --- a/src/testRunner/unittests/tsserver/projectReferencesSourcemap.ts +++ b/src/testRunner/unittests/tsserver/projectReferencesSourcemap.ts @@ -1,10 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, - TestServerHost, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, closeFilesForSession, @@ -14,7 +8,13 @@ import { openFilesForSession, TestSession, TestSessionRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, + TestServerHost, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: with project references and tsbuild source map", () => { const dependecyLocation = `/user/username/projects/myproject/dependency`; diff --git a/src/testRunner/unittests/tsserver/projects.ts b/src/testRunner/unittests/tsserver/projects.ts index e4f076b6d95f4..4745650a853d6 100644 --- a/src/testRunner/unittests/tsserver/projects.ts +++ b/src/testRunner/unittests/tsserver/projects.ts @@ -2,13 +2,7 @@ import * as ts from "../../_namespaces/ts"; import { commonFile1, commonFile2, -} from "../tscWatch/helpers"; -import { - createServerHost, - File, - libFile, - TestServerHost, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/tscWatch"; import { baselineTsserverLogs, closeFilesForSession, @@ -25,7 +19,13 @@ import { toExternalFile, toExternalFiles, verifyGetErrRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, + TestServerHost, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: projects::", () => { it("handles the missing files - that were added to program because they were added with /// { diff --git a/src/testRunner/unittests/tsserver/projectsWithReferences.ts b/src/testRunner/unittests/tsserver/projectsWithReferences.ts index a4fc9218a3cb5..1594df78fffc5 100644 --- a/src/testRunner/unittests/tsserver/projectsWithReferences.ts +++ b/src/testRunner/unittests/tsserver/projectsWithReferences.ts @@ -1,14 +1,14 @@ +import { + baselineTsserverLogs, + createLoggerWithInMemoryLogs, + createProjectService, +} from "../helpers/tsserver"; import { createServerHost, File, getTsBuildProjectFile, libFile, -} from "../virtualFileSystemWithWatch"; -import { - baselineTsserverLogs, - createLoggerWithInMemoryLogs, - createProjectService, -} from "./helpers"; +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: projects with references: invoking when references are already built", () => { it("on sample project", () => { diff --git a/src/testRunner/unittests/tsserver/refactors.ts b/src/testRunner/unittests/tsserver/refactors.ts index c8885712174ff..6b38ba34878d0 100644 --- a/src/testRunner/unittests/tsserver/refactors.ts +++ b/src/testRunner/unittests/tsserver/refactors.ts @@ -1,14 +1,14 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: refactors", () => { it("use formatting options", () => { diff --git a/src/testRunner/unittests/tsserver/reload.ts b/src/testRunner/unittests/tsserver/reload.ts index b35c8e234af9d..1930c9b5e5cc2 100644 --- a/src/testRunner/unittests/tsserver/reload.ts +++ b/src/testRunner/unittests/tsserver/reload.ts @@ -1,8 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, closeFilesForSession, @@ -10,7 +6,11 @@ import { createSession, logInferredProjectsOrphanStatus, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: reload", () => { it("should work with temp file", () => { diff --git a/src/testRunner/unittests/tsserver/reloadProjects.ts b/src/testRunner/unittests/tsserver/reloadProjects.ts index 92d915db65e8c..925a080ae7a3c 100644 --- a/src/testRunner/unittests/tsserver/reloadProjects.ts +++ b/src/testRunner/unittests/tsserver/reloadProjects.ts @@ -1,10 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, - TestServerHost, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -13,7 +7,13 @@ import { openFilesForSession, setCompilerOptionsForInferredProjectsRequestForSession, TestSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, + TestServerHost, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: reloadProjects", () => { const configFile: File = { diff --git a/src/testRunner/unittests/tsserver/rename.ts b/src/testRunner/unittests/tsserver/rename.ts index 71d60988656e9..01d657dadce77 100644 --- a/src/testRunner/unittests/tsserver/rename.ts +++ b/src/testRunner/unittests/tsserver/rename.ts @@ -1,15 +1,15 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, protocolFileLocationFromSubstring, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: rename", () => { it("works with fileToRename", () => { diff --git a/src/testRunner/unittests/tsserver/resolutionCache.ts b/src/testRunner/unittests/tsserver/resolutionCache.ts index 4c95a43f60a01..4458e2307db00 100644 --- a/src/testRunner/unittests/tsserver/resolutionCache.ts +++ b/src/testRunner/unittests/tsserver/resolutionCache.ts @@ -1,15 +1,7 @@ import * as ts from "../../_namespaces/ts"; import * as Utils from "../../_namespaces/Utils"; -import { - compilerOptionsToConfigJson, -} from "../tsc/helpers"; -import { - createServerHost, - File, - libFile, - TestServerHost, -} from "../virtualFileSystemWithWatch"; +import { compilerOptionsToConfigJson } from "../helpers/contents"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -20,7 +12,13 @@ import { TestTypingsInstaller, toExternalFiles, verifyGetErrRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, + TestServerHost, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: resolutionCache:: tsserverProjectSystem extra resolution pass in server host", () => { it("can load typings that are proper modules", () => { diff --git a/src/testRunner/unittests/tsserver/session.ts b/src/testRunner/unittests/tsserver/session.ts index 02d77d225685e..21b76867d54a8 100644 --- a/src/testRunner/unittests/tsserver/session.ts +++ b/src/testRunner/unittests/tsserver/session.ts @@ -5,7 +5,7 @@ import * as ts from "../../_namespaces/ts"; import { createHasErrorMessageLogger, nullLogger, -} from "./helpers"; +} from "../helpers/tsserver"; let lastWrittenToHost: string; const noopFileWatcher: ts.FileWatcher = { close: ts.noop }; diff --git a/src/testRunner/unittests/tsserver/skipLibCheck.ts b/src/testRunner/unittests/tsserver/skipLibCheck.ts index e9295631f7d57..f14917af5d70e 100644 --- a/src/testRunner/unittests/tsserver/skipLibCheck.ts +++ b/src/testRunner/unittests/tsserver/skipLibCheck.ts @@ -1,5 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { createServerHost } from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -7,7 +6,8 @@ import { openExternalProjectForSession, openFilesForSession, toExternalFiles, -} from "./helpers"; +} from "../helpers/tsserver"; +import { createServerHost } from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: with skipLibCheck", () => { it("should be turned on for js-only inferred projects", () => { diff --git a/src/testRunner/unittests/tsserver/smartSelection.ts b/src/testRunner/unittests/tsserver/smartSelection.ts index c37a63f6149b9..8b6285deac2bd 100644 --- a/src/testRunner/unittests/tsserver/smartSelection.ts +++ b/src/testRunner/unittests/tsserver/smartSelection.ts @@ -1,15 +1,15 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; // More tests in fourslash/smartSelection_* diff --git a/src/testRunner/unittests/tsserver/symLinks.ts b/src/testRunner/unittests/tsserver/symLinks.ts index 74e98786950a0..0da7e4779aa4a 100644 --- a/src/testRunner/unittests/tsserver/symLinks.ts +++ b/src/testRunner/unittests/tsserver/symLinks.ts @@ -1,11 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, - SymLink, - TestServerHost, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -13,7 +6,14 @@ import { openFilesForSession, protocolLocationFromSubstring, verifyGetErrRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, + SymLink, + TestServerHost, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: symLinks", () => { it("rename in common file renames all project", () => { diff --git a/src/testRunner/unittests/tsserver/symlinkCache.ts b/src/testRunner/unittests/tsserver/symlinkCache.ts index f7c8b04ec61de..4729f2c69a2ce 100644 --- a/src/testRunner/unittests/tsserver/symlinkCache.ts +++ b/src/testRunner/unittests/tsserver/symlinkCache.ts @@ -1,15 +1,15 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - SymLink, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + SymLink, +} from "../helpers/virtualFileSystemWithWatch"; const appTsconfigJson: File = { path: "/packages/app/tsconfig.json", diff --git a/src/testRunner/unittests/tsserver/syntacticServer.ts b/src/testRunner/unittests/tsserver/syntacticServer.ts index 6328a6a94f373..d862f671d2ee9 100644 --- a/src/testRunner/unittests/tsserver/syntacticServer.ts +++ b/src/testRunner/unittests/tsserver/syntacticServer.ts @@ -1,9 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, closeFilesForSession, @@ -13,7 +8,12 @@ import { protocolFileLocationFromSubstring, TestSession, TestSessionRequest, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: Semantic operations on Syntax server", () => { function setup() { diff --git a/src/testRunner/unittests/tsserver/syntaxOperations.ts b/src/testRunner/unittests/tsserver/syntaxOperations.ts index b25223377f6cb..7e9b236627f7e 100644 --- a/src/testRunner/unittests/tsserver/syntaxOperations.ts +++ b/src/testRunner/unittests/tsserver/syntaxOperations.ts @@ -1,15 +1,15 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: syntax operations", () => { it("works when file is removed and added with different content", () => { diff --git a/src/testRunner/unittests/tsserver/telemetry.ts b/src/testRunner/unittests/tsserver/telemetry.ts index 233bd9a99e232..8110855af22d3 100644 --- a/src/testRunner/unittests/tsserver/telemetry.ts +++ b/src/testRunner/unittests/tsserver/telemetry.ts @@ -1,5 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { createServerHost, File } from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, closeFilesForSession, @@ -8,7 +7,8 @@ import { openExternalProjectForSession, openFilesForSession, toExternalFiles, -} from "./helpers"; +} from "../helpers/tsserver"; +import { createServerHost, File } from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: project telemetry", () => { it("does nothing for inferred project", () => { diff --git a/src/testRunner/unittests/tsserver/textStorage.ts b/src/testRunner/unittests/tsserver/textStorage.ts index 39e65cb3d4016..1fd554836296d 100644 --- a/src/testRunner/unittests/tsserver/textStorage.ts +++ b/src/testRunner/unittests/tsserver/textStorage.ts @@ -1,6 +1,6 @@ import * as ts from "../../_namespaces/ts"; -import { createServerHost } from "../virtualFileSystemWithWatch"; -import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createProjectService } from "./helpers"; +import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createProjectService } from "../helpers/tsserver"; +import { createServerHost } from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: Text storage", () => { const f = { diff --git a/src/testRunner/unittests/tsserver/typeAquisition.ts b/src/testRunner/unittests/tsserver/typeAquisition.ts index e9d79b930ffc3..a8b1ef9105189 100644 --- a/src/testRunner/unittests/tsserver/typeAquisition.ts +++ b/src/testRunner/unittests/tsserver/typeAquisition.ts @@ -1,12 +1,12 @@ import * as ts from "../../_namespaces/ts"; -import { createServerHost } from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createProjectService, TestTypingsInstaller, toExternalFile, -} from "./helpers"; +} from "../helpers/tsserver"; +import { createServerHost } from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: typeAquisition:: autoDiscovery", () => { it("does not depend on extension", () => { diff --git a/src/testRunner/unittests/tsserver/typeOnlyImportChains.ts b/src/testRunner/unittests/tsserver/typeOnlyImportChains.ts index c500f042d60c1..8c94118ace930 100644 --- a/src/testRunner/unittests/tsserver/typeOnlyImportChains.ts +++ b/src/testRunner/unittests/tsserver/typeOnlyImportChains.ts @@ -1,15 +1,15 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: typeOnlyImportChains", () => { it("named export -> type-only namespace import -> named export -> named import", () => { diff --git a/src/testRunner/unittests/tsserver/typeReferenceDirectives.ts b/src/testRunner/unittests/tsserver/typeReferenceDirectives.ts index 40f69969667b8..cd655c090180f 100644 --- a/src/testRunner/unittests/tsserver/typeReferenceDirectives.ts +++ b/src/testRunner/unittests/tsserver/typeReferenceDirectives.ts @@ -1,14 +1,14 @@ -import { - createServerHost, - File, - libFile, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, createSession, openFilesForSession, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: typeReferenceDirectives", () => { it("when typeReferenceDirective contains UpperCasePackage", () => { diff --git a/src/testRunner/unittests/tsserver/typingsInstaller.ts b/src/testRunner/unittests/tsserver/typingsInstaller.ts index 05cafb1a711ff..e8bdc29c4c692 100644 --- a/src/testRunner/unittests/tsserver/typingsInstaller.ts +++ b/src/testRunner/unittests/tsserver/typingsInstaller.ts @@ -1,10 +1,4 @@ import * as ts from "../../_namespaces/ts"; -import { - createServerHost, - File, - libFile, - TestServerHost, -} from "../virtualFileSystemWithWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -18,7 +12,13 @@ import { TestTypingsInstaller, TestTypingsInstallerWorker, toExternalFile, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, + TestServerHost, +} from "../helpers/virtualFileSystemWithWatch"; import validatePackageName = ts.JsTyping.validatePackageName; import NameValidationResult = ts.JsTyping.NameValidationResult; diff --git a/src/testRunner/unittests/tsserver/watchEnvironment.ts b/src/testRunner/unittests/tsserver/watchEnvironment.ts index ea7e84cf4c54a..56ed33c1fca5e 100644 --- a/src/testRunner/unittests/tsserver/watchEnvironment.ts +++ b/src/testRunner/unittests/tsserver/watchEnvironment.ts @@ -2,13 +2,7 @@ import * as ts from "../../_namespaces/ts"; import { commonFile1, commonFile2, -} from "../tscWatch/helpers"; -import { - createServerHost, - File, - libFile, - Tsc_WatchDirectory, -} from "../virtualFileSystemWithWatch"; +} from "../helpers/tscWatch"; import { baselineTsserverLogs, createLoggerWithInMemoryLogs, @@ -21,7 +15,13 @@ import { setCompilerOptionsForInferredProjectsRequestForSession, TestSession, toExternalFiles, -} from "./helpers"; +} from "../helpers/tsserver"; +import { + createServerHost, + File, + libFile, + Tsc_WatchDirectory, +} from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: watchEnvironment:: tsserverProjectSystem watchDirectories implementation", () => { function verifyCompletionListWithNewFileInSubFolder(scenario: string, tscWatchDirectory: Tsc_WatchDirectory) {