diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index 8830e1cb01a..c034258533b 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -30,11 +30,11 @@ interface Array { length: number; [n: number]: T; }` inodeWatching?: boolean; } - export function createWatchedSystem(fileOrFolderList: readonly FileOrFolderOrSymLink[], params?: TestServerHostCreationParameters): TestServerHost { + export function createWatchedSystem(fileOrFolderList: FileOrFolderOrSymLinkMap | readonly FileOrFolderOrSymLink[], params?: TestServerHostCreationParameters): TestServerHost { return new TestServerHost(fileOrFolderList, params); } - export function createServerHost(fileOrFolderList: readonly FileOrFolderOrSymLink[], params?: TestServerHostCreationParameters): TestServerHost { + export function createServerHost(fileOrFolderList: FileOrFolderOrSymLinkMap | readonly FileOrFolderOrSymLink[], params?: TestServerHostCreationParameters): TestServerHost { const host = new TestServerHost(fileOrFolderList, params); // Just like sys, patch the host to use writeFile patchWriteFileEnsuringDirectory(host); @@ -59,6 +59,9 @@ interface Array { length: number; [n: number]: T; }` } export type FileOrFolderOrSymLink = File | Folder | SymLink; + export interface FileOrFolderOrSymLinkMap { + [path: string]: string | Omit; + } export function isFile(fileOrFolderOrSymLink: FileOrFolderOrSymLink): fileOrFolderOrSymLink is File { return isString((fileOrFolderOrSymLink as File).content); } @@ -289,7 +292,6 @@ interface Array { length: number; [n: number]: T; }` useCaseSensitiveFileNames: boolean; executingFilePath: string; currentDirectory: string; - fileOrFolderorSymLinkList: readonly FileOrFolderOrSymLink[]; newLine?: string; useWindowsStylePaths?: boolean; environmentVariables?: ESMap; @@ -326,7 +328,7 @@ interface Array { length: number; [n: number]: T; }` private readonly inodes?: ESMap; watchDirectory: HostWatchDirectory; constructor( - fileOrFolderorSymLinkList: readonly FileOrFolderOrSymLink[], + fileOrFolderorSymLinkList: FileOrFolderOrSymLinkMap | readonly FileOrFolderOrSymLink[], { useCaseSensitiveFileNames, executingFilePath, currentDirectory, newLine, windowsStyleRoot, environmentVariables, @@ -415,16 +417,27 @@ interface Array { length: number; [n: number]: T; }` return new Date(this.time); } - private reloadFS(fileOrFolderOrSymLinkList: readonly FileOrFolderOrSymLink[]) { + private reloadFS(fileOrFolderOrSymLinkList: FileOrFolderOrSymLinkMap | readonly FileOrFolderOrSymLink[]) { Debug.assert(this.fs.size === 0); - const filesOrFoldersToLoad: readonly FileOrFolderOrSymLink[] = !this.windowsStyleRoot ? fileOrFolderOrSymLinkList : - fileOrFolderOrSymLinkList.map(f => { - const result = clone(f); - result.path = this.getHostSpecificPath(f.path); - return result; - }); - for (const fileOrDirectory of filesOrFoldersToLoad) { - this.ensureFileOrFolder(fileOrDirectory); + if (isArray(fileOrFolderOrSymLinkList)) { + fileOrFolderOrSymLinkList.forEach(f => this.ensureFileOrFolder(!this.windowsStyleRoot ? + f : + { ...f, path: this.getHostSpecificPath(f.path) } + )); + } + else { + for (const key in fileOrFolderOrSymLinkList) { + if (hasProperty(fileOrFolderOrSymLinkList, key)) { + const path = this.getHostSpecificPath(key); + const value = fileOrFolderOrSymLinkList[key]; + if (isString(value)) { + this.ensureFileOrFolder({ path, content: value }); + } + else { + this.ensureFileOrFolder({ path, ...value }); + } + } + } } } diff --git a/src/testRunner/unittests/tscWatch/emit.ts b/src/testRunner/unittests/tscWatch/emit.ts index 217d4c059a5..8c9ec7150b1 100644 --- a/src/testRunner/unittests/tscWatch/emit.ts +++ b/src/testRunner/unittests/tscWatch/emit.ts @@ -6,21 +6,12 @@ namespace ts.tscWatch { scenario, subScenario: `emit with outFile or out setting/${subScenario}`, commandLineArgs: ["--w", "-p", "/a/tsconfig.json"], - sys: () => { - const config: File = { - path: "/a/tsconfig.json", - content: JSON.stringify({ compilerOptions: { out, outFile } }) - }; - const f1: File = { - path: "/a/a.ts", - content: "let x = 1" - }; - const f2: File = { - path: "/a/b.ts", - content: "let y = 1" - }; - return createWatchedSystem([f1, f2, config, libFile]); - }, + sys: () => createWatchedSystem({ + "/a/a.ts": "let x = 1", + "/a/b.ts": "let y = 1", + "/a/tsconfig.json": JSON.stringify({ compilerOptions: { out, outFile } }), + [libFile.path]: libFile.content, + }), changes: [ { caption: "Make change in the file", diff --git a/src/testRunner/unittests/tscWatch/helpers.ts b/src/testRunner/unittests/tscWatch/helpers.ts index 70b79aba0b6..92ad07cd8d8 100644 --- a/src/testRunner/unittests/tscWatch/helpers.ts +++ b/src/testRunner/unittests/tscWatch/helpers.ts @@ -432,7 +432,7 @@ namespace ts.tscWatch { return sys; } - export function createSystemWithSolutionBuild(solutionRoots: readonly string[], files: readonly TestFSWithWatch.FileOrFolderOrSymLink[], params?: TestFSWithWatch.TestServerHostCreationParameters) { + export function createSystemWithSolutionBuild(solutionRoots: readonly string[], files: TestFSWithWatch.FileOrFolderOrSymLinkMap | readonly TestFSWithWatch.FileOrFolderOrSymLink[], params?: TestFSWithWatch.TestServerHostCreationParameters) { return solutionBuildWithBaseline(createWatchedSystem(files, params), solutionRoots); } } diff --git a/src/testRunner/unittests/tscWatch/watchEnvironment.ts b/src/testRunner/unittests/tscWatch/watchEnvironment.ts index 72081fdb0c7..5cc92d55b5f 100644 --- a/src/testRunner/unittests/tscWatch/watchEnvironment.ts +++ b/src/testRunner/unittests/tscWatch/watchEnvironment.ts @@ -587,22 +587,18 @@ namespace ts.tscWatch { scenario, subScenario: `fsWatch/when using file watching thats on inode`, commandLineArgs: ["-w", "--extendedDiagnostics"], - sys: () => { - const configFile: File = { - path: `${projectRoot}/tsconfig.json`, - content: JSON.stringify({ watchOptions: { watchFile: "useFsEvents" }, files: ["foo.d.ts", "main.ts"] }) - }; - const main: File = { - path: `${projectRoot}/main.ts`, - content: `import { foo } from "./foo"; foo();` - }; - const foo: File = { - path: `${projectRoot}/foo.d.ts`, - content: `export function foo(): string;` - }; - const files = [libFile, main, foo, configFile]; - return createWatchedSystem(files, { currentDirectory: projectRoot, inodeWatching: true }); - }, + sys: () => createWatchedSystem( + { + [libFile.path]: libFile.content, + [`${projectRoot}/main.ts`]: `import { foo } from "./foo"; foo();`, + [`${projectRoot}/foo.d.ts`]: `export function foo(): string;`, + [`${projectRoot}/tsconfig.json`]: JSON.stringify({ watchOptions: { watchFile: "useFsEvents" }, files: ["foo.d.ts", "main.ts"] }), + }, + { + currentDirectory: projectRoot, + inodeWatching: true + } + ), changes: [ { caption: "Replace file with rename event that introduces error",