Add tests and optimize spread

This commit is contained in:
Alex
2024-07-06 14:48:26 -04:00
parent d4404f7ae2
commit a05b1222b5
14 changed files with 432 additions and 191 deletions

View File

@ -0,0 +1,46 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`attr > supports conditional expression in "css" attribute 1`] = `
"// src/.temp-attr/index.tsx
import { jsx } from "react/jsx-runtime";
function Hello({
isCenter
}) {
return /* @__PURE__ */ jsx("div", { className: isCenter ? "tw-gqn2k6" : void 0, children: "Hello, world!" });
}
export {
Hello
};
"
`;
exports[`attr > supports conditional expression in "css" attribute 2`] = `
"/* babel-tailwind:/Users/aet/Documents/Git/babel-tailwind/src/.temp-attr/index.css */
.tw-gqn2k6 {
text-align: center;
}
"
`;
exports[`attr > supports grouped array css attribute 1`] = `
"// src/.temp-attr/index.tsx
import { jsx } from "react/jsx-runtime";
function Hello() {
return /* @__PURE__ */ jsx("div", { className: "tw-gqn2k6 tw-1qtvvjy", children: "Hello, world!" });
}
export {
Hello
};
"
`;
exports[`attr > supports grouped array css attribute 2`] = `
"/* babel-tailwind:/Users/aet/Documents/Git/babel-tailwind/src/.temp-attr/index.css */
.tw-gqn2k6 {
text-align: center;
}
.tw-1qtvvjy:hover {
font-weight: 600;
}
"
`;

View File

@ -0,0 +1,21 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`options > supports custom jsxAttributeName 1`] = `
"// src/.temp-options/index.tsx
import { jsx } from "react/jsx-runtime";
function Hello() {
return /* @__PURE__ */ jsx("div", { className: "tw-gqn2k6", children: "Hello, world!" });
}
export {
Hello
};
"
`;
exports[`options > supports custom jsxAttributeName 2`] = `
"/* babel-tailwind:/Users/aet/Documents/Git/babel-tailwind/src/.temp-options/index.css */
.tw-gqn2k6 {
text-align: center;
}
"
`;

View File

@ -0,0 +1,51 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`spread > supports spread attribute in "css" attribute (2) 1`] = `
"// src/.temp-spread/index.tsx
import { cx as _cx } from "@emotion/css";
import * as _tslib from "tslib";
import { jsx } from "react/jsx-runtime";
function Hello(props) {
props = {
...props,
className: "text-center"
};
return /* @__PURE__ */ jsx("div", { ..._tslib.__rest(props, ["className"]), className: _cx("tw-gqn2k6", props.className), children: "Hello, world!" });
}
export {
Hello
};
"
`;
exports[`spread > supports spread attribute in "css" attribute (2) 2`] = `
"/* babel-tailwind:/Users/aet/Documents/Git/babel-tailwind/src/.temp-spread/index.css */
.tw-gqn2k6 {
text-align: center;
}
"
`;
exports[`spread > supports spread attribute in "css" attribute 1`] = `
"// src/.temp-spread/index.tsx
import { cx as _cx } from "@emotion/css";
import { jsx } from "react/jsx-runtime";
function Hello({
className: _className,
...props
}) {
return /* @__PURE__ */ jsx("div", { ...props, className: _cx("tw-gqn2k6", _className), children: "Hello, world!" });
}
export {
Hello
};
"
`;
exports[`spread > supports spread attribute in "css" attribute 2`] = `
"/* babel-tailwind:/Users/aet/Documents/Git/babel-tailwind/src/.temp-spread/index.css */
.tw-gqn2k6 {
text-align: center;
}
"
`;

View File

@ -0,0 +1,56 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`babel-tailwind > supports .hover, .focus, .active, .group-hover, .group-focus, .group-active 1`] = `
"// babel-tailwind:/Users/aet/Documents/Git/babel-tailwind/src/.temp-styleObject/index.tailwindStyle.js
var tw_12x0ow0 = {
"&:focus": {
fontWeight: "700"
}
};
var tw_m4tg46 = {
"&:active": {
fontWeight: "300"
}
};
var tw_rqrjo3 = {
"&:hover:active": {
padding: "0.5rem"
}
};
var tw_1qtvvjy = {
"&:hover": {
fontWeight: "600"
}
};
// src/.temp-styleObject/index.tsx
var style = [tw_1qtvvjy, tw_12x0ow0, tw_m4tg46, tw_rqrjo3];
export {
style
};
"
`;
exports[`babel-tailwind > supports conversion into CSSProperties 1`] = `
"// babel-tailwind:/Users/aet/Documents/Git/babel-tailwind/src/.temp-styleObject/index.tailwindStyle.js
var tw_kt12th = {
padding: "0.5rem",
textAlign: "center",
"&:hover": {
fontWeight: "600"
},
"@media (min-width: 640px)": {
padding: "0.25rem"
}
};
// src/.temp-styleObject/index.tsx
import { jsx } from "react/jsx-runtime";
function Hello() {
return /* @__PURE__ */ jsx("div", { style: tw_kt12th, children: "Hello, world!" });
}
export {
Hello
};
"
`;

View File

@ -0,0 +1,44 @@
import { describe, expect, it } from "vitest";
import { getBuild } from "./utils";
describe("attr", () => {
const compileESBuild = getBuild("attr");
it("supports grouped array css attribute", async () => {
const { files } = await compileESBuild({
clsx: "emotion",
expectFiles: 2,
javascript: /* tsx */ `
export function Hello() {
return (
<div css={["text-center", { hover: "font-semibold" }]}>
Hello, world!
</div>
);
}
`,
});
expect(files.js.text).toMatchSnapshot();
expect(files.css.text).toMatchSnapshot();
});
it('supports conditional expression in "css" attribute', async () => {
const { files } = await compileESBuild({
clsx: "emotion",
expectFiles: 2,
javascript: /* tsx */ `
export function Hello({ isCenter }) {
return (
<div css={isCenter ? "text-center" : undefined}>
Hello, world!
</div>
);
}
`,
});
expect(files.js.text).toMatchSnapshot();
expect(files.css.text).toMatchSnapshot();
});
});

View File

@ -0,0 +1,50 @@
/* eslint-disable unicorn/string-content */
import { describe, expect, it } from "vitest";
import { getClassName } from "../index";
import { getBuild } from "./utils";
describe("merges with existing className attribute", () => {
const compileESBuild = getBuild("merge");
it("string literal", async () => {
const { files } = await compileESBuild({
clsx: "emotion",
expectFiles: 2,
javascript: /* tsx */ `
export function Hello() {
return (
<div className="text-center" css="text-center">
Hello, world!
</div>
);
}
`,
});
const clsName = getClassName("text-center");
expect(files.js.text).toContain(`className: "text-center ${clsName}"`);
expect(files.css.text).toMatch(`.${clsName} {\n text-align: center;\n}`);
});
it("existing function", async () => {
const { files } = await compileESBuild({
clsx: "emotion",
expectFiles: 2,
javascript: /* tsx */ `
export function Hello() {
return (
<div className={({ isEntering }) => isEntering ? "enter" : "exit"} css="text-center">
Hello, world!
</div>
);
}
`,
});
const clsName = getClassName("text-center");
expect(files.js.text).toContain(
`className: ({\n isEntering\n }) => _cx(isEntering ? "enter" : "exit", "${clsName}")`
);
expect(files.css.text).toMatch(`.${clsName} {\n text-align: center;\n}`);
});
});

View File

@ -0,0 +1,44 @@
import { describe, expect, it } from "vitest";
import { getBuild } from "./utils";
describe("options", () => {
const compileESBuild = getBuild("options");
it("supports custom jsxAttributeName", async () => {
const { files } = await compileESBuild({
clsx: "emotion",
jsxAttributeName: "tw",
expectFiles: 2,
javascript: /* tsx */ `
export function Hello() {
return (
<div tw="text-center">
Hello, world!
</div>
);
}
`,
});
expect(files.js.text).toMatchSnapshot();
expect(files.css.text).toMatchSnapshot();
});
it("does not remove the attribute if `preserveAttribute` is true", async () => {
const { files } = await compileESBuild({
clsx: "emotion",
jsxAttributeAction: "preserve",
expectFiles: 2,
javascript: /* tsx */ `
export function Hello() {
return (
<div css="text-center">
Hello, world!
</div>
);
}
`,
});
expect(files.js.text).toContain(`css: "text-center"`);
});
});

View File

@ -0,0 +1,46 @@
/* eslint-disable unicorn/string-content */
import { describe, expect, it } from "vitest";
import { getBuild } from "./utils";
describe("spread", () => {
const compileESBuild = getBuild("spread");
it('supports spread attribute in "css" attribute', async () => {
const { files } = await compileESBuild({
clsx: "emotion",
expectFiles: 2,
javascript: /* tsx */ `
export function Hello(props) {
return (
<div css="text-center" {...props}>
Hello, world!
</div>
);
}
`,
});
expect(files.js.text).toMatchSnapshot();
expect(files.css.text).toMatchSnapshot();
});
it('supports spread attribute in "css" attribute (2)', async () => {
const { files } = await compileESBuild({
clsx: "emotion",
expectFiles: 2,
javascript: /* tsx */ `
export function Hello(props) {
props = { ...props, className: "text-center" };
return (
<div css="text-center" {...props}>
Hello, world!
</div>
);
}
`,
});
expect(files.js.text).toMatchSnapshot();
expect(files.css.text).toMatchSnapshot();
});
});

View File

@ -1,6 +1,5 @@
import { describe, expect, it } from "vitest";
import { getBuild } from "./utils";
import { getClassName } from "../index";
describe("babel-tailwind", () => {
const compileESBuild = getBuild("styleObject");
@ -22,25 +21,7 @@ describe("babel-tailwind", () => {
`,
});
const clsName = getClassName("p-2 text-center hover:font-semibold sm:p-1").replace(
/^tw-/,
"tw_"
);
expect(files.js.text).toContain(
[
`var ${clsName} = {`,
' padding: "0.5rem",',
' textAlign: "center",',
' "&:hover": {',
' fontWeight: "600"',
" },",
' "@media (min-width: 640px)": {',
' padding: "0.25rem"',
" }",
"}",
].join("\n")
);
expect(files.js.text).toContain(`style: ${clsName}`);
expect(files.js.text).toMatchSnapshot();
});
it("supports .hover, .focus, .active, .group-hover, .group-focus, .group-active", async () => {
@ -59,34 +40,6 @@ describe("babel-tailwind", () => {
`,
});
const semibold = getClassName("hover:font-semibold").replace(/^tw-/, "tw_");
const bold = getClassName("focus:font-bold").replace(/^tw-/, "tw_");
const light = getClassName("active:font-light").replace(/^tw-/, "tw_");
const p = getClassName("active:hover:p-2").replace(/^tw-/, "tw_");
expect(files.js.text).toContain(
[
`var ${bold} = {`,
' "&:focus": {',
' fontWeight: "700"',
" }",
"};",
`var ${light} = {`,
' "&:active": {',
' fontWeight: "300"',
" }",
"};",
`var ${p} = {`,
' "&:hover:active": {',
' padding: "0.5rem"',
" }",
"};",
`var ${semibold} = {`,
' "&:hover": {',
' fontWeight: "600"',
" }",
"};",
].join("\n")
);
expect(files.js.text).toMatchSnapshot();
});
});

View File

@ -47,7 +47,7 @@ export function getBuild(name: string) {
const result = await esbuild.build({
bundle: true,
write: false,
external: ["react/jsx-runtime", "@emotion/css", "clsx"],
external: ["react/jsx-runtime", "@emotion/css", "clsx", "tslib"],
outdir: "dist",
format: "esm",
entryPoints: [await write("index.tsx", dedent(javascript))],