video 블록 및 리펙터링
CI / pr_and_merge (push) Has been skipped
CI / test (push) Failing after 46m46s
CI / test (pull_request) Failing after 43m8s
CI / pr_and_merge (pull_request) Has been skipped

This commit is contained in:
2025-11-27 10:07:59 +09:00
parent 672cca5271
commit 48e13d2a75
223 changed files with 8979 additions and 2125 deletions
+174
View File
@@ -0,0 +1,174 @@
import { describe, it, expect } from "vitest";
import {
computeButtonPbTokens,
computeButtonPublicTokens,
computeButtonEditorTokens,
} from "@/features/editor/utils/buttonHelpers";
import type { ButtonBlockProps } from "@/features/editor/state/editorStore";
const baseProps = {
align: "left" as const,
size: "md" as const,
variant: "solid" as const,
colorPalette: "primary" as const,
};
describe("buttonHelpers.computeButtonPbTokens", () => {
it("기본 버튼은 pb-text-left / pb-btn-size-md / pb-btn-variant-solid-primary / pb-btn-radius-md 를 포함해야 한다", () => {
const tokens = computeButtonPbTokens(baseProps);
expect(tokens.alignClass).toBe("pb-text-left");
expect(tokens.sizeClass).toBe("pb-btn-size-md");
expect(tokens.variantClass).toBe("pb-btn-variant-solid-primary");
expect(tokens.radiusClass).toBe("pb-btn-radius-md");
expect(tokens.inlineStyles.length).toBe(0);
});
it("정렬/사이즈/팔레트/둥글기 스케일은 pb 토큰으로 올바르게 매핑되어야 한다", () => {
const tokens = computeButtonPbTokens({
align: "center",
size: "lg",
variant: "outline",
colorPalette: "danger",
borderRadius: "full",
});
expect(tokens.alignClass).toBe("pb-text-center");
expect(tokens.sizeClass).toBe("pb-btn-size-lg");
expect(tokens.variantClass).toBe("pb-btn-variant-outline-danger");
expect(tokens.radiusClass).toBe("pb-btn-radius-full");
});
it("widthMode=fixed, widthPx, paddingX/paddingY, fill/stroke/text 색상은 inlineStyles 에 포함되어야 한다", () => {
const tokens = computeButtonPbTokens({
align: "right",
size: "sm",
widthMode: "fixed",
widthPx: 200,
paddingX: 16,
paddingY: 8,
fillColorCustom: "#111111",
strokeColorCustom: "#222222",
textColorCustom: "#ffffff",
});
expect(tokens.alignClass).toBe("pb-text-right");
expect(tokens.inlineStyles).toContain("width:200px");
expect(tokens.inlineStyles).toContain("padding-left:16px");
expect(tokens.inlineStyles).toContain("padding-right:16px");
expect(tokens.inlineStyles).toContain("padding-top:8px");
expect(tokens.inlineStyles).toContain("padding-bottom:8px");
expect(tokens.inlineStyles).toContain("background-color:#111111");
expect(tokens.inlineStyles).toContain("border-color:#222222");
expect(tokens.inlineStyles).toContain("color:#ffffff");
});
});
describe("buttonHelpers.computeButtonPublicTokens", () => {
it("색상 커스텀 값은 backgroundColor/borderColor/borderWidth/borderStyle/color 에 반영되어야 한다", () => {
const tokens = computeButtonPublicTokens({
label: "컬러 버튼",
href: "#",
align: "center",
fillColorCustom: "#123456",
strokeColorCustom: "#ff0000",
textColorCustom: "#00ff00",
} as ButtonBlockProps);
expect(tokens.alignClass).toBe("text-center");
expect(tokens.styleOverrides.backgroundColor).toBe("#123456");
expect(tokens.styleOverrides.borderColor).toBe("#ff0000");
expect(tokens.styleOverrides.borderWidth).toBe("1px");
expect(tokens.styleOverrides.borderStyle).toBe("solid");
expect(tokens.styleOverrides.color).toBe("#00ff00");
});
it("widthMode=fixed 인 경우 widthPx/paddingX/paddingY 는 em 단위로 변환되어야 한다", () => {
const tokens = computeButtonPublicTokens({
label: "레이아웃 버튼",
href: "#",
align: "left",
widthMode: "fixed",
widthPx: 320,
paddingX: 16,
paddingY: 8,
} as ButtonBlockProps);
expect(tokens.alignClass).toBe("text-left");
expect(tokens.styleOverrides.width).toBe("20em");
expect(tokens.styleOverrides.paddingInline).toBe("1em");
expect(tokens.styleOverrides.paddingBlock).toBe("0.5em");
});
it("borderRadius 토큰은 em 단위 둥글기 또는 9999px 로 변환되어야 한다", () => {
const lgTokens = computeButtonPublicTokens({
label: "둥근 버튼",
href: "#",
borderRadius: "lg",
} as ButtonBlockProps);
expect(lgTokens.styleOverrides.borderRadius).toBe("0.75em");
const fullTokens = computeButtonPublicTokens({
label: "풀 둥근 버튼",
href: "#",
borderRadius: "full",
} as ButtonBlockProps);
expect(fullTokens.styleOverrides.borderRadius).toBe("9999px");
});
});
describe("buttonHelpers.computeButtonEditorTokens", () => {
it("fullWidth 나 widthMode 에 따라 wrapperWidthClass 와 버튼 스타일이 계산되어야 한다", () => {
const tokens = computeButtonEditorTokens({
label: "테스트 버튼",
href: "#",
align: "center",
size: "lg",
variant: "outline",
colorPalette: "success",
borderRadius: "full",
fullWidth: true,
fontSizeCustom: "18px",
lineHeightCustom: "1.8",
letterSpacingCustom: "0.1em",
fillColorCustom: "#123456",
strokeColorCustom: "#654321",
textColorCustom: "#ff0000",
paddingX: 16,
paddingY: 10,
} as ButtonBlockProps);
// fullWidth=true 이므로 wrapperWidthClass 는 w-full 이어야 한다.
expect(tokens.wrapperWidthClass).toBe("w-full");
// 버튼 스타일에 색상/패딩/타이포 값이 그대로 반영되어야 한다.
expect(tokens.buttonStyle.backgroundColor).toBe("#123456");
expect(tokens.buttonStyle.borderColor).toBe("#654321");
expect(tokens.buttonStyle.color).toBe("#ff0000");
expect(tokens.buttonStyle.paddingInline).toBe("16px");
expect(tokens.buttonStyle.paddingBlock).toBe("10px");
expect(tokens.buttonStyle.fontSize).toBe("18px");
expect(tokens.buttonStyle.lineHeight).toBe("1.8");
expect(tokens.buttonStyle.letterSpacing).toBe("0.1em");
});
it("widthMode=fixed 인 경우 widthPx 는 버튼 width 스타일에 반영되고 wrapperWidthClass 는 inline-block 이어야 한다", () => {
const tokens = computeButtonEditorTokens({
label: "고정 너비 버튼",
href: "#",
align: "left",
size: "md",
variant: "solid",
colorPalette: "primary",
borderRadius: "md",
fullWidth: false,
widthMode: "fixed",
widthPx: 200,
} as ButtonBlockProps);
expect(tokens.wrapperWidthClass).toBe("inline-block");
expect(tokens.buttonStyle.width).toBe("200px");
});
});