GUIDES
Testing
Test styles at the component, the browser and the type checker.
Three questions get asked of a style, and each has its own answer. Does the component that uses it behave? Does the page it renders actually look right? Does the type checker accept the calls it should, and reject the rest?
Components
@plumeria/core ships types and no runtime. A component test only runs once the styling prop has been compiled away, so the transform has to sit in the test runner's module pipeline:
Either way the class names in the DOM are the ones the build gives them.
What jsdom does not give you
The class names are real, but no stylesheet is loaded into the document — document.styleSheets is empty, and getComputedStyle returns initial values for every property the styles set. A test can see that the right classes were attached; it cannot see what they do.
Anything that turns on the cascade — specificity between two styles, a @media branch, a marker and its extended styles — needs a real browser. Run those end to end, against the build, where the emitted stylesheet is actually applied.
Types
Because the package is types-only, the API surface can be tested with nothing but tsc. Write the calls you expect to hold, mark the ones you expect to fail, and type-check the file:
import * as css from '@plumeria/core';
const styles = css.create({
text: { fontSize: '12px', color: 'red' },
variant: (size: number) => ({ width: `${size}px` }),
});
export const atomic: string = styles.text.color;
export const fromVariant: string = styles.variant(8).width;
// @ts-expect-error atomic class names are branded per property
export const crossed: css.AtomicClassNameFor<'color', 'red'> = styles.text.fontSize;
// @ts-expect-error the key was never defined
export const missing: string = styles.nope.color;tsc --noEmitAn @ts-expect-error that stops being an error is itself reported, as TS2578: Unused '@ts-expect-error' directive, so the file fails when a guarantee quietly disappears.
The work is already divided by the time a test runs. TypeScript offers the property names and values as you write them, and the lint rules check what you wrote — spelling, values, pseudos, selectors, order-dependent overlap. What neither of them states is the type that comes back out, and that is what this file pins: the branding that keeps one property's class name from being passed off as another's, and keys that do not exist.