video 블록 및 리펙터링
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import {
|
||||
computeListExportTokens,
|
||||
computeListEditorTokens,
|
||||
computeListPublicTokens,
|
||||
} from "@/features/editor/utils/listHelpers";
|
||||
import type { ListBlockProps } from "@/features/editor/state/editorStore";
|
||||
|
||||
const baseProps: ListBlockProps = {
|
||||
items: [],
|
||||
ordered: false,
|
||||
align: "left",
|
||||
};
|
||||
|
||||
describe("listHelpers.computeListExportTokens", () => {
|
||||
it("기본 unordered 리스트는 Tag=ul, left 정렬, items 플랫닝을 수행해야 한다", () => {
|
||||
const props: ListBlockProps = {
|
||||
...baseProps,
|
||||
items: [" first ", "", " second"],
|
||||
};
|
||||
|
||||
const tokens = computeListExportTokens(props);
|
||||
|
||||
expect(tokens.Tag).toBe("ul");
|
||||
expect(tokens.items).toEqual([" first ", " second"]);
|
||||
expect(tokens.listStyleParts).toContain("text-align:left");
|
||||
});
|
||||
|
||||
it("ordered=true 인 경우 Tag=ol 이어야 한다", () => {
|
||||
const props: ListBlockProps = {
|
||||
...baseProps,
|
||||
ordered: true,
|
||||
items: ["one", "two"],
|
||||
};
|
||||
|
||||
const tokens = computeListExportTokens(props);
|
||||
|
||||
expect(tokens.Tag).toBe("ol");
|
||||
expect(tokens.items).toEqual(["one", "two"]);
|
||||
});
|
||||
|
||||
it("itemsTree 가 있으면 중첩 트리를 DFS 순서로 평탄화해야 한다", () => {
|
||||
const props: ListBlockProps = {
|
||||
...baseProps,
|
||||
itemsTree: [
|
||||
{
|
||||
id: "n1",
|
||||
text: "parent",
|
||||
children: [
|
||||
{ id: "n1-1", text: "child-1", children: [] },
|
||||
{ id: "n1-2", text: "child-2", children: [] },
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const tokens = computeListExportTokens(props);
|
||||
|
||||
expect(tokens.items).toEqual(["parent", "child-1", "child-2"]);
|
||||
});
|
||||
|
||||
it("align 값에 따라 text-align 스타일이 left/center/right 로 설정되어야 한다", () => {
|
||||
const centerTokens = computeListExportTokens({ ...baseProps, align: "center", items: ["a"] });
|
||||
const rightTokens = computeListExportTokens({ ...baseProps, align: "right", items: ["a"] });
|
||||
|
||||
expect(centerTokens.listStyleParts).toContain("text-align:center");
|
||||
expect(rightTokens.listStyleParts).toContain("text-align:right");
|
||||
});
|
||||
|
||||
it("backgroundColorCustom 이 있으면 background-color 스타일을 추가해야 한다", () => {
|
||||
const tokens = computeListExportTokens({
|
||||
...baseProps,
|
||||
items: ["a"],
|
||||
backgroundColorCustom: " #ff0000 ",
|
||||
});
|
||||
|
||||
expect(tokens.listStyleParts).toContain("background-color:#ff0000");
|
||||
});
|
||||
|
||||
it("items 와 itemsTree 가 모두 비어 있으면 items 배열은 빈 배열이어야 한다", () => {
|
||||
const tokens = computeListExportTokens({ ...baseProps });
|
||||
expect(tokens.items).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("listHelpers.computeListEditorTokens", () => {
|
||||
it("gapY 토큰에 따라 gapPx 가 sm=4, md=8, lg=16 으로 계산되어야 한다", () => {
|
||||
const sm = computeListEditorTokens({ ...baseProps, gapY: "sm" });
|
||||
const md = computeListEditorTokens({ ...baseProps, gapY: "md" });
|
||||
const lg = computeListEditorTokens({ ...baseProps, gapY: "lg" });
|
||||
|
||||
expect(sm.gapPx).toBe(4);
|
||||
expect(md.gapPx).toBe(8);
|
||||
expect(lg.gapPx).toBe(16);
|
||||
});
|
||||
|
||||
it("gapYPx 가 있으면 gapY 토큰보다 우선해서 gapPx 를 설정해야 한다", () => {
|
||||
const tokens = computeListEditorTokens({ ...baseProps, gapY: "sm", gapYPx: 24 });
|
||||
|
||||
expect(tokens.gapPx).toBe(24);
|
||||
});
|
||||
|
||||
it("fontSizeCustom / lineHeightCustom / textColorCustom 이 listStyle 에 반영되어야 한다", () => {
|
||||
const tokens = computeListEditorTokens({
|
||||
...baseProps,
|
||||
fontSizeCustom: "18px",
|
||||
lineHeightCustom: "1.8",
|
||||
textColorCustom: "#ff0000",
|
||||
});
|
||||
|
||||
expect(tokens.listStyle.fontSize).toBe("18px");
|
||||
expect(tokens.listStyle.lineHeight).toBe("1.8");
|
||||
expect(tokens.listStyle.color).toBe("#ff0000");
|
||||
});
|
||||
|
||||
it("bulletStyle 은 bulletStyle 지정값 또는 ordered 여부에 따라 결정되어야 한다", () => {
|
||||
const defaultDisc = computeListEditorTokens({
|
||||
...baseProps,
|
||||
ordered: false,
|
||||
bulletStyle: undefined,
|
||||
});
|
||||
|
||||
const defaultDecimal = computeListEditorTokens({
|
||||
...baseProps,
|
||||
ordered: true,
|
||||
bulletStyle: undefined,
|
||||
});
|
||||
|
||||
const none = computeListEditorTokens({
|
||||
...baseProps,
|
||||
bulletStyle: "none",
|
||||
});
|
||||
|
||||
expect(defaultDisc.bulletStyle).toBe("disc");
|
||||
expect(defaultDecimal.bulletStyle).toBe("decimal");
|
||||
expect(none.bulletStyle).toBe("none");
|
||||
});
|
||||
});
|
||||
|
||||
describe("listHelpers.computeListPublicTokens", () => {
|
||||
it("align 값에 따라 alignClass 가 text-left/center/right 로 설정되어야 한다", () => {
|
||||
const leftTokens = computeListPublicTokens({ ...baseProps, align: "left" });
|
||||
const centerTokens = computeListPublicTokens({ ...baseProps, align: "center" });
|
||||
const rightTokens = computeListPublicTokens({ ...baseProps, align: "right" });
|
||||
|
||||
expect(leftTokens.alignClass).toBe("text-left");
|
||||
expect(centerTokens.alignClass).toBe("text-center");
|
||||
expect(rightTokens.alignClass).toBe("text-right");
|
||||
});
|
||||
|
||||
it("gapYPx 와 gapY 토큰에 따라 gapEm 이 px/16 값으로 계산되어야 한다", () => {
|
||||
const byPx = computeListPublicTokens({ ...baseProps, gapYPx: 24 });
|
||||
const byTokenSm = computeListPublicTokens({ ...baseProps, gapY: "sm" });
|
||||
const byTokenLg = computeListPublicTokens({ ...baseProps, gapY: "lg" });
|
||||
|
||||
expect(byPx.gapEm).toBe(24 / 16);
|
||||
expect(byTokenSm.gapEm).toBe(4 / 16);
|
||||
expect(byTokenLg.gapEm).toBe(16 / 16);
|
||||
});
|
||||
|
||||
it("fontSizeCustom 이 px 인 경우 em 단위로 변환되어야 하고, backgroundColorCustom 은 trim 되어야 한다", () => {
|
||||
const tokens = computeListPublicTokens({
|
||||
...baseProps,
|
||||
fontSizeCustom: "32px",
|
||||
backgroundColorCustom: " #123456 ",
|
||||
});
|
||||
|
||||
expect(tokens.listStyle.fontSize).toBe("2em");
|
||||
expect(tokens.listStyle.backgroundColor).toBe("#123456");
|
||||
});
|
||||
|
||||
it("bulletStyle 은 bulletStyle 지정값 또는 ordered 여부에 따라 결정되어야 한다", () => {
|
||||
const defaultDisc = computeListPublicTokens({ ...baseProps, ordered: false, bulletStyle: undefined });
|
||||
const defaultDecimal = computeListPublicTokens({ ...baseProps, ordered: true, bulletStyle: undefined });
|
||||
const none = computeListPublicTokens({ ...baseProps, bulletStyle: "none" });
|
||||
|
||||
expect(defaultDisc.bulletStyle).toBe("disc");
|
||||
expect(defaultDecimal.bulletStyle).toBe("decimal");
|
||||
expect(none.bulletStyle).toBe("none");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user