feat(b05): 원단위 표가 아직 안 읽는 칸에 「표에 안 쓰임」 — 골막이·바닥막이·큰돌쌓기·흙막이 23칸 · 값을 바꿔 돌려 보는 시험이 표시를 지킴(①)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
This commit is contained in:
@@ -38,6 +38,8 @@ export interface StructureOptionField {
|
||||
/** 이 값을 넘으면 칸이 경고색 + 툴팁(막지 않음) — 기준값과 까닭 한 줄. */
|
||||
warn_above?: number | null;
|
||||
warn_message?: string | null;
|
||||
/** 원단위 표가 아직 안 읽는 칸 — 칸 이름 옆 「표에 안 쓰임」 + 툴팁 사유. */
|
||||
not_in_table?: string | null;
|
||||
}
|
||||
|
||||
/** 구조물 배치 폼을 어느 화면이 쓰는가 — B05 는 유무·종류·위치만, **B06/B07 은 상세
|
||||
|
||||
@@ -1279,7 +1279,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 실무 구조물도 식으로 돎(뒷길이 + 0.30) — 값을 넣으면 그 값이 이김"
|
||||
"empty_means": "비우면 실무 구조물도 식으로 돎(뒷길이 + 0.30) — 값을 넣으면 그 값이 이김",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 흙막이는 「떼」만 서고 치수가 정본 평균 붙박이 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "thickness_bottom_m",
|
||||
@@ -1289,7 +1290,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 상부 + 0.30×(H−1) 로 돎 — 값을 넣으면 그 값이 이김"
|
||||
"empty_means": "비우면 상부 + 0.30×(H−1) 로 돎 — 값을 넣으면 그 값이 이김",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 흙막이는 「떼」만 서고 치수가 정본 평균 붙박이 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "back_len_cm",
|
||||
@@ -1299,7 +1301,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 돌쌓기 기본값으로 서고 「기본값으로 섰음」이 줄로 뜸 — 돌이 아닌 형태도 있어 필수로 못 검"
|
||||
"empty_means": "비우면 돌쌓기 기본값으로 서고 「기본값으로 섰음」이 줄로 뜸 — 돌이 아닌 형태도 있어 필수로 못 검",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 흙막이는 「떼」만 서고 치수가 정본 평균 붙박이 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "stone_kind",
|
||||
@@ -1309,7 +1312,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 야면석 계수 열로 서고 그 사실이 줄로 뜸 — 돌이 아닌 형태도 있어 필수로 못 검"
|
||||
"empty_means": "비우면 야면석 계수 열로 서고 그 사실이 줄로 뜸 — 돌이 아닌 형태도 있어 필수로 못 검",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 흙막이는 「떼」만 서고 치수가 정본 평균 붙박이 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "stone_supply",
|
||||
@@ -1319,7 +1323,8 @@
|
||||
"default": "채집",
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"default_basis": "「채집」 — 별표2 「야면석 등은 가급적 현장에서 채취·사용」 권고. 구조물마다 바꿀 수 있음"
|
||||
"default_basis": "「채집」 — 별표2 「야면석 등은 가급적 현장에서 채취·사용」 권고. 구조물마다 바꿀 수 있음",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 흙막이는 「떼」만 서고 치수가 정본 평균 붙박이 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "stone_coeff_basis",
|
||||
@@ -1329,7 +1334,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 품셈 열로 돎 — 실무 관행 열은 골라야 씀"
|
||||
"empty_means": "비우면 품셈 열로 돎 — 실무 관행 열은 골라야 씀",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 흙막이는 「떼」만 서고 치수가 정본 평균 붙박이 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "fill_concrete_mpa",
|
||||
@@ -1339,7 +1345,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 계산 쪽 기준 강도로 돎"
|
||||
"empty_means": "비우면 계산 쪽 기준 강도로 돎",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 흙막이는 「떼」만 서고 치수가 정본 평균 붙박이 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "face_slope_ratio",
|
||||
@@ -1348,7 +1355,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 품셈 표준경사로 자동 판정 — 값을 넣으면 그 값이 이김"
|
||||
"empty_means": "비우면 품셈 표준경사로 자동 판정 — 값을 넣으면 그 값이 이김",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 흙막이는 「떼」만 서고 치수가 정본 평균 붙박이 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "foundation",
|
||||
@@ -1367,7 +1375,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 국가기준 Ø50 으로 돎 — 사용자 확정 「국가기준 + 숫자 변경 가능하게」"
|
||||
"empty_means": "비우면 국가기준 Ø50 으로 돎 — 사용자 확정 「국가기준 + 숫자 변경 가능하게」",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 흙막이는 「떼」만 서고 치수가 정본 평균 붙박이 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "weep_hole_area_m2",
|
||||
@@ -1377,7 +1386,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 국가기준 2㎡당 1개로 돎 — 사용자 확정 「국가기준 + 숫자 변경 가능하게」"
|
||||
"empty_means": "비우면 국가기준 2㎡당 1개로 돎 — 사용자 확정 「국가기준 + 숫자 변경 가능하게」",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 흙막이는 「떼」만 서고 치수가 정본 평균 붙박이 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1454,7 +1464,8 @@
|
||||
"choices": ["채집", "구입"],
|
||||
"default": "채집",
|
||||
"required": false,
|
||||
"phase": "detail"
|
||||
"phase": "detail",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 큰돌쌓기는 채집석 공제를 아직 안 셈 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "stone_coeff_basis",
|
||||
@@ -1464,7 +1475,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 품셈 열로 돎 — 실무 관행 열은 골라야 씀"
|
||||
"empty_means": "비우면 품셈 열로 돎 — 실무 관행 열은 골라야 씀",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 큰돌쌓기(13-6)는 계수 열을 아직 안 가름 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "fill_concrete_mpa",
|
||||
@@ -1474,7 +1486,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 계산 쪽 기준 강도로 돎"
|
||||
"empty_means": "비우면 계산 쪽 기준 강도로 돎",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 큰돌쌓기(13-6)는 채움 콘크리트를 품에 포함 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "face_slope_ratio",
|
||||
@@ -1510,7 +1523,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 국가기준 Ø50 으로 돎 — 사용자 확정 「국가기준 + 숫자 변경 가능하게」"
|
||||
"empty_means": "비우면 국가기준 Ø50 으로 돎 — 사용자 확정 「국가기준 + 숫자 변경 가능하게」",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 큰돌쌓기는 물빼기 관을 아직 안 셈 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "weep_hole_area_m2",
|
||||
@@ -1520,7 +1534,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 국가기준 2㎡당 1개로 돎 — 사용자 확정 「국가기준 + 숫자 변경 가능하게」"
|
||||
"empty_means": "비우면 국가기준 2㎡당 1개로 돎 — 사용자 확정 「국가기준 + 숫자 변경 가능하게」",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 큰돌쌓기는 물빼기 관을 아직 안 셈 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "blinding_concrete",
|
||||
@@ -1648,7 +1663,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 실무 구조물도 식으로 돎(뒷길이 + 0.30) — 값을 넣으면 그 값이 이김"
|
||||
"empty_means": "비우면 실무 구조물도 식으로 돎(뒷길이 + 0.30) — 값을 넣으면 그 값이 이김",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 골막이 두께는 정본 식(ℓ3+0.1H · ℓ3+0.4H)으로만 셈 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "thickness_bottom_m",
|
||||
@@ -1658,7 +1674,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 상부 + 0.30×(H−1) 로 돎 — 값을 넣으면 그 값이 이김"
|
||||
"empty_means": "비우면 상부 + 0.30×(H−1) 로 돎 — 값을 넣으면 그 값이 이김",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 골막이 두께는 정본 식(ℓ3+0.1H · ℓ3+0.4H)으로만 셈 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "back_len_cm",
|
||||
@@ -1676,7 +1693,8 @@
|
||||
"choices": ["채집", "구입"],
|
||||
"default": "채집",
|
||||
"required": false,
|
||||
"phase": "detail"
|
||||
"phase": "detail",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 골막이는 채집석 공제를 아직 안 셈 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "stone_coeff_basis",
|
||||
@@ -1686,7 +1704,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 품셈 열로 돎 — 실무 관행 열은 골라야 씀"
|
||||
"empty_means": "비우면 품셈 열로 돎 — 실무 관행 열은 골라야 씀",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 골막이는 계수 열을 아직 안 가름 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "fill_concrete_mpa",
|
||||
@@ -1797,7 +1816,8 @@
|
||||
"choices": ["채집", "구입"],
|
||||
"default": "채집",
|
||||
"required": false,
|
||||
"phase": "detail"
|
||||
"phase": "detail",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 바닥막이는 채집석 공제를 아직 안 셈 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "stone_coeff_basis",
|
||||
@@ -1807,7 +1827,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 품셈 열로 돎 — 실무 관행 열은 골라야 씀"
|
||||
"empty_means": "비우면 품셈 열로 돎 — 실무 관행 열은 골라야 씀",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 바닥막이 원단위는 돌붙임 정본 표 붙박이 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "fill_concrete_mpa",
|
||||
@@ -1817,7 +1838,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 계산 쪽 기준 강도로 돎"
|
||||
"empty_means": "비우면 계산 쪽 기준 강도로 돎",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 바닥막이 원단위는 돌붙임 정본 표 붙박이 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "face_slope_ratio",
|
||||
@@ -1826,7 +1848,8 @@
|
||||
"default": null,
|
||||
"required": false,
|
||||
"phase": "detail",
|
||||
"empty_means": "비우면 품셈 표준경사로 자동 판정 — 값을 넣으면 그 값이 이김"
|
||||
"empty_means": "비우면 품셈 표준경사로 자동 판정 — 값을 넣으면 그 값이 이김",
|
||||
"not_in_table": "아직 표에 안 쓰임 — 바닥막이는 평면적(돌붙임 ㎡)이라 기울기 몫이 없음 · 넣어도 수량·금액이 안 바뀜(2026-09-14)"
|
||||
},
|
||||
{
|
||||
"key": "foundation",
|
||||
|
||||
@@ -64,6 +64,9 @@ class StructureOptionField(BaseModel):
|
||||
# 넘는지 보는 기준값과 그 까닭 한 줄(원문 쪽·줄 번호).
|
||||
warn_above: float | None = None
|
||||
warn_message: str | None = None
|
||||
# 칸은 있는데 **원단위 표가 아직 안 읽는** 칸 — 넣어도 수량·금액이 안 바뀜을 칸 옆에 보임(2026-09-14 ①).
|
||||
# 참말인지는 `test_b05_not_in_table_marks` 가 값을 바꿔 돌려 보고 지킴.
|
||||
not_in_table: str | None = None
|
||||
|
||||
|
||||
class StructureType(BaseModel):
|
||||
|
||||
@@ -43,6 +43,8 @@ interface OptionShape {
|
||||
/** 이 값을 넘으면 칸이 경고색 + 툴팁(막지 않음). */
|
||||
warn_above?: number | null;
|
||||
warn_message?: string | null;
|
||||
/** 원단위 표가 아직 안 읽는 칸 — 툴팁이 이 사유를 먼저 보임. */
|
||||
not_in_table?: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,6 +59,8 @@ export function optionControl(
|
||||
): HTMLInputElement | HTMLSelectElement {
|
||||
const value = stored === undefined || stored === null ? "" : String(stored);
|
||||
const suggested = option.default === null || option.default === "" ? "" : String(option.default);
|
||||
// 툴팁 — 표가 아직 안 읽는 칸이면 그 사유가 먼저(넣어도 안 바뀜을 알아야 함), 아니면 비울 때의 뜻.
|
||||
const tip = option.not_in_table ?? option.empty_means ?? "";
|
||||
if (option.input === "select") {
|
||||
const blank = suggested
|
||||
? `— 안 정함 (제안 ${suggested}) —`
|
||||
@@ -65,7 +69,7 @@ export function optionControl(
|
||||
: "— 안 정함 —";
|
||||
const element = select([["", blank], ...option.choices.map((c) => [c, c] as [string, string])]);
|
||||
element.value = value;
|
||||
if (option.empty_means) element.title = option.empty_means;
|
||||
if (tip) element.title = tip;
|
||||
return element;
|
||||
}
|
||||
const element =
|
||||
@@ -73,14 +77,14 @@ export function optionControl(
|
||||
if (option.input !== "number") element.type = "text";
|
||||
element.value = value;
|
||||
element.placeholder = suggested ? `제안 ${suggested}` : option.required ? "필수 입력" : "";
|
||||
if (option.empty_means) element.title = option.empty_means;
|
||||
if (tip) element.title = tip;
|
||||
const limit = option.warn_above;
|
||||
if (typeof limit === "number") {
|
||||
// 기준을 넘으면 알리기만 — 막지 않음(2026-09-14 브레인 판정 ①·㉰).
|
||||
const warn = (): void => {
|
||||
const over = element.value.trim() !== "" && Number(element.value) > limit;
|
||||
element.classList.toggle("is-outside-standard", over);
|
||||
element.title = over ? (option.warn_message ?? "") : (option.empty_means ?? "");
|
||||
element.title = over ? (option.warn_message ?? "") : tip;
|
||||
};
|
||||
element.addEventListener("input", warn);
|
||||
warn();
|
||||
|
||||
@@ -322,7 +322,7 @@ export function createStructuresSection(
|
||||
// 첫 보기를 미리 안 고름(2026-09-14 브레인 판정 ①②, `optionControl` 주석).
|
||||
const input = optionControl(option, values[option.key]);
|
||||
suggestions.push({ input, suggested: String(option.default ?? "") });
|
||||
const label = option.unit ? `${option.label} (${option.unit})` : option.label;
|
||||
const label = `${option.unit ? `${option.label} (${option.unit})` : option.label}${option.not_in_table ? " · 표에 안 쓰임" : ""}`;
|
||||
// `enabled:false` 는 칸을 남기고 잠그기만 한다 — 값은 기본값이 그대로 저장된다
|
||||
// (고를 수 없는 칸이라 제안이 아니라 프로그램 값).
|
||||
const locked = option.enabled === false;
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""「칸은 있는데 표가 안 읽음」 — 등록부 칸 옆에 「아직 표에 안 쓰임」 (2026-09-14 브레인 차례 ①).
|
||||
|
||||
사용자가 값을 넣어도 수량·금액이 아무것도 안 바뀌는 칸. 사유를 표에만 두지 말고 칸 옆에도 보임
|
||||
(브레인 판정 ③ 「B」). 표시가 참말인지 **값을 바꿔 돌려 보고** 지킴 — 표가 그 칸을 읽기 시작하면
|
||||
여기서 깨지고, 그때 표시를 걷음(표시가 거짓말로 남지 않게).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
if str(ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from B05_Profile.B05_Profile_Structures_Schema import structure_type_map # noqa: E402
|
||||
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table # noqa: E402
|
||||
|
||||
#: 종류 → (표가 서는 기준 제원, 안 읽는 칸). 2026-09-14 값을 바꿔 전수 대조한 결과.
|
||||
#: ⚠ 기초(foundation)·높이는 인계 구조물터파기 심도 구간이 읽어 뺌 · 단 수·올림·이동은 횡단도 칸이라 뺌.
|
||||
MARKED: dict[str, tuple[dict, list[str]]] = {
|
||||
"erosion_check": (
|
||||
{"height_m": 2.0, "top_length_m": 6.0, "bottom_length_m": 4.0, "form": "돌"},
|
||||
["thickness_top_m", "thickness_bottom_m", "stone_supply", "stone_coeff_basis"],
|
||||
),
|
||||
"bed_sill": (
|
||||
{"area_m2": 10.0, "form": "돌붙임(찰)"},
|
||||
["stone_supply", "stone_coeff_basis", "fill_concrete_mpa", "face_slope_ratio"],
|
||||
),
|
||||
"boulder_masonry": (
|
||||
{"height_m": 2.5, "length_m": 10.0, "stone_cm": "60~80", "bond": "찰쌓기"},
|
||||
[
|
||||
"stone_supply",
|
||||
"stone_coeff_basis",
|
||||
"fill_concrete_mpa",
|
||||
"weep_hole_diameter_mm",
|
||||
"weep_hole_area_m2",
|
||||
],
|
||||
),
|
||||
"soil_guard": (
|
||||
{"height_m": 1.0, "length_m": 10.0, "form": "떼"},
|
||||
[
|
||||
"thickness_top_m",
|
||||
"thickness_bottom_m",
|
||||
"back_len_cm",
|
||||
"stone_kind",
|
||||
"stone_supply",
|
||||
"stone_coeff_basis",
|
||||
"fill_concrete_mpa",
|
||||
"face_slope_ratio",
|
||||
"weep_hole_diameter_mm",
|
||||
"weep_hole_area_m2",
|
||||
],
|
||||
),
|
||||
}
|
||||
|
||||
FIELDS = (ROOT / "B05_Profile" / "B05_Profile_UI_Structures_Fields.ts").read_text(encoding="utf-8")
|
||||
PANEL = (ROOT / "B05_Profile" / "B05_Profile_UI_Structures_Panel.ts").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def _snapshot(type_id: str, options: dict) -> str:
|
||||
structure = {
|
||||
"structure_id": "p",
|
||||
"type_id": type_id,
|
||||
"start_m": 0.0,
|
||||
"end_m": 10.0,
|
||||
"chainage_m": 5.0,
|
||||
"options": options,
|
||||
}
|
||||
table = build_table([structure], {}, {5.0: "both_fill"}, None, 0.2)
|
||||
# 저장 제원을 그대로 되돌려 싣는 칸(`options`)은 뺌 — 값이 **표에 닿았는지**만 봄.
|
||||
for row in table["structures"]:
|
||||
row.pop("options", None)
|
||||
return json.dumps(table, ensure_ascii=False, sort_keys=True, default=str)
|
||||
|
||||
|
||||
def _probe_values(option) -> list:
|
||||
if option.choices:
|
||||
return list(option.choices)
|
||||
return [0.73, 1.37] if option.input == "number" else ["x"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("type_id", sorted(MARKED))
|
||||
def test_등록부에_표시가_있다(type_id: str) -> None:
|
||||
options = {option.key: option for option in structure_type_map()[type_id].options}
|
||||
for key in MARKED[type_id][1]:
|
||||
note = options[key].not_in_table
|
||||
assert note and "아직 표에 안 쓰임" in note, f"{type_id}.{key}"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("type_id", sorted(MARKED))
|
||||
def test_표시한_칸은_정말_안_읽힌다(type_id: str) -> None:
|
||||
base, keys = MARKED[type_id]
|
||||
options = {option.key: option for option in structure_type_map()[type_id].options}
|
||||
reference = _snapshot(type_id, dict(base))
|
||||
assert '"components": []' not in reference, "기준 제원으로 표가 안 섬 — 시험이 무의미"
|
||||
for key in keys:
|
||||
for value in _probe_values(options[key]):
|
||||
assert _snapshot(type_id, {**base, key: value}) == reference, (
|
||||
f"{type_id}.{key}={value!r} 로 표가 바뀜 — 이제 읽힘, 표시를 걷을 것"
|
||||
)
|
||||
|
||||
|
||||
def test_폼_칸_이름에_붙는다() -> None:
|
||||
assert "not_in_table" in FIELDS and "not_in_table" in PANEL
|
||||
Reference in New Issue
Block a user