Tests
This commit is contained in:
Родитель
969b2b3819
Коммит
3c0372e84c
|
@ -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();
|
||||
}
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче