Merge remote-tracking branch 'origin/main_desktop_1' into main_laptop_1
This commit is contained in:
@@ -62,7 +62,7 @@ const BORDER_LINES: BorderLine[] = [
|
||||
|
||||
type TextKey = Parameters<typeof st>[0];
|
||||
|
||||
const UNIT_GROUPS: [label: TextKey, items: string[]][] = [
|
||||
export const UNIT_GROUPS: [label: TextKey, items: string[]][] = [
|
||||
["UnitGroup_area", ["㎡", "㎥", "m", "㎝", "㎜", "㎞", "Φ"]],
|
||||
["UnitGroup_weight", ["kg", "t", "ℓ", "㎖"]],
|
||||
["UnitGroup_count", ["개", "본", "식", "EA", "매"]],
|
||||
@@ -70,7 +70,7 @@ const UNIT_GROUPS: [label: TextKey, items: string[]][] = [
|
||||
["UnitGroup_op", ["×", "÷", "±", "≤", "≥", "Σ"]],
|
||||
];
|
||||
/** 숫자 앞에 붙는 단위(관 지름 Φ300) — 나머지는 뒤에 붙음 */
|
||||
const UNIT_PREFIX = ["Φ"];
|
||||
export const UNIT_PREFIX = ["Φ"];
|
||||
const UNIT_RECENT_MAX = 8;
|
||||
const UNIT_RECENT_KEY = "aislo-ss-recent-units";
|
||||
|
||||
@@ -95,7 +95,7 @@ function pushRecentUnit(unit: string): string[] {
|
||||
|
||||
/** 숫자 형식 코드 끝 따옴표 글자(전에 붙인 단위)를 떼고 새 단위를 붙임 — 없으면 "0" 에서 시작.
|
||||
* 앞 단위(Φ)는 코드 앞에 붙임(`"Φ"0`) — 앞에 붙은 앞 단위는 먼저 뗌. */
|
||||
function attachUnitToFormat(code: string, unit: string): string {
|
||||
export function attachUnitToFormat(code: string, unit: string): string {
|
||||
const base = code || "0";
|
||||
if (!UNIT_PREFIX.includes(unit)) return base.replace(/"[^"]*"\s*$/, "") + `"${unit}"`;
|
||||
let plain = base;
|
||||
|
||||
@@ -174,4 +174,19 @@ eq(
|
||||
linkHues(["철근|ton"]).get("철근|ton"),
|
||||
);
|
||||
|
||||
// clearLinksCommand(81-4, 메인 판 함수에 맞춤) — 시트 하나뿐인 문서 · 거듭 불러도 안전
|
||||
const singleSheetBook = (): Workbook =>
|
||||
({
|
||||
종류: "통합문서",
|
||||
판: 1,
|
||||
열: "t",
|
||||
서식: [{}],
|
||||
시트: [{ id: "s1", 이름: "하나", 칸: {}, 연결: [{ 키: "k|m", 칸: "A1", 이름: "k" }] }],
|
||||
활성: "s1",
|
||||
}) as unknown as Workbook;
|
||||
b = singleSheetBook();
|
||||
run(b, clearLinksCommand(b));
|
||||
eq("한 시트 문서 — 모두 해제 뒤 연결 없음", links(b), [null]);
|
||||
eq("거듭 불러도 안전 = null", clearLinksCommand(b), null);
|
||||
|
||||
console.log(JSON.stringify({ pass, fail: failures.length, failures }));
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/* 단위 Φ(81-5) 순수 길 시험 진입 — vite --ssr 로 번들해 Node 로 돌림(메인 판 attachUnitToFormat ·
|
||||
* UNIT_PREFIX · UNIT_GROUPS 에 맞춤 — 81-3·81-4·81-5 겹침 정리).
|
||||
* 결과 = JSON {pass, fail, failures} 한 줄(`test_spreadsheet_toolbar_unit.py` 가 읽음) */
|
||||
import {
|
||||
attachUnitToFormat,
|
||||
UNIT_GROUPS,
|
||||
UNIT_PREFIX,
|
||||
} from "../../../A00_Common/spreadsheet/spreadsheet_toolbar";
|
||||
|
||||
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 PHI = "Φ";
|
||||
|
||||
// Φ 는 길이 묶음(UnitGroup_area) 끝 — 다른 묶음엔 안 들어감 · 앞 단위 목록에 있음
|
||||
const lengthGroup = UNIT_GROUPS.find(([label]) => label === "UnitGroup_area")!;
|
||||
eq("Φ = 길이 묶음 끝", lengthGroup[1][lengthGroup[1].length - 1], PHI);
|
||||
eq(
|
||||
"Φ 는 다른 묶음에 없음",
|
||||
UNIT_GROUPS.filter(([label]) => label !== "UnitGroup_area").some((g) => g[1].includes(PHI)),
|
||||
false,
|
||||
);
|
||||
eq("Φ 는 앞 단위 목록에 있음", UNIT_PREFIX.includes(PHI), true);
|
||||
|
||||
// 보통 단위(뒤에 붙음) — 지금처럼
|
||||
eq("보통 단위 서식 — 뒤", attachUnitToFormat("0", "㎡"), '0"㎡"');
|
||||
eq("보통 단위 서식 — 옛 단위 바꿈", attachUnitToFormat('0"㎡"', "㎝"), '0"㎝"');
|
||||
|
||||
// Φ(지름) — 숫자 앞(메인 판 attachUnitToFormat 이 앞/뒤를 한 함수에서 갈라 처리)
|
||||
eq("Φ 서식 — 앞", attachUnitToFormat("0", PHI), '"Φ"0');
|
||||
eq("Φ 서식 — 빈 코드도 0 기준", attachUnitToFormat("", PHI), '"Φ"0');
|
||||
eq("Φ 서식 — 옛 Φ 바꿈(겹쳐 안 붙음)", attachUnitToFormat('"Φ"0', PHI), '"Φ"0');
|
||||
eq("Φ 서식 — 뒤 단위와 공존", attachUnitToFormat('0"㎡"', PHI), '"Φ"0"㎡"');
|
||||
|
||||
console.log(JSON.stringify({ pass, fail: failures.length, failures }));
|
||||
@@ -55,7 +55,7 @@ def test_setLink_순수_길():
|
||||
assert run.stdout.strip(), run.stderr
|
||||
result = json.loads(run.stdout)
|
||||
assert result["fail"] == 0, result["failures"]
|
||||
assert result["pass"] == 35
|
||||
assert result["pass"] == 37
|
||||
|
||||
|
||||
def test_손잡이_setLink_몸():
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
"""단위 Φ(81-5) — `spreadsheet_toolbar.ts` UNIT_GROUPS 길이 묶음 끝에 Φ · 숫자 앞에 붙임.
|
||||
|
||||
순수 길(`attachUnitToFormat` · `UNIT_PREFIX` · `UNIT_GROUPS`)을 vite `--ssr` 로
|
||||
번들해 Node 로 돌림(81장 겹침 정리 — 메인 판 함수에 맞춤). 화면(단위 ▾ 팝오버 · 누르면 붙음)은 ORCA 로 확인.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
ENTRY = ROOT / "resources" / "tester" / "spreadsheet" / "spreadsheet_toolbar_unit_entry.ts"
|
||||
VITE = ROOT / "config" / "node_modules" / "vite" / "bin" / "vite.js"
|
||||
|
||||
|
||||
@pytest.mark.skipif(shutil.which("node") is None, reason="node 가 없음")
|
||||
def test_단위_파이_순수_길():
|
||||
with tempfile.TemporaryDirectory(prefix="spreadsheet_toolbar_unit_") as outdir:
|
||||
entry_rel = "../" + str(ENTRY.relative_to(ROOT)).replace("\\", "/")
|
||||
build = subprocess.run(
|
||||
[
|
||||
"node",
|
||||
str(VITE),
|
||||
"build",
|
||||
"--configLoader",
|
||||
"runner",
|
||||
"--ssr",
|
||||
entry_rel,
|
||||
"--outDir",
|
||||
outdir,
|
||||
],
|
||||
cwd=str(ROOT),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
timeout=120,
|
||||
)
|
||||
assert build.returncode == 0, f"vite ssr 번들 실패:\n{build.stdout}\n{build.stderr}"
|
||||
run = subprocess.run(
|
||||
["node", str(Path(outdir) / "spreadsheet_toolbar_unit_entry.js")],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
timeout=60,
|
||||
)
|
||||
assert run.stdout.strip(), run.stderr
|
||||
result = json.loads(run.stdout)
|
||||
assert result["fail"] == 0, result["failures"]
|
||||
assert result["pass"] == 9
|
||||
@@ -25,13 +25,15 @@ def _text() -> str:
|
||||
@pytest.mark.skipif(shutil.which("node") is None, reason="node 가 없음")
|
||||
def test_형식_코드_앞_단위_뒤_단위():
|
||||
src = _text()
|
||||
prefix = re.search(r"^const UNIT_PREFIX = .*;$", src, re.M)
|
||||
func = re.search(r"^function attachUnitToFormat[\s\S]*?^}", src, re.M)
|
||||
prefix = re.search(r"^(?:export )?const UNIT_PREFIX = .*;$", src, re.M)
|
||||
func = re.search(r"^(?:export )?function attachUnitToFormat[\s\S]*?^}", src, re.M)
|
||||
assert prefix and func
|
||||
script = (
|
||||
prefix.group(0)
|
||||
prefix.group(0).replace("export ", "")
|
||||
+ "\n"
|
||||
+ func.group(0).replace(": string", "") # 형 이름 뗌 — Node 가 그대로 돌게
|
||||
+ func.group(0)
|
||||
.replace("export ", "")
|
||||
.replace(": string", "") # 형 이름 뗌 — Node 가 그대로 돌게
|
||||
+ """
|
||||
const f = attachUnitToFormat;
|
||||
console.log(JSON.stringify([
|
||||
|
||||
Reference in New Issue
Block a user