Skip to content

Commit 172c32f

Browse files
committed
test: add a syntactic error, refactor a bit
- add a file to `errors` with a syntax error in it - apparently this does throw syntax err, but does not cause `emitSkipped: true`... odd... - so may need another test for that... - `abortOnError: false` / `check: false` both cause Rollup to error out instead - rename `errors/index` -> `errors/semantic` since we have different kinds now - change the `include` to only take a single file, so that we don't unnecessarily generate declarations or type-check other error files - refactor(test): rewrite `genBundle` in both files to take a relative path to a file - simplifies the `emitDeclarationOnly` test as we can now just reuse the local `genBundle` instead of calling `helpers.genBundle` directly - use the same structure for `errors`'s different files as well - add a slightly hacky workaround to get `fs.remove` to not error - seems to be a race condition due to the thrown errors and file handles not being closed immediately on throw (seems like they close during garbage collection instead?) - see linked issue in the comment; workaround is to just give it some more time - not sure that there is a true fix for this, since an improper close may cause indeterminate behavior
1 parent 7abbe38 commit 172c32f

File tree

4 files changed

+44
-31
lines changed

4 files changed

+44
-31
lines changed

__tests__/integration/errors.spec.ts

+28-13
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,53 @@ const local = (x: string) => path.resolve(__dirname, x);
1313
const cacheRoot = local("__temp/errors/rpt2-cache"); // don't use the one in node_modules
1414
const onwarn = jest.fn();
1515

16-
afterAll(() => fs.remove(cacheRoot));
16+
afterAll(async () => {
17+
// workaround: there seems to be some race condition causing fs.remove to fail, so give it a sec first (c.f. https://github.com/jprichardson/node-fs-extra/issues/532)
18+
await new Promise(resolve => setTimeout(resolve, 1000));
19+
await fs.remove(cacheRoot);
20+
});
1721

18-
async function genBundle(extraOpts?: RPT2Options) {
22+
async function genBundle(relInput: string, extraOpts?: RPT2Options) {
23+
const input = local(`fixtures/errors/${relInput}`)
1924
return helpers.genBundle({
20-
input: local("fixtures/errors/index.ts"),
25+
input,
2126
tsconfig: local("fixtures/errors/tsconfig.json"),
2227
cacheRoot,
23-
extraOpts,
28+
extraOpts: { include: [input], ...extraOpts }, // only include the input itself, not other error files (to only generate types and type-check the one file)
2429
onwarn,
2530
});
2631
}
2732

28-
test("integration - errors", async () => {
33+
test("integration - tsconfig errors", async () => {
2934
// TODO: move to parse-tsconfig unit tests?
30-
expect(genBundle({
31-
tsconfig: 'non-existent-tsconfig',
35+
expect(genBundle("semantic.ts", {
36+
tsconfig: "non-existent-tsconfig",
3237
})).rejects.toThrow("rpt2: failed to open 'undefined'"); // FIXME: bug: this should be "non-existent-tsconfig", not "undefined"
38+
});
3339

34-
expect(genBundle()).rejects.toThrow(`semantic error TS2322: ${red("Type 'string' is not assignable to type 'number'.")}`);
40+
test("integration - semantic error", async () => {
41+
expect(genBundle("semantic.ts")).rejects.toThrow(`semantic error TS2322: ${red("Type 'string' is not assignable to type 'number'.")}`);
3542
});
3643

37-
test("integration - errors - abortOnError: false / check: false", async () => {
44+
test("integration - semantic error - abortOnError: false / check: false", async () => {
3845
// either warning or not type-checking should result in the same bundle
39-
const { output } = await genBundle({ abortOnError: false });
40-
const { output: output2 } = await genBundle({ check: false });
46+
const { output } = await genBundle("semantic.ts", { abortOnError: false });
47+
const { output: output2 } = await genBundle("semantic.ts", { check: false });
4148
expect(output).toEqual(output2);
4249

4350
expect(output[0].fileName).toEqual("index.js");
44-
expect(output[1].fileName).toEqual("index.d.ts");
45-
expect(output[2].fileName).toEqual("index.d.ts.map");
51+
expect(output[1].fileName).toEqual("semantic.d.ts");
52+
expect(output[2].fileName).toEqual("semantic.d.ts.map");
4653
expect(output.length).toEqual(3); // no other files
4754
expect(onwarn).toBeCalledTimes(1);
4855
});
4956

57+
test("integration - syntax error", () => {
58+
expect(genBundle("syntax.ts")).rejects.toThrow(`syntax error TS1005: ${red("';' expected.")}`);
59+
});
5060

61+
test("integration - syntax error - abortOnError: false / check: false", () => {
62+
const err = "Unexpected token (Note that you need plugins to import files that are not JavaScript)";
63+
expect(genBundle("syntax.ts", { abortOnError: false })).rejects.toThrow(err);
64+
expect(genBundle("syntax.ts", { check: false })).rejects.toThrow(err);
65+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const incorrectSyntax => {
2+
return "a + b";
3+
}

__tests__/integration/no-errors.spec.ts

+13-18
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,21 @@ const cacheRoot = local("__temp/no-errors/rpt2-cache"); // don't use the one in
1313

1414
afterAll(() => fs.remove(cacheRoot));
1515

16-
async function genBundle(extraOpts?: RPT2Options) {
16+
async function genBundle(relInput: string, extraOpts?: RPT2Options) {
1717
return helpers.genBundle({
18-
input: local("fixtures/no-errors/index.ts"),
18+
input: local(`fixtures/no-errors/${relInput}`),
1919
tsconfig: local("fixtures/no-errors/tsconfig.json"),
2020
cacheRoot,
2121
extraOpts,
2222
});
2323
}
2424

2525
test("integration - no errors", async () => {
26-
const { output } = await genBundle({ clean: true });
26+
const { output } = await genBundle("index.ts", { clean: true });
2727

2828
// populate the cache
29-
await genBundle();
30-
const { output: outputWithCache } = await genBundle();
29+
await genBundle("index.ts");
30+
const { output: outputWithCache } = await genBundle("index.ts");
3131
expect(output).toEqual(outputWithCache);
3232

3333
expect(output[0].fileName).toEqual("index.js");
@@ -45,7 +45,7 @@ test("integration - no errors", async () => {
4545

4646
test("integration - no errors - no declaration maps", async () => {
4747
const noDeclarationMaps = { compilerOptions: { declarationMap: false } };
48-
const { output } = await genBundle({
48+
const { output } = await genBundle("index.ts", {
4949
tsconfigOverride: noDeclarationMaps,
5050
clean: true,
5151
});
@@ -60,7 +60,7 @@ test("integration - no errors - no declaration maps", async () => {
6060

6161
test("integration - no errors - no declarations", async () => {
6262
const noDeclarations = { compilerOptions: { declaration: false, declarationMap: false } };
63-
const { output } = await genBundle({
63+
const { output } = await genBundle("index.ts", {
6464
tsconfigOverride: noDeclarations,
6565
clean: true,
6666
});
@@ -70,17 +70,12 @@ test("integration - no errors - no declarations", async () => {
7070
});
7171

7272
test("integration - no errors - allowJs + emitDeclarationOnly", async () => {
73-
const { output } = await helpers.genBundle({
74-
input: local("fixtures/no-errors/some-js-import.js"),
75-
tsconfig: local("fixtures/no-errors/tsconfig.json"),
76-
cacheRoot,
77-
extraOpts: {
78-
include: ["**/*.js"],
79-
tsconfigOverride: {
80-
compilerOptions: {
81-
allowJs: true,
82-
emitDeclarationOnly: true,
83-
},
73+
const { output } = await genBundle("some-js-import.js", {
74+
include: ["**/*.js"],
75+
tsconfigOverride: {
76+
compilerOptions: {
77+
allowJs: true,
78+
emitDeclarationOnly: true,
8479
},
8580
},
8681
});

0 commit comments

Comments
 (0)