Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KYZ2HWWdUwZWYnn3tQz7X
142 lines
4.7 KiB
TypeScript
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);
|
|
});
|
|
});
|