/** * 블록 라이브러리 저장·해제 검증 (조사표 4절 BLOCK/INSERT). * 실행: cd B07_DesignDetail/openwebcad && npx vitest run --config vitest.tmp.config.ts * jsdom을 새로 깔지 않으려고 이 모듈이 쓰는 브라우저 전역 둘만 흉내 낸다. */ import { Point, Segment } from '@flatten-js/core'; import { describe, expect, it } from 'vitest'; const store = new Map(); Object.assign(globalThis, { window: { dispatchEvent: () => true }, CustomEvent: class { constructor(public type: string) {} }, localStorage: { getItem: (key: string) => store.get(key) ?? null, setItem: (key: string, value: string) => void store.set(key, value), }, }); const { deleteBlock, deserializeBlock, getBlocks, saveBlockFromEntities } = await import( '../../../B07_DesignDetail/openwebcad/src/blocks/block-library' ); const { LineEntity } = await import( '../../../B07_DesignDetail/openwebcad/src/entities/LineEntity' ); describe('블록 라이브러리', () => { it('기준점은 선택 영역 중심이고, 다시 풀어 삽입점으로 옮기면 그 점이 중심이 된다', async () => { const line = new LineEntity('layer-1', new Segment(new Point(0, 0), new Point(100, 50))); await saveBlockFromEntities('테스트블록', [line]); const block = getBlocks().find((candidate) => candidate.name === '테스트블록'); expect(block).toBeDefined(); if (!block) return; expect(block.basePoint).toEqual({ x: 50, y: 25 }); const [copy] = await deserializeBlock(block); expect(copy.id).not.toBe(line.id); expect(copy.groupId).toBeTruthy(); // 삽입점 (200, 100)으로 옮기면 원본 크기 100×50이 그 점을 중심으로 놓인다 copy.move(200 - block.basePoint.x, 100 - block.basePoint.y); const box = copy.getBoundingBox(); expect([box.xmin, box.ymin, box.xmax, box.ymax]).toEqual([150, 75, 250, 125]); deleteBlock('테스트블록'); expect(getBlocks().find((candidate) => candidate.name === '테스트블록')).toBeUndefined(); }); });