auto: 2026-09-30 07:36 (ESD_LAPTOP)

This commit is contained in:
2026-09-30 07:36:32 +09:00
parent bf21676ef5
commit 559d445e4e
6 changed files with 304 additions and 13 deletions
@@ -255,6 +255,49 @@ trail.commit(step(1, { logic: "earthwork" }));
trail.commit(step(2, null));
const historyRecs = [trail.undo(), trail.undo(), trail.redo(), trail.redo()].map((one) => one.rec);
// ⑧ 비중 고정(계획서 26-2c) — 고정한 값은 안 움직이고 나머지가 합 100 을 맞춘다.
const W = { expected: 70, earthwork: 15, grade: 15 };
const L = (...keys) => ({ expected: false, earthwork: false, grade: false, ...Object.fromEntries(keys.map((k) => [k, true])) });
const sweep = [];
for (const locks of [L(), L("expected"), L("earthwork"), L("grade"), L("expected", "grade")]) {
for (const key of ["expected", "earthwork", "grade"]) {
for (let v = -5; v <= 105; v += 5) {
const out = model.moveWeight(W, locks, key, v);
sweep.push({
sum: out.expected + out.earthwork + out.grade,
lockedSame: Object.keys(locks).every((k) => !locks[k] || out[k] === W[k]),
range: [out.expected, out.earthwork, out.grade].every((n) => Number.isInteger(n) && n >= 0 && n <= 100),
});
}
}
}
const weightLocks = {
freeThree: model.moveWeight(W, L(), "expected", 40),
lockExpected: model.moveWeight(W, L("expected"), "earthwork", 20),
lockExpectedClamp: model.moveWeight(W, L("expected"), "earthwork", 90),
twoLocked: model.moveWeight({ expected: 70, earthwork: 20, grade: 10 }, L("expected", "earthwork"), "grade", 50),
movingLocked: model.moveWeight(W, L("expected"), "expected", 10),
derived: [model.derivedWeightKey(L()), model.derivedWeightKey(L("expected")), model.derivedWeightKey(L("expected", "earthwork"))],
canLock: {
none: model.canLockWeight(L(), "grade"),
one: model.canLockWeight(L("expected"), "grade"),
two: model.canLockWeight(L("expected", "earthwork"), "grade"),
unlockOfTwo: model.canLockWeight(L("expected", "earthwork"), "expected"),
},
input: {
free: model.inputWeight(W, L(), "earthwork", 55),
lockedOk: model.inputWeight(W, L("expected"), "earthwork", 20),
lockedTooBig: model.inputWeight(W, L("expected"), "earthwork", 40),
fraction: model.inputWeight(W, L(), "earthwork", 1.5),
negative: model.inputWeight(W, L(), "earthwork", -1),
over: model.inputWeight(W, L(), "earthwork", 101),
nan: model.inputWeight(W, L(), "earthwork", Number.NaN),
onLocked: model.inputWeight(W, L("earthwork"), "earthwork", 15),
derivedSame: model.inputWeight({ expected: 70, earthwork: 20, grade: 10 }, L("expected", "earthwork"), "grade", 10),
derivedOther: model.inputWeight({ expected: 70, earthwork: 20, grade: 10 }, L("expected", "earthwork"), "grade", 30),
},
};
// ④ 캐시 왕복 — 결과 통 프로젝트 칸. 꼴이 틀린 값은 안 읽는다.
model.writeInitialChoice("p-1", plain);
const readBack = model.readInitialChoice("p-1");
@@ -296,5 +339,7 @@ process.stdout.write(
initialRoute,
mapLines,
historyRecs,
sweep,
weightLocks,
}),
);
@@ -213,3 +213,36 @@ def test_노선_추천_다듬기_23_3():
assert "calc(var(--z-modal, 1000) + 2)" in css # 라벨 패널(+1) 위
assert "writing-mode: vertical-lr" in css
assert 'backdropClass: "b05-routerec-backdrop"' in read("B05_Profile_UI_RouteEdit_Recommend.ts")
def test_비중_고정_합_100_규칙(results):
"""고정한 값은 안 움직이고 나머지가 합 100 — 어떤 고정 · 어떤 값으로 옮겨도 정수 0~100 · 합 100."""
assert all(row["sum"] == 100 and row["lockedSame"] and row["range"] for row in results["sweep"])
w = results["weightLocks"]
# 안 고정: 지금 비율대로 나눔(기존 규칙)
assert w["freeThree"] == {"expected": 40, "earthwork": 30, "grade": 30}
# 예상 70 고정 → 토공을 끌면 기울기만 따라 바뀜
assert w["lockExpected"] == {"expected": 70, "earthwork": 20, "grade": 10}
# 남는 몫(30)을 넘게 끌면 잘림
assert w["lockExpectedClamp"] == {"expected": 70, "earthwork": 30, "grade": 0}
# 둘 고정 → 셋째는 저절로 정해져 안 움직임
assert w["twoLocked"] == {"expected": 70, "earthwork": 20, "grade": 10}
assert w["movingLocked"] == {"expected": 70, "earthwork": 15, "grade": 15}
assert w["derived"] == [None, None, "grade"]
# 셋 다 고정은 막음 · 푸는 것은 늘 됨
assert w["canLock"] == {"none": True, "one": True, "two": False, "unlockOfTwo": True}
def test_비중_값_칸_직접_입력(results):
"""0~100 정수 · 고정 규칙 아래 합 100 을 못 맞추면 받지 않음(빨간 테두리 · 안 보냄)."""
i = results["weightLocks"]["input"]
assert i["free"] == {"ok": True, "weights": {"expected": 37, "earthwork": 55, "grade": 8}}
assert i["lockedOk"] == {"ok": True, "weights": {"expected": 70, "earthwork": 20, "grade": 10}}
for name in ("lockedTooBig", "fraction", "negative", "over", "nan", "onLocked"):
assert i[name]["ok"] is False, name
assert i[name]["weights"] == {"expected": 70, "earthwork": 15, "grade": 15}, name
assert i["derivedSame"]["ok"] is True
assert i["derivedOther"] == {
"ok": False,
"weights": {"expected": 70, "earthwork": 20, "grade": 10},
}