Files
page-builder/tests/unit/dividerHelpers.spec.ts
jaybe a5b432fb7b
CI / test (push) Failing after 2m54s
CI / e2e (push) Has been skipped
CI / pr_and_merge (push) Has been skipped
TDD,E2E 개선, 미적용 스타일 개선
2025-12-07 09:52:42 +09:00

184 lines
6.2 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { expectNoPxInStyleObject, expectNoPxInStyleString } from "./styleInvariants";
import {
computeDividerExportTokens,
computeDividerEditorTokens,
computeDividerPublicTokens,
} from "@/features/editor/utils/dividerHelpers";
import type { DividerBlockProps } from "@/features/editor/state/editorStore";
const baseProps: DividerBlockProps = {
align: "left",
thickness: "thin",
colorHex: undefined,
marginYPx: undefined,
};
describe("dividerHelpers.computeDividerExportTokens", () => {
const escapers = { escapeAttr: (v: string) => v };
it("기본 값은 1px 두께, 기본 색상(#475569), marginY=1em 이어야 한다", () => {
const tokens = computeDividerExportTokens(baseProps, escapers);
expect(tokens.style).toBe("border:0;border-bottom:1px solid #475569;margin:1em 0;");
});
it("thickness=\"medium\" 인 경우 2px 두께로 렌더링되어야 한다", () => {
const tokens = computeDividerExportTokens({ ...baseProps, thickness: "medium" }, escapers);
expect(tokens.style).toContain("border-bottom:2px solid #475569;");
});
it("colorHex 가 설정되면 공백을 제거한 뒤 해당 색상으로 border-color 를 사용해야 한다", () => {
const tokens = computeDividerExportTokens({ ...baseProps, colorHex: " #ff0000 " }, escapers);
expect(tokens.style).toContain("border-bottom:1px solid #ff0000;");
});
it("marginYPx > 0 이면 해당 값을 margin Y 로 사용해야 한다", () => {
const tokens = computeDividerExportTokens({ ...baseProps, marginYPx: 24 }, escapers);
expect(tokens.style).toContain("margin:1.5em 0;");
});
it("marginYPx 가 0 이하이거나 숫자가 아니면 기본 1em 을 사용해야 한다", () => {
const zeroTokens = computeDividerExportTokens({ ...baseProps, marginYPx: 0 }, escapers);
expect(zeroTokens.style).toContain("margin:1em 0;");
});
it("widthMode=\"fixed\" 인 경우 widthPx 는 em 단위 width 로 Export style 에 반영되어야 한다", () => {
const tokens = computeDividerExportTokens(
{
...baseProps,
align: "center",
widthMode: "fixed",
widthPx: 480,
},
escapers,
);
expect(tokens.style).toContain("width:30em");
expect(tokens.style).toContain("margin-left:auto");
expect(tokens.style).toContain("margin-right:auto");
});
it("Export 구분선 style 에서는 border-bottom 두께를 제외하고 px 단위가 없어야 한다", () => {
const tokens = computeDividerExportTokens({
...baseProps,
thickness: "medium",
colorHex: "#123456",
marginYPx: 24,
}, escapers);
expectNoPxInStyleString(tokens.style, {
allowPatterns: [/border-bottom:\d+px/],
});
});
});
describe("dividerHelpers.computeDividerEditorTokens", () => {
it("기본 값은 얇은 두께, 기본 색상, 전체 폭, margin 16px 이어야 한다", () => {
const tokens = computeDividerEditorTokens(baseProps);
expect(tokens.thicknessClass).toBe("border-t");
expect(tokens.borderColor).toBe("#475569");
expect(tokens.innerWidthClass).toBe("w-full");
expect(tokens.widthPx).toBeUndefined();
expect(tokens.marginPx).toBe(16);
});
it("thickness=\"medium\", colorHex, widthMode=\"auto\", marginYPx 가 있으면 그대로 반영되어야 한다", () => {
const tokens = computeDividerEditorTokens({
...baseProps,
thickness: "medium",
colorHex: " #ff0000 ",
widthMode: "auto",
marginYPx: 20,
});
expect(tokens.thicknessClass).toBe("border-t-2");
expect(tokens.borderColor).toBe("#ff0000");
expect(tokens.innerWidthClass).toBe("w-1/2");
expect(tokens.widthPx).toBeUndefined();
expect(tokens.marginPx).toBe(20);
});
it("widthMode=\"fixed\" 이고 widthPx 가 양수이면 해당 px 로 width 를 사용해야 한다", () => {
const tokens = computeDividerEditorTokens({
...baseProps,
widthMode: "fixed",
widthPx: 480,
marginY: "lg",
});
expect(tokens.innerWidthClass).toBe("");
expect(tokens.widthPx).toBe(480);
expect(tokens.marginPx).toBe(24);
});
it("widthMode=\"fixed\" 이지만 widthPx 가 없거나 0 이하이면 기본 320px 을 사용해야 한다", () => {
const tokens = computeDividerEditorTokens({
...baseProps,
widthMode: "fixed",
widthPx: undefined,
});
expect(tokens.innerWidthClass).toBe("");
expect(tokens.widthPx).toBe(320);
});
});
describe("dividerHelpers.computeDividerPublicTokens", () => {
it("colorHex 가 있으면 해당 색상을, 없으면 기본 색상(#475569)을 사용해야 한다", () => {
const withColor = computeDividerPublicTokens({
thickness: "thin",
colorHex: "#123456",
} as DividerBlockProps);
expect(withColor.lineStyle.backgroundColor).toBe("#123456");
const withoutColor = computeDividerPublicTokens({
thickness: "thin",
} as DividerBlockProps);
expect(withoutColor.lineStyle.backgroundColor).toBe("#475569");
});
it("marginYPx 와 marginY 토큰은 em 스케일 wrapperMarginEm 으로 변환되어야 한다", () => {
const withMarginPx = computeDividerPublicTokens({
thickness: "thin",
marginYPx: 32,
} as DividerBlockProps);
expect(withMarginPx.wrapperMarginEm).toBe("2em");
const withMarginToken = computeDividerPublicTokens({
thickness: "thin",
marginY: "lg",
} as DividerBlockProps);
expect(withMarginToken.wrapperMarginEm).toBe("1.5em");
});
it("widthMode=fixed 인 경우 widthPx 는 라인 width 에 em 으로 반영되어야 한다", () => {
const tokens = computeDividerPublicTokens({
thickness: "thin",
widthMode: "fixed",
widthPx: 480,
} as DividerBlockProps);
expect(tokens.innerWidthClass).toBe("");
expect(tokens.innerStyle.width).toBe("auto");
expect(tokens.lineStyle.width).toBe("30em");
});
it("퍼블릭 구분선 스타일에 px 단위 값이 포함되지 않아야 한다", () => {
const tokens = computeDividerPublicTokens({
align: "center",
thickness: "medium",
colorHex: "#123456",
marginYPx: 32,
widthMode: "fixed",
widthPx: 480,
} as DividerBlockProps);
expectNoPxInStyleObject(tokens.innerStyle);
expectNoPxInStyleObject(tokens.lineStyle);
});
});