auto: 2026-09-30 07:36 (ESD_LAPTOP)
This commit is contained in:
@@ -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},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user