mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Report config file parsing diagnostics correctly with tsc --b (#36520)
* Refactor the test * Add tests for syntax errors in tsconfig not being reported * Report config file parsing diagnostics correctly Fixes #36515 * Fix errors in existing tests for unintended tsconfig parse errors * Fix lint
This commit is contained in:
@@ -107,6 +107,7 @@
|
||||
"unittests/services/textChanges.ts",
|
||||
"unittests/services/transpile.ts",
|
||||
"unittests/tsbuild/amdModulesWithOut.ts",
|
||||
"unittests/tsbuild/configFileErrors.ts",
|
||||
"unittests/tsbuild/containerOnlyReferenced.ts",
|
||||
"unittests/tsbuild/demo.ts",
|
||||
"unittests/tsbuild/emitDeclarationOnly.ts",
|
||||
@@ -116,7 +117,6 @@
|
||||
"unittests/tsbuild/inferredTypeFromTransitiveModule.ts",
|
||||
"unittests/tsbuild/javascriptProjectEmit.ts",
|
||||
"unittests/tsbuild/lateBoundSymbol.ts",
|
||||
"unittests/tsbuild/missingExtendedFile.ts",
|
||||
"unittests/tsbuild/moduleSpecifiers.ts",
|
||||
"unittests/tsbuild/noEmitOnError.ts",
|
||||
"unittests/tsbuild/outFile.ts",
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
namespace ts {
|
||||
describe("unittests:: tsbuild:: configFileErrors:: when tsconfig extends the missing file", () => {
|
||||
verifyTsc({
|
||||
scenario: "configFileErrors",
|
||||
subScenario: "when tsconfig extends the missing file",
|
||||
fs: () => loadProjectFromDisk("tests/projects/missingExtendedConfig"),
|
||||
commandLineArgs: ["--b", "/src/tsconfig.json"],
|
||||
});
|
||||
});
|
||||
|
||||
describe("unittests:: tsbuild:: configFileErrors:: reports syntax errors in config file", () => {
|
||||
verifyTscIncrementalEdits({
|
||||
scenario: "configFileErrors",
|
||||
subScenario: "reports syntax errors in config file",
|
||||
fs: () => loadProjectFromFiles({
|
||||
"/src/a.ts": "export function foo() { }",
|
||||
"/src/b.ts": "export function bar() { }",
|
||||
"/src/tsconfig.json": Utils.dedent`
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
},
|
||||
"files": [
|
||||
"a.ts"
|
||||
"b.ts"
|
||||
]
|
||||
}`
|
||||
}),
|
||||
commandLineArgs: ["--b", "/src/tsconfig.json"],
|
||||
incrementalScenarios: [
|
||||
{
|
||||
buildKind: BuildKind.IncrementalDtsUnchanged,
|
||||
modifyFs: fs => replaceText(fs, "/src/tsconfig.json", ",", `,
|
||||
"declaration": true,`),
|
||||
subScenario: "reports syntax errors after change to config file"
|
||||
},
|
||||
{
|
||||
buildKind: BuildKind.IncrementalDtsUnchanged,
|
||||
modifyFs: fs => appendText(fs, "/src/a.ts", "export function fooBar() { }"),
|
||||
subScenario: "reports syntax errors after change to ts file"
|
||||
},
|
||||
noChangeRun,
|
||||
{
|
||||
buildKind: BuildKind.IncrementalDtsChange,
|
||||
modifyFs: fs => fs.writeFileSync(
|
||||
"/src/tsconfig.json",
|
||||
JSON.stringify({
|
||||
compilerOptions: { composite: true, declaration: true },
|
||||
files: ["a.ts", "b.ts"]
|
||||
})
|
||||
),
|
||||
subScenario: "builds after fixing config file errors"
|
||||
},
|
||||
]
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,18 +1,9 @@
|
||||
namespace ts {
|
||||
describe("unittests:: tsbuild:: when containerOnly project is referenced", () => {
|
||||
let projFs: vfs.FileSystem;
|
||||
before(() => {
|
||||
projFs = loadProjectFromDisk("tests/projects/containerOnlyReferenced");
|
||||
});
|
||||
|
||||
after(() => {
|
||||
projFs = undefined!; // Release the contents
|
||||
});
|
||||
|
||||
verifyTscIncrementalEdits({
|
||||
scenario: "containerOnlyReferenced",
|
||||
subScenario: "verify that subsequent builds after initial build doesnt build anything",
|
||||
fs: () => projFs,
|
||||
fs: () => loadProjectFromDisk("tests/projects/containerOnlyReferenced"),
|
||||
commandLineArgs: ["--b", "/src", "--verbose"],
|
||||
incrementalScenarios: [noChangeRun]
|
||||
});
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace ts {
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": null
|
||||
"outDir": null,
|
||||
"composite": true
|
||||
},
|
||||
"include": ["index.ts", "obj.json"]
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
namespace ts {
|
||||
describe("unittests:: tsbuild:: lateBoundSymbol:: interface is merged and contains late bound member", () => {
|
||||
let projFs: vfs.FileSystem;
|
||||
before(() => {
|
||||
projFs = loadProjectFromDisk("tests/projects/lateBoundSymbol");
|
||||
});
|
||||
after(() => {
|
||||
projFs = undefined!; // Release the contents
|
||||
});
|
||||
|
||||
verifyTscIncrementalEdits({
|
||||
subScenario: "interface is merged and contains late bound member",
|
||||
fs: () => projFs,
|
||||
fs: () => loadProjectFromDisk("tests/projects/lateBoundSymbol"),
|
||||
scenario: "lateBoundSymbol",
|
||||
commandLineArgs: ["--b", "/src/tsconfig.json", "--verbose"],
|
||||
incrementalScenarios: [{
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
namespace ts {
|
||||
describe("unittests:: tsbuild:: when tsconfig extends the missing file", () => {
|
||||
let projFs: vfs.FileSystem;
|
||||
before(() => {
|
||||
projFs = loadProjectFromDisk("tests/projects/missingExtendedConfig");
|
||||
});
|
||||
after(() => {
|
||||
projFs = undefined!;
|
||||
});
|
||||
verifyTsc({
|
||||
scenario: "missingExtendedConfig",
|
||||
subScenario: "when tsconfig extends the missing file",
|
||||
fs: () => projFs,
|
||||
commandLineArgs: ["--b", "/src/tsconfig.json"],
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,16 +1,9 @@
|
||||
namespace ts {
|
||||
describe("unittests:: tsbuild - with noEmitOnError", () => {
|
||||
let projFs: vfs.FileSystem;
|
||||
before(() => {
|
||||
projFs = loadProjectFromDisk("tests/projects/noEmitOnError");
|
||||
});
|
||||
after(() => {
|
||||
projFs = undefined!;
|
||||
});
|
||||
verifyTsc({
|
||||
scenario: "noEmitOnError",
|
||||
subScenario: "has empty files diagnostic when files is empty and no references are provided",
|
||||
fs: () => projFs,
|
||||
fs: () => loadProjectFromDisk("tests/projects/noEmitOnError"),
|
||||
commandLineArgs: ["--b", "/src/tsconfig.json"],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -453,7 +453,7 @@ namespace ts {
|
||||
|
||||
function stripInternalOfThird(fs: vfs.FileSystem) {
|
||||
replaceText(fs, sources[project.third][source.config], `"declaration": true,`, `"declaration": true,
|
||||
"stripInternal": true`);
|
||||
"stripInternal": true,`);
|
||||
}
|
||||
|
||||
function stripInternalScenario(fs: vfs.FileSystem, removeCommentsDisabled?: boolean, jsDocStyle?: boolean) {
|
||||
|
||||
@@ -71,19 +71,10 @@ export default hello.hello`);
|
||||
});
|
||||
|
||||
describe("unittests:: tsbuild:: with resolveJsonModule option on project importJsonFromProjectReference", () => {
|
||||
let projFs: vfs.FileSystem;
|
||||
before(() => {
|
||||
projFs = loadProjectFromDisk("tests/projects/importJsonFromProjectReference");
|
||||
});
|
||||
|
||||
after(() => {
|
||||
projFs = undefined!; // Release the contents
|
||||
});
|
||||
|
||||
verifyTscIncrementalEdits({
|
||||
scenario: "resolveJsonModule",
|
||||
subScenario: "importing json module from project reference",
|
||||
fs: () => projFs,
|
||||
fs: () => loadProjectFromDisk("tests/projects/importJsonFromProjectReference"),
|
||||
commandLineArgs: ["--b", "src/tsconfig.json", "--verbose"],
|
||||
incrementalScenarios: [noChangeRun]
|
||||
});
|
||||
|
||||
@@ -1266,8 +1266,7 @@ const a = {
|
||||
),
|
||||
changes: [
|
||||
sys => {
|
||||
const content = sys.readFile(`${projectsLocation}/reexport/src/pure/session.ts`)!;
|
||||
sys.writeFile(`${projectsLocation}/reexport/src/pure/session.ts`, content.replace("// ", ""));
|
||||
replaceFileText(sys, `${projectsLocation}/reexport/src/pure/session.ts`, "// ", "");
|
||||
sys.checkTimeoutQueueLengthAndRun(1); // build src/pure
|
||||
sys.checkTimeoutQueueLengthAndRun(1); // build src/main
|
||||
sys.checkTimeoutQueueLengthAndRun(1); // build src
|
||||
@@ -1275,8 +1274,7 @@ const a = {
|
||||
return "Introduce error";
|
||||
},
|
||||
sys => {
|
||||
const content = sys.readFile(`${projectsLocation}/reexport/src/pure/session.ts`)!;
|
||||
sys.writeFile(`${projectsLocation}/reexport/src/pure/session.ts`, content.replace("bar: ", "// bar: "));
|
||||
replaceFileText(sys, `${projectsLocation}/reexport/src/pure/session.ts`, "bar: ", "// bar: ");
|
||||
sys.checkTimeoutQueueLengthAndRun(1); // build src/pure
|
||||
sys.checkTimeoutQueueLengthAndRun(1); // build src/main
|
||||
sys.checkTimeoutQueueLengthAndRun(1); // build src
|
||||
@@ -1286,4 +1284,63 @@ const a = {
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
describe("unittests:: tsbuild:: watchMode:: configFileErrors:: reports syntax errors in config file", () => {
|
||||
verifyTscWatch({
|
||||
scenario: "configFileErrors",
|
||||
subScenario: "reports syntax errors in config file",
|
||||
sys: () => createWatchedSystem(
|
||||
[
|
||||
{ path: `${projectRoot}/a.ts`, content: "export function foo() { }" },
|
||||
{ path: `${projectRoot}/b.ts`, content: "export function bar() { }" },
|
||||
{
|
||||
path: `${projectRoot}/tsconfig.json`,
|
||||
content: Utils.dedent`
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
},
|
||||
"files": [
|
||||
"a.ts"
|
||||
"b.ts"
|
||||
]
|
||||
}`
|
||||
},
|
||||
libFile
|
||||
],
|
||||
{ currentDirectory: projectRoot }
|
||||
),
|
||||
commandLineArgs: ["--b", "-w"],
|
||||
changes: [
|
||||
sys => {
|
||||
replaceFileText(sys, `${projectRoot}/tsconfig.json`, ",", `,
|
||||
"declaration": true,`);
|
||||
sys.checkTimeoutQueueLengthAndRun(1); // build the project
|
||||
sys.checkTimeoutQueueLength(0);
|
||||
return "reports syntax errors after change to config file";
|
||||
},
|
||||
sys => {
|
||||
replaceFileText(sys, `${projectRoot}/a.ts`, "foo", "fooBar");
|
||||
sys.checkTimeoutQueueLengthAndRun(1); // build the project
|
||||
sys.checkTimeoutQueueLength(0);
|
||||
return "reports syntax errors after change to ts file";
|
||||
},
|
||||
sys => {
|
||||
replaceFileText(sys, `${projectRoot}/tsconfig.json`, "", "");
|
||||
sys.checkTimeoutQueueLengthAndRun(1); // build the project
|
||||
sys.checkTimeoutQueueLength(0);
|
||||
return "reports error when there is no change to tsconfig file";
|
||||
},
|
||||
sys => {
|
||||
sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({
|
||||
compilerOptions: { composite: true, declaration: true },
|
||||
files: ["a.ts", "b.ts"]
|
||||
}));
|
||||
sys.checkTimeoutQueueLengthAndRun(1); // build the project
|
||||
sys.checkTimeoutQueueLength(0);
|
||||
return "builds after fixing config file errors";
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -417,4 +417,9 @@ namespace ts.tscWatch {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function replaceFileText(sys: WatchedSystem, file: string, searchValue: string | RegExp, replaceValue: string) {
|
||||
const content = Debug.assertDefined(sys.readFile(file));
|
||||
sys.writeFile(file, content.replace(searchValue, replaceValue));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1086,8 +1086,7 @@ export function two() {
|
||||
});
|
||||
|
||||
function changeParameterTypeOfBFile(sys: WatchedSystem, parameterName: string, toType: string) {
|
||||
const oldContent = sys.readFile(`${projectRoot}/b.ts`)!;
|
||||
sys.writeFile(`${projectRoot}/b.ts`, oldContent.replace(new RegExp(`${parameterName}\: [a-z]*`), `${parameterName}: ${toType}`));
|
||||
replaceFileText(sys, `${projectRoot}/b.ts`, new RegExp(`${parameterName}\: [a-z]*`), `${parameterName}: ${toType}`);
|
||||
sys.runQueuedTimeoutCallbacks();
|
||||
return `Changed ${parameterName} type to ${toType}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user