From 41d3e0da1cfb19fdb0ec6a4a98babb727eed7006 Mon Sep 17 00:00:00 2001 From: userquin Date: Mon, 13 Jan 2025 19:33:04 +0100 Subject: [PATCH] chore: include test --- test/__snapshots__/cjs-exports.test.ts.snap | 157 ++++++++++++++++++ test/cjs-exports.test.ts | 89 ++++++++++ .../mixed-declarations/build.config.ts | 12 ++ .../mixed-declarations/index.ts | 18 ++ .../mixed-declarations/package.json | 24 +++ .../reexport-types/build.config.ts | 12 ++ .../cjs-types-fixture/reexport-types/index.ts | 7 + .../reexport-types/package.json | 37 +++++ .../cjs-types-fixture/reexport-types/types.ts | 15 ++ 9 files changed, 371 insertions(+) create mode 100644 test/__snapshots__/cjs-exports.test.ts.snap create mode 100644 test/cjs-exports.test.ts create mode 100644 test/cjs-types-fixture/mixed-declarations/build.config.ts create mode 100644 test/cjs-types-fixture/mixed-declarations/index.ts create mode 100644 test/cjs-types-fixture/mixed-declarations/package.json create mode 100644 test/cjs-types-fixture/reexport-types/build.config.ts create mode 100644 test/cjs-types-fixture/reexport-types/index.ts create mode 100644 test/cjs-types-fixture/reexport-types/package.json create mode 100644 test/cjs-types-fixture/reexport-types/types.ts diff --git a/test/__snapshots__/cjs-exports.test.ts.snap b/test/__snapshots__/cjs-exports.test.ts.snap new file mode 100644 index 0000000..064dde3 --- /dev/null +++ b/test/__snapshots__/cjs-exports.test.ts.snap @@ -0,0 +1,157 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Node10 and Node16 Default Exports Types > Mixed Declaration Types 1`] = ` +[ + [ + "index.d.cts", + [ + { + "code": "export type { A, B, C, Options }", + "end": 259, + "exports": " A, B, C, Options", + "names": [ + "A", + "B", + "C", + "Options", + ], + "specifier": undefined, + "start": 227, + "type": "named", + }, + ], + [], + ], + [ + "index.d.ts", + [ + { + "code": "export type { A, B, C, Options }", + "end": 259, + "exports": " A, B, C, Options", + "names": [ + "A", + "B", + "C", + "Options", + ], + "specifier": undefined, + "start": 227, + "type": "named", + }, + ], + [], + ], +] +`; + +exports[`Node10 and Node16 Default Exports Types > Re-Export Types 1`] = ` +[ + [ + "index.d.cts", + [], + [ + { + "code": "export { A, B, CC as C, CC } from './types.cjs'", + "end": 86, + "exports": " A, B, CC as C, CC", + "names": [ + "A", + "B", + "C", + "CC", + ], + "specifier": "./types.cjs", + "start": 39, + "type": "named", + }, + { + "code": "export { Options }", + "end": 177, + "exports": " Options", + "name": "Options", + "names": [ + "Options", + ], + "specifier": undefined, + "start": 159, + "type": "named", + }, + ], + ], + [ + "index.d.ts", + [], + [ + { + "code": "export { A, B, CC as C, CC } from './types.js'", + "end": 84, + "exports": " A, B, CC as C, CC", + "names": [ + "A", + "B", + "C", + "CC", + ], + "specifier": "./types.js", + "start": 38, + "type": "named", + }, + { + "code": "export { Options }", + "end": 175, + "exports": " Options", + "name": "Options", + "names": [ + "Options", + ], + "specifier": undefined, + "start": 157, + "type": "named", + }, + ], + ], + [ + "types.d.cts", + [ + { + "code": "export type { A, B, C, C as CC, Options }", + "end": 200, + "exports": " A, B, C, C as CC, Options", + "names": [ + "A", + "B", + "C", + "CC", + "Options", + ], + "specifier": undefined, + "start": 159, + "type": "named", + }, + ], + [], + ], + [ + "types.d.ts", + [ + { + "code": "export type { A, B, C, C as CC, Options }", + "end": 200, + "exports": " A, B, C, C as CC, Options", + "names": [ + "A", + "B", + "C", + "CC", + "Options", + ], + "specifier": undefined, + "start": 159, + "type": "named", + }, + ], + [], + ], +] +`; diff --git a/test/cjs-exports.test.ts b/test/cjs-exports.test.ts new file mode 100644 index 0000000..5ffcb89 --- /dev/null +++ b/test/cjs-exports.test.ts @@ -0,0 +1,89 @@ +import { describe, it, expect } from "vitest"; +import { build } from "../src"; +import { resolve } from "pathe"; +import { fileURLToPath } from "node:url"; +import { readdir, readFile } from "node:fs/promises"; +import { type ESMExport, findExports, findTypeExports } from "mlly"; + +describe("Node10 and Node16 Default Exports Types", () => { + const dtsFiles = /\.d\.(c)?ts$/; + + async function readDtsFiles( + dist: string, + ): Promise<[name: string, types: ESMExport[], exports: ESMExport[]][]> { + const files = await readdir(dist).then((files) => + files.filter((f) => dtsFiles.test(f)).map((f) => [f, resolve(dist, f)]), + ); + return await Promise.all( + files.map(async ([name, path]) => { + const content = await readFile(path, "utf8"); + return [name, findTypeExports(content), findExports(content)]; + }), + ); + } + + it("Mixed Declaration Types", async () => { + const root = resolve( + fileURLToPath(import.meta.url), + "../cjs-types-fixture/mixed-declarations", + ); + await build(root, false); + const files = await readDtsFiles(resolve(root, "dist")); + expect(files).toHaveLength(2); + for (const [name, types, exports] of files) { + expect(exports).toHaveLength(0); + expect(types).toHaveLength(1); + expect( + types.find((e) => e.names.includes("default")), + `${name} should not have a default export`, + ).toBeUndefined(); + } + expect(files).toMatchSnapshot(); + }); + + it("Re-Export Types", async () => { + const warnings: string[] = []; + const root = resolve( + fileURLToPath(import.meta.url), + "../cjs-types-fixture/reexport-types", + ); + await build(root, false, { + hooks: { + "rollup:options": (_, options) => { + const _onwarn = options.onwarn; + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + options.onwarn = (warning, handler) => { + if (warning.code === "EMPTY_BUNDLE") { + warnings.push(warning.message); + return; + } + return _onwarn?.(warning, handler); + }; + }, + }, + }); + expect(warnings).toHaveLength(2); + expect(warnings[0]).toBe('Generated an empty chunk: "types".'); + expect(warnings[1]).toBe('Generated an empty chunk: "types".'); + const files = await readDtsFiles(resolve(root, "dist")); + expect(files).toHaveLength(4); + for (const [name, types, exports] of files) { + if (name.startsWith("types")) { + expect(exports).toHaveLength(0); + expect(types).toHaveLength(1); + expect( + types.find((e) => e.names.includes("default")), + `${name} should not have a default export`, + ).toBeUndefined(); + } else { + expect(exports).toHaveLength(2); + expect(types).toHaveLength(0); + expect( + exports.find((e) => e.names.includes("default")), + `${name} should not have a default export`, + ).toBeUndefined(); + } + } + expect(files).toMatchSnapshot(); + }); +}); diff --git a/test/cjs-types-fixture/mixed-declarations/build.config.ts b/test/cjs-types-fixture/mixed-declarations/build.config.ts new file mode 100644 index 0000000..dd704e2 --- /dev/null +++ b/test/cjs-types-fixture/mixed-declarations/build.config.ts @@ -0,0 +1,12 @@ +import { defineBuildConfig } from "../../../src"; + +export default defineBuildConfig({ + entries: ["./index.ts"], + declaration: true, + clean: true, + // avoid exit code 1 on warnings + failOnWarn: false, + rollup: { + emitCJS: true, + }, +}); diff --git a/test/cjs-types-fixture/mixed-declarations/index.ts b/test/cjs-types-fixture/mixed-declarations/index.ts new file mode 100644 index 0000000..bd7ec01 --- /dev/null +++ b/test/cjs-types-fixture/mixed-declarations/index.ts @@ -0,0 +1,18 @@ +export interface A { + name: string; +} +export interface B { + name: string; +} +export interface C { + name: string; +} +export interface Options { + a?: A; + b?: B; + c?: C; +} + +export default function plugin(options: Options = {}): Options { + return options; +} diff --git a/test/cjs-types-fixture/mixed-declarations/package.json b/test/cjs-types-fixture/mixed-declarations/package.json new file mode 100644 index 0000000..0e11b3f --- /dev/null +++ b/test/cjs-types-fixture/mixed-declarations/package.json @@ -0,0 +1,24 @@ +{ + "name": "cjs-types-mixed-declarations-fixture", + "version": "0.0.0", + "private": "true", + "type": "module", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.d.mjs" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.d.cjs" + } + } + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ] +} diff --git a/test/cjs-types-fixture/reexport-types/build.config.ts b/test/cjs-types-fixture/reexport-types/build.config.ts new file mode 100644 index 0000000..17aaa78 --- /dev/null +++ b/test/cjs-types-fixture/reexport-types/build.config.ts @@ -0,0 +1,12 @@ +import { defineBuildConfig } from "../../../src"; + +export default defineBuildConfig({ + entries: ["./index.ts", "./types.ts"], + declaration: true, + clean: true, + // avoid exit code 1 on warnings + failOnWarn: false, + rollup: { + emitCJS: true, + }, +}); diff --git a/test/cjs-types-fixture/reexport-types/index.ts b/test/cjs-types-fixture/reexport-types/index.ts new file mode 100644 index 0000000..5cc1fd3 --- /dev/null +++ b/test/cjs-types-fixture/reexport-types/index.ts @@ -0,0 +1,7 @@ +import type { Options } from "./types"; + +export type * from "./types"; + +export default function plugin(options: Options = {}): Options { + return options; +} diff --git a/test/cjs-types-fixture/reexport-types/package.json b/test/cjs-types-fixture/reexport-types/package.json new file mode 100644 index 0000000..dd13071 --- /dev/null +++ b/test/cjs-types-fixture/reexport-types/package.json @@ -0,0 +1,37 @@ +{ + "name": "cjs-types-reexport-types-fixture", + "version": "0.0.0", + "private": "true", + "type": "module", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.d.mjs" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.d.cjs" + } + }, + "./types": { + "types": { + "import": "./dist/types.d.mts", + "require": "./dist/types.d.cts" + } + } + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "typesVersions": { + "*": { + "types": [ + "./dist/types.d.ts" + ] + } + }, + "files": [ + "dist" + ] +} diff --git a/test/cjs-types-fixture/reexport-types/types.ts b/test/cjs-types-fixture/reexport-types/types.ts new file mode 100644 index 0000000..50e075f --- /dev/null +++ b/test/cjs-types-fixture/reexport-types/types.ts @@ -0,0 +1,15 @@ +export interface A { + name: string; +} +export interface B { + name: string; +} +export interface C { + name: string; +} +export type { C as CC }; +export interface Options { + a?: A; + b?: B; + c?: C; +}