|
| 1 | +// @vitest-environment jsdom |
| 2 | +/** |
| 3 | + * NoteListToolbar 过滤芯片着色测试(批 7 T18;§C2.4 / §C11.3「做」的落点)。 |
| 4 | + * |
| 5 | + * @ai-context: 判据 = 「过滤面板的芯片色与 `tag_colors` 一致」(§C2.4 逐字)—— 与 `NoteListRow` |
| 6 | + * 同口径(`paletteHex(id, theme) + "22"` 透明度后缀)。上色**只动 `background`**:本文件的 |
| 7 | + * `nativeButton 4 / 边框 3 / 越界圆角 2` 三格已满(§C9.12),判据见 `surfaceBaseline.ts` |
| 8 | + * 与 `nativeButtonBaseline.ts`(本件不做棘轮断言 —— 那是棘轮判据件的职责,重复一份会造两套口径)。 |
| 9 | + * @ai-context: 具名断言的变量体 = 「删掉 toolbar 的 `tagColors` 透传」⇒ 有色芯片回落默认灰底, |
| 10 | + * 两条断言(等于查色值 / 不等于无色底)同时红。 |
| 11 | + */ |
| 12 | +import { cleanup, render, screen } from "@testing-library/react"; |
| 13 | +import { afterEach, describe, expect, it } from "vitest"; |
| 14 | +import { paletteHex } from "../utils/colorPalette"; |
| 15 | +import NoteListToolbar from "./NoteListToolbar"; |
| 16 | + |
| 17 | +afterEach(cleanup); |
| 18 | + |
| 19 | +/** |
| 20 | + * `#RRGGBBAA` → jsdom(cssstyle)归一后的 `rgba(r, g, b, a)`。 |
| 21 | + * Why 不写字面量:色板真源是 `paletteHex`(改真源时本判据应随之走,而不是留一个过期常量)。 |
| 22 | + */ |
| 23 | +const asRgba = (hex8: string): string => { |
| 24 | + const [r, g, b] = [1, 3, 5].map((i) => parseInt(hex8.slice(i, i + 2), 16)); |
| 25 | + const alpha = Number((parseInt(hex8.slice(7, 9), 16) / 255).toFixed(3)); |
| 26 | + return `rgba(${r}, ${g}, ${b}, ${alpha})`; |
| 27 | +}; |
| 28 | + |
| 29 | +const baseProps = { selectionMode: false, |
| 30 | + selectionCount: 0, |
| 31 | + onToggleBatchMode: () => {}, |
| 32 | + onCreate: () => {}, |
| 33 | + keyword: "", |
| 34 | + onKeywordChange: () => {}, |
| 35 | + onRefresh: () => {}, |
| 36 | + sortMode: "updated-desc" as const, |
| 37 | + onSortModeChange: () => {}, |
| 38 | + allTags: ["化妆", "编程"], |
| 39 | + tagFilter: null, |
| 40 | + onTagFilterChange: () => {}, |
| 41 | +}; |
| 42 | + |
| 43 | +describe("NoteListToolbar 过滤芯片着色(批 7 T18 · §C11.3)", () => { |
| 44 | + it("① 有色芯片的底色 == paletteHex(查色表值) + 22(与 NoteListRow 同口径)", () => { |
| 45 | + // Arrange / Act |
| 46 | + render(<NoteListToolbar {...baseProps} tagColors={{ 化妆: "purple" }} />); |
| 47 | + // Assert |
| 48 | + const colored = screen.getByTestId("tag-chip-化妆"); |
| 49 | + const plain = screen.getByTestId("tag-chip-编程"); |
| 50 | + expect(colored.style.background, "有色芯片没取到查色表的值").toBe(asRgba(`${paletteHex("purple", "light")}22`)); |
| 51 | + expect(colored.style.background, "有色芯片的底色不含色板 RGB(查色表取错了 id)").toContain("142, 78, 198"); |
| 52 | + expect(plain.style.background, "无色芯片不该继承别人的色").not.toBe(colored.style.background); |
| 53 | + }); |
| 54 | + |
| 55 | + it("② 缺省 tagColors ⇒ 沿用原底色(加法式改动,无查色表时行为不变)", () => { |
| 56 | + // Arrange / Act |
| 57 | + render(<NoteListToolbar {...baseProps} />); |
| 58 | + // Assert:与加了空表的渲染逐字一致 |
| 59 | + const chip = screen.getByTestId("tag-chip-化妆"); |
| 60 | + expect(chip.style.background).toBe("rgb(249, 250, 251)"); |
| 61 | + }); |
| 62 | + |
| 63 | + it("③ 选中态的边框/字色仍是原契约(上色不夺走选中态)", () => { |
| 64 | + // Arrange / Act |
| 65 | + render(<NoteListToolbar {...baseProps} tagFilter="化妆" tagColors={{ 化妆: "purple" }} />); |
| 66 | + // Assert |
| 67 | + const chip = screen.getByTestId("tag-chip-化妆"); |
| 68 | + expect(chip.style.border).toContain("rgb(13, 148, 136)"); |
| 69 | + expect(chip.style.color).toBe("rgb(13, 148, 136)"); |
| 70 | + }); |
| 71 | +}); |
0 commit comments