Skip to content

Commit

Permalink
add test for type-only file with type errors
Browse files Browse the repository at this point in the history
- now that the integration tests exist, we can actually test this scenario

- refactor: give each test their own `onwarn` mock when necessary
  - while `restoreMocks` is set in the `jest.config.js`, Jest apparently has poor isolation of mocks: jestjs/jest#7136
    - if two tests ran in parallel, `onwarn` was getting results from both, screwing up the `toBeCalledTimes` number
  - couldn't get the syntax error to work with `toBeCalledTimes` either
    - if no mock is given, it _does_ print warnings, but if a mock is given, it doesn't print, yet isn't called?
      - I think the mock is getting screwed up by the error being thrown here; maybe improperly saved or something
  • Loading branch information
agilgur5 committed Jul 7, 2022
1 parent 3a027ca commit 01373c1
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 6 deletions.
44 changes: 38 additions & 6 deletions __tests__/integration/errors.spec.ts
@@ -1,4 +1,5 @@
import { jest, afterAll, test, expect } from "@jest/globals";
import { Mock } from "jest-mock"
import * as path from "path";
import { normalizePath as normalize } from "@rollup/pluginutils";
import * as fs from "fs-extra";
Expand All @@ -12,15 +13,14 @@ jest.setTimeout(15000);

const local = (x: string) => path.resolve(__dirname, x);
const cacheRoot = local("__temp/errors/rpt2-cache"); // don't use the one in node_modules
const onwarn = jest.fn();

afterAll(async () => {
// 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)
await new Promise(resolve => setTimeout(resolve, 1000));
await fs.remove(cacheRoot);
});

async function genBundle(relInput: string, extraOpts?: RPT2Options) {
async function genBundle(relInput: string, extraOpts?: RPT2Options, onwarn?: Mock) {
const input = normalize(local(`fixtures/errors/${relInput}`));
return helpers.genBundle({
input,
Expand All @@ -43,9 +43,10 @@ test("integration - semantic error", async () => {
});

test("integration - semantic error - abortOnError: false / check: false", async () => {
const onwarn = jest.fn();
// either warning or not type-checking should result in the same bundle
const { output } = await genBundle("semantic.ts", { abortOnError: false });
const { output: output2 } = await genBundle("semantic.ts", { check: false });
const { output } = await genBundle("semantic.ts", { abortOnError: false }, onwarn);
const { output: output2 } = await genBundle("semantic.ts", { check: false }, onwarn);
expect(output).toEqual(output2);

expect(output[0].fileName).toEqual("index.js");
Expand All @@ -60,7 +61,38 @@ test("integration - syntax error", () => {
});

test("integration - syntax error - abortOnError: false / check: false", () => {
const onwarn = jest.fn();
const err = "Unexpected token (Note that you need plugins to import files that are not JavaScript)";
expect(genBundle("syntax.ts", { abortOnError: false })).rejects.toThrow(err);
expect(genBundle("syntax.ts", { check: false })).rejects.toThrow(err);
expect(genBundle("syntax.ts", { abortOnError: false }, onwarn)).rejects.toThrow(err);
expect(genBundle("syntax.ts", { check: false }, onwarn)).rejects.toThrow(err);
});

const typeOnlyIncludes = ["**/import-type-error.ts", "**/type-only-import-with-error.ts"];

test("integration - type-only import error", () => {
expect(genBundle("import-type-error.ts", {
include: typeOnlyIncludes,
})).rejects.toThrow("Property 'nonexistent' does not exist on type 'someObj'.");
});

test("integration - type-only import error - abortOnError: false / check: false", async () => {
const onwarn = jest.fn();
// either warning or not type-checking should result in the same bundle
const { output } = await genBundle("import-type-error.ts", {
include: typeOnlyIncludes,
abortOnError: false,
}, onwarn);
const { output: output2 } = await genBundle("import-type-error.ts", {
include: typeOnlyIncludes,
check: false,
}, onwarn);
expect(output).toEqual(output2);

expect(output[0].fileName).toEqual("index.js");
expect(output[1].fileName).toEqual("import-type-error.d.ts");
expect(output[2].fileName).toEqual("import-type-error.d.ts.map");
expect(output[3].fileName).toEqual("type-only-import-with-error.d.ts");
expect(output[4].fileName).toEqual("type-only-import-with-error.d.ts.map");
expect(output.length).toEqual(5); // no other files
expect(onwarn).toBeCalledTimes(1);
});
8 changes: 8 additions & 0 deletions __tests__/integration/fixtures/errors/import-type-error.ts
@@ -0,0 +1,8 @@
// this file has no errors itself; it is used an entry file to test an error in a type-only import

export type { typeError } from "./type-only-import-with-error";

// some code so this file isn't empty
export function sum(a: number, b: number) {
return a + b;
}
@@ -0,0 +1,2 @@
type someObj = {};
export type typeError = someObj['nonexistent'];

0 comments on commit 01373c1

Please sign in to comment.