feat(banner): 首页常驻滚动通知与管理配置及类型样式支持
This commit is contained in:
101
web/test/banner-title.test.ts
Normal file
101
web/test/banner-title.test.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
|
||||
import {
|
||||
BANNER_TITLE_FONT_FAMILIES,
|
||||
bannerTitleCharCount,
|
||||
bannerTitleContrastRatio,
|
||||
bannerTitlePlainText,
|
||||
bannerTitleRunStyle,
|
||||
lowContrastBannerTitleColors,
|
||||
normalizeBannerTitleHex,
|
||||
normalizeBannerTitleRuns,
|
||||
parseBannerTitleColor,
|
||||
} from "@/lib/announcements/banner-title";
|
||||
|
||||
describe("通知标题样式分段清洗", () => {
|
||||
test("合并相邻同样式分段,跳过空文本", () => {
|
||||
const runs = normalizeBannerTitleRuns([
|
||||
{ text: "限时", fontSize: 16, color: "#FF0000" },
|
||||
{ text: "活动", fontSize: 16, color: "#ff0000" },
|
||||
{ text: "", fontSize: 16 },
|
||||
{ text: "上线", fontSize: 20 },
|
||||
]);
|
||||
expect(runs).toEqual([
|
||||
{ text: "限时活动", fontSize: 16, color: "#FF0000" },
|
||||
{ text: "上线", fontSize: 20 },
|
||||
]);
|
||||
});
|
||||
|
||||
test("丢弃白名单外的字号、字重、字体与颜色", () => {
|
||||
expect(normalizeBannerTitleRuns([{ text: "标题", fontSize: 9 }])).toEqual([{ text: "标题" }]);
|
||||
expect(normalizeBannerTitleRuns([{ text: "标题", fontSize: 21 }])).toEqual([{ text: "标题" }]);
|
||||
expect(normalizeBannerTitleRuns([{ text: "标题", fontWeight: 6000 }])).toEqual([{ text: "标题" }]);
|
||||
expect(normalizeBannerTitleRuns([{ text: "标题", fontFamily: "comic" as never }])).toEqual([{ text: "标题" }]);
|
||||
expect(normalizeBannerTitleRuns([{ text: "标题", color: "red" }])).toEqual([{ text: "标题" }]);
|
||||
expect(normalizeBannerTitleRuns([{ text: "标题", color: "#fff;background:url(x)" }])).toEqual([{ text: "标题" }]);
|
||||
});
|
||||
|
||||
test("sans 视为默认字体,不写入分段", () => {
|
||||
expect(normalizeBannerTitleRuns([{ text: "标题", fontFamily: "sans" }])).toEqual([{ text: "标题" }]);
|
||||
expect(normalizeBannerTitleRuns([{ text: "标题", fontFamily: "mono" }])).toEqual([{ text: "标题", fontFamily: "mono" }]);
|
||||
});
|
||||
|
||||
test("纯文本与字符数按码点统计", () => {
|
||||
const runs = [{ text: "限时" }, { text: "活动🎉" }];
|
||||
expect(bannerTitlePlainText(runs)).toBe("限时活动🎉");
|
||||
expect(bannerTitleCharCount(runs)).toBe(5);
|
||||
});
|
||||
});
|
||||
|
||||
describe("通知标题样式输出", () => {
|
||||
test("只输出已设置的维度", () => {
|
||||
expect(bannerTitleRunStyle({ text: "标题" })).toEqual({});
|
||||
expect(bannerTitleRunStyle({ text: "标题", fontSize: 20, fontWeight: 700, color: "#FF0000" })).toEqual({
|
||||
fontSize: "20px",
|
||||
fontWeight: 700,
|
||||
color: "#FF0000",
|
||||
});
|
||||
});
|
||||
|
||||
test("字体档位输出对应字体栈", () => {
|
||||
const serif = BANNER_TITLE_FONT_FAMILIES.find((item) => item.key === "serif");
|
||||
expect(bannerTitleRunStyle({ text: "标题", fontFamily: "serif" }).fontFamily).toBe(serif?.css);
|
||||
});
|
||||
|
||||
test("十六进制颜色归一化", () => {
|
||||
expect(normalizeBannerTitleHex("#abc")).toBe("#AABBCC");
|
||||
expect(normalizeBannerTitleHex("5f6ae4")).toBe("#5F6AE4");
|
||||
expect(normalizeBannerTitleHex("#12345")).toBe("");
|
||||
expect(parseBannerTitleColor("rgb(95, 106, 228)")).toEqual([95, 106, 228]);
|
||||
expect(parseBannerTitleColor("not-a-color")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("通知标题对比度检查", () => {
|
||||
test("白字在通知条两种底色上的对比度", () => {
|
||||
expect(bannerTitleContrastRatio("#FFFFFF", "#5C67E2")).toBeCloseTo(4.67, 2);
|
||||
expect(bannerTitleContrastRatio("#FFFFFF", "#3F4590")).toBeCloseTo(8.52, 2);
|
||||
expect(bannerTitleContrastRatio("not-a-color", "#3F4590")).toBeNull();
|
||||
expect(bannerTitleContrastRatio("#FFFFFF", "")).toBeNull();
|
||||
});
|
||||
|
||||
test("通知条底色 token 的白字对比度必须达到 AA(改 token 时同步更新此处)", () => {
|
||||
// globals.css 的 --palette-banner-notice-500 / -700(「公告」类型);默认标题为白色 12px 正文,需 >= 4.5:1。
|
||||
// 四种类型的完整覆盖见 test/banner-notice.test.ts。
|
||||
expect(bannerTitleContrastRatio("#FFFFFF", "#5C67E2")).toBeGreaterThanOrEqual(4.5);
|
||||
expect(bannerTitleContrastRatio("#FFFFFF", "#3F4590")).toBeGreaterThanOrEqual(4.5);
|
||||
});
|
||||
|
||||
test("挑出对比度不足的颜色并去重,默认无色不参与检查", () => {
|
||||
const runs = [
|
||||
{ text: "低", color: "#808BF5" },
|
||||
{ text: "也低", color: "#808BF5" },
|
||||
{ text: "足够", color: "#FFFFFF" },
|
||||
{ text: "没设颜色" },
|
||||
];
|
||||
expect(lowContrastBannerTitleColors(runs, "#5C67E2")).toEqual(["#808BF5"]);
|
||||
expect(lowContrastBannerTitleColors(runs, "#3F4590")).toEqual(["#808BF5"]);
|
||||
expect(lowContrastBannerTitleColors([{ text: "足够", color: "#FFFFFF" }], "#5C67E2")).toEqual([]);
|
||||
expect(lowContrastBannerTitleColors(runs, "")).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user