mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Merge pull request #24471 from Microsoft/watchInSiblingOfRoot
Instead of creating filter for subDirectories to watch in the ancestor directory of root, watch those subDirectories for failed lookup locations
This commit is contained in:
commit
2226cd6a99
@ -60,15 +60,12 @@ namespace ts {
|
||||
watcher: FileWatcher;
|
||||
/** ref count keeping this directory watch alive */
|
||||
refCount: number;
|
||||
/** map of refcount for the subDirectory */
|
||||
subDirectoryMap?: Map<number>;
|
||||
}
|
||||
|
||||
interface DirectoryOfFailedLookupWatch {
|
||||
dir: string;
|
||||
dirPath: Path;
|
||||
ignore?: true;
|
||||
subDirectory?: Path;
|
||||
}
|
||||
|
||||
export const maxNumberOfFilesToIterateForInvalidation = 256;
|
||||
@ -403,20 +400,21 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Use some ancestor of the root directory
|
||||
let subDirectory: Path | undefined;
|
||||
let subDirectoryPath: Path | undefined, subDirectory: string | undefined;
|
||||
if (rootPath !== undefined) {
|
||||
while (!isInDirectoryPath(dirPath, rootPath)) {
|
||||
const parentPath = getDirectoryPath(dirPath);
|
||||
if (parentPath === dirPath) {
|
||||
break;
|
||||
}
|
||||
subDirectory = dirPath.slice(parentPath.length + directorySeparator.length) as Path;
|
||||
subDirectoryPath = dirPath;
|
||||
subDirectory = dir;
|
||||
dirPath = parentPath;
|
||||
dir = getDirectoryPath(dir);
|
||||
}
|
||||
}
|
||||
|
||||
return filterFSRootDirectoriesToWatch({ dir, dirPath, subDirectory }, dirPath);
|
||||
return filterFSRootDirectoriesToWatch({ dir: subDirectory || dir, dirPath: subDirectoryPath || dirPath }, dirPath);
|
||||
}
|
||||
|
||||
function isPathWithDefaultFailedLookupExtension(path: Path) {
|
||||
@ -439,7 +437,7 @@ namespace ts {
|
||||
let setAtRoot = false;
|
||||
for (const failedLookupLocation of failedLookupLocations) {
|
||||
const failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
|
||||
const { dir, dirPath, ignore , subDirectory } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
const { dir, dirPath, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
if (!ignore) {
|
||||
// If the failed lookup location path is not one of the supported extensions,
|
||||
// store it in the custom path
|
||||
@ -451,7 +449,7 @@ namespace ts {
|
||||
setAtRoot = true;
|
||||
}
|
||||
else {
|
||||
setDirectoryWatcher(dir, dirPath, subDirectory);
|
||||
setDirectoryWatcher(dir, dirPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -461,20 +459,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function setDirectoryWatcher(dir: string, dirPath: Path, subDirectory?: Path) {
|
||||
let dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
||||
function setDirectoryWatcher(dir: string, dirPath: Path) {
|
||||
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
||||
if (dirWatcher) {
|
||||
dirWatcher.refCount++;
|
||||
}
|
||||
else {
|
||||
dirWatcher = { watcher: createDirectoryWatcher(dir, dirPath), refCount: 1 };
|
||||
directoryWatchesOfFailedLookups.set(dirPath, dirWatcher);
|
||||
}
|
||||
|
||||
if (subDirectory) {
|
||||
const subDirectoryMap = dirWatcher.subDirectoryMap || (dirWatcher.subDirectoryMap = createMap());
|
||||
const existing = subDirectoryMap.get(subDirectory) || 0;
|
||||
subDirectoryMap.set(subDirectory, existing + 1);
|
||||
directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath), refCount: 1 });
|
||||
}
|
||||
}
|
||||
|
||||
@ -492,7 +483,7 @@ namespace ts {
|
||||
let removeAtRoot = false;
|
||||
for (const failedLookupLocation of failedLookupLocations) {
|
||||
const failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
|
||||
const { dirPath, ignore, subDirectory } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
const { dirPath, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
if (!ignore) {
|
||||
const refCount = customFailedLookupPaths.get(failedLookupLocationPath);
|
||||
if (refCount) {
|
||||
@ -509,7 +500,7 @@ namespace ts {
|
||||
removeAtRoot = true;
|
||||
}
|
||||
else {
|
||||
removeDirectoryWatcher(dirPath, subDirectory);
|
||||
removeDirectoryWatcher(dirPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -518,30 +509,12 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function removeDirectoryWatcher(dirPath: string, subDirectory?: Path) {
|
||||
function removeDirectoryWatcher(dirPath: string) {
|
||||
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath)!;
|
||||
if (subDirectory) {
|
||||
const existing = dirWatcher.subDirectoryMap!.get(subDirectory)!;
|
||||
if (existing === 1) {
|
||||
dirWatcher.subDirectoryMap!.delete(subDirectory);
|
||||
}
|
||||
else {
|
||||
dirWatcher.subDirectoryMap!.set(subDirectory, existing - 1);
|
||||
}
|
||||
}
|
||||
// Do not close the watcher yet since it might be needed by other failed lookup locations.
|
||||
dirWatcher.refCount--;
|
||||
}
|
||||
|
||||
function inWatchedSubdirectory(dirPath: Path, fileOrDirectoryPath: Path) {
|
||||
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
||||
if (!dirWatcher || !dirWatcher.subDirectoryMap) return false;
|
||||
return forEachKey(dirWatcher.subDirectoryMap, subDirectory => {
|
||||
const fullSubDirectory = `${dirPath}/${subDirectory}` as Path;
|
||||
return fullSubDirectory === fileOrDirectoryPath || isInDirectoryPath(fullSubDirectory, fileOrDirectoryPath);
|
||||
});
|
||||
}
|
||||
|
||||
function createDirectoryWatcher(directory: string, dirPath: Path) {
|
||||
return resolutionHost.watchDirectoryOfFailedLookupLocation(directory, fileOrDirectory => {
|
||||
const fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
|
||||
@ -550,13 +523,8 @@ namespace ts {
|
||||
cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
|
||||
}
|
||||
|
||||
// If the files are added to project root or node_modules directory, always run through the invalidation process
|
||||
// Otherwise run through invalidation only if adding to the immediate directory
|
||||
if (!allFilesHaveInvalidatedResolution &&
|
||||
(dirPath === rootPath || isNodeModulesDirectory(dirPath) || getDirectoryPath(fileOrDirectoryPath) === dirPath || inWatchedSubdirectory(dirPath, fileOrDirectoryPath))) {
|
||||
if (invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath)) {
|
||||
resolutionHost.onInvalidatedResolution();
|
||||
}
|
||||
if (!allFilesHaveInvalidatedResolution && invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath)) {
|
||||
resolutionHost.onInvalidatedResolution();
|
||||
}
|
||||
}, WatchDirectoryFlags.Recursive);
|
||||
}
|
||||
|
||||
@ -10,9 +10,12 @@ namespace ts.tscWatch {
|
||||
import checkArray = TestFSWithWatch.checkArray;
|
||||
import libFile = TestFSWithWatch.libFile;
|
||||
import checkWatchedFiles = TestFSWithWatch.checkWatchedFiles;
|
||||
import checkWatchedFilesDetailed = TestFSWithWatch.checkWatchedFilesDetailed;
|
||||
import checkWatchedDirectories = TestFSWithWatch.checkWatchedDirectories;
|
||||
import checkWatchedDirectoriesDetailed = TestFSWithWatch.checkWatchedDirectoriesDetailed;
|
||||
import checkOutputContains = TestFSWithWatch.checkOutputContains;
|
||||
import checkOutputDoesNotContain = TestFSWithWatch.checkOutputDoesNotContain;
|
||||
import Tsc_WatchDirectory = TestFSWithWatch.Tsc_WatchDirectory;
|
||||
|
||||
export function checkProgramActualFiles(program: Program, expectedFiles: string[]) {
|
||||
checkArray(`Program actual files`, program.getSourceFiles().map(file => file.fileName), expectedFiles);
|
||||
@ -2379,7 +2382,7 @@ declare module "fs" {
|
||||
});
|
||||
|
||||
describe("tsc-watch when watchDirectories implementation", () => {
|
||||
function verifyRenamingFileInSubFolder(tscWatchDirectory: TestFSWithWatch.Tsc_WatchDirectory) {
|
||||
function verifyRenamingFileInSubFolder(tscWatchDirectory: Tsc_WatchDirectory) {
|
||||
const projectFolder = "/a/username/project";
|
||||
const projectSrcFolder = `${projectFolder}/src`;
|
||||
const configFile: File = {
|
||||
@ -2399,8 +2402,8 @@ declare module "fs" {
|
||||
const projectFolders = [projectFolder, projectSrcFolder, `${projectFolder}/node_modules/@types`];
|
||||
// Watching files config file, file, lib file
|
||||
const expectedWatchedFiles = files.map(f => f.path);
|
||||
const expectedWatchedDirectories = tscWatchDirectory === TestFSWithWatch.Tsc_WatchDirectory.NonRecursiveWatchDirectory ? projectFolders : emptyArray;
|
||||
if (tscWatchDirectory === TestFSWithWatch.Tsc_WatchDirectory.WatchFile) {
|
||||
const expectedWatchedDirectories = tscWatchDirectory === Tsc_WatchDirectory.NonRecursiveWatchDirectory ? projectFolders : emptyArray;
|
||||
if (tscWatchDirectory === Tsc_WatchDirectory.WatchFile) {
|
||||
expectedWatchedFiles.push(...projectFolders);
|
||||
}
|
||||
|
||||
@ -2410,7 +2413,7 @@ declare module "fs" {
|
||||
file.path = file.path.replace("file1.ts", "file2.ts");
|
||||
expectedWatchedFiles[0] = file.path;
|
||||
host.reloadFS(files);
|
||||
if (tscWatchDirectory === TestFSWithWatch.Tsc_WatchDirectory.DynamicPolling) {
|
||||
if (tscWatchDirectory === Tsc_WatchDirectory.DynamicPolling) {
|
||||
// With dynamic polling the fs change would be detected only by running timeouts
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
}
|
||||
@ -2429,21 +2432,21 @@ declare module "fs" {
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ true);
|
||||
|
||||
// Watching config file, file, lib file and directories
|
||||
TestFSWithWatch.checkMultiMapEachKeyWithCount("watchedFiles", host.watchedFiles, expectedWatchedFiles, 1);
|
||||
TestFSWithWatch.checkMultiMapEachKeyWithCount("watchedDirectories", host.watchedDirectories, expectedWatchedDirectories, 1);
|
||||
checkWatchedFilesDetailed(host, expectedWatchedFiles, 1);
|
||||
checkWatchedDirectoriesDetailed(host, expectedWatchedDirectories, 1, /*recursive*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
it("uses watchFile when renaming file in subfolder", () => {
|
||||
verifyRenamingFileInSubFolder(TestFSWithWatch.Tsc_WatchDirectory.WatchFile);
|
||||
verifyRenamingFileInSubFolder(Tsc_WatchDirectory.WatchFile);
|
||||
});
|
||||
|
||||
it("uses non recursive watchDirectory when renaming file in subfolder", () => {
|
||||
verifyRenamingFileInSubFolder(TestFSWithWatch.Tsc_WatchDirectory.NonRecursiveWatchDirectory);
|
||||
verifyRenamingFileInSubFolder(Tsc_WatchDirectory.NonRecursiveWatchDirectory);
|
||||
});
|
||||
|
||||
it("uses non recursive dynamic polling when renaming file in subfolder", () => {
|
||||
verifyRenamingFileInSubFolder(TestFSWithWatch.Tsc_WatchDirectory.DynamicPolling);
|
||||
verifyRenamingFileInSubFolder(Tsc_WatchDirectory.DynamicPolling);
|
||||
});
|
||||
|
||||
it("when there are symlinks to folders in recursive folders", () => {
|
||||
@ -2482,7 +2485,7 @@ declare module "fs" {
|
||||
};
|
||||
const files = [file1, tsconfig, realA, realB, symLinkA, symLinkB, symLinkBInA, symLinkAInB];
|
||||
const environmentVariables = createMap<string>();
|
||||
environmentVariables.set("TSC_WATCHDIRECTORY", TestFSWithWatch.Tsc_WatchDirectory.NonRecursiveWatchDirectory);
|
||||
environmentVariables.set("TSC_WATCHDIRECTORY", Tsc_WatchDirectory.NonRecursiveWatchDirectory);
|
||||
const host = createWatchedSystem(files, { environmentVariables, currentDirectory: cwd });
|
||||
createWatchOfConfigFile("tsconfig.json", host);
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ true);
|
||||
@ -2491,4 +2494,46 @@ declare module "fs" {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsc-watch with modules linked to sibling folder", () => {
|
||||
const projectRoot = "/user/username/projects/project";
|
||||
const mainPackageRoot = `${projectRoot}/main`;
|
||||
const linkedPackageRoot = `${projectRoot}/linked-package`;
|
||||
const mainFile: File = {
|
||||
path: `${mainPackageRoot}/index.ts`,
|
||||
content: "import { Foo } from '@scoped/linked-package'"
|
||||
};
|
||||
const config: File = {
|
||||
path: `${mainPackageRoot}/tsconfig.json`,
|
||||
content: JSON.stringify({
|
||||
compilerOptions: { module: "commonjs", moduleResolution: "node", baseUrl: ".", rootDir: "." },
|
||||
files: ["index.ts"]
|
||||
})
|
||||
};
|
||||
const linkedPackageInMain: SymLink = {
|
||||
path: `${mainPackageRoot}/node_modules/@scoped/linked-package`,
|
||||
symLink: `${linkedPackageRoot}`
|
||||
};
|
||||
const linkedPackageJson: File = {
|
||||
path: `${linkedPackageRoot}/package.json`,
|
||||
content: JSON.stringify({ name: "@scoped/linked-package", version: "0.0.1", types: "dist/index.d.ts", main: "dist/index.js" })
|
||||
};
|
||||
const linkedPackageIndex: File = {
|
||||
path: `${linkedPackageRoot}/dist/index.d.ts`,
|
||||
content: "export * from './other';"
|
||||
};
|
||||
const linkedPackageOther: File = {
|
||||
path: `${linkedPackageRoot}/dist/other.d.ts`,
|
||||
content: 'export declare const Foo = "BAR";'
|
||||
};
|
||||
|
||||
it("verify watched directories", () => {
|
||||
const files = [libFile, mainFile, config, linkedPackageInMain, linkedPackageJson, linkedPackageIndex, linkedPackageOther];
|
||||
const host = createWatchedSystem(files, { currentDirectory: mainPackageRoot });
|
||||
createWatchOfConfigFile("tsconfig.json", host);
|
||||
checkWatchedFilesDetailed(host, [libFile.path, mainFile.path, config.path, linkedPackageIndex.path, linkedPackageOther.path], 1);
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
|
||||
checkWatchedDirectoriesDetailed(host, [mainPackageRoot, linkedPackageRoot, `${mainPackageRoot}/node_modules/@types`, `${projectRoot}/node_modules/@types`], 1, /*recursive*/ true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ namespace ts.projectSystem {
|
||||
export import checkWatchedDirectories = TestFSWithWatch.checkWatchedDirectories;
|
||||
export import checkWatchedDirectoriesDetailed = TestFSWithWatch.checkWatchedDirectoriesDetailed;
|
||||
import safeList = TestFSWithWatch.safeList;
|
||||
import Tsc_WatchDirectory = TestFSWithWatch.Tsc_WatchDirectory;
|
||||
|
||||
export const customTypesMap = {
|
||||
path: <Path>"/typesMap.json",
|
||||
@ -6259,7 +6260,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
function verifyCalledOnEachEntryNTimes(callback: CalledMaps, expectedKeys: ReadonlyArray<string>, nTimes: number) {
|
||||
TestFSWithWatch.checkMultiMapEachKeyWithCount(callback, calledMaps[callback], expectedKeys, nTimes);
|
||||
TestFSWithWatch.checkMultiMapKeyCount(callback, calledMaps[callback], expectedKeys, nTimes);
|
||||
}
|
||||
|
||||
function verifyNoHostCalls() {
|
||||
@ -7813,14 +7814,10 @@ new C();`
|
||||
checkCompleteEvent(session, 2, expectedSequenceId);
|
||||
}
|
||||
|
||||
function createSingleWatchMap(paths: string[]) {
|
||||
return arrayToMap(paths, p => p, () => 1);
|
||||
}
|
||||
|
||||
function verifyWatchedFilesAndDirectories(host: TestServerHost, files: string[], directories: string[]) {
|
||||
checkWatchedFilesDetailed(host, createSingleWatchMap(files.filter(f => f !== recognizersDateTimeSrcFile.path)));
|
||||
checkWatchedFilesDetailed(host, files.filter(f => f !== recognizersDateTimeSrcFile.path), 1);
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
|
||||
checkWatchedDirectoriesDetailed(host, createSingleWatchMap(directories), /*recursive*/ true);
|
||||
checkWatchedDirectoriesDetailed(host, directories, 1, /*recursive*/ true);
|
||||
}
|
||||
|
||||
function createSessionAndOpenFile(host: TestServerHost) {
|
||||
@ -7842,7 +7839,7 @@ new C();`
|
||||
const filesAfterCompilation = [...filesWithNodeModulesSetup, recongnizerTextDistTypingFile];
|
||||
|
||||
const watchedDirectoriesWithResolvedModule = [`${recognizersDateTime}/src`, withPathMapping ? packages : recognizersDateTime, ...getTypeRootsFromLocation(recognizersDateTime)];
|
||||
const watchedDirectoriesWithUnresolvedModule = [recognizersDateTime, ...watchedDirectoriesWithResolvedModule, ...getNodeModuleDirectories(packages)];
|
||||
const watchedDirectoriesWithUnresolvedModule = [recognizersDateTime, ...(withPathMapping ? [recognizersText] : emptyArray), ...watchedDirectoriesWithResolvedModule, ...getNodeModuleDirectories(packages)];
|
||||
|
||||
function verifyProjectWithResolvedModule(session: TestSession) {
|
||||
const projectService = session.getProjectService();
|
||||
@ -8315,7 +8312,7 @@ new C();`
|
||||
});
|
||||
|
||||
describe("tsserverProjectSystem watchDirectories implementation", () => {
|
||||
function verifyCompletionListWithNewFileInSubFolder(tscWatchDirectory: TestFSWithWatch.Tsc_WatchDirectory) {
|
||||
function verifyCompletionListWithNewFileInSubFolder(tscWatchDirectory: Tsc_WatchDirectory) {
|
||||
const projectFolder = "/a/username/project";
|
||||
const projectSrcFolder = `${projectFolder}/src`;
|
||||
const configFile: File = {
|
||||
@ -8336,9 +8333,9 @@ new C();`
|
||||
// All closed files(files other than index), project folder, project/src folder and project/node_modules/@types folder
|
||||
const expectedWatchedFiles = arrayToMap(fileNames.slice(1), s => s, () => 1);
|
||||
const expectedWatchedDirectories = createMap<number>();
|
||||
const mapOfDirectories = tscWatchDirectory === TestFSWithWatch.Tsc_WatchDirectory.NonRecursiveWatchDirectory ?
|
||||
const mapOfDirectories = tscWatchDirectory === Tsc_WatchDirectory.NonRecursiveWatchDirectory ?
|
||||
expectedWatchedDirectories :
|
||||
tscWatchDirectory === TestFSWithWatch.Tsc_WatchDirectory.WatchFile ?
|
||||
tscWatchDirectory === Tsc_WatchDirectory.WatchFile ?
|
||||
expectedWatchedFiles :
|
||||
createMap();
|
||||
// For failed resolution lookup and tsconfig files
|
||||
@ -8385,15 +8382,15 @@ new C();`
|
||||
}
|
||||
|
||||
it("uses watchFile when file is added to subfolder, completion list has new file", () => {
|
||||
verifyCompletionListWithNewFileInSubFolder(TestFSWithWatch.Tsc_WatchDirectory.WatchFile);
|
||||
verifyCompletionListWithNewFileInSubFolder(Tsc_WatchDirectory.WatchFile);
|
||||
});
|
||||
|
||||
it("uses non recursive watchDirectory when file is added to subfolder, completion list has new file", () => {
|
||||
verifyCompletionListWithNewFileInSubFolder(TestFSWithWatch.Tsc_WatchDirectory.NonRecursiveWatchDirectory);
|
||||
verifyCompletionListWithNewFileInSubFolder(Tsc_WatchDirectory.NonRecursiveWatchDirectory);
|
||||
});
|
||||
|
||||
it("uses dynamic polling when file is added to subfolder, completion list has new file", () => {
|
||||
verifyCompletionListWithNewFileInSubFolder(TestFSWithWatch.Tsc_WatchDirectory.DynamicPolling);
|
||||
verifyCompletionListWithNewFileInSubFolder(Tsc_WatchDirectory.DynamicPolling);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -175,7 +175,10 @@ interface Array<T> {}`
|
||||
}
|
||||
}
|
||||
|
||||
export function checkMultiMapKeyCount(caption: string, actual: MultiMap<any>, expectedKeys: Map<number>) {
|
||||
export function checkMultiMapKeyCount(caption: string, actual: MultiMap<any>, expectedKeys: ReadonlyMap<number>): void;
|
||||
export function checkMultiMapKeyCount(caption: string, actual: MultiMap<any>, expectedKeys: ReadonlyArray<string>, eachKeyCount: number): void;
|
||||
export function checkMultiMapKeyCount(caption: string, actual: MultiMap<any>, expectedKeysMapOrArray: ReadonlyMap<number> | ReadonlyArray<string>, eachKeyCount?: number) {
|
||||
const expectedKeys = isArray(expectedKeysMapOrArray) ? arrayToMap(expectedKeysMapOrArray, s => s, () => eachKeyCount!) : expectedKeysMapOrArray;
|
||||
verifyMapSize(caption, actual, arrayFrom(expectedKeys.keys()));
|
||||
expectedKeys.forEach((count, name) => {
|
||||
assert.isTrue(actual.has(name), `${caption}: expected to contain ${name}, actual keys: ${arrayFrom(actual.keys())}`);
|
||||
@ -183,10 +186,6 @@ interface Array<T> {}`
|
||||
});
|
||||
}
|
||||
|
||||
export function checkMultiMapEachKeyWithCount(caption: string, actual: MultiMap<any>, expectedKeys: ReadonlyArray<string>, count: number) {
|
||||
return checkMultiMapKeyCount(caption, actual, arrayToMap(expectedKeys, s => s, () => count));
|
||||
}
|
||||
|
||||
export function checkArray(caption: string, actual: ReadonlyArray<string>, expected: ReadonlyArray<string>) {
|
||||
assert.equal(actual.length, expected.length, `${caption}: incorrect actual number of files, expected:\r\n${expected.join("\r\n")}\r\ngot: ${actual.join("\r\n")}`);
|
||||
for (const f of expected) {
|
||||
@ -198,16 +197,31 @@ interface Array<T> {}`
|
||||
checkMapKeys("watchedFiles", host.watchedFiles, expectedFiles);
|
||||
}
|
||||
|
||||
export function checkWatchedFilesDetailed(host: TestServerHost, expectedFiles: Map<number>) {
|
||||
checkMultiMapKeyCount("watchedFiles", host.watchedFiles, expectedFiles);
|
||||
export function checkWatchedFilesDetailed(host: TestServerHost, expectedFiles: ReadonlyMap<number>): void;
|
||||
export function checkWatchedFilesDetailed(host: TestServerHost, expectedFiles: ReadonlyArray<string>, eachFileWatchCount: number): void;
|
||||
export function checkWatchedFilesDetailed(host: TestServerHost, expectedFiles: ReadonlyMap<number> | ReadonlyArray<string>, eachFileWatchCount?: number) {
|
||||
if (isArray(expectedFiles)) {
|
||||
checkMultiMapKeyCount("watchedFiles", host.watchedFiles, expectedFiles, eachFileWatchCount!);
|
||||
}
|
||||
else {
|
||||
checkMultiMapKeyCount("watchedFiles", host.watchedFiles, expectedFiles);
|
||||
}
|
||||
}
|
||||
|
||||
export function checkWatchedDirectories(host: TestServerHost, expectedDirectories: string[], recursive: boolean) {
|
||||
checkMapKeys(`watchedDirectories${recursive ? " recursive" : ""}`, recursive ? host.watchedDirectoriesRecursive : host.watchedDirectories, expectedDirectories);
|
||||
}
|
||||
|
||||
export function checkWatchedDirectoriesDetailed(host: TestServerHost, expectedDirectories: Map<number>, recursive: boolean) {
|
||||
checkMultiMapKeyCount(`watchedDirectories${recursive ? " recursive" : ""}`, recursive ? host.watchedDirectoriesRecursive : host.watchedDirectories, expectedDirectories);
|
||||
export function checkWatchedDirectoriesDetailed(host: TestServerHost, expectedDirectories: ReadonlyMap<number>, recursive: boolean): void;
|
||||
export function checkWatchedDirectoriesDetailed(host: TestServerHost, expectedDirectories: ReadonlyArray<string>, eachDirectoryWatchCount: number, recursive: boolean): void;
|
||||
export function checkWatchedDirectoriesDetailed(host: TestServerHost, expectedDirectories: ReadonlyMap<number> | ReadonlyArray<string>, recursiveOrEachDirectoryWatchCount: boolean | number, recursive?: boolean) {
|
||||
if (isArray(expectedDirectories)) {
|
||||
checkMultiMapKeyCount(`watchedDirectories${recursive ? " recursive" : ""}`, recursive ? host.watchedDirectoriesRecursive : host.watchedDirectories, expectedDirectories, recursiveOrEachDirectoryWatchCount as number);
|
||||
}
|
||||
else {
|
||||
recursive = recursiveOrEachDirectoryWatchCount as boolean;
|
||||
checkMultiMapKeyCount(`watchedDirectories${recursive ? " recursive" : ""}`, recursive ? host.watchedDirectoriesRecursive : host.watchedDirectories, expectedDirectories);
|
||||
}
|
||||
}
|
||||
|
||||
export function checkOutputContains(host: TestServerHost, expected: ReadonlyArray<string>) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user