Files
Aislo/resources/tester/cad/table-export.test.ts
T

142 lines
4.7 KiB
TypeScript

/**
* CAD → 부모 표 보내기(`integration/aislo-table-export.ts` · M02 83-2) 검증.
* 실행: cd B07_DesignDetail/openwebcad && npx vitest run --dir ../../resources/tester/cad table-export
* (시험 파일은 바깥 라이브러리를 직접 부르지 않음 — 엔티티는 fromJson 으로 만듦)
*/
import { beforeEach, describe, expect, it, vi } from "vitest";
import {
getCommandById,
isViewOnlyCommand,
} from "../../../B07_DesignDetail/openwebcad/src/commands/registry.ts";
import type { JsonEntity } from "../../../B07_DesignDetail/openwebcad/src/entities/Entity.ts";
import { LineEntity } from "../../../B07_DesignDetail/openwebcad/src/entities/LineEntity.ts";
import { TextEntity } from "../../../B07_DesignDetail/openwebcad/src/entities/TextEntity.ts";
import {
AISLO_EXPORT_TABLE_MESSAGE,
AISLO_EXPORT_TABLE_REQUEST_MESSAGE,
handleTableExportMessage,
selectionTable,
} from "../../../B07_DesignDetail/openwebcad/src/integration/aislo-table-export.ts";
import {
getEntities,
setEntities,
setLayers,
setSelectedEntityIds,
} from "../../../B07_DesignDetail/openwebcad/src/state.ts";
const layer = { id: "layer-1", isLocked: false, isVisible: true, name: "작업" };
const line = (x1: number, y1: number, x2: number, y2: number) =>
LineEntity.fromJson({
id: crypto.randomUUID(),
type: "Line",
lineColor: "#fff",
lineWidth: 1,
layerId: layer.id,
shapeData: { startPoint: { x: x1, y: y1 }, endPoint: { x: x2, y: y2 } },
} as unknown as JsonEntity<never>);
const text = (label: string, x: number, y: number) =>
TextEntity.fromJson({
id: crypto.randomUUID(),
type: "Text",
lineColor: "#fff",
lineWidth: 1,
layerId: layer.id,
shapeData: {
label,
basePoint: { x, y },
options: {
textDirection: { x: 1, y: 0 },
textAlign: "left",
textColor: "#fff",
fontSize: 2.5,
fontFamily: "Noto Sans KR",
},
},
} as unknown as JsonEntity<never>);
/** 2×2 선 표 + 글 넷 + 표 밖 선 하나(고르지 않음) */
async function drawing() {
const parts = await Promise.all([
line(0, 20, 40, 20),
line(0, 10, 40, 10),
line(0, 0, 40, 0),
line(0, 0, 0, 20),
line(20, 0, 20, 20),
line(40, 0, 40, 20),
text("항목", 2, 14),
text("수량", 22, 14),
text("흙깎기", 2, 4),
text("1,500", 22, 4),
]);
const outside = await line(100, 100, 200, 100);
setEntities([...parts, outside]);
return { parts, outside };
}
beforeEach(() => {
setLayers([layer]);
setEntities([]);
setSelectedEntityIds([]);
});
describe("고른 범위 → 표 자료", () => {
it("고른 선 + 글만 표로 · 숫자 글은 숫자", async () => {
const { parts } = await drawing();
setSelectedEntityIds(parts.map((entity) => entity.id));
const table = await selectionTable();
expect(table).toMatchObject({
kind: "grid",
rows: [
["항목", "수량"],
["흙깎기", 1500],
],
colWidths: [20, 20],
});
});
it("고른 것 없음 = empty · 글 없는 선 = no-text", async () => {
const { outside } = await drawing();
expect(await selectionTable()).toBe("empty");
setSelectedEntityIds([outside.id]);
expect(await selectionTable()).toBe("no-text");
});
});
describe("부모 요청 메시지", () => {
it("export-table-request = 고른 범위를 export-table{table} 로 회신 · 도면은 그대로", async () => {
const { parts } = await drawing();
setSelectedEntityIds(parts.map((entity) => entity.id));
const before = getEntities();
const notify = vi.fn();
expect(
await handleTableExportMessage({ type: AISLO_EXPORT_TABLE_REQUEST_MESSAGE }, notify),
).toBe(true);
expect(notify).toHaveBeenCalledTimes(1);
const [type, payload] = notify.mock.calls[0];
expect(type).toBe(AISLO_EXPORT_TABLE_MESSAGE);
expect(payload.table.rows[1]).toEqual(["흙깎기", 1500]);
expect(getEntities()).toBe(before);
});
it("고른 것이 없으면 회신 안 함 · 다른 메시지는 false", async () => {
await drawing();
const notify = vi.fn();
expect(
await handleTableExportMessage({ type: AISLO_EXPORT_TABLE_REQUEST_MESSAGE }, notify),
).toBe(true);
expect(notify).not.toHaveBeenCalled();
expect(await handleTableExportMessage({ type: "aislo:b08:save-request" }, notify)).toBe(false);
expect(await handleTableExportMessage(null, notify)).toBe(false);
});
});
describe("CAD 명령 TOAREA", () => {
it("고른 것이 있어야 하고 · 확정(보기 전용) 도면에서도 됨", () => {
const command = getCommandById("TOAREA");
expect(command?.label).toBe("면적산출로 보내기");
expect(command?.needsSelection).toBe(true);
expect(command && isViewOnlyCommand(command)).toBe(true);
});
});