Skip to content

Commit 9e17a66

Browse files
committed
Sym links into single test
1 parent 5234b8b commit 9e17a66

File tree

4 files changed

+292
-297
lines changed

4 files changed

+292
-297
lines changed

src/testRunner/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
"unittests/tsserverProjectLoadingEvents.ts",
9494
"unittests/tsserverProjectSystem.ts",
9595
"unittests/tsserverProjectUpdatedInBackgroundEvent.ts",
96+
"unittests/tsserverSymLinks.ts",
9697
"unittests/typingsInstaller.ts",
9798
"unittests/versionCache.ts",
9899
"unittests/watchEnvironment.ts",

src/testRunner/unittests/tsserverHelpers.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -482,14 +482,15 @@ namespace ts.projectSystem {
482482
const toLocation = protocolToLocation(str);
483483
return { start: toLocation(span.start), end: toLocation(textSpanEnd(span)) };
484484
}
485-
//function protocolRenameSpanFromSubstring(
486-
// str: string,
487-
// substring: string,
488-
// options?: SpanFromSubstringOptions,
489-
// prefixSuffixText?: { readonly prefixText?: string, readonly suffixText?: string },
490-
//): protocol.RenameTextSpan {
491-
// return { ...protocolTextSpanFromSubstring(str, substring, options), ...prefixSuffixText };
492-
//}
485+
486+
export function protocolRenameSpanFromSubstring(
487+
str: string,
488+
substring: string,
489+
options?: SpanFromSubstringOptions,
490+
prefixSuffixText?: { readonly prefixText?: string, readonly suffixText?: string },
491+
): protocol.RenameTextSpan {
492+
return { ...protocolTextSpanFromSubstring(str, substring, options), ...prefixSuffixText };
493+
}
493494

494495
export function textSpanFromSubstring(str: string, substring: string, options?: SpanFromSubstringOptions): TextSpan {
495496
const start = nthIndexOf(str, substring, options ? options.index : 0);

src/testRunner/unittests/tsserverProjectSystem.ts

Lines changed: 0 additions & 289 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,6 @@ namespace ts.projectSystem {
77
checkArray("ScriptInfos files", arrayFrom(projectService.filenameToScriptInfo.values(), info => info.fileName), expectedFiles);
88
}
99

10-
function protocolRenameSpanFromSubstring(
11-
str: string,
12-
substring: string,
13-
options?: SpanFromSubstringOptions,
14-
prefixSuffixText?: { readonly prefixText?: string, readonly suffixText?: string },
15-
): protocol.RenameTextSpan {
16-
return { ...protocolTextSpanFromSubstring(str, substring, options), ...prefixSuffixText };
17-
}
1810
function protocolFileLocationFromSubstring(file: File, substring: string): protocol.FileLocationRequestArgs {
1911
return { file: file.path, ...protocolLocationFromSubstring(file.content, substring) };
2012
}
@@ -5144,287 +5136,6 @@ var x = 10;`
51445136
});
51455137
});
51465138

5147-
describe("tsserverProjectSystem with symLinks", () => {
5148-
it("rename in common file renames all project", () => {
5149-
const projects = "/users/username/projects";
5150-
const folderA = `${projects}/a`;
5151-
const aFile: File = {
5152-
path: `${folderA}/a.ts`,
5153-
content: `import {C} from "./c/fc"; console.log(C)`
5154-
};
5155-
const aTsconfig: File = {
5156-
path: `${folderA}/tsconfig.json`,
5157-
content: JSON.stringify({ compilerOptions: { module: "commonjs" } })
5158-
};
5159-
const aC: SymLink = {
5160-
path: `${folderA}/c`,
5161-
symLink: "../c"
5162-
};
5163-
const aFc = `${folderA}/c/fc.ts`;
5164-
5165-
const folderB = `${projects}/b`;
5166-
const bFile: File = {
5167-
path: `${folderB}/b.ts`,
5168-
content: `import {C} from "./c/fc"; console.log(C)`
5169-
};
5170-
const bTsconfig: File = {
5171-
path: `${folderB}/tsconfig.json`,
5172-
content: JSON.stringify({ compilerOptions: { module: "commonjs" } })
5173-
};
5174-
const bC: SymLink = {
5175-
path: `${folderB}/c`,
5176-
symLink: "../c"
5177-
};
5178-
const bFc = `${folderB}/c/fc.ts`;
5179-
5180-
const folderC = `${projects}/c`;
5181-
const cFile: File = {
5182-
path: `${folderC}/fc.ts`,
5183-
content: `export const C = 8`
5184-
};
5185-
5186-
const files = [cFile, libFile, aFile, aTsconfig, aC, bFile, bTsconfig, bC];
5187-
const host = createServerHost(files);
5188-
const session = createSession(host);
5189-
const projectService = session.getProjectService();
5190-
openFilesForSession(
5191-
[
5192-
{ file: aFile, projectRootPath: folderA },
5193-
{ file: bFile, projectRootPath: folderB },
5194-
{ file: aFc, projectRootPath: folderA },
5195-
{ file: bFc, projectRootPath: folderB },
5196-
],
5197-
session);
5198-
checkNumberOfProjects(projectService, { configuredProjects: 2 });
5199-
assert.isDefined(projectService.configuredProjects.get(aTsconfig.path));
5200-
assert.isDefined(projectService.configuredProjects.get(bTsconfig.path));
5201-
5202-
const response = executeSessionRequest<protocol.RenameRequest, protocol.RenameResponse>(session, protocol.CommandTypes.Rename, { file: aFc, ...protocolLocationFromSubstring(cFile.content, "C") });
5203-
5204-
assert.equal(aFile.content, bFile.content);
5205-
const abLocs: protocol.RenameTextSpan[] = [
5206-
protocolRenameSpanFromSubstring(aFile.content, "C"),
5207-
protocolRenameSpanFromSubstring(aFile.content, "C", { index: 1 }),
5208-
];
5209-
const span = protocolRenameSpanFromSubstring(cFile.content, "C");
5210-
const cLocs: protocol.RenameTextSpan[] = [span];
5211-
assert.deepEqual<protocol.RenameResponseBody | undefined>(response, {
5212-
info: {
5213-
canRename: true,
5214-
displayName: "C",
5215-
fileToRename: undefined,
5216-
fullDisplayName: '"/users/username/projects/a/c/fc".C',
5217-
kind: ScriptElementKind.constElement,
5218-
kindModifiers: ScriptElementKindModifier.exportedModifier,
5219-
triggerSpan: protocolTextSpanFromSubstring(cFile.content, "C"),
5220-
},
5221-
locs: [
5222-
{ file: aFc, locs: cLocs },
5223-
{ file: aFile.path, locs: abLocs },
5224-
{ file: bFc, locs: cLocs },
5225-
{ file: bFile.path, locs: abLocs },
5226-
],
5227-
});
5228-
});
5229-
5230-
describe("module resolution when symlinked folder contents change and resolve modules", () => {
5231-
const projectRootPath = "/users/username/projects/myproject";
5232-
const packages = `${projectRootPath}/javascript/packages`;
5233-
const recognizersDateTime = `${packages}/recognizers-date-time`;
5234-
const recognizersText = `${packages}/recognizers-text`;
5235-
const recognizersTextDist = `${recognizersText}/dist`;
5236-
const moduleName = "@microsoft/recognizers-text";
5237-
const moduleNameInFile = `"${moduleName}"`;
5238-
const recognizersDateTimeSrcFile: File = {
5239-
path: `${recognizersDateTime}/src/datetime/baseDate.ts`,
5240-
content: `import {C} from ${moduleNameInFile};
5241-
new C();`
5242-
};
5243-
const recognizerDateTimeTsconfigPath = `${recognizersDateTime}/tsconfig.json`;
5244-
const recognizerDateTimeTsconfigWithoutPathMapping: File = {
5245-
path: recognizerDateTimeTsconfigPath,
5246-
content: JSON.stringify({
5247-
include: ["src"]
5248-
})
5249-
};
5250-
const recognizerDateTimeTsconfigWithPathMapping: File = {
5251-
path: recognizerDateTimeTsconfigPath,
5252-
content: JSON.stringify({
5253-
compilerOptions: {
5254-
rootDir: "src",
5255-
baseUrl: "./",
5256-
paths: {
5257-
"@microsoft/*": ["../*"]
5258-
}
5259-
},
5260-
include: ["src"]
5261-
})
5262-
};
5263-
const nodeModulesRecorgnizersText: SymLink = {
5264-
path: `${recognizersDateTime}/node_modules/@microsoft/recognizers-text`,
5265-
symLink: recognizersText
5266-
};
5267-
const recognizerTextSrcFile: File = {
5268-
path: `${recognizersText}/src/recognizers-text.ts`,
5269-
content: `export class C { method () { return 10; } }`
5270-
};
5271-
const recongnizerTextDistTypingFile: File = {
5272-
path: `${recognizersTextDist}/types/recognizers-text.d.ts`,
5273-
content: `export class C { method(): number; }`
5274-
};
5275-
const recongnizerTextPackageJson: File = {
5276-
path: `${recognizersText}/package.json`,
5277-
content: JSON.stringify({
5278-
typings: "dist/types/recognizers-text.d.ts"
5279-
})
5280-
};
5281-
const filesInProjectWithUnresolvedModule = [recognizerDateTimeTsconfigPath, libFile.path, recognizersDateTimeSrcFile.path];
5282-
const filesInProjectWithResolvedModule = [...filesInProjectWithUnresolvedModule, recongnizerTextDistTypingFile.path];
5283-
5284-
function verifyErrors(session: TestSession, semanticErrors: protocol.Diagnostic[]) {
5285-
session.clearMessages();
5286-
const expectedSequenceId = session.getNextSeq();
5287-
session.executeCommandSeq<protocol.GeterrRequest>({
5288-
command: server.CommandNames.Geterr,
5289-
arguments: {
5290-
delay: 0,
5291-
files: [recognizersDateTimeSrcFile.path],
5292-
}
5293-
});
5294-
5295-
const host = session.host;
5296-
host.checkTimeoutQueueLengthAndRun(1);
5297-
5298-
checkErrorMessage(session, "syntaxDiag", { file: recognizersDateTimeSrcFile.path, diagnostics: [] });
5299-
session.clearMessages();
5300-
5301-
host.runQueuedImmediateCallbacks(1);
5302-
5303-
checkErrorMessage(session, "semanticDiag", { file: recognizersDateTimeSrcFile.path, diagnostics: semanticErrors });
5304-
session.clearMessages();
5305-
5306-
host.runQueuedImmediateCallbacks(1);
5307-
5308-
checkErrorMessage(session, "suggestionDiag", {
5309-
file: recognizersDateTimeSrcFile.path,
5310-
diagnostics: [],
5311-
});
5312-
checkCompleteEvent(session, 2, expectedSequenceId);
5313-
}
5314-
5315-
function verifyWatchedFilesAndDirectories(host: TestServerHost, files: string[], recursiveDirectories: ReadonlyMap<number>, nonRecursiveDirectories: string[]) {
5316-
checkWatchedFilesDetailed(host, files.filter(f => f !== recognizersDateTimeSrcFile.path), 1);
5317-
checkWatchedDirectoriesDetailed(host, nonRecursiveDirectories, 1, /*recursive*/ false);
5318-
checkWatchedDirectoriesDetailed(host, recursiveDirectories, /*recursive*/ true);
5319-
}
5320-
5321-
function createSessionAndOpenFile(host: TestServerHost) {
5322-
const session = createSession(host, { canUseEvents: true });
5323-
session.executeCommandSeq<protocol.OpenRequest>({
5324-
command: protocol.CommandTypes.Open,
5325-
arguments: {
5326-
file: recognizersDateTimeSrcFile.path,
5327-
projectRootPath
5328-
}
5329-
});
5330-
return session;
5331-
}
5332-
5333-
function verifyModuleResolution(withPathMapping: boolean) {
5334-
describe(withPathMapping ? "when tsconfig file contains path mapping" : "when tsconfig does not contain path mapping", () => {
5335-
const filesWithSources = [libFile, recognizersDateTimeSrcFile, withPathMapping ? recognizerDateTimeTsconfigWithPathMapping : recognizerDateTimeTsconfigWithoutPathMapping, recognizerTextSrcFile, recongnizerTextPackageJson];
5336-
const filesWithNodeModulesSetup = [...filesWithSources, nodeModulesRecorgnizersText];
5337-
const filesAfterCompilation = [...filesWithNodeModulesSetup, recongnizerTextDistTypingFile];
5338-
5339-
const watchedDirectoriesWithResolvedModule = arrayToMap(getTypeRootsFromLocation(recognizersDateTime), k => k, () => 1);
5340-
watchedDirectoriesWithResolvedModule.set(`${recognizersDateTime}/src`, withPathMapping ? 1 : 2); // wild card + failed lookups
5341-
if (!withPathMapping) {
5342-
watchedDirectoriesWithResolvedModule.set(`${recognizersDateTime}/node_modules`, 1); // failed lookups
5343-
}
5344-
const watchedDirectoriesWithUnresolvedModule = cloneMap(watchedDirectoriesWithResolvedModule);
5345-
watchedDirectoriesWithUnresolvedModule.set(`${recognizersDateTime}/src`, 2); // wild card + failed lookups
5346-
[`${recognizersDateTime}/node_modules`, ...(withPathMapping ? [recognizersText] : emptyArray), ...getNodeModuleDirectories(packages)].forEach(d => {
5347-
watchedDirectoriesWithUnresolvedModule.set(d, 1);
5348-
});
5349-
const nonRecursiveWatchedDirectories = withPathMapping ? [packages] : emptyArray;
5350-
5351-
function verifyProjectWithResolvedModule(session: TestSession) {
5352-
const projectService = session.getProjectService();
5353-
const project = projectService.configuredProjects.get(recognizerDateTimeTsconfigPath)!;
5354-
checkProjectActualFiles(project, filesInProjectWithResolvedModule);
5355-
verifyWatchedFilesAndDirectories(session.host, filesInProjectWithResolvedModule, watchedDirectoriesWithResolvedModule, nonRecursiveWatchedDirectories);
5356-
verifyErrors(session, []);
5357-
}
5358-
5359-
function verifyProjectWithUnresolvedModule(session: TestSession) {
5360-
const projectService = session.getProjectService();
5361-
const project = projectService.configuredProjects.get(recognizerDateTimeTsconfigPath)!;
5362-
checkProjectActualFiles(project, filesInProjectWithUnresolvedModule);
5363-
verifyWatchedFilesAndDirectories(session.host, filesInProjectWithUnresolvedModule, watchedDirectoriesWithUnresolvedModule, nonRecursiveWatchedDirectories);
5364-
const startOffset = recognizersDateTimeSrcFile.content.indexOf('"') + 1;
5365-
verifyErrors(session, [
5366-
createDiagnostic({ line: 1, offset: startOffset }, { line: 1, offset: startOffset + moduleNameInFile.length }, Diagnostics.Cannot_find_module_0, [moduleName])
5367-
]);
5368-
}
5369-
5370-
it("when project compiles from sources", () => {
5371-
const host = createServerHost(filesWithSources);
5372-
const session = createSessionAndOpenFile(host);
5373-
verifyProjectWithUnresolvedModule(session);
5374-
5375-
host.reloadFS(filesAfterCompilation);
5376-
host.runQueuedTimeoutCallbacks();
5377-
5378-
verifyProjectWithResolvedModule(session);
5379-
});
5380-
5381-
it("when project has node_modules setup but doesnt have modules in typings folder and then recompiles", () => {
5382-
const host = createServerHost(filesWithNodeModulesSetup);
5383-
const session = createSessionAndOpenFile(host);
5384-
verifyProjectWithUnresolvedModule(session);
5385-
5386-
host.reloadFS(filesAfterCompilation);
5387-
host.runQueuedTimeoutCallbacks();
5388-
5389-
if (withPathMapping) {
5390-
verifyProjectWithResolvedModule(session);
5391-
}
5392-
else {
5393-
// Cannot handle the resolution update
5394-
verifyProjectWithUnresolvedModule(session);
5395-
}
5396-
});
5397-
5398-
it("when project recompiles after deleting generated folders", () => {
5399-
const host = createServerHost(filesAfterCompilation);
5400-
const session = createSessionAndOpenFile(host);
5401-
5402-
verifyProjectWithResolvedModule(session);
5403-
5404-
host.deleteFolder(recognizersTextDist, /*recursive*/ true);
5405-
host.runQueuedTimeoutCallbacks();
5406-
5407-
verifyProjectWithUnresolvedModule(session);
5408-
5409-
host.ensureFileOrFolder(recongnizerTextDistTypingFile);
5410-
host.runQueuedTimeoutCallbacks();
5411-
5412-
if (withPathMapping) {
5413-
verifyProjectWithResolvedModule(session);
5414-
}
5415-
else {
5416-
// Cannot handle the resolution update
5417-
verifyProjectWithUnresolvedModule(session);
5418-
}
5419-
});
5420-
});
5421-
}
5422-
5423-
verifyModuleResolution(/*withPathMapping*/ false);
5424-
verifyModuleResolution(/*withPathMapping*/ true);
5425-
});
5426-
});
5427-
54285139
describe("tsserverProjectSystem forceConsistentCasingInFileNames", () => {
54295140
it("works when extends is specified with a case insensitive file system", () => {
54305141
const rootPath = "/Users/username/dev/project";

0 commit comments

Comments
 (0)