Adding test for #16329 to verify the caching of file system when opening file
This commit is contained in:
parent
3908325f46
commit
7173da2134
|
@ -3996,4 +3996,130 @@ namespace ts.projectSystem {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("CachingFileSystemInformation", () => {
|
||||
function getFunctionWithCalledMapForSingleArgumentCb<T>(cb: (f: string) => T) {
|
||||
const calledMap = createMultiMap<true>();
|
||||
return {
|
||||
cb: (f: string) => {
|
||||
calledMap.add(f, /*value*/ true);
|
||||
return cb(f);
|
||||
},
|
||||
calledMap
|
||||
};
|
||||
}
|
||||
|
||||
function getFunctionWithCalledMapForFiveArgumentCb<T, U, V, W, X>(cb: (f: string, arg1?: U, arg2?: V, arg3?: W, arg4?: X) => T) {
|
||||
const calledMap = createMultiMap<[U, V, W, X]>();
|
||||
return {
|
||||
cb: (f: string, arg1?: U, arg2?: V, arg3?: W, arg4?: X) => {
|
||||
calledMap.add(f, [arg1, arg2, arg3, arg4]);
|
||||
return cb(f, arg1, arg2, arg3, arg4);
|
||||
},
|
||||
calledMap
|
||||
};
|
||||
}
|
||||
|
||||
function checkMultiMapKeysForSingleEntry<T>(caption: string, multiMap: MultiMap<T>, expectedKeys: string[]) {
|
||||
assert.equal(multiMap.size, expectedKeys.length, `${caption}: incorrect size of map: Actual keys: ${arrayFrom(multiMap.keys())} Expected: ${expectedKeys}`);
|
||||
for (const name of expectedKeys) {
|
||||
assert.isTrue(multiMap.has(name), `${caption} is expected to contain ${name}, actual keys: ${arrayFrom(multiMap.keys())}`);
|
||||
assert.equal(multiMap.get(name).length, 1, `${caption} is expected to have just one entry for key ${name}, actual entry: ${multiMap.get(name)}`);
|
||||
}
|
||||
}
|
||||
|
||||
it("when calling goto definition of module", () => {
|
||||
const clientFile: FileOrFolder = {
|
||||
path: "/a/b/controllers/vessels/client.ts",
|
||||
content: `
|
||||
import { Vessel } from '~/models/vessel';
|
||||
const v = new Vessel();
|
||||
`
|
||||
};
|
||||
const anotherModuleFile: FileOrFolder = {
|
||||
path: "/a/b/utils/db.ts",
|
||||
content: "export class Bookshelf { }"
|
||||
};
|
||||
const moduleFile: FileOrFolder = {
|
||||
path: "/a/b/models/vessel.ts",
|
||||
content: `
|
||||
import { Bookshelf } from '~/utils/db';
|
||||
export class Vessel extends Bookshelf {}
|
||||
`
|
||||
};
|
||||
const tsconfigFile: FileOrFolder = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: JSON.stringify({
|
||||
compilerOptions: {
|
||||
target: "es6",
|
||||
module: "es6",
|
||||
baseUrl: "./", // all paths are relative to the baseUrl
|
||||
paths: {
|
||||
"~/*": ["*"] // resolve any `~/foo/bar` to `<baseUrl>/foo/bar`
|
||||
}
|
||||
},
|
||||
exclude: [
|
||||
"api",
|
||||
"build",
|
||||
"node_modules",
|
||||
"public",
|
||||
"seeds",
|
||||
"sql_updates",
|
||||
"tests.build"
|
||||
]
|
||||
})
|
||||
};
|
||||
|
||||
const projectFiles = [clientFile, anotherModuleFile, moduleFile, tsconfigFile];
|
||||
const host = createServerHost(projectFiles);
|
||||
const session = createSession(host);
|
||||
const projectService = session.getProjectService();
|
||||
const { configFileName } = projectService.openClientFile(clientFile.path);
|
||||
|
||||
assert.isDefined(configFileName, `should find config`);
|
||||
checkNumberOfConfiguredProjects(projectService, 1);
|
||||
|
||||
const project = projectService.configuredProjects.get(tsconfigFile.path);
|
||||
checkProjectActualFiles(project, map(projectFiles, f => f.path));
|
||||
|
||||
const fileExistsCalledOn = getFunctionWithCalledMapForSingleArgumentCb<boolean>(host.fileExists.bind(host));
|
||||
host.fileExists = fileExistsCalledOn.cb;
|
||||
const directoryExistsCalledOn = getFunctionWithCalledMapForSingleArgumentCb<boolean>(host.directoryExists.bind(host));
|
||||
host.directoryExists = directoryExistsCalledOn.cb;
|
||||
const getDirectoriesCalledOn = getFunctionWithCalledMapForSingleArgumentCb<string[]>(host.getDirectories.bind(host));
|
||||
host.getDirectories = getDirectoriesCalledOn.cb;
|
||||
const readFileCalledOn = getFunctionWithCalledMapForSingleArgumentCb<string>(host.readFile.bind(host));
|
||||
host.readFile = readFileCalledOn.cb;
|
||||
const readDirectoryCalledOn = getFunctionWithCalledMapForFiveArgumentCb<string[], ReadonlyArray<string>, ReadonlyArray<string>, ReadonlyArray<string>, number>(host.readDirectory.bind(host));
|
||||
host.readDirectory = readDirectoryCalledOn.cb;
|
||||
|
||||
|
||||
// Get definitions shouldnt make host requests
|
||||
const getDefinitionRequest = makeSessionRequest<protocol.FileLocationRequestArgs>(protocol.CommandTypes.Definition, {
|
||||
file: clientFile.path,
|
||||
position: clientFile.content.indexOf("/vessel") + 1,
|
||||
line: undefined,
|
||||
offset: undefined
|
||||
});
|
||||
const { response } = session.executeCommand(getDefinitionRequest);
|
||||
assert.equal(response[0].file, moduleFile.path, "Should go to definition of vessel: response: " + JSON.stringify(response));
|
||||
assert.equal(fileExistsCalledOn.calledMap.size, 0, `fileExists shouldnt be called`);
|
||||
assert.equal(directoryExistsCalledOn.calledMap.size, 0, `directoryExists shouldnt be called`);
|
||||
assert.equal(getDirectoriesCalledOn.calledMap.size, 0, `getDirectories shouldnt be called`);
|
||||
assert.equal(readFileCalledOn.calledMap.size, 0, `readFile shouldnt be called`);
|
||||
assert.equal(readDirectoryCalledOn.calledMap.size, 0, `readDirectory shouldnt be called`);
|
||||
|
||||
// Open the file should call only file exists on module directory and use cached value for parental directory
|
||||
const { configFileName: config2 } = projectService.openClientFile(moduleFile.path);
|
||||
assert.equal(config2, configFileName);
|
||||
checkMultiMapKeysForSingleEntry("fileExists", fileExistsCalledOn.calledMap, ["/a/b/models/tsconfig.json", "/a/b/models/jsconfig.json"]);
|
||||
assert.equal(directoryExistsCalledOn.calledMap.size, 0, `directoryExists shouldnt be called`);
|
||||
assert.equal(getDirectoriesCalledOn.calledMap.size, 0, `getDirectories shouldnt be called`);
|
||||
assert.equal(readFileCalledOn.calledMap.size, 0, `readFile shouldnt be called`);
|
||||
assert.equal(readDirectoryCalledOn.calledMap.size, 0, `readDirectory shouldnt be called`);
|
||||
|
||||
checkNumberOfConfiguredProjects(projectService, 1);
|
||||
assert.strictEqual(projectService.configuredProjects.get(tsconfigFile.path), project);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue