417 lines
12 KiB
Plaintext
417 lines
12 KiB
Plaintext
import {
|
|
loadTsconfig,
|
|
tsConfigLoader,
|
|
walkForTsConfig,
|
|
} from "../tsconfig-loader";
|
|
import { join } from "path";
|
|
|
|
describe("tsconfig-loader", () => {
|
|
it("should find tsconfig in cwd", () => {
|
|
const result = tsConfigLoader({
|
|
cwd: "/foo/bar",
|
|
getEnv: (_: string) => undefined,
|
|
loadSync: (cwd: string) => {
|
|
return {
|
|
tsConfigPath: `${cwd}/tsconfig.json`,
|
|
baseUrl: "./",
|
|
paths: {},
|
|
};
|
|
},
|
|
});
|
|
|
|
// assert.equal(result.tsConfigPath, "/foo/bar/tsconfig.json");
|
|
expect(result.tsConfigPath).toBe("/foo/bar/tsconfig.json");
|
|
});
|
|
|
|
it("should return loaderResult.tsConfigPath as undefined when not found", () => {
|
|
const result = tsConfigLoader({
|
|
cwd: "/foo/bar",
|
|
getEnv: (_: string) => undefined,
|
|
loadSync: (_: string) => {
|
|
return {
|
|
tsConfigPath: undefined,
|
|
baseUrl: "./",
|
|
paths: {},
|
|
};
|
|
},
|
|
});
|
|
|
|
// assert.isUndefined(result.tsConfigPath);
|
|
expect(result.tsConfigPath).toBeUndefined();
|
|
});
|
|
|
|
it("should use TS_NODE_PROJECT env if exists", () => {
|
|
const result = tsConfigLoader({
|
|
cwd: "/foo/bar",
|
|
getEnv: (key: string) =>
|
|
key === "TS_NODE_PROJECT" ? "/foo/baz" : undefined,
|
|
loadSync: (cwd: string, fileName: string) => {
|
|
if (cwd === "/foo/bar" && fileName === "/foo/baz") {
|
|
return {
|
|
tsConfigPath: "/foo/baz/tsconfig.json",
|
|
baseUrl: "./",
|
|
paths: {},
|
|
};
|
|
}
|
|
|
|
return {
|
|
tsConfigPath: undefined,
|
|
baseUrl: "./",
|
|
paths: {},
|
|
};
|
|
},
|
|
});
|
|
|
|
// assert.equal(result.tsConfigPath, "/foo/baz/tsconfig.json");
|
|
expect(result.tsConfigPath).toBe("/foo/baz/tsconfig.json");
|
|
});
|
|
|
|
it("should use TS_NODE_BASEURL env if exists", () => {
|
|
const result = tsConfigLoader({
|
|
cwd: "/foo/bar",
|
|
getEnv: (key: string) =>
|
|
key === "TS_NODE_BASEURL" ? "SOME_BASEURL" : undefined,
|
|
loadSync: (_0: string, _1: string, baseUrl: string) => {
|
|
return {
|
|
tsConfigPath: undefined,
|
|
baseUrl,
|
|
paths: {},
|
|
};
|
|
},
|
|
});
|
|
|
|
// assert.equal(result.baseUrl, "SOME_BASEURL");
|
|
expect(result.baseUrl).toBe("SOME_BASEURL");
|
|
});
|
|
|
|
it("should not use TS_NODE_BASEURL env if it does not exist", () => {
|
|
const result = tsConfigLoader({
|
|
cwd: "/foo/bar",
|
|
getEnv: (_: string) => {
|
|
return undefined;
|
|
},
|
|
loadSync: (_0: string, _1: string, baseUrl: string) => {
|
|
return {
|
|
tsConfigPath: undefined,
|
|
baseUrl,
|
|
paths: {},
|
|
};
|
|
},
|
|
});
|
|
|
|
// assert.equal(result.baseUrl, undefined);
|
|
expect(result.baseUrl).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("walkForTsConfig", () => {
|
|
it("should find tsconfig in starting directory", () => {
|
|
const pathToTsconfig = join("/root", "dir1", "tsconfig.json");
|
|
const res = walkForTsConfig(
|
|
join("/root", "dir1"),
|
|
(path) => path === pathToTsconfig
|
|
);
|
|
// assert.equal(res, pathToTsconfig);
|
|
expect(res).toBe(pathToTsconfig);
|
|
});
|
|
|
|
it("should find tsconfig in parent directory", () => {
|
|
const pathToTsconfig = join("/root", "tsconfig.json");
|
|
const res = walkForTsConfig(
|
|
join("/root", "dir1"),
|
|
(path) => path === pathToTsconfig
|
|
);
|
|
// assert.equal(res, pathToTsconfig);
|
|
expect(res).toBe(pathToTsconfig);
|
|
});
|
|
|
|
it("should return undefined when reaching the top", () => {
|
|
const res = walkForTsConfig(join("/root", "dir1", "kalle"), () => false);
|
|
// assert.equal(res, undefined);
|
|
expect(res).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("loadConfig", () => {
|
|
it("should load a config", () => {
|
|
const config = { compilerOptions: { baseUrl: "hej" } };
|
|
const res = loadTsconfig(
|
|
"/root/dir1/tsconfig.json",
|
|
(path) => path === "/root/dir1/tsconfig.json",
|
|
(_) => JSON.stringify(config)
|
|
);
|
|
// assert.deepEqual(res, config);
|
|
expect(res).toStrictEqual(config);
|
|
});
|
|
|
|
it("should load a config with comments", () => {
|
|
const config = { compilerOptions: { baseUrl: "hej" } };
|
|
const res = loadTsconfig(
|
|
"/root/dir1/tsconfig.json",
|
|
(path) => path === "/root/dir1/tsconfig.json",
|
|
(_) => `{
|
|
// my comment
|
|
"compilerOptions": {
|
|
"baseUrl": "hej"
|
|
}
|
|
}`
|
|
);
|
|
// assert.deepEqual(res, config);
|
|
expect(res).toStrictEqual(config);
|
|
});
|
|
|
|
it("should load a config with trailing commas", () => {
|
|
const config = { compilerOptions: { baseUrl: "hej" } };
|
|
const res = loadTsconfig(
|
|
"/root/dir1/tsconfig.json",
|
|
(path) => path === "/root/dir1/tsconfig.json",
|
|
(_) => `{
|
|
"compilerOptions": {
|
|
"baseUrl": "hej",
|
|
},
|
|
}`
|
|
);
|
|
// assert.deepEqual(res, config);
|
|
expect(res).toStrictEqual(config);
|
|
});
|
|
|
|
it("should throw an error including the file path when encountering invalid JSON5", () => {
|
|
expect(() =>
|
|
loadTsconfig(
|
|
"/root/dir1/tsconfig.json",
|
|
(path) => path === "/root/dir1/tsconfig.json",
|
|
(_) => `{
|
|
"compilerOptions": {
|
|
}`
|
|
)
|
|
).toThrowError(
|
|
"/root/dir1/tsconfig.json is malformed JSON5: invalid end of input at 3:12"
|
|
);
|
|
});
|
|
|
|
it("should load a config with string extends and overwrite all options", () => {
|
|
const firstConfig = {
|
|
extends: "../base-config.json",
|
|
compilerOptions: { baseUrl: "kalle", paths: { foo: ["bar2"] } },
|
|
};
|
|
const firstConfigPath = join("/root", "dir1", "tsconfig.json");
|
|
const baseConfig = {
|
|
compilerOptions: {
|
|
baseUrl: "olle",
|
|
paths: { foo: ["bar1"] },
|
|
strict: true,
|
|
},
|
|
};
|
|
const baseConfigPath = join("/root", "base-config.json");
|
|
const res = loadTsconfig(
|
|
join("/root", "dir1", "tsconfig.json"),
|
|
(path) => path === firstConfigPath || path === baseConfigPath,
|
|
(path) => {
|
|
if (path === firstConfigPath) {
|
|
return JSON.stringify(firstConfig);
|
|
}
|
|
if (path === baseConfigPath) {
|
|
return JSON.stringify(baseConfig);
|
|
}
|
|
return "";
|
|
}
|
|
);
|
|
|
|
// assert.deepEqual(res, {
|
|
// extends: "../base-config.json",
|
|
// compilerOptions: {
|
|
// baseUrl: "kalle",
|
|
// paths: { foo: ["bar2"] },
|
|
// strict: true,
|
|
// },
|
|
// });
|
|
expect(res).toEqual({
|
|
extends: "../base-config.json",
|
|
compilerOptions: {
|
|
baseUrl: "kalle",
|
|
paths: { foo: ["bar2"] },
|
|
strict: true,
|
|
},
|
|
});
|
|
});
|
|
|
|
it("should load a config with string extends from node_modules and overwrite all options", () => {
|
|
const firstConfig = {
|
|
extends: "my-package/base-config.json",
|
|
compilerOptions: { baseUrl: "kalle", paths: { foo: ["bar2"] } },
|
|
};
|
|
const firstConfigPath = join("/root", "dir1", "tsconfig.json");
|
|
const baseConfig = {
|
|
compilerOptions: {
|
|
baseUrl: "olle",
|
|
paths: { foo: ["bar1"] },
|
|
strict: true,
|
|
},
|
|
};
|
|
const baseConfigPath = join(
|
|
"/root",
|
|
"dir1",
|
|
"node_modules",
|
|
"my-package",
|
|
"base-config.json"
|
|
);
|
|
const res = loadTsconfig(
|
|
join("/root", "dir1", "tsconfig.json"),
|
|
(path) => path === firstConfigPath || path === baseConfigPath,
|
|
(path) => {
|
|
if (path === firstConfigPath) {
|
|
return JSON.stringify(firstConfig);
|
|
}
|
|
if (path === baseConfigPath) {
|
|
return JSON.stringify(baseConfig);
|
|
}
|
|
return "";
|
|
}
|
|
);
|
|
|
|
// assert.deepEqual(res, {
|
|
// extends: "my-package/base-config.json",
|
|
// compilerOptions: {
|
|
// baseUrl: "kalle",
|
|
// paths: { foo: ["bar2"] },
|
|
// strict: true,
|
|
// },
|
|
// });
|
|
expect(res).toEqual({
|
|
extends: "my-package/base-config.json",
|
|
compilerOptions: {
|
|
baseUrl: "kalle",
|
|
paths: { foo: ["bar2"] },
|
|
strict: true,
|
|
},
|
|
});
|
|
});
|
|
|
|
it("should use baseUrl relative to location of extended tsconfig", () => {
|
|
const firstConfig = { compilerOptions: { baseUrl: "." } };
|
|
const firstConfigPath = join("/root", "first-config.json");
|
|
const secondConfig = { extends: "../first-config.json" };
|
|
const secondConfigPath = join("/root", "dir1", "second-config.json");
|
|
const thirdConfig = { extends: "../second-config.json" };
|
|
const thirdConfigPath = join("/root", "dir1", "dir2", "third-config.json");
|
|
const res = loadTsconfig(
|
|
join("/root", "dir1", "dir2", "third-config.json"),
|
|
(path) =>
|
|
path === firstConfigPath ||
|
|
path === secondConfigPath ||
|
|
path === thirdConfigPath,
|
|
(path) => {
|
|
if (path === firstConfigPath) {
|
|
return JSON.stringify(firstConfig);
|
|
}
|
|
if (path === secondConfigPath) {
|
|
return JSON.stringify(secondConfig);
|
|
}
|
|
if (path === thirdConfigPath) {
|
|
return JSON.stringify(thirdConfig);
|
|
}
|
|
return "";
|
|
}
|
|
);
|
|
|
|
// assert.deepEqual(res, {
|
|
// extends: "../second-config.json",
|
|
// compilerOptions: { baseUrl: join("..", "..") },
|
|
// });
|
|
expect(res).toEqual({
|
|
extends: "../second-config.json",
|
|
compilerOptions: { baseUrl: join("..", "..") },
|
|
});
|
|
});
|
|
|
|
it("should load a config with array extends and overwrite all options", () => {
|
|
const baseConfig1 = {
|
|
compilerOptions: { baseUrl: ".", paths: { foo: ["bar"] } },
|
|
};
|
|
const baseConfig1Path = join("/root", "base-config-1.json");
|
|
const baseConfig2 = { compilerOptions: { baseUrl: "." } };
|
|
const baseConfig2Path = join("/root", "dir1", "base-config-2.json");
|
|
const baseConfig3 = {
|
|
compilerOptions: { baseUrl: ".", paths: { foo: ["bar2"] } },
|
|
};
|
|
const baseConfig3Path = join("/root", "dir1", "dir2", "base-config-3.json");
|
|
const actualConfig = {
|
|
extends: [
|
|
"./base-config-1.json",
|
|
"./dir1/base-config-2.json",
|
|
"./dir1/dir2/base-config-3.json",
|
|
],
|
|
};
|
|
const actualConfigPath = join("/root", "tsconfig.json");
|
|
|
|
const res = loadTsconfig(
|
|
join("/root", "tsconfig.json"),
|
|
(path) =>
|
|
[
|
|
baseConfig1Path,
|
|
baseConfig2Path,
|
|
baseConfig3Path,
|
|
actualConfigPath,
|
|
].indexOf(path) >= 0,
|
|
(path) => {
|
|
if (path === baseConfig1Path) {
|
|
return JSON.stringify(baseConfig1);
|
|
}
|
|
if (path === baseConfig2Path) {
|
|
return JSON.stringify(baseConfig2);
|
|
}
|
|
if (path === baseConfig3Path) {
|
|
return JSON.stringify(baseConfig3);
|
|
}
|
|
if (path === actualConfigPath) {
|
|
return JSON.stringify(actualConfig);
|
|
}
|
|
return "";
|
|
}
|
|
);
|
|
|
|
expect(res).toEqual({
|
|
extends: [
|
|
"./base-config-1.json",
|
|
"./dir1/base-config-2.json",
|
|
"./dir1/dir2/base-config-3.json",
|
|
],
|
|
compilerOptions: {
|
|
baseUrl: join("dir1", "dir2"),
|
|
paths: { foo: ["bar2"] },
|
|
},
|
|
});
|
|
});
|
|
|
|
it("should load a config with array extends without .json extension", () => {
|
|
const baseConfig = {
|
|
compilerOptions: { baseUrl: ".", paths: { foo: ["bar"] } },
|
|
};
|
|
const baseConfigPath = join("/root", "base-config-1.json");
|
|
const actualConfig = { extends: ["./base-config-1"] };
|
|
const actualConfigPath = join("/root", "tsconfig.json");
|
|
|
|
const res = loadTsconfig(
|
|
join("/root", "tsconfig.json"),
|
|
(path) => [baseConfigPath, actualConfigPath].indexOf(path) >= 0,
|
|
(path) => {
|
|
if (path === baseConfigPath) {
|
|
return JSON.stringify(baseConfig);
|
|
}
|
|
if (path === actualConfigPath) {
|
|
return JSON.stringify(actualConfig);
|
|
}
|
|
return "";
|
|
}
|
|
);
|
|
|
|
expect(res).toEqual({
|
|
extends: ["./base-config-1"],
|
|
compilerOptions: {
|
|
baseUrl: ".",
|
|
paths: { foo: ["bar"] },
|
|
},
|
|
});
|
|
});
|
|
});
|