mirror of
https://github.com/home-assistant/frontend.git
synced 2026-07-02 12:05:39 +01:00
e4cc1eaad2
computeCssVariable built its nested var() fallback chain with props.reverse(), which reverses the caller's array in place. Every current caller passes a freshly built array so there is no visible corruption today, but mutating an input parameter is a latent trap: a shared, memoized, or frozen array would produce wrong output or throw. Use reduceRight to build the same chain from last to first without mutating or copying the array. Output is unchanged. Add tests for computeCssVariable (including a no-mutation guarantee) and computeCssValue, which previously had no coverage.
72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
computeCssVariable,
|
|
computeCssValue,
|
|
} from "../../src/resources/css-variables";
|
|
|
|
describe("computeCssVariable", () => {
|
|
it("wraps a single property in var()", () => {
|
|
expect(computeCssVariable("--primary-color")).toBe("var(--primary-color)");
|
|
});
|
|
|
|
it("builds a nested fallback chain in order for an array", () => {
|
|
expect(computeCssVariable(["--a", "--b", "--c"])).toBe(
|
|
"var(--a, var(--b, var(--c)))"
|
|
);
|
|
});
|
|
|
|
it("handles a single-element array", () => {
|
|
expect(computeCssVariable(["--only"])).toBe("var(--only)");
|
|
});
|
|
|
|
it("returns undefined for an empty array", () => {
|
|
expect(computeCssVariable([])).toBeUndefined();
|
|
});
|
|
|
|
it("does not mutate the input array", () => {
|
|
const props = ["--a", "--b", "--c"];
|
|
computeCssVariable(props);
|
|
expect(props).toEqual(["--a", "--b", "--c"]);
|
|
});
|
|
|
|
it("returns the same result when called repeatedly with the same array", () => {
|
|
const props = ["--a", "--b", "--c"];
|
|
const first = computeCssVariable(props);
|
|
const second = computeCssVariable(props);
|
|
expect(second).toBe(first);
|
|
});
|
|
});
|
|
|
|
describe("computeCssValue", () => {
|
|
const computedStyles = {
|
|
getPropertyValue: (prop: string) =>
|
|
({
|
|
"--a-color": " red ",
|
|
"--b-color": "blue",
|
|
})[prop] ?? "",
|
|
} as CSSStyleDeclaration;
|
|
|
|
it("returns the trimmed value of a color property", () => {
|
|
expect(computeCssValue("--a-color", computedStyles)).toBe("red");
|
|
});
|
|
|
|
it("ignores properties that do not end with -color", () => {
|
|
expect(computeCssValue("--a-size", computedStyles)).toBeUndefined();
|
|
});
|
|
|
|
it("returns the first resolved value from an array", () => {
|
|
expect(
|
|
computeCssValue(["--missing-color", "--b-color"], computedStyles)
|
|
).toBe("blue");
|
|
});
|
|
|
|
it("returns undefined when no property resolves", () => {
|
|
expect(
|
|
computeCssValue(
|
|
["--missing-color", "--also-missing-color"],
|
|
computedStyles
|
|
)
|
|
).toBeUndefined();
|
|
});
|
|
});
|