# -*- coding: utf-8 -*- """스프레드시트 D 입력 — 고름 · 입력 글 규칙 · 참조 가리키기 자리 · 채우기 끌기 목표(엑셀 동작 기준). Node 도우미(helper_spreadsheet_d.cjs)가 TS 를 풀어 돌리고 JSON 을 줌 — 남의 몫이 빈 몸이면 가짜 부품. 화면 조작(한글 첫 글자 · 수식 입력줄 · 끌기)은 harness_spreadsheet_d.html 을 ORCA 로. """ import json import os import subprocess import pytest HERE = os.path.dirname(os.path.abspath(__file__)) @pytest.fixture(scope="module") def r(): proc = subprocess.run( ["node", os.path.join(HERE, "helper_spreadsheet_d.cjs")], capture_output=True, text=True, encoding="utf-8", timeout=60, ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) def test_merge_selection(r): assert r["mergeClick"] == "C4|C4:F4" assert r["mergeMove"] == ["G4|G4", "C4|C4:F4", "B4|B4"] assert r["colHead"] == "A:H" # 걸친 병합(A1:H1 · C3:F3 · A6:G6)만큼 늘림 def test_shift_ctrl_arrows(r): assert r["shiftExtend"] == ["A4|A4:B4", "A4|A4:F4", "A4|A4:B4", "A4|A4:B5"] assert r["ctrlJump"] == ["A6|A6:G6", "A1048576|A1048576", "A6|A6:G6"] assert r["hiddenSkip"] == ["K1"] assert r["usedEnd"] == "J6" def test_cycle_in_selection(r): assert r["cycleEnter"] == ["K12", "L11", "L12", "K11"] assert r["cycleTab"] == ["L11", "K12", "L12"] assert r["cycleSingle"] is None def test_text_to_cell(r): got = r["textToCell"] assert [c.get("값", c.get("식")) for c in got] == [ 12, 1234.5, 0.5, -1000, True, "=12", "=", "A1+1", None, "1,23", "abc", ] assert "식" in got[7] and all(c["서식"] == 4 for c in got) assert r["textToCellNoStyle"] is None def test_cell_to_text(r): assert r["cellToText"] == ["'=12", "'12", "abc", "1.5", "FALSE", "=A1*2", ""] def test_pointing(r): assert r["insertable"] == [True, True, False, True, True, True, False, False] assert r["highlights"] == ["s1:A1:0", "s1:B2:C3:1", "s1:A1:0", "s2:B1:2"] def test_fill_target(r): assert r["fill"] == [ ["B2:C10", None], ["B2:G4", None], ["B2:B4", "C2:C4"], ["B2:C3", "B4:C4"], ] def test_formula_hint(r): assert r["hint"] == [ {"prefix": "su"}, {"prefix": "ro"}, None, {"func": "ROUND", "arg": 1}, {"func": "SUM", "arg": 2}, {"func": "IF", "arg": 1}, None, ]