Files
Aislo/resources/tester/spreadsheet/spreadsheet_link_set_entry.ts
T

128 lines
5.3 KiB
TypeScript

/* setLink 순수 길(`spreadsheet_link_set.ts`) 시험 진입 — vite --ssr 로 번들해 Node 로 돌림.
* 결과 = JSON {pass, fail, failures} 한 줄(`test_spreadsheet_set_link.py` 가 읽음) */
import { applyCommand } from "../../../A00_Common/spreadsheet/spreadsheet_commands";
import { linkHues } from "../../../A00_Common/spreadsheet/spreadsheet_link_color";
import { linkAreaCell, linkCommand } from "../../../A00_Common/spreadsheet/spreadsheet_link_set";
import type { Command, Workbook } from "../../../A00_Common/spreadsheet/spreadsheet_types";
let pass = 0;
const failures: string[] = [];
const eq = (name: string, got: unknown, want: unknown): void => {
if (JSON.stringify(got) === JSON.stringify(want)) pass += 1;
else failures.push(`${name}: ${JSON.stringify(got)} ≠ ${JSON.stringify(want)}`);
};
const book = (): Workbook =>
({
종류: "통합문서",
판: 1,
열: "t",
서식: [{}],
시트: [
{
id: "s1",
이름: "면적산출",
칸: { B1: { 값: 12.5 } },
연결: [{ 키: "깔기|㎡", 이름: "깔기", 단위: "㎡", 칸: "B6" }],
},
{ id: "s2", 이름: "둘", 칸: {}, 연결: [{ 키: "치기|㎥", 이름: "치기", 칸: "C3" }] },
],
활성: "s1",
}) as unknown as Workbook;
const links = (b: Workbook) => b.시트.map((s) => s.연결 ?? null);
const run = (b: Workbook, c: Command | null | false) => {
if (!c) return null;
return applyCommand(b, c).undo;
};
// 새 키를 칸에 — 이름 · 단위 · 자재가 같이 들어감 · 소문자 · 빈칸 주소도 받음
let b = book();
const mt = { 코드: "MT000008", 이름: "치즐", 규격: "", 단위: "EA" };
let undo = run(
b,
linkCommand(b, "s1", "자재|MT000008", " d2 ", { 이름: "치즐", 단위: "EA", 자재: mt }),
);
eq("새 연결", b.시트[0].연결?.[1], {
키: "자재|MT000008",
칸: "D2",
이름: "치즐",
단위: "EA",
자재: mt,
});
// 되돌리기 = 처음 그대로
run(b, undo);
eq("되돌림", links(b), links(book()));
// 있는 키를 다른 칸으로 — 옛 칸 빠지고 이름 · 단위는 있던 것
b = book();
run(b, linkCommand(b, "s1", "깔기|㎡", "B1"));
eq("옮김", b.시트[0].연결, [{ 키: "깔기|㎡", 칸: "B1", 이름: "깔기", 단위: "㎡" }]);
// 같은 칸에 다른 키 — 그 칸 옛 키 빠짐(칸 하나 = 키 하나)
b = book();
run(b, linkCommand(b, "s1", "새|m", "B6", { 이름: "새", 단위: "m" }));
eq("칸 하나 키 하나", b.시트[0].연결, [{ 키: "새|m", 칸: "B6", 이름: "새", 단위: "m" }]);
// 다른 시트에 있던 키를 이 시트로 — 저쪽 연결 빠짐(연결 칸 없으면 `연결` 지움) · 되돌리기 한 번에 둘 다
b = book();
undo = run(b, linkCommand(b, "s1", "치기|㎥", "A1"));
eq("시트 넘어 옮김", links(b), [
[
{ 키: "깔기|㎡", 이름: "깔기", 단위: "㎡", 칸: "B6" },
{ 키: "치기|㎥", 칸: "A1", 이름: "치기" },
],
null,
]);
run(b, undo);
eq("시트 넘어 되돌림", links(b), links(book()));
// 풀기 — 그 키만 빠지고 마지막이면 `연결` 칸이 없어짐
b = book();
run(b, linkCommand(b, "s1", "깔기|㎡", null));
eq("풀기", links(b), [null, [{ 키: "치기|㎥", 이름: "치기", 칸: "C3" }]]);
// 바뀔 것 없음 = null · 틀린 주소 = false · 없는 시트 = false
b = book();
eq("이미 그 칸", linkCommand(b, "s1", "깔기|㎡", "b6"), null);
eq("없는 키 풀기", linkCommand(b, "s1", "없음", null), null);
eq("틀린 주소", linkCommand(b, "s1", "깔기|㎡", "가1"), false);
eq("빈 주소", linkCommand(b, "s1", "깔기|㎡", ""), false);
eq("없는 시트", linkCommand(b, "s9", "깔기|㎡", "A1"), false);
eq("문서 그대로", links(b), links(book()));
// linkAreaCell — 새 문서(받은 문서 그대로) · 활성 시트 · 번호 칸 그대로 · 틀린 주소 null · 풀기
b = { ...book(), 면적번: "SA-000001" } as Workbook & { 면적번: string };
const before = JSON.stringify(b);
const got = linkAreaCell(b, "철근|ton", "c9", { 이름: "철근", 단위: "ton" });
eq("받은 문서 그대로", JSON.stringify(b), before);
eq("새 문서 연결", got?.시트[0].연결?.[1], { 키: "철근|ton", 칸: "C9", 이름: "철근", 단위: "ton" });
eq("번호 그대로", (got as { 면적번?: string } | null)?.면적번, "SA-000001");
eq("틀린 주소", linkAreaCell(b, "철근|ton", "9C"), null);
eq("풀기 · 시트 넘어", links(linkAreaCell(b, "치기|㎥", null)!), [links(book())[0], null]);
eq("바뀔 것 없음 = 사본", JSON.stringify(linkAreaCell(b, "깔기|㎡", "B6")), before);
// linkHues — 키로 정해짐 · 차례 무관 · 24 개까지 서로 다름 · 12 개까지 30° 바퀴 · 15° 눈금
const keys = Array.from({ length: 24 }, (_, i) => `알약${i}|㎡`);
const h1 = linkHues(keys);
const h2 = linkHues([...keys].reverse());
eq("차례 무관", [...h1.entries()].sort(), [...h2.entries()].sort());
eq("24 개 서로 다름", new Set(h1.values()).size, 24);
eq(
"15° 눈금",
[...h1.values()].every((h) => h % 15 === 0 && h >= 0 && h < 360),
true,
);
const few = linkHues(keys.slice(0, 12));
eq(
"12 개 = 30° 바퀴",
[...few.values()].every((h) => h % 30 === 0),
true,
);
eq(
"같은 키 같은 색",
linkHues(["철근|ton", "깔기|㎡"]).get("철근|ton"),
linkHues(["철근|ton"]).get("철근|ton"),
);
console.log(JSON.stringify({ pass, fail: failures.length, failures }));