import { promises as fs } from "node:fs"; import { join, resolve } from "node:path"; import dedent from "dedent"; import * as esbuild from "esbuild"; import { afterEach, beforeEach, expect } from "vitest"; import { type TailwindPluginOptions, babelPlugin, getTailwindPlugins } from "../index"; export { name } from "../../package.json" with { type: "json" }; export const minCSS = (text: string) => esbuild.transformSync(text, { minify: true, loader: "css" }).code; const findByExt = (outputFiles: esbuild.OutputFile[], ext: string) => outputFiles.find(file => file.path.endsWith(ext))!; export function getBuild(name: string) { const folder = resolve(import.meta.dirname, "..", ".temp-" + name); async function write(path: string, content: string) { const resolved = join(folder, path); await fs.writeFile(resolved, content); return `./src/.temp-${name}/${path}`; } beforeEach(async () => { await fs.mkdir(folder, { recursive: true }); }); afterEach(async () => { await fs.rm(folder, { recursive: true, force: true }); }); return async function compileESBuild({ javascript, esbuild: esbuildOptions, expectFiles, ...options }: Omit & { esbuild?: esbuild.BuildOptions; javascript: string; expectFiles?: number; }) { const tailwind = getTailwindPlugins({ tailwindConfig: {}, ...options, }); const result = await esbuild.build({ bundle: true, write: false, external: [ "react", "react/jsx-runtime", "@emotion/css", "clsx", "tslib", "@aet/tailwind/classed", ], outdir: "dist", format: "esm", entryPoints: [await write("index.tsx", dedent(javascript))], plugins: [babelPlugin({ plugins: [tailwind.babel()] }), tailwind.esbuild()], ...esbuildOptions, }); const { errors, warnings, outputFiles } = result; expect(errors).toHaveLength(0); expect(warnings).toHaveLength(0); if (expectFiles != null) { expect(outputFiles).toHaveLength(expectFiles); } return { outputFiles: outputFiles!, files: new Proxy({} as Files, { get: (_, ext: string) => findByExt(outputFiles!, ext), }), }; }; } type Files = Record; export function matchSnapshot(files: Files, noCSS = false) { expect(files.js.text.replace(/\/\/ src.+\n/g, "").trim()).toMatchSnapshot(); if (!noCSS) { expect( files.css.text.replace(/\/\* babel-tailwind:[^*]+\*\/\n/g, "").trim() ).toMatchSnapshot(); } }