- ☰ [설정] 마우스 탭 = 휠 방향 + 옮기기 버튼 라디오 · 규칙 글 = 고른 버튼 끌기 옮김(가운데는 늘) - 끌면 옮김 · 덜 끌고 떼면 그 버튼 제 몫(고름 · 메뉴 · CAD Enter) · 오른쪽 끌기 뒤 메뉴 안 뜸 - 왼쪽 옮김은 페이지가 잡은 누름(B05 노드 · 손잡이 · 마커 · 재기 · D03 겹 · 그림 안 도형)에선 비킴 - 자리: B05 · B06 · D03 노선 지도 · CAD · 공용 SVG 확대 · B04 지도 · 3D(오른쪽만) · B05 배수 · 종단 가로 · B08 이정표 · M02 흐름도 · 노임 - 시험: CAD 오른쪽 끌기 옮김 · 옮기기 자리 배선 대조 · 낡은 헬퍼 둘 새 import 대응 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
167 lines
6.2 KiB
TypeScript
167 lines
6.2 KiB
TypeScript
/**
|
|
* CAD 설정 배선(PLAN 332-3) — ☰ [설정] 휠 확대 방향 · 내 별칭(`A00_Common/input_prefs.ts`).
|
|
* 휠 = 기본 밂(앞으로 굴리면 확대 · 오토캐드 · 337) · 당김 저장 뒤 뒤집힘 · 핀치는 늘 벌리면 확대.
|
|
* 별칭 = 명령 이름 > 내 별칭 > 기본 별칭 · 저장 즉시 따름.
|
|
* 바꾼 키(588-3) = 새 키만 먹음 · 옛 키는 안 먹음 · 한글 자판도 자판 자리로.
|
|
* 옮기기 버튼(588-4) = 오른쪽을 고르면 오른쪽 끌기로 화면 옮김 · 기본(가운데)이면 오른쪽 끌기는 안 옮김.
|
|
* 실행: cd B07_DesignDetail/openwebcad && npx vitest run --dir ../../resources/tester/cad input-prefs-cad
|
|
*/
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { INPUT_PREFS_KEY } from "../../../A00_Common/input_prefs";
|
|
import { wheelZoom } from "../../../B07_DesignDetail/openwebcad/src/inputController/input-wheel";
|
|
import {
|
|
matchCommandPrefixes,
|
|
resolveCommandInput,
|
|
} from "../../../B07_DesignDetail/openwebcad/src/commands/registry";
|
|
import {
|
|
getActiveToolActor,
|
|
getPanStartLocation,
|
|
getScreenCanvasDrawController,
|
|
getSnapEnabled,
|
|
} from "../../../B07_DesignDetail/openwebcad/src/state";
|
|
import { initApplication } from "../../../B07_DesignDetail/openwebcad/test/helpers/init-application";
|
|
|
|
const store = new Map<string, string>();
|
|
|
|
const savePrefs = (value: unknown) => store.set(INPUT_PREFS_KEY, JSON.stringify(value));
|
|
|
|
beforeEach(() => {
|
|
store.clear();
|
|
vi.stubGlobal("localStorage", {
|
|
getItem: (key: string) => store.get(key) ?? null,
|
|
setItem: (key: string, value: string) => store.set(key, value),
|
|
removeItem: (key: string) => store.delete(key),
|
|
});
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
const wheel = (deltaY: number, ctrlKey = false) =>
|
|
wheelZoom({ deltaY, deltaMode: 0, ctrlKey })?.delta;
|
|
|
|
describe("휠 확대 방향", () => {
|
|
it("저장 없음 = 밂(앞으로 deltaY < 0 → 확대 = 음수 delta) — 오토캐드(337)", () => {
|
|
expect(wheel(-100)).toBe(-100);
|
|
expect(wheel(100)).toBe(100);
|
|
});
|
|
|
|
it("당김 저장 → 뒤집힘 · 깨진 값 = 밂", () => {
|
|
savePrefs({ wheelZoom: "pull" });
|
|
expect(wheel(100)).toBe(-100);
|
|
expect(wheel(-100)).toBe(100);
|
|
store.set(INPUT_PREFS_KEY, "{깨짐");
|
|
expect(wheel(100)).toBe(100);
|
|
});
|
|
|
|
it("트랙패드 핀치(ctrl · 잔 델타)는 설정과 상관없이 벌리면(deltaY < 0) 확대", () => {
|
|
expect(wheel(-7, true)).toBe(-7);
|
|
expect(wheel(7, true)).toBe(7);
|
|
savePrefs({ wheelZoom: "pull" });
|
|
expect(wheel(-7, true)).toBe(-7);
|
|
// 마우스 Ctrl+휠(큰 델타)은 설정 방향
|
|
expect(wheel(100, true)).toBe(-100);
|
|
});
|
|
});
|
|
|
|
describe("내 별칭", () => {
|
|
it("기본 별칭 그대로 · 내 별칭이 기본 별칭을 이김 · 명령 이름이 내 별칭을 이김", () => {
|
|
expect(resolveCommandInput("L")?.id).toBe("LINE");
|
|
savePrefs({ cadAliases: { CIRCLE: ["L"], ARC: ["LINE"] } });
|
|
expect(resolveCommandInput("l")?.id).toBe("CIRCLE");
|
|
expect(resolveCommandInput("LINE")?.id).toBe("LINE");
|
|
});
|
|
|
|
it("새 별칭 · 자동완성 후보 맨 앞 · 없는 명령 이름은 무시", () => {
|
|
savePrefs({ cadAliases: { RECTANG: ["QQ"], NOPE: ["QZ"] } });
|
|
expect(resolveCommandInput("QQ")?.id).toBe("RECTANG");
|
|
expect(matchCommandPrefixes("Q")[0]?.id).toBe("RECTANG");
|
|
expect(resolveCommandInput("QZ")?.id).not.toBe("NOPE");
|
|
});
|
|
|
|
it("CAD 키 입력 — 「qq␣」 = 사각형 명령", () => {
|
|
savePrefs({ cadAliases: { RECTANG: ["QQ"] } });
|
|
const controller = initApplication();
|
|
getActiveToolActor()?.send({ type: "ESC" }); // 쉬는 상태에서(337 — 점 묻는 중 명령 이름 거절)
|
|
for (const k of ["q", "q", " "]) {
|
|
controller.handleKeyStroke({
|
|
key: k,
|
|
code: "",
|
|
keyCode: 0,
|
|
isComposing: false,
|
|
shiftKey: false,
|
|
ctrlKey: false,
|
|
altKey: false,
|
|
metaKey: false,
|
|
repeat: false,
|
|
target: null,
|
|
preventDefault: vi.fn(),
|
|
stopPropagation: vi.fn(),
|
|
} as unknown as KeyboardEvent);
|
|
}
|
|
expect(getActiveToolActor()?.getSnapshot()?.context.type).toBe("RECTANGLE");
|
|
});
|
|
});
|
|
|
|
describe("바꾼 키(588-3)", () => {
|
|
const key = (controller: ReturnType<typeof initApplication>, extra: Partial<KeyboardEvent>) =>
|
|
controller.handleKeyStroke({
|
|
key: "",
|
|
code: "",
|
|
keyCode: 0,
|
|
isComposing: false,
|
|
shiftKey: false,
|
|
ctrlKey: false,
|
|
altKey: false,
|
|
metaKey: false,
|
|
repeat: false,
|
|
target: null,
|
|
preventDefault: vi.fn(),
|
|
stopPropagation: vi.fn(),
|
|
...extra,
|
|
} as unknown as KeyboardEvent);
|
|
|
|
it("스냅 F3 → Ctrl+Q — 새 키(한글 자판 「ㅂ」)만 켜고 끔 · F3 안 먹음", () => {
|
|
const controller = initApplication();
|
|
const before = getSnapEnabled();
|
|
key(controller, { key: "F3", code: "F3" });
|
|
expect(getSnapEnabled()).toBe(!before);
|
|
savePrefs({ keys: { "cad.snap": ["Ctrl+Q"] } });
|
|
key(controller, { key: "F3", code: "F3" });
|
|
expect(getSnapEnabled()).toBe(!before);
|
|
key(controller, { key: "ㅂ", code: "KeyQ", ctrlKey: true });
|
|
expect(getSnapEnabled()).toBe(before);
|
|
});
|
|
});
|
|
|
|
describe("옮기기 버튼(588-4)", () => {
|
|
const mouse = (button: number, x: number, y = 100) =>
|
|
({
|
|
button,
|
|
clientX: x,
|
|
clientY: y,
|
|
shiftKey: false,
|
|
ctrlKey: false,
|
|
target: null,
|
|
preventDefault: vi.fn(),
|
|
stopPropagation: vi.fn(),
|
|
}) as unknown as MouseEvent;
|
|
const rightDrag = (controller: ReturnType<typeof initApplication>) => {
|
|
const before = getScreenCanvasDrawController().getScreenOffset().clone();
|
|
controller.handleMouseDown(mouse(2, 100));
|
|
controller.handleMouseMove(mouse(2, 160));
|
|
controller.handleMouseUp(mouse(2, 160));
|
|
const after = getScreenCanvasDrawController().getScreenOffset();
|
|
return Math.hypot(after.x - before.x, after.y - before.y);
|
|
};
|
|
|
|
it("기본(가운데) = 오른쪽 끌기 안 옮김 · 오른쪽 고름 = 옮김 · 놓으면 끝", () => {
|
|
const controller = initApplication();
|
|
expect(rightDrag(controller)).toBe(0);
|
|
savePrefs({ panButton: "right" });
|
|
expect(rightDrag(controller)).toBeGreaterThan(0);
|
|
expect(getPanStartLocation()).toBeNull();
|
|
});
|
|
});
|