This commit is contained in:
Sheetal Nandi
2025-05-16 14:56:21 -07:00
parent 2a08064091
commit c9dcebe350
16 changed files with 38669 additions and 0 deletions
@@ -0,0 +1,135 @@
import { dedent } from "../../_namespaces/Utils.js";
import { jsonToReadableText } from "../helpers.js";
import { TscWatchCompileChange } from "./tscWatch.js";
import { TestServerHost } from "./virtualFileSystemWithWatch.js";
function getRandomFileContent() {
return "export const x = 10;";
}
export function forEachPackageJsonScopeScenario(
forTsserver: boolean,
action: (
scenario: string,
sys: () => TestServerHost,
edits: () => readonly TscWatchCompileChange[],
project: string,
mainFile: string,
) => void,
): void {
action(
"project with package json scope",
() =>
(!forTsserver ? TestServerHost.createWatchedSystem : TestServerHost.createServerHost)({
"/home/src/workspaces/project/src/tsconfig.json": jsonToReadableText({
compilerOptions: {
target: "es2016",
composite: true,
module: "node16",
outDir: "../out",
traceResolution: true,
},
files: [
"main.ts",
"fileA.ts",
"fileB.mts",
"randomFile.ts",
"a/randomFile.ts",
"b/ba/randomFile.ts",
"b/randomFile.ts",
"c/ca/randomFile.ts",
"c/ca/caa/randomFile.ts",
"c/ca/caa/caaa/randomFile.ts",
"c/cb/randomFile.ts",
"d/da/daa/daaa/x/y/z/randomFile.ts",
"d/da/daa/daaa/randomFile.ts",
"d/da/daa/randomFile.ts",
"d/da/randomFile.ts",
"e/ea/randomFile.ts",
"e/ea/eaa/randomFile.ts",
"e/ea/eaa/eaaa/randomFile.ts",
"e/ea/eaa/eaaa/x/y/z/randomFile.ts",
"f/fa/faa/x/y/z/randomFile.ts",
"f/fa/faa/faaa/randomFile.ts",
],
}),
"/home/src/workspaces/project/src/main.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/fileA.ts": dedent`
import { foo } from "./fileB.mjs";
foo();
`,
"/home/src/workspaces/project/src/fileB.mts": `export function foo() {}`,
"/home/src/workspaces/project/src/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/a/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/b/ba/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/b/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/c/ca/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/c/ca/caa/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/c/ca/caa/caaa/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/c/cb/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/d/da/daa/daaa/x/y/z/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/d/da/daa/daaa/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/d/da/daa/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/d/da/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/e/ea/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/e/ea/eaa/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/e/ea/eaa/eaaa/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/e/ea/eaa/eaaa/x/y/z/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/f/fa/faa/faaa/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/src/f/fa/faa/x/y/z/randomFile.ts": getRandomFileContent(),
"/home/src/workspaces/project/package.json": jsonToReadableText({ name: "app", version: "1.0.0" }),
}, { currentDirectory: "/home/src/workspaces/project" }),
() => [
{
caption: "random edit",
edit: sys => sys.appendFile("/home/src/workspaces/project/src/randomFile.ts", `export const y = 10;`),
timeouts: sys => {
sys.runQueuedTimeoutCallbacks(); // Failed lookups
sys.runQueuedTimeoutCallbacks(); // actual update
},
},
{
caption: "Modify package json file to add type module",
edit: sys => sys.writeFile(`/home/src/workspaces/project/package.json`, jsonToReadableText({ name: "app", version: "1.0.0", type: "module" })),
timeouts: sys => {
sys.runQueuedTimeoutCallbacks(); // Failed lookups
sys.runQueuedTimeoutCallbacks(); // actual update
},
},
{
caption: "Modify package.json file to remove type module",
edit: sys => sys.writeFile(`/home/src/workspaces/project/package.json`, jsonToReadableText({ name: "app", version: "1.0.0" })),
timeouts: sys => {
sys.runQueuedTimeoutCallbacks(); // Failed lookups
sys.runQueuedTimeoutCallbacks(); // actual update
},
},
{
caption: "Delete package.json",
edit: sys => sys.deleteFile(`/home/src/workspaces/project/package.json`),
timeouts: sys => {
sys.runQueuedTimeoutCallbacks(); // Failed lookups
sys.runQueuedTimeoutCallbacks(); // actual update
},
},
{
caption: "Add package json file with type module",
edit: sys => sys.writeFile(`/home/src/workspaces/project/package.json`, jsonToReadableText({ name: "app", version: "1.0.0", type: "module" })),
timeouts: sys => {
sys.runQueuedTimeoutCallbacks(); // Failed lookups
sys.runQueuedTimeoutCallbacks(); // actual update
},
},
{
caption: "Delete package.json",
edit: sys => sys.deleteFile(`/home/src/workspaces/project/package.json`),
timeouts: sys => {
sys.runQueuedTimeoutCallbacks(); // Failed lookups
sys.runQueuedTimeoutCallbacks(); // actual update
},
},
],
"/home/src/workspaces/project/src/tsconfig.json",
"/home/src/workspaces/project/src/main.ts",
);
}
@@ -0,0 +1,454 @@
import { emptyArray } from "../../_namespaces/ts.js";
import { dedent } from "../../_namespaces/Utils.js";
import { jsonToReadableText } from "../helpers.js";
import { forEachPackageJsonScopeScenario } from "./packageJsonScope.js";
import { solutionBuildWithBaseline } from "./solutionBuilder.js";
import { TscWatchCompileChange } from "./tscWatch.js";
import { TestServerHost } from "./virtualFileSystemWithWatch.js";
function getRandomFileContent() {
return "export const x = 10;";
}
function getPkgPackageJsonContent(pkg: number) {
return jsonToReadableText({
name: `pkg${pkg}`,
version: "0.0.1",
exports: {
import: "./import.js",
require: "./require.js",
},
});
}
function getPkgImportContent(type: "Import" | "Require", pkg: number) {
return `export interface ${type}Interface${pkg} {}`;
}
function getPkgTypeRefContent(type: "Import" | "Require", pkg: number) {
return dedent`
export {};
declare global {
interface ${type}Interface${pkg} {}
}
`;
}
function getPkg01ImportImportContent() {
return dedent`
import type { ImportInterface0 } from "pkg0";
import type { ImportInterface1 } from "pkg1";
`;
}
function forEachResolutionCacheProjectWithImportsScenario(
forTsserver: boolean,
action: ResolutionCacheLifeTimeAction,
) {
action(
"project with imports",
() =>
(!forTsserver ? TestServerHost.createWatchedSystem : TestServerHost.createServerHost)({
"/home/src/workspaces/project/tsconfig.json": jsonToReadableText({
compilerOptions: { traceResolution: true },
include: ["*.ts"],
exclude: ["*.d.ts"],
}),
"/home/src/workspaces/project/main.ts": getRandomFileContent(),
"/home/src/workspaces/project/fileWithImports.ts": dedent`
import type { ImportInterface0 } from "pkg0" assert { "resolution-mode": "import" };
import type { RequireInterface1 } from "pkg1" assert { "resolution-mode": "require" };
`,
"/home/src/workspaces/project/randomFileForImport.ts": getRandomFileContent(),
"/home/src/workspaces/project/node_modules/pkg0/package.json": getPkgPackageJsonContent(0),
"/home/src/workspaces/project/node_modules/pkg0/import.d.ts": getPkgImportContent("Import", 0),
"/home/src/workspaces/project/node_modules/pkg0/require.d.ts": getPkgImportContent("Require", 0),
"/home/src/workspaces/project/node_modules/pkg1/package.json": getPkgPackageJsonContent(1),
"/home/src/workspaces/project/node_modules/pkg1/import.d.ts": getPkgImportContent("Import", 1),
"/home/src/workspaces/project/fileWithTypeRefs.ts": dedent`
/// <reference types="pkg2" resolution-mode="import"/>
/// <reference types="pkg3" resolution-mode="require"/>
interface LocalInterface extends ImportInterface2, RequireInterface3 {}
export {}
`,
"/home/src/workspaces/project/randomFileForTypeRef.ts": getRandomFileContent(),
"/home/src/workspaces/project/node_modules/pkg2/package.json": getPkgPackageJsonContent(2),
"/home/src/workspaces/project/node_modules/pkg2/import.d.ts": getPkgTypeRefContent("Import", 2),
"/home/src/workspaces/project/node_modules/pkg2/require.d.ts": getPkgTypeRefContent("Require", 2),
"/home/src/workspaces/project/node_modules/pkg3/package.json": getPkgPackageJsonContent(3),
"/home/src/workspaces/project/node_modules/pkg3/import.d.ts": getPkgTypeRefContent("Import", 3),
"/home/src/workspaces/project/node_modules/@types/pkg4/index.d.ts": getRandomFileContent(),
}, { currentDirectory: "/home/src/workspaces/project" }),
() => [
{
caption: "modify randomFileForImport by adding import",
edit: sys => sys.prependFile("/home/src/workspaces/project/randomFileForImport.ts", `import type { ImportInterface0 } from "pkg0" assert { "resolution-mode": "import" };\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "modify randomFileForTypeRef by adding typeRef",
edit: sys => sys.prependFile("/home/src/workspaces/project/randomFileForTypeRef.ts", `/// <reference types="pkg2" resolution-mode="import"/>\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "write file not resolved by import",
edit: sys => sys.writeFile("/home/src/workspaces/project/node_modules/pkg1/require.d.ts", getPkgImportContent("Require", 1)),
timeouts: sys => {
sys.runQueuedTimeoutCallbacks(); // failed lookup
sys.runQueuedTimeoutCallbacks(); // actual update
},
},
{
caption: "write file not resolved by typeRef",
edit: sys => sys.writeFile("/home/src/workspaces/project/node_modules/pkg3/require.d.ts", getPkgTypeRefContent("Require", 3)),
timeouts: sys => {
sys.runQueuedTimeoutCallbacks(); // failed lookup
sys.runQueuedTimeoutCallbacks(); // actual update
},
},
{
caption: "modify package.json and that should re-resolve",
edit: sys => sys.replaceFileText("/home/src/workspaces/project/node_modules/pkg1/package.json", "./require.js", "./require1.js"),
timeouts: sys => {
sys.runQueuedTimeoutCallbacks(); // failed lookup
sys.runQueuedTimeoutCallbacks(); // actual update
},
},
{
caption: "write file not resolved by import",
edit: sys => sys.writeFile("/home/src/workspaces/project/node_modules/pkg1/require1.d.ts", getPkgImportContent("Require", 1)),
timeouts: sys => {
sys.runQueuedTimeoutCallbacks(); // failed lookup
sys.runQueuedTimeoutCallbacks(); // actual update
},
},
{
caption: "delete file with imports",
edit: sys => sys.deleteFile("/home/src/workspaces/project/fileWithImports.ts"),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "delete file with typeRefs",
edit: sys => sys.deleteFile("/home/src/workspaces/project/fileWithTypeRefs.ts"),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "delete resolved import file",
edit: sys => sys.deleteFile("/home/src/workspaces/project/node_modules/pkg0/import.d.ts"),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "delete resolved typeRef file",
edit: sys => sys.deleteFile("/home/src/workspaces/project/node_modules/pkg2/import.d.ts"),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
],
"/home/src/workspaces/project/tsconfig.json",
"/home/src/workspaces/project/main.ts",
ResolutionCacheLifeTimeScenarios.SingleProject,
);
}
function forEachResolutionCacheProjectWithMultiplePlacesImportsScenario(
forTsserver: boolean,
action: ResolutionCacheLifeTimeAction,
) {
action(
"project with multiple places imports",
() =>
(!forTsserver ? TestServerHost.createWatchedSystem : TestServerHost.createServerHost)({
"/home/src/workspaces/project/tsconfig.json": configFileContent(/*bBAFileWithImport*/ true),
"/home/src/workspaces/project/main.ts": getRandomFileContent(),
"/home/src/workspaces/project/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/randomFileForImport.ts": getRandomFileContent(),
"/home/src/workspaces/project/a/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/b/ba/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/b/randomFileForImport.ts": getRandomFileContent(),
"/home/src/workspaces/project/c/ca/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/c/ca/caa/randomFileForImport.ts": getRandomFileContent(),
"/home/src/workspaces/project/c/ca/caa/caaa/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/c/cb/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/d/da/daa/daaa/x/y/z/randomFileForImport.ts": getRandomFileContent(),
"/home/src/workspaces/project/d/da/daa/daaa/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/d/da/daa/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/d/da/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/e/ea/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/e/ea/eaa/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/e/ea/eaa/eaaa/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/e/ea/eaa/eaaa/x/y/z/randomFileForImport.ts": getRandomFileContent(),
"/home/src/workspaces/project/f/fa/faa/faaa/fileWithImports.ts": getPkg01ImportImportContent(),
"/home/src/workspaces/project/f/fa/faa/x/y/z/randomFileForImport.ts": getRandomFileContent(),
"/home/src/workspaces/project/node_modules/pkg0/index.d.ts": getPkgImportContent("Import", 0),
}, { currentDirectory: "/home/src/workspaces/project" }),
() => [
{
caption: "modify randomFileForImport by adding import",
edit: sys => sys.prependFile("/home/src/workspaces/project/randomFileForImport.ts", `import type { ImportInterface0 } from "pkg0";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "modify b/randomFileForImport by adding import",
edit: sys => sys.prependFile("/home/src/workspaces/project/b/randomFileForImport.ts", `import type { ImportInterface0 } from "pkg0";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "modify c/ca/caa/randomFileForImport by adding import",
edit: sys => sys.prependFile("/home/src/workspaces/project/c/ca/caa/randomFileForImport.ts", `import type { ImportInterface0 } from "pkg0";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "modify d/da/daa/daaa/x/y/z/randomFileForImport by adding import",
edit: sys => sys.prependFile("/home/src/workspaces/project/d/da/daa/daaa/x/y/z/randomFileForImport.ts", `import type { ImportInterface0 } from "pkg0";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "modify e/ea/eaa/eaaa/x/y/z/randomFileForImport by adding import",
edit: sys => sys.prependFile("/home/src/workspaces/project/e/ea/eaa/eaaa/x/y/z/randomFileForImport.ts", `import type { ImportInterface0 } from "pkg0";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "modify randomFileForImport by adding unresolved import",
edit: sys => sys.prependFile("/home/src/workspaces/project/randomFileForImport.ts", `import type { ImportInterface1 } from "pkg1";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "modify b/randomFileForImport by adding unresolved import",
edit: sys => sys.prependFile("/home/src/workspaces/project/b/randomFileForImport.ts", `import type { ImportInterface1 } from "pkg1";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "modify c/ca/caa/randomFileForImport by adding unresolved import",
edit: sys => sys.prependFile("/home/src/workspaces/project/c/ca/caa/randomFileForImport.ts", `import type { ImportInterface1 } from "pkg1";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "modify d/da/daa/daaa/x/y/z/randomFileForImport by adding unresolved import",
edit: sys => sys.prependFile("/home/src/workspaces/project/d/da/daa/daaa/x/y/z/randomFileForImport.ts", `import type { ImportInterface1 } from "pkg1";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "modify e/ea/eaa/eaaa/x/y/z/randomFileForImport by adding unresolved import",
edit: sys => sys.prependFile("/home/src/workspaces/project/e/ea/eaa/eaaa/x/y/z/randomFileForImport.ts", `import type { ImportInterface1 } from "pkg1";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "modify f/fa/faa/x/y/z/randomFileForImport by adding import",
edit: sys => sys.prependFile("/home/src/workspaces/project/f/fa/faa/x/y/z/randomFileForImport.ts", `import type { ImportInterface0 } from "pkg0";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "modify f/fa/faa/x/y/z/randomFileForImport by adding unresolved import",
edit: sys => sys.prependFile("/home/src/workspaces/project/f/fa/faa/x/y/z/randomFileForImport.ts", `import type { ImportInterface1 } from "pkg1";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
{
caption: "add file for unresolved import and random edit",
edit: sys => {
sys.ensureFileOrFolder({
path: "/home/src/workspaces/project/node_modules/pkg1/index.d.ts",
content: getPkgImportContent("Import", 1),
});
sys.appendFile("/home/src/workspaces/project/randomFileForImport.ts", `export const y = 10;`);
},
timeouts: sys => {
sys.runQueuedTimeoutCallbacks(); // Failed lookups
sys.runQueuedTimeoutCallbacks(); // actual update
},
},
{
caption: "delete file b/ba/fileWithImports.ts",
edit: sys => {
sys.deleteFile("/home/src/workspaces/project/b/ba/fileWithImports.ts");
sys.writeFile("/home/src/workspaces/project/tsconfig.json", configFileContent(/*bBAFileWithImport*/ false));
},
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
],
"/home/src/workspaces/project/tsconfig.json",
"/home/src/workspaces/project/main.ts",
ResolutionCacheLifeTimeScenarios.SingleProjectWithMultiplePlacesResolutions,
);
function configFileContent(bBAFileWithImport: boolean) {
return jsonToReadableText({
compilerOptions: { traceResolution: true },
files: [
"main.ts",
"fileWithImports.ts",
"randomFileForImport.ts",
"a/fileWithImports.ts",
...(bBAFileWithImport ? ["b/ba/fileWithImports.ts"] : emptyArray),
"b/randomFileForImport.ts",
"c/ca/fileWithImports.ts",
"c/ca/caa/randomFileForImport.ts",
"c/ca/caa/caaa/fileWithImports.ts",
"c/cb/fileWithImports.ts",
"d/da/daa/daaa/x/y/z/randomFileForImport.ts",
"d/da/daa/daaa/fileWithImports.ts",
"d/da/daa/fileWithImports.ts",
"d/da/fileWithImports.ts",
"e/ea/fileWithImports.ts",
"e/ea/eaa/fileWithImports.ts",
"e/ea/eaa/eaaa/fileWithImports.ts",
"e/ea/eaa/eaaa/x/y/z/randomFileForImport.ts",
"f/fa/faa/x/y/z/randomFileForImport.ts",
"f/fa/faa/faaa/fileWithImports.ts",
],
});
}
}
function getSysForResolutionCacheMultipleProjects(forTsserver: boolean) {
const sys = (!forTsserver ? TestServerHost.createWatchedSystem : TestServerHost.createServerHost)({
"/home/src/workspaces/project/tsconfig.a.json": jsonToReadableText({
compilerOptions: {
composite: true,
traceResolution: true,
},
files: [
"aMain.ts",
"aFileWithImports.ts",
"aRandomFileForImport.ts",
"aRandomFileForImport2.ts",
],
}),
"/home/src/workspaces/project/aMain.ts": getRandomFileContent(),
"/home/src/workspaces/project/aFileWithImports.ts": dedent`
import type { ImportInterface0 } from "pkg0";
export { x } from "./aRandomFileForImport";
export { x as x2 } from "./aRandomFileForImport2";
export const y = 10;
`,
"/home/src/workspaces/project/aRandomFileForImport.ts": getRandomFileContent(),
"/home/src/workspaces/project/aRandomFileForImport2.ts": getRandomFileContent(),
"/home/src/workspaces/project/node_modules/pkg0/index.d.ts": getPkgImportContent("Import", 0),
"/home/src/workspaces/project/tsconfig.b.json": jsonToReadableText({
compilerOptions: {
composite: true,
traceResolution: true,
},
files: [
"bMain.ts",
"bFileWithImports.ts",
"bRandomFileForImport.ts",
"bRandomFileForImport2.ts",
],
references: [
{ path: "./tsconfig.a.json" },
],
}),
"/home/src/workspaces/project/bMain.ts": getRandomFileContent(),
"/home/src/workspaces/project/bFileWithImports.ts": dedent`
export { y } from "./aFileWithImports";
export { x } from "./bRandomFileForImport";
import type { ImportInterface0 } from "pkg0";
`,
"/home/src/workspaces/project/bRandomFileForImport.ts": getRandomFileContent(),
"/home/src/workspaces/project/bRandomFileForImport2.ts": getRandomFileContent(),
"/home/src/workspaces/project/tsconfig.json": jsonToReadableText({
compilerOptions: {
composite: true,
traceResolution: true,
module: "amd",
},
files: [
"cMain.ts",
"cFileWithImports.ts",
"cRandomFileForImport.ts",
"cRandomFileForImport2.ts",
],
references: [
{ path: "./tsconfig.a.json" },
{ path: "./tsconfig.b.json" },
],
}),
"/home/src/workspaces/project/cMain.ts": getRandomFileContent(),
"/home/src/workspaces/project/cFileWithImports.ts": dedent`
import { y } from "./bFileWithImports";
import type { ImportInterface0 } from "pkg0";
`,
"/home/src/workspaces/project/cRandomFileForImport.ts": getRandomFileContent(),
"/home/src/workspaces/project/cRandomFileForImport2.ts": getRandomFileContent(),
"/home/src/workspaces/project/pkg0.d.ts": getPkgImportContent("Import", 0),
}, { currentDirectory: "/home/src/workspaces/project" });
solutionBuildWithBaseline(sys, ["/home/src/workspaces/project"]);
return sys;
}
function forEachResolutionCacheMultipleProjectsScenario(
forTsserver: boolean,
action: ResolutionCacheLifeTimeAction,
) {
[
{
project: "/home/src/workspaces/project/tsconfig.b.json",
mainFile: "/home/src/workspaces/project/bMain.ts",
file: "bRandomFileForImport",
},
{
project: "/home/src/workspaces/project/tsconfig.json",
mainFile: "/home/src/workspaces/project/cMain.ts",
file: "cRandomFileForImport",
},
].forEach(
({ project, mainFile, file }) =>
action(
`multiple projects${mainFile.endsWith("cMain.ts") ? " with redirect options" : ""}`,
() => getSysForResolutionCacheMultipleProjects(forTsserver),
() => [
{
caption: `modify ${file} by adding import`,
edit: sys => sys.prependFile(`/home/src/workspaces/project/${file}.ts`, `export type { ImportInterface0 } from "pkg0";\n`),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
],
project,
mainFile,
ResolutionCacheLifeTimeScenarios.MultipleProjects,
),
);
}
export enum ResolutionCacheLifeTimeScenarios {
SingleProject,
MultipleProjects,
SingleProjectWithMultiplePlacesResolutions,
SingleProjectWithPackageJsonEdits,
}
export type ResolutionCacheLifeTimeAction = (
scenario: string,
sys: () => TestServerHost,
edits: () => readonly TscWatchCompileChange[],
project: string,
mainFile: string,
kind: ResolutionCacheLifeTimeScenarios,
) => void;
export function forEachResolutionCacheLifeTimeScenario(
forTsserver: boolean,
action: ResolutionCacheLifeTimeAction,
): void {
describe("resolutionCache:: on project with imports sharing", () => {
forEachResolutionCacheProjectWithImportsScenario(forTsserver, action);
});
describe("resolutionCache:: resolutions are shared from multiple places", () => {
forEachResolutionCacheProjectWithMultiplePlacesImportsScenario(forTsserver, action);
});
describe("resolutionCache:: with multiple projects", () => {
forEachResolutionCacheMultipleProjectsScenario(forTsserver, action);
});
describe("resolutionCache:: with package json edits", () => {
forEachPackageJsonScopeScenario(
forTsserver,
(scenario, sys, edits, project, mainFile) =>
action(
scenario,
sys,
edits,
project,
mainFile,
ResolutionCacheLifeTimeScenarios.SingleProjectWithPackageJsonEdits,
),
);
});
}
@@ -7,6 +7,7 @@ import { dedent } from "../../_namespaces/Utils.js";
import { jsonToReadableText } from "../helpers.js";
import { verifyAlternateResultScenario } from "../helpers/alternateResult.js";
import { compilerOptionsToConfigJson } from "../helpers/contents.js";
import { forEachPackageJsonScopeScenario } from "../helpers/packageJsonScope.js";
import { verifyTsc } from "../helpers/tsc.js";
import { TestServerHost } from "../helpers/virtualFileSystemWithWatch.js";
@@ -200,4 +201,16 @@ describe("unittests:: tsc:: moduleResolution::", () => {
},
],
});
forEachPackageJsonScopeScenario(
/*forTsserver*/ false,
(subScenario, sys, edits, project) =>
verifyTsc({
scenario: "moduleResolution",
subScenario,
sys,
commandLineArgs: ["-p", project, "--explainFiles", "--extendedDiagnostics"],
edits: edits(),
}),
);
});
@@ -2,6 +2,7 @@ import * as ts from "../../_namespaces/ts.js";
import { dedent } from "../../_namespaces/Utils.js";
import { jsonToReadableText } from "../helpers.js";
import { createBaseline } from "../helpers/baseline.js";
import { forEachResolutionCacheLifeTimeScenario } from "../helpers/resolutionCache.js";
import {
createWatchCompilerHostOfFilesAndCompilerOptionsForBaseline,
runWatchBaseline,
@@ -758,3 +759,17 @@ declare namespace NodeJS {
],
});
});
describe("unittests:: tsc-watch:: resolutionCache:: resolution lifetime", () => {
forEachResolutionCacheLifeTimeScenario(
/*forTsserver*/ false,
(subScenario, sys, edits, project) =>
verifyTscWatch({
scenario: "resolutionCache",
subScenario,
commandLineArgs: ["-w", "-p", project, "--explainFiles", "--extendedDiagnostics"],
sys,
edits: edits(),
}),
);
});
@@ -5,8 +5,13 @@ import {
compilerOptionsToConfigJson,
getPathForTypeScriptTypingInstallerCacheTest,
} from "../helpers/contents.js";
import {
forEachResolutionCacheLifeTimeScenario,
ResolutionCacheLifeTimeScenarios,
} from "../helpers/resolutionCache.js";
import {
baselineTsserverLogs,
forEachTscWatchEdit,
openExternalProjectForSession,
openFilesForSession,
setCompilerOptionsForInferredProjectsRequestForSession,
@@ -749,3 +754,32 @@ describe("unittests:: tsserver:: resolutionCache:: global typings and inferred p
);
}
});
describe("unittests:: tsserver:: resolutionCache:: resolution lifetime", () => {
forEachResolutionCacheLifeTimeScenario(
/*forTsserver*/ true,
(scenario, getHost, edits, _project, mainFile, kind) =>
it(scenario, () => {
const host = getHost();
const session = new TestSession(host);
openFilesForSession([mainFile], session);
forEachTscWatchEdit(session, edits(), ts.noop);
if (kind === ResolutionCacheLifeTimeScenarios.MultipleProjects) {
// Try opening other project files
applyOtherFileEdits(
mainFile.endsWith("cMain.ts") ?
mainFile.replace("cMain.ts", "bMain.ts") :
mainFile.replace("bMain.ts", "cMain.ts"),
mainFile.endsWith("cMain.ts") ? "bRandomFileForImport" : "cRandomFileForImport",
);
applyOtherFileEdits("/home/src/workspaces/project/aMain.ts", "aRandomFileForImport");
}
baselineTsserverLogs("resolutionCache", scenario, session);
function applyOtherFileEdits(mainFile: string, file: string) {
openFilesForSession([mainFile], session);
session.logger.info(`modify ${file} by adding import`);
host.prependFile(`/home/src/workspaces/project/${file}.ts`, `export type { ImportInterface0 } from "pkg0";\n`);
host.runQueuedTimeoutCallbacks();
}
}),
);
});
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff