Skip to content

Commit c9c4292

Browse files
committed
Add module resolution within project references test
1 parent 4fe8f90 commit c9c4292

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

src/testRunner/unittests/reuseProgramStructure.ts

+86
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,92 @@ namespace ts {
793793
}
794794
});
795795

796+
it("can reuse module resolutions within project references", () => {
797+
const commonOptions = {
798+
composite: true,
799+
declaration: true,
800+
target: ScriptTarget.ES2015,
801+
traceResolution: true,
802+
moduleResolution: ModuleResolutionKind.Classic,
803+
};
804+
const tsconfigA = {
805+
compilerOptions: commonOptions,
806+
include: ["src"]
807+
};
808+
const tsconfigB = {
809+
compilerOptions: {
810+
...commonOptions,
811+
paths: {
812+
a: ["/a/src/index.ts"]
813+
}
814+
},
815+
projectReferences: [
816+
{ path: "/a" }
817+
]
818+
};
819+
820+
const files = [
821+
{ name: "/a/src/x.ts", text: SourceText.New("", "export const x = 1;", "") },
822+
{ name: "/a/src/index.ts", text: SourceText.New("", "export { x } from './x';", "") },
823+
{ name: "/a/tsconfig.json", text: SourceText.New("", "", JSON.stringify(tsconfigA)) },
824+
{ name: "/b/src/b.ts", text: SourceText.New("", "import { x } from 'a';", "") },
825+
];
826+
const rootNamesA = ["/a/src/index.ts", "/a/src/x.ts"];
827+
const rootNamesB = ["/b/src/b.ts"];
828+
829+
const host = createTestCompilerHost(files, commonOptions.target);
830+
831+
// Instead of hard-coding file system entries for this test, we could also write a function that more
832+
// generally transforms a list of files into a tree of FileSystemEntries.
833+
function getFileSystemEntries(path: string) {
834+
const mapPathToFileSystemEntries: { [path: string]: FileSystemEntries | undefined } = {
835+
"/a": { files: [], directories: ["src"] },
836+
"/a/src": { files: ["index.ts", "x.ts"], directories: [] }
837+
};
838+
839+
const entries = mapPathToFileSystemEntries[path];
840+
if (!entries) {
841+
throw new Error(`Unexpected path "${path}" requested from readDirectory. Test is broken.`);
842+
}
843+
return entries;
844+
}
845+
846+
host.readDirectory = (rootDir, extensions, excludes, includes, depth) =>
847+
matchFiles(
848+
rootDir,
849+
extensions,
850+
excludes,
851+
includes,
852+
/*useCaseSensitiveFileNames*/ true,
853+
/*currentDirectory*/ "/",
854+
depth,
855+
getFileSystemEntries,
856+
/*realpath*/ path => path);
857+
858+
createProgram(rootNamesA, tsconfigA.compilerOptions, host);
859+
createProgram({
860+
rootNames: rootNamesB,
861+
options: tsconfigB.compilerOptions,
862+
host,
863+
projectReferences: tsconfigB.projectReferences
864+
});
865+
866+
// Resolution should not be performed for "./x" from "/a/src/index.ts" multiple times.
867+
assert.deepEqual(host.getTrace(), [
868+
"======== Resolving module './x' from '/a/src/index.ts'. ========",
869+
"Explicitly specified module resolution kind: 'Classic'.",
870+
"File '/a/src/x.ts' exist - use it as a name resolution result.",
871+
"======== Module name './x' was successfully resolved to '/a/src/x.ts'. ========",
872+
"======== Resolving module 'a' from '/b/src/b.ts'. ========",
873+
"Explicitly specified module resolution kind: 'Classic'.",
874+
"'paths' option is specified, looking for a pattern to match module name 'a'.",
875+
"Module name 'a', matched pattern 'a'.",
876+
"Trying substitution '/a/src/index.ts', candidate module location: '/a/src/index.ts'.",
877+
"File '/a/src/index.ts' exist - use it as a name resolution result.",
878+
"======== Module name 'a' was successfully resolved to '/a/src/index.ts'. ========",
879+
], "should reuse resolution to /a/src/x.ts");
880+
});
881+
796882
describe("redirects", () => {
797883
const axIndex = "/node_modules/a/node_modules/x/index.d.ts";
798884
const axPackage = "/node_modules/a/node_modules/x/package.json";

0 commit comments

Comments
 (0)