fix(spreadsheet): 이름 정의 풀이 — =SUM(값들) 이 범위로 풀림 · 행열 넣기 · 지우기 때 이름 범위 따라감
- 엔진: 식 나무의 이름을 Sheet.이름정의 범위로 바꿔 풂(자기 시트 먼저 · 없으면 다른 시트 · 없는 이름 #NAME?) · 의존 그래프도 범위로 이어짐 - 식 캐시는 시트마다 · rebuild 때 비움 — 이름 바꾸기 · 지우기(시트통째) 뒤 새로 풂 - 행열 넣기 · 지우기: 병합과 같은 범위 옮김으로 이름 범위도 옮김 · 통째로 지워진 이름은 뺌 - 수식 계산 걸음도 이름을 풂 - 시험: test_spreadsheet_analysis.py names 묶음 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TULoa94ZFL26KU6ZqVpjkF
This commit is contained in:
@@ -164,4 +164,69 @@ section("errcheck", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
// ── 4. 이름 정의 풀이 ────────────────────────────────────────────────────────
|
||||
section("names", () => {
|
||||
const { C, E, F } = require("./helper_spreadsheet_engine.cjs");
|
||||
const N = load("spreadsheet_names");
|
||||
const show = (v) => (v === null ? null : E.isError(v) ? v.error : E.isFrac(v) ? F.fracToString(v) : v);
|
||||
const b = book(
|
||||
{ A1: 1, A2: 2, A3: 3, B1: 10, C1: "=SUM(값들)", C2: "=단가*2", C3: "=없는이름+1", C4: "=SUM(값들)*단가" },
|
||||
{ D1: "=SUM(값들)", D2: "=SUM(둘값)", E1: 100 },
|
||||
);
|
||||
b.시트[0].이름정의 = [
|
||||
{ 이름: "값들", 범위: A.parseRange("A1:A3") },
|
||||
{ 이름: "단가", 범위: A.parseRange("B1") },
|
||||
];
|
||||
b.시트[1].이름정의 = [{ 이름: "둘값", 범위: A.parseRange("E1") }];
|
||||
const e = G.createCalcEngine(b);
|
||||
const v = (a1, s = "s1") => {
|
||||
const p = A.parseA1(a1);
|
||||
return show(e.value(s, p.r, p.c));
|
||||
};
|
||||
eq("풀이", ["C1", "C2", "C3", "C4"].map((a) => v(a)), ["6", "20", "#NAME?", "60"]);
|
||||
eq("다른 시트에서 · 자기 시트 이름", [v("D1", "s2"), v("D2", "s2")], ["6", "100"]);
|
||||
// 이름 범위 칸을 고치면 따라 풂
|
||||
C.applyCommand(b, { 종류: "칸", 시트: "s1", 칸: { A1: { 값: 5 } } });
|
||||
e.update([{ 시트: "s1", r: 0, c: 0 }]);
|
||||
eq("딸린 칸 다시 풂", [v("C1"), v("C4"), v("D1", "s2")], ["10", "100", "10"]);
|
||||
// 식 계산 걸음도 이름을 품
|
||||
const p = A.parseA1("C4");
|
||||
eq(
|
||||
"계산 걸음",
|
||||
ST.evalSteps(b, e, "s1", p.r, p.c).map((s) => s.글),
|
||||
["SUM(값들)*단가", "10*단가", "10*10", "100"],
|
||||
);
|
||||
|
||||
// 이름 바꾸기 · 지우기(sub4 명령 → 시트통째 → rebuild)
|
||||
const ctx = {
|
||||
get book() {
|
||||
return b;
|
||||
},
|
||||
sheet: () => b.시트[0],
|
||||
dispatch: (cmd) => {
|
||||
C.applyCommand(b, cmd);
|
||||
e.rebuild(b);
|
||||
},
|
||||
};
|
||||
eq("이름 바꿈", N.renameName(ctx, "값들", "수량"), null);
|
||||
eq("바꾼 뒤", [b.시트[0].칸.C1.식, v("C1"), v("D1", "s2")], ["SUM(수량)", "10", "10"]);
|
||||
N.deleteName(ctx, "단가");
|
||||
eq("지운 뒤 #NAME?", [v("C2"), v("C4")], ["#NAME?", "#NAME?"]);
|
||||
|
||||
// 행 넣기 · 지우기 때 이름 범위가 따라감 · 되돌리기
|
||||
const fx = C.applyCommand(b, { 종류: "행넣기", 시트: "s1", at: 0, 수: 1 });
|
||||
e.rebuild(b);
|
||||
eq("넣은 뒤 범위", A.rangeToA1(b.시트[0].이름정의[0].범위), "A2:A4");
|
||||
eq("넣은 뒤 값", [v("C2"), v("D1", "s2")], ["10", "10"]);
|
||||
C.applyCommand(b, fx.undo);
|
||||
e.rebuild(b);
|
||||
eq("되돌린 범위", A.rangeToA1(b.시트[0].이름정의[0].범위), "A1:A3");
|
||||
C.applyCommand(b, { 종류: "행지우기", 시트: "s1", at: 1, 수: 1 });
|
||||
e.rebuild(b);
|
||||
eq("가운데 지움", [A.rangeToA1(b.시트[0].이름정의[0].범위), v("C1")], ["A1:A2", "8"]);
|
||||
C.applyCommand(b, { 종류: "열지우기", 시트: "s1", at: 0, 수: 1 });
|
||||
e.rebuild(b);
|
||||
eq("통째 지움 → 이름 빠짐", [b.시트[0].이름정의.length, v("B1")], [0, "#NAME?"]);
|
||||
});
|
||||
|
||||
process.stdout.write(JSON.stringify(results));
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
|
||||
선행 · 종속 추적(누를 때마다 한 단계 · 범위 화살 · 오류 칸 빨강 · 다른 시트 · 더 없으면 false) ·
|
||||
수식 계산 걸음(왼쪽 먼저 · 빈 칸 0 · 범위는 함수가 · IF 첫 인자만 · 괄호 안 밑줄 · 오류 전파) ·
|
||||
오류 검사(순환 · 식 결과 오류 · 숫자처럼 보이는 글).
|
||||
오류 검사(순환 · 식 결과 오류 · 숫자처럼 보이는 글) ·
|
||||
이름 정의 풀이(범위로 · 자기 시트 먼저 · 바꾸기 · 지우기 · 행열 넣기 · 지우기 때 범위 따라감 · 없는 이름 #NAME?).
|
||||
화면(화살 겹판 · 계산 창 · ⚠ 풍선)은 harness_analysis.html 을 ORCA 로.
|
||||
"""
|
||||
|
||||
@@ -14,7 +15,7 @@ import subprocess
|
||||
import pytest
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
GROUPS = ["trace", "eval_steps", "errcheck"]
|
||||
GROUPS = ["trace", "eval_steps", "errcheck", "names"]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
|
||||
Reference in New Issue
Block a user