import { describe, expect, it } from "vitest"; import { transform } from "./codemod-t5-motion.mjs"; describe("codemod t5 motion (spec 17.2, 17.4, 17.7)", () => { it("puts movement behind motion-full: instead of motion-safe:", () => { expect(transform('cn("size-4 motion-safe:transition-transform", open && "rotate-180")')).toBe( 'cn("size-4 motion-full:transition-transform", open && "rotate-180")', ); expect(transform('"holo-stage bg-holo-bg motion-safe:animate-pulse"')).toBe('"holo-stage bg-holo-bg motion-full:animate-pulse"'); expect(transform('" motion-safe:animate-spin"')).toBe('" motion-full:animate-spin"'); expect(transform('"motion-safe:data-open:zoom-in-95 motion-safe:slide-in-from-top-2"')).toBe( '"motion-full:data-open:zoom-in-95 motion-full:slide-in-from-top-2"', ); expect(transform('"motion-safe:-translate-y-1 motion-safe:scale-95 motion-safe:rotate-90"')).toBe( '"motion-full:-translate-y-1 motion-full:scale-95 motion-full:rotate-90"', ); }); it("drops the variant from colour and opacity transitions (off sets their duration to zero)", () => { expect(transform('"rounded-lg px-2 motion-safe:transition-colors hover:bg-muted"')).toBe( '"rounded-lg px-2 transition-colors hover:bg-muted"', ); expect(transform('"motion-safe:transition-opacity"')).toBe('"transition-opacity"'); }); it("gates bare pulse and spin behind full motion and drops motion-reduce:animate-none", () => { expect(transform('"size-4 animate-spin motion-reduce:animate-none"')).toBe('"size-4 motion-full:animate-spin"'); expect(transform('"h-14 animate-pulse rounded-xl"')).toBe('"h-14 motion-full:animate-pulse rounded-xl"'); expect(transform('"size-4 animate-spin"')).toBe('"size-4 motion-full:animate-spin"'); }); it("leaves other animate classes, tokens and identifiers alone", () => { const untouched = [ '"data-open:animate-in data-closed:animate-out"', '"motion-full:animate-pulse"', "const isAnimating = animate-spinner;", '"animate-page-in"', "// motion-safe: is forbidden for movement", ]; for (const text of untouched) expect(transform(text)).toBe(text); }); it("is idempotent", () => { const once = transform('"a motion-safe:transition-transform animate-spin motion-reduce:animate-none motion-safe:transition-colors"'); expect(transform(once)).toBe(once); }); });