|
| 1 | +import { describe, expect, it, vi } from "vitest"; |
| 2 | + |
| 3 | +import { createStyleRecipe } from "./style-recipe.js"; |
| 4 | +import { createThemedRecipes } from "./themed-recipes.js"; |
| 5 | + |
| 6 | +const heading = |
| 7 | + "A recipe's config names variants, options, or slots that it does not declare, so they add nothing:"; |
| 8 | + |
| 9 | +/** Returns what `create` warns about, without printing it. */ |
| 10 | +function warningsOf(create: () => unknown): readonly string[] { |
| 11 | + const messages: string[] = []; |
| 12 | + const warn = vi |
| 13 | + .spyOn(console, "warn") |
| 14 | + .mockImplementation((message: unknown) => { |
| 15 | + messages.push(String(message)); |
| 16 | + }); |
| 17 | + try { |
| 18 | + create(); |
| 19 | + } finally { |
| 20 | + warn.mockRestore(); |
| 21 | + } |
| 22 | + return messages; |
| 23 | +} |
| 24 | + |
| 25 | +interface Theme { |
| 26 | + readonly gap: number; |
| 27 | +} |
| 28 | + |
| 29 | +describe("a config declared before the call", () => { |
| 30 | + it("warns about a compound variant that names an undeclared variant", () => { |
| 31 | + const boxConfig = { |
| 32 | + compoundVariants: [ |
| 33 | + { |
| 34 | + style: { borderWidth: 2 }, |
| 35 | + variants: { size: "sm", tonne: "danger" }, |
| 36 | + }, |
| 37 | + ], |
| 38 | + variants: { |
| 39 | + size: { md: { padding: 8 }, sm: { padding: 4 } }, |
| 40 | + tone: { danger: { opacity: 1 }, neutral: { opacity: 0.6 } }, |
| 41 | + }, |
| 42 | + } as const; |
| 43 | + |
| 44 | + expect(warningsOf(() => createStyleRecipe(boxConfig))).toStrictEqual([ |
| 45 | + `${heading}\n- Compound variant 0 names the variant "tonne".`, |
| 46 | + ]); |
| 47 | + expect( |
| 48 | + createStyleRecipe(boxConfig)({ size: "sm", tone: "danger" }), |
| 49 | + ).toStrictEqual({ opacity: 1, padding: 4 }); |
| 50 | + }); |
| 51 | +}); |
| 52 | + |
| 53 | +describe("a themed recipe", () => { |
| 54 | + it("warns once, whatever the number of themes", () => { |
| 55 | + const { createStyleRecipe: createThemedStyleRecipe } = |
| 56 | + createThemedRecipes<Theme>(); |
| 57 | + const chip = createThemedStyleRecipe((theme) => ({ |
| 58 | + compoundVariants: [ |
| 59 | + { style: { borderWidth: 1 }, variants: { dense: true, sise: "sm" } }, |
| 60 | + ], |
| 61 | + variants: { |
| 62 | + dense: { true: { padding: theme.gap } }, |
| 63 | + size: { sm: { height: 24 } }, |
| 64 | + }, |
| 65 | + })); |
| 66 | + |
| 67 | + expect( |
| 68 | + warningsOf(() => [ |
| 69 | + chip({ gap: 4 }, { size: "sm" }), |
| 70 | + chip({ gap: 8 }, { size: "sm" }), |
| 71 | + ]), |
| 72 | + ).toStrictEqual([ |
| 73 | + `${heading}\n- Compound variant 0 names the variant "sise".`, |
| 74 | + ]); |
| 75 | + }); |
| 76 | +}); |
0 commit comments