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
+144
View File
@@ -0,0 +1,144 @@
import { describe, it, expect } from "vitest";
import {
computeTextPbTokens,
computeTextEditorTokens,
computeTextPublicTokens,
} from "@/features/editor/utils/textHelpers";
import type { TextBlockProps } from "@/features/editor/state/editorStore";
const baseProps = {
text: "텍스트",
align: "left" as const,
size: "base" as const,
};
describe("textHelpers.computeTextPbTokens", () => {
it("기본 텍스트는 pb-text-left / pb-text-base / pb-leading-normal / pb-font-normal / pb-text-color-strong / pb-whitespace-pre-wrap 를 포함해야 한다", () => {
const tokens = computeTextPbTokens(baseProps);
expect(tokens.alignClass).toBe("pb-text-left");
expect(tokens.sizeClass).toBe("pb-text-base");
expect(tokens.leadingClass).toBe("pb-leading-normal");
expect(tokens.weightClass).toBe("pb-font-normal");
expect(tokens.colorClass).toBe("pb-text-color-strong");
expect(tokens.extraClasses).toContain("pb-whitespace-pre-wrap");
});
it("스케일 모드 텍스트는 폰트/라인하이트/굵기 스케일 토큰을 올바르게 매핑해야 한다", () => {
const tokens = computeTextPbTokens({
...baseProps,
align: "center",
fontSizeMode: "scale",
fontSizeScale: "lg",
lineHeightMode: "scale",
lineHeightScale: "relaxed",
fontWeightMode: "scale",
fontWeightScale: "semibold",
colorMode: "palette",
colorPalette: "strong",
underline: true,
italic: true,
});
expect(tokens.alignClass).toBe("pb-text-center");
expect(tokens.sizeClass).toBe("pb-text-lg");
expect(tokens.leadingClass).toBe("pb-leading-relaxed");
expect(tokens.weightClass).toBe("pb-font-semibold");
expect(tokens.colorClass).toBe("pb-text-color-strong");
expect(tokens.extraClasses).toContain("pb-underline");
expect(tokens.extraClasses).toContain("pb-italic");
});
it("커스텀 색상과 배경색은 inlineStyles 에 color/background-color 로 포함되어야 한다", () => {
const tokens = computeTextPbTokens({
...baseProps,
colorMode: "custom",
colorCustom: "#ff0000",
backgroundColorCustom: "#123456",
});
expect(tokens.inlineStyles).toContain("color:#ff0000");
expect(tokens.inlineStyles).toContain("background-color:#123456");
});
it("maxWidthScale 가 prose/narrow 인 경우 pb-text-maxw-* 클래스를 포함해야 한다", () => {
const prose = computeTextPbTokens({ ...baseProps, maxWidthMode: "scale", maxWidthScale: "prose" });
const narrow = computeTextPbTokens({ ...baseProps, maxWidthMode: "scale", maxWidthScale: "narrow" });
expect(prose.maxWidthClass).toBe("pb-text-maxw-prose");
expect(narrow.maxWidthClass).toBe("pb-text-maxw-narrow");
});
});
describe("textHelpers.computeTextEditorTokens", () => {
const baseBlockProps: TextBlockProps = {
text: "텍스트",
align: "left",
size: "base",
} as TextBlockProps;
it("기본 텍스트는 pb-text-left / pb-text-base / pb-leading-normal / pb-font-normal / pb-text-color-default 를 사용해야 한다", () => {
const tokens = computeTextEditorTokens(baseBlockProps);
expect(tokens.alignClass).toBe("pb-text-left");
expect(tokens.sizeClass).toBe("pb-text-base");
expect(tokens.leadingClass).toBe("pb-leading-normal");
expect(tokens.weightClass).toBe("pb-font-normal");
expect(tokens.colorClass).toBe("pb-text-color-default");
expect(tokens.styleOverrides.color).toBeUndefined();
});
it("colorCustom / backgroundColorCustom / maxWidthCustom 이 styleOverrides 에 반영되어야 한다", () => {
const tokens = computeTextEditorTokens({
...baseBlockProps,
align: "center",
colorCustom: "#ff0000",
backgroundColorCustom: "#123456",
maxWidthCustom: "320px",
} as TextBlockProps);
expect(tokens.alignClass).toBe("pb-text-center");
expect(tokens.styleOverrides.color).toBe("#ff0000");
expect(tokens.styleOverrides.backgroundColor).toBe("#123456");
expect(tokens.styleOverrides.maxWidth).toBe("320px");
});
});
describe("textHelpers.computeTextPublicTokens", () => {
const baseBlockProps: TextBlockProps = {
text: "텍스트",
align: "left",
size: "base",
} as TextBlockProps;
it("기본 텍스트는 text-left / text-base 를 사용하고 색상/배경 styleOverrides 는 없어야 한다", () => {
const tokens = computeTextPublicTokens(baseBlockProps);
expect(tokens.alignClass).toBe("text-left");
expect(tokens.sizeClass).toBe("text-base");
expect(tokens.styleOverrides.color).toBeUndefined();
expect(tokens.styleOverrides.backgroundColor).toBeUndefined();
});
it("fontSizeMode=custom 인 경우 sizeClass 는 비워지고 styleOverrides.fontSize 에 값이 설정되어야 한다", () => {
const tokens = computeTextPublicTokens({
...baseBlockProps,
fontSizeMode: "custom",
fontSizeCustom: "24px",
} as TextBlockProps);
expect(tokens.sizeClass).toBe("");
expect(tokens.styleOverrides.fontSize).toBe("24px");
});
it("colorCustom / backgroundColorCustom 이 styleOverrides 에 반영되어야 한다", () => {
const tokens = computeTextPublicTokens({
...baseBlockProps,
colorCustom: "#ff0000",
backgroundColorCustom: "#123456",
} as TextBlockProps);
expect(tokens.styleOverrides.color).toBe("#ff0000");
expect(tokens.styleOverrides.backgroundColor).toBe("#123456");
});
});