Skip to content

Commit f30c951

Browse files
committed
Add tests for library redirections
1 parent 0a98b32 commit f30c951

24 files changed

+14537
-22
lines changed

src/testRunner/tests.ts

+5
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ import "./unittests/tsbuild/graphOrdering";
7878
import "./unittests/tsbuild/inferredTypeFromTransitiveModule";
7979
import "./unittests/tsbuild/javascriptProjectEmit";
8080
import "./unittests/tsbuild/lateBoundSymbol";
81+
import "./unittests/tsbuild/libraryResolution";
8182
import "./unittests/tsbuild/moduleResolution";
8283
import "./unittests/tsbuild/moduleSpecifiers";
8384
import "./unittests/tsbuild/noEmit";
@@ -92,6 +93,7 @@ import "./unittests/tsbuild/sample";
9293
import "./unittests/tsbuild/transitiveReferences";
9394
import "./unittests/tsbuildWatch/configFileErrors";
9495
import "./unittests/tsbuildWatch/demo";
96+
import "./unittests/tsbuildWatch/libraryResolution";
9597
import "./unittests/tsbuildWatch/moduleResolution";
9698
import "./unittests/tsbuildWatch/noEmit";
9799
import "./unittests/tsbuildWatch/noEmitOnError";
@@ -105,6 +107,7 @@ import "./unittests/tsc/composite";
105107
import "./unittests/tsc/declarationEmit";
106108
import "./unittests/tsc/forceConsistentCasingInFileNames";
107109
import "./unittests/tsc/incremental";
110+
import "./unittests/tsc/libraryResolution";
108111
import "./unittests/tsc/listFilesOnly";
109112
import "./unittests/tsc/projectReferences";
110113
import "./unittests/tsc/projectReferencesConfig";
@@ -116,6 +119,7 @@ import "./unittests/tscWatch/nodeNextWatch";
116119
import "./unittests/tscWatch/emitAndErrorUpdates";
117120
import "./unittests/tscWatch/forceConsistentCasingInFileNames";
118121
import "./unittests/tscWatch/incremental";
122+
import "./unittests/tscWatch/libraryResolution";
119123
import "./unittests/tscWatch/moduleResolution";
120124
import "./unittests/tscWatch/programUpdates";
121125
import "./unittests/tscWatch/projectsWithReferences";
@@ -155,6 +159,7 @@ import "./unittests/tsserver/inlayHints";
155159
import "./unittests/tsserver/inferredProjects";
156160
import "./unittests/tsserver/jsdocTag";
157161
import "./unittests/tsserver/languageService";
162+
import "./unittests/tsserver/libraryResolution";
158163
import "./unittests/tsserver/maxNodeModuleJsDepth";
159164
import "./unittests/tsserver/metadataInResponse";
160165
import "./unittests/tsserver/moduleResolution";

src/testRunner/unittests/helpers/contents.ts

+4
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,7 @@ interface Symbol {
1919
readonly [Symbol.toStringTag]: string;
2020
}
2121
`;
22+
23+
export interface FsContents {
24+
[path: string]: string;
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { dedent } from "../../_namespaces/Utils";
2+
import { FsContents, libContent } from "./contents";
3+
import { loadProjectFromFiles } from "./vfs";
4+
import { createServerHost, createWatchedSystem } from "./virtualFileSystemWithWatch";
5+
6+
function getFsContentsForLibResolution(libRedirection?: boolean): FsContents {
7+
return {
8+
"/home/src/projects/project1/utils.d.ts": `export const y = 10;`,
9+
"/home/src/projects/project1/file.ts": `export const file = 10;`,
10+
"/home/src/projects/project1/core.d.ts": `export const core = 10;`,
11+
"/home/src/projects/project1/index.ts": `export const x = "type1";`,
12+
"/home/src/projects/project1/file2.ts": dedent`
13+
/// <reference lib="webworker"/>
14+
/// <reference lib="scripthost"/>
15+
/// <reference lib="es5"/>
16+
`,
17+
"/home/src/projects/project1/tsconfig.json": JSON.stringify({
18+
compilerOptions: { composite: true, typeRoots: ["./typeroot1"], lib: ["es5", "dom"], traceResolution: true },
19+
}),
20+
"/home/src/projects/project1/typeroot1/sometype/index.d.ts": `export type TheNum = "type1";`,
21+
"/home/src/projects/project2/utils.d.ts": `export const y = 10;`,
22+
"/home/src/projects/project2/index.ts": `export const y = 10`,
23+
"/home/src/projects/project2/tsconfig.json": JSON.stringify({
24+
compilerOptions: { composite: true, lib: ["es5", "dom"], traceResolution: true },
25+
}),
26+
"/home/src/projects/project3/utils.d.ts": `export const y = 10;`,
27+
"/home/src/projects/project3/index.ts": `export const z = 10`,
28+
"/home/src/projects/project3/tsconfig.json": JSON.stringify({
29+
compilerOptions: { composite: true, lib: ["es5", "dom"], traceResolution: true },
30+
}),
31+
"/home/src/projects/project4/utils.d.ts": `export const y = 10;`,
32+
"/home/src/projects/project4/index.ts": `export const z = 10`,
33+
"/home/src/projects/project4/tsconfig.json": JSON.stringify({
34+
compilerOptions: { composite: true, lib: ["esnext", "dom", "webworker"], traceResolution: true },
35+
}),
36+
"/home/src/lib/lib.es5.d.ts": libContent,
37+
"/home/src/lib/lib.esnext.d.ts": libContent,
38+
"/home/src/lib/lib.dom.d.ts": "interface DOMInterface { }",
39+
"/home/src/lib/lib.webworker.d.ts": "interface WebWorkerInterface { }",
40+
"/home/src/lib/lib.scripthost.d.ts": "interface ScriptHostInterface { }",
41+
"/home/src/projects/node_modules/@typescript/unlreated/index.d.ts": "export const unrelated = 10;",
42+
...libRedirection ? {
43+
"/home/src/projects/node_modules/@typescript/lib-es5/index.d.ts": libContent,
44+
"/home/src/projects/node_modules/@typescript/lib-esnext/index.d.ts": libContent,
45+
"/home/src/projects/node_modules/@typescript/lib-dom/index.d.ts": "interface DOMInterface { }",
46+
"/home/src/projects/node_modules/@typescript/lib-webworker/index.d.ts": "interface WebworkerInterface { }",
47+
"/home/src/projects/node_modules/@typescript/lib-scripthost/index.d.ts": "interface ScriptHostInterface { }",
48+
} : undefined
49+
};
50+
}
51+
52+
export function getFsForLibResolution(libRedirection: true | undefined) {
53+
return loadProjectFromFiles(
54+
getFsContentsForLibResolution(libRedirection),
55+
{
56+
cwd: "/home/src/projects",
57+
executingFilePath: "/home/src/lib/tsc.js",
58+
}
59+
);
60+
}
61+
62+
export function getSysForLibResolution(libRedirection?: true) {
63+
return createWatchedSystem(
64+
getFsContentsForLibResolution(libRedirection),
65+
{
66+
currentDirectory: "/home/src/projects",
67+
executingFilePath: "/home/src/lib/tsc.js",
68+
}
69+
);
70+
}
71+
72+
export function getServerHosForLibResolution(libRedirection?: true) {
73+
return createServerHost(
74+
getFsContentsForLibResolution(libRedirection),
75+
{
76+
currentDirectory: "/home/src/projects",
77+
executingFilePath: "/home/src/lib/tsc.js",
78+
}
79+
);
80+
}
81+
82+
export function getCommandLineArgsForLibResolution(withoutConfig: true | undefined) {
83+
return withoutConfig ?
84+
["project1/core.d.ts", "project1/utils.d.ts", "project1/file.ts", "project1/index.ts", "project1/file2.ts", "--lib", "es5,dom", "--traceResolution", "--explainFiles"] :
85+
["-p", "project1", "--explainFiles"];
86+
}

src/testRunner/unittests/helpers/tsc.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export function testTscCompileLike(input: TestTscCompileLike) {
6969
const fs = inputFs.shadow();
7070

7171
// Create system
72-
const sys = new fakes.System(fs, { executingFilePath: "/lib/tsc", env: environmentVariables }) as TscCompileSystem;
72+
const sys = new fakes.System(fs, { executingFilePath: `${fs.meta.get("defaultLibLocation")}/tsc`, env: environmentVariables }) as TscCompileSystem;
7373
sys.storeFilesChangingSignatureDuringEmit = true;
7474
sys.write(`${sys.getExecutingFilePath()} ${commandLineArgs.join(" ")}\n`);
7575
sys.exit = exitCode => sys.exitCode = exitCode;

src/testRunner/unittests/helpers/vfs.ts

+28-21
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,54 @@
11
import * as Harness from "../../_namespaces/Harness";
2+
import { getDirectoryPath } from "../../_namespaces/ts";
23
import * as vfs from "../../_namespaces/vfs";
34
import * as vpath from "../../_namespaces/vpath";
45
import { libContent } from "./contents";
56

7+
export interface FsOptions {
8+
libContentToAppend?: string;
9+
cwd?: string;
10+
executingFilePath?: string;
11+
}
12+
export type FsOptionsOrLibContentsToAppend = FsOptions | string;
13+
14+
function valueOfFsOptions(options: FsOptionsOrLibContentsToAppend | undefined, key: keyof FsOptions) {
15+
return typeof options === "string" ?
16+
key === "libContentToAppend" ? options : undefined :
17+
options?.[key];
18+
}
19+
620
/**
721
* Load project from disk into /src folder
822
*/
9-
1023
export function loadProjectFromDisk(
1124
root: string,
12-
libContentToAppend?: string
25+
options?: FsOptionsOrLibContentsToAppend
1326
): vfs.FileSystem {
1427
const resolver = vfs.createResolver(Harness.IO);
15-
const fs = new vfs.FileSystem(/*ignoreCase*/ true, {
16-
files: {
17-
["/src"]: new vfs.Mount(vpath.resolve(Harness.IO.getWorkspaceRoot(), root), resolver)
18-
},
19-
cwd: "/",
20-
meta: { defaultLibLocation: "/lib" },
21-
});
22-
addLibAndMakeReadonly(fs, libContentToAppend);
23-
return fs;
28+
return loadProjectFromFiles({
29+
["/src"]: new vfs.Mount(vpath.resolve(Harness.IO.getWorkspaceRoot(), root), resolver)
30+
}, options);
2431
}
32+
2533
/**
2634
* All the files must be in /src
2735
*/
28-
2936
export function loadProjectFromFiles(
3037
files: vfs.FileSet,
31-
libContentToAppend?: string
38+
options?: FsOptionsOrLibContentsToAppend,
3239
): vfs.FileSystem {
40+
const executingFilePath = valueOfFsOptions(options, "executingFilePath");
41+
const defaultLibLocation = executingFilePath ? getDirectoryPath(executingFilePath) : "/lib";
3342
const fs = new vfs.FileSystem(/*ignoreCase*/ true, {
3443
files,
35-
cwd: "/",
36-
meta: { defaultLibLocation: "/lib" },
44+
cwd: valueOfFsOptions(options, "cwd") || "/",
45+
meta: { defaultLibLocation },
3746
});
38-
addLibAndMakeReadonly(fs, libContentToAppend);
39-
return fs;
40-
}
41-
function addLibAndMakeReadonly(fs: vfs.FileSystem, libContentToAppend?: string) {
42-
fs.mkdirSync("/lib");
43-
fs.writeFileSync("/lib/lib.d.ts", libContentToAppend ? `${libContent}${libContentToAppend}` : libContent);
47+
const libContentToAppend = valueOfFsOptions(options, "libContentToAppend");
48+
fs.mkdirpSync(defaultLibLocation);
49+
fs.writeFileSync(`${defaultLibLocation}/lib.d.ts`, libContentToAppend ? `${libContent}${libContentToAppend}` : libContent);
4450
fs.makeReadonly();
51+
return fs;
4552
}
4653

4754
export function replaceText(fs: vfs.FileSystem, path: string, oldText: string, newText: string) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { getFsForLibResolution } from "../helpers/libraryResolution";
2+
import { verifyTsc } from "../helpers/tsc";
3+
4+
describe("unittests:: tsbuild:: libraryResolution:: library file resolution", () => {
5+
function verify(libRedirection?: true) {
6+
verifyTsc({
7+
scenario: "libraryResolution",
8+
subScenario: `with config${libRedirection ? " with redirection" : ""}`,
9+
fs: () => getFsForLibResolution(libRedirection),
10+
commandLineArgs: ["-b", "project1", "project2", "project3", "project4", "--verbose", "--explainFiles"],
11+
baselinePrograms: true,
12+
});
13+
}
14+
verify();
15+
verify(/*libRedirection*/ true);
16+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { getSysForLibResolution } from "../helpers/libraryResolution";
2+
import { verifyTscWatch } from "../helpers/tscWatch";
3+
4+
describe("unittests:: tsbuildWatch:: watchMode:: libraryResolution:: library file resolution", () => {
5+
function verify(libRedirection?: true) {
6+
verifyTscWatch({
7+
scenario: "libraryResolution",
8+
subScenario: `with config${libRedirection ? " with redirection" : ""}`,
9+
sys: () => getSysForLibResolution(libRedirection),
10+
commandLineArgs: ["-b", "-w", "project1", "project2", "project3", "project4", "--verbose", "--explainFiles", "--extendedDiagnostics"],
11+
});
12+
}
13+
verify();
14+
verify(/*libRedirection*/ true);
15+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { getCommandLineArgsForLibResolution, getFsForLibResolution } from "../helpers/libraryResolution";
2+
import { verifyTsc } from "../helpers/tsc";
3+
4+
describe("unittests:: tsc:: libraryResolution:: library file resolution", () => {
5+
function verify(libRedirection?: true, withoutConfig?: true) {
6+
verifyTsc({
7+
scenario: "libraryResolution",
8+
subScenario: `${withoutConfig ? "without" : "with"} config${libRedirection ? " with redirection" : ""}`,
9+
fs: () => getFsForLibResolution(libRedirection),
10+
commandLineArgs: getCommandLineArgsForLibResolution(withoutConfig),
11+
baselinePrograms: true,
12+
});
13+
}
14+
verify();
15+
verify(/*libRedirection*/ true);
16+
verify(/*libRedirection*/ undefined, /*withoutConfig*/ true);
17+
verify(/*libRedirection*/ true, /*withoutConfig*/ true);
18+
});

0 commit comments

Comments
 (0)