register/zlayer/anchor/motion/density are pure cores over plain data, so most of the suite runs with no DOM at all; jsdom covers only what is genuinely DOM. 100 tests, zero elements. These five are why v4 had 11 hand-built modals and 7 hand-built popovers: there was nothing shared to reuse. register makes an element exist only because a file defined it; portal gives every overlay one stacking parent; zlayer owns the only z-index in the app; dismiss keeps one stack so Escape pops the top and not the modal underneath; anchor measures, flips and clamps once. Three bugs the tests found: unmount() called removeChild on null when no portal existed yet, focusables() checked aria-hidden on the element instead of its ancestors so a hidden subtree stayed tab-reachable, and the density ratios v4 hand-tuned are now derived from the gap they were meant to allow for.
33 lines
1.0 KiB
JavaScript
33 lines
1.0 KiB
JavaScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
import { parseDuration } from "../internals/motion.js";
|
|
|
|
test("ms and s both parse to milliseconds", () => {
|
|
assert.equal(parseDuration("120ms"), 120);
|
|
assert.equal(parseDuration("0.12s"), 120);
|
|
assert.equal(parseDuration("1s"), 1000);
|
|
});
|
|
|
|
test("whitespace from getPropertyValue is tolerated", () => {
|
|
// getComputedStyle returns custom properties with their leading space intact.
|
|
assert.equal(parseDuration(" 180ms "), 180);
|
|
});
|
|
|
|
test("a bare number is treated as milliseconds", () => {
|
|
assert.equal(parseDuration("0"), 0);
|
|
assert.equal(parseDuration("250"), 250);
|
|
});
|
|
|
|
test("missing or unreadable values are zero, never NaN", () => {
|
|
// A NaN duration becomes a setTimeout that fires immediately or never, and
|
|
// the teardown it was guarding is stranded either way.
|
|
for (const bad of ["", null, undefined, "auto", "abc", {}]) {
|
|
assert.equal(parseDuration(bad), 0);
|
|
}
|
|
});
|
|
|
|
test("negative durations clamp to zero", () => {
|
|
assert.equal(parseDuration("-100ms"), 0);
|
|
});
|