From 47a63d3fa4f85dafc81393a1684c6a606627c9ee Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 19 Oct 2026 19:22:10 +0900 Subject: [PATCH] =?UTF-8?q?feat(478-2=20=EB=AC=B8=EC=84=9C=20=EC=82=AC?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8):=20=EC=A7=84=EC=A7=9C=20=EC=B6=94=EC=B6=9C?= =?UTF-8?q?=EB=A1=9C=20=EB=A7=9E=EC=B6=A4=20=E2=80=94=20TypeDoc=20kind-dir?= =?UTF-8?q?(=EB=8C=80=EC=86=8C=EB=AC=B8=EC=9E=90=20=EA=B2=B9=EC=B9=A8=20?= =?UTF-8?q?=EB=A7=89=EC=9D=8C)=20=C2=B7=20=EB=8F=84=EA=B5=AC=20=EB=8C=80?= =?UTF-8?q?=20=EC=B6=94=EC=B6=9C=20=EB=B9=84=EA=B5=90=20=EA=B7=9C=EC=B9=99?= =?UTF-8?q?=20=C2=B7=20=EA=B3=B5=EC=9A=A9=20=EB=8F=84=EA=B5=AC=20=EB=AC=B6?= =?UTF-8?q?=EC=9D=8C=20=C2=B7=20=EC=86=90=EA=B8=80=20=EC=A7=80=EB=AC=B8=20?= =?UTF-8?q?=C2=B7=20TS=20=EB=A9=94=EB=89=B4=20=EC=AA=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TypeDoc router kind-dir — structure 는 같은 이름 인터페이스 · 함수가 Windows 에서 한 파일로 덮임 · 겹침 링크 안 함 - 비교: TS = export 함수 · 메서드 · 생성자 · 접근자(상속 · 숨은 생성자 뺌 · export * 는 원본으로) · 파이썬 = 안쪽 함수 뺀 전부 ↔ griffe(속성 · 자동 생성 __init__ 반영) - groups.yml 공용 도구(common_util_* 끝 규칙) · 묶음 없음 0 · 손글 18 묶음 지문 - 결과: 함수 5,746 · 묶음 18 · 세션 칸 45 · 서버 주소 41 · strict 경고 0 · test_478_docs 9 통과 Co-Authored-By: Claude Opus 5.5 --- docs/guide/B05_B06/groups/common.md | 5 ++ docs/guide/B05_B06/groups/corridor.md | 4 + docs/guide/B05_B06/groups/cross.md | 4 + docs/guide/B05_B06/groups/cross_view.md | 4 + docs/guide/B05_B06/groups/drainage.md | 4 + docs/guide/B05_B06/groups/earthwork.md | 4 + docs/guide/B05_B06/groups/footprint.md | 4 + docs/guide/B05_B06/groups/ground.md | 4 + docs/guide/B05_B06/groups/pipeline.md | 4 + docs/guide/B05_B06/groups/profile.md | 4 + docs/guide/B05_B06/groups/recommend.md | 4 + docs/guide/B05_B06/groups/route_edit.md | 4 + docs/guide/B05_B06/groups/route_save.md | 4 + docs/guide/B05_B06/groups/save.md | 4 + docs/guide/B05_B06/groups/screen.md | 4 + docs/guide/B05_B06/groups/server.md | 4 + docs/guide/B05_B06/groups/stations.md | 4 + docs/guide/B05_B06/groups/structures.md | 4 + docs/tools/build.py | 72 +++++++++++++----- docs/tools/groups.yml | 9 +++ .../tester/fixtures/478_docs/functions.json | 74 ++++++++++++++----- resources/tester/test_478_docs.py | 55 +++++++------- 22 files changed, 223 insertions(+), 60 deletions(-) create mode 100644 docs/guide/B05_B06/groups/common.md diff --git a/docs/guide/B05_B06/groups/common.md b/docs/guide/B05_B06/groups/common.md new file mode 100644 index 000000000..847f681f8 --- /dev/null +++ b/docs/guide/B05_B06/groups/common.md @@ -0,0 +1,5 @@ +--- +지문: a0ee5171a3 +--- + +공용 도구 — 인증 · 좌표계 · 저장소 · 프로젝트 설정 · 그림 같은 여러 페이지가 함께 쓰는 도우미. diff --git a/docs/guide/B05_B06/groups/corridor.md b/docs/guide/B05_B06/groups/corridor.md index 3309eca4a..89490b107 100644 --- a/docs/guide/B05_B06/groups/corridor.md +++ b/docs/guide/B05_B06/groups/corridor.md @@ -1,3 +1,7 @@ +--- +지문: 10df7a8380 +--- + 3D 길 모형 — 종단 · 횡단으로 길 몸체를 지음. - 노선 초안 · 종단 고침 동안 낡음 표시 · [저장] 뒤 서버 Node 가 다시 지음. diff --git a/docs/guide/B05_B06/groups/cross.md b/docs/guide/B05_B06/groups/cross.md index 7e7d768b0..4ab4cc873 100644 --- a/docs/guide/B05_B06/groups/cross.md +++ b/docs/guide/B05_B06/groups/cross.md @@ -1,3 +1,7 @@ +--- +지문: f4a6907e23 +--- + 횡단 설계선 · 면적 계산 — 브라우저 즉시 · [저장] 때 서버 Node 정본. - 설계선 = [[computeCrossDesign]] ↔ 파이썬 짝 · 단면적은 표준 · 구조물 측점 모두 Node. diff --git a/docs/guide/B05_B06/groups/cross_view.md b/docs/guide/B05_B06/groups/cross_view.md index 774bc174a..7e4fe8032 100644 --- a/docs/guide/B05_B06/groups/cross_view.md +++ b/docs/guide/B05_B06/groups/cross_view.md @@ -1,3 +1,7 @@ +--- +지문: dce3f67328 +--- + 횡단 화면 — 카드 단추 · 조정창 · 반폭 · 표준횡단 · 상세 표. - 카드 단추 = 세션 `crossdesign` 의 바꾼 칸만 · 메모리 상세 설계를 안 덮음. diff --git a/docs/guide/B05_B06/groups/drainage.md b/docs/guide/B05_B06/groups/drainage.md index f6577f5f7..476c083a8 100644 --- a/docs/guide/B05_B06/groups/drainage.md +++ b/docs/guide/B05_B06/groups/drainage.md @@ -1,3 +1,7 @@ +--- +지문: f36ccf36ae +--- + 관 · 배수 — 배수판 관 편집 · 배수유역 · 관 옵션. - 관 주인 = 가게 `pipes` · 배수 편집기는 숨어도 가게를 따름. diff --git a/docs/guide/B05_B06/groups/earthwork.md b/docs/guide/B05_B06/groups/earthwork.md index 5594aca1a..52844c501 100644 --- a/docs/guide/B05_B06/groups/earthwork.md +++ b/docs/guide/B05_B06/groups/earthwork.md @@ -1,3 +1,7 @@ +--- +지문: a0e40f1c62 +--- + 누가토량 · 유토 배분 · 운반거리. - 누가토량 = TS 한 벌(브라우저 · Node) · 그릴 때 셈(접혀도 셈). diff --git a/docs/guide/B05_B06/groups/footprint.md b/docs/guide/B05_B06/groups/footprint.md index 07cc730df..c400a73b9 100644 --- a/docs/guide/B05_B06/groups/footprint.md +++ b/docs/guide/B05_B06/groups/footprint.md @@ -1,3 +1,7 @@ +--- +지문: 582a7c1377 +--- + 평면 발자국 — 횡단 결과로 평면에 깎기 · 쌓기 테두리. - 묶음 마지막 단계 · B07 은 따로(파이썬) · 거울 시험. diff --git a/docs/guide/B05_B06/groups/ground.md b/docs/guide/B05_B06/groups/ground.md index 3e58e3aa4..1a2c78376 100644 --- a/docs/guide/B05_B06/groups/ground.md +++ b/docs/guide/B05_B06/groups/ground.md @@ -1,3 +1,7 @@ +--- +지문: e6f779df26 +--- + 측점마다 원지반 표본 — 브라우저 지형 격자 · 서버 npz. - 표본 짝 = 브라우저 격자 ↔ 서버 `sample_xy`(거울 시험) · 입력 선이 달라 mm 차. diff --git a/docs/guide/B05_B06/groups/pipeline.md b/docs/guide/B05_B06/groups/pipeline.md index ae9d6e444..1dd048ae6 100644 --- a/docs/guide/B05_B06/groups/pipeline.md +++ b/docs/guide/B05_B06/groups/pipeline.md @@ -1,3 +1,7 @@ +--- +지문: 86e59255e5 +--- + 계산 묶음 · 설계 가게 · 상세 가게 — 입력 → 파생 한 방향. - 묶음 단계 = 노선 → 따라감 → 측점 → 지반 → 첫 계획선 → 종단 → 횡단 → 발자국 · 차례 번호 · 옛 차례 버림. diff --git a/docs/guide/B05_B06/groups/profile.md b/docs/guide/B05_B06/groups/profile.md index 77d773762..666b2dc32 100644 --- a/docs/guide/B05_B06/groups/profile.md +++ b/docs/guide/B05_B06/groups/profile.md @@ -1,3 +1,7 @@ +--- +지문: eb1c3888ea +--- + 종단 계획고 — ▲▼ · 직선화 · 자유지정 · 쉬프트 · 종단 R · 시종점 · 페이지 설정. - 편집값 주인 = 가게 `alignmentDraft`(세션 `alignment-draft`) · 지금 값 = 초안 ?? 서버 저장분. diff --git a/docs/guide/B05_B06/groups/recommend.md b/docs/guide/B05_B06/groups/recommend.md index 009d818bb..9ed9eb6d1 100644 --- a/docs/guide/B05_B06/groups/recommend.md +++ b/docs/guide/B05_B06/groups/recommend.md @@ -1,3 +1,7 @@ +--- +지문: 9abd21f485 +--- + 추천 노선 후보를 서버가 찾고 화면이 보여 줌 · 고른 후보를 [적용]. - 후보 초기 종단 = [적용] 체인과 같은 조각을 메모리에서 셈 · 저장본 `route_recommend/initial`. diff --git a/docs/guide/B05_B06/groups/route_edit.md b/docs/guide/B05_B06/groups/route_edit.md index 5c4534989..743222080 100644 --- a/docs/guide/B05_B06/groups/route_edit.md +++ b/docs/guide/B05_B06/groups/route_edit.md @@ -1,3 +1,7 @@ +--- +지문: d59d1cfa21 +--- + 평면 노선 편집기 — 교점 끌기 · 방향키 · 교점 추가 · 삭제 · 곡선 R · L · 스냅. - 조작은 편집기 메모리 → 놓을 때 세션 `route-draft` · 첫 초안이면 초안 전 상세를 hold. diff --git a/docs/guide/B05_B06/groups/route_save.md b/docs/guide/B05_B06/groups/route_save.md index 431fea4b0..54a1905ea 100644 --- a/docs/guide/B05_B06/groups/route_save.md +++ b/docs/guide/B05_B06/groups/route_save.md @@ -1,3 +1,7 @@ +--- +지문: 61b274fe26 +--- + 노선이 바뀐 [저장] — 새 노선 짜기 · 관 · 구조물 · 추가 측점 따라감 · 횡단 고침 넘김. - 서버 [[run_route_save_chain]] = 노선 · 측점 · 표본 · 횡단을 처음부터 · 전부 아니면 없음. diff --git a/docs/guide/B05_B06/groups/save.md b/docs/guide/B05_B06/groups/save.md index 2c2071272..f53202535 100644 --- a/docs/guide/B05_B06/groups/save.md +++ b/docs/guide/B05_B06/groups/save.md @@ -1,3 +1,7 @@ +--- +지문: 14969d7db0 +--- + [저장] · [확정] · [초기화] · 떠남. - [저장] · [확정] = 한 본문 한 요청 · 서버가 차례(노선 → 설정 → 관 → 구조물 → 추가 측점 → 종단 → 관 옵션 → 상단측 → 횡단)로 · 하나라도 실패 = 되돌림. diff --git a/docs/guide/B05_B06/groups/screen.md b/docs/guide/B05_B06/groups/screen.md index ab30a602b..1e3d8f64e 100644 --- a/docs/guide/B05_B06/groups/screen.md +++ b/docs/guide/B05_B06/groups/screen.md @@ -1,3 +1,7 @@ +--- +지문: 4f0dd19e4e +--- + 페이지 틀 · 보기 전환 · 패널 · 고름. - B05 ↔ B06 전환 = 보기 숨김 · 보임만 · 보인 보기가 가게 · 세션을 다시 읽음 · 묶음은 숨은 동안도 셈. diff --git a/docs/guide/B05_B06/groups/server.md b/docs/guide/B05_B06/groups/server.md index a47a6b96f..e0b0b939f 100644 --- a/docs/guide/B05_B06/groups/server.md +++ b/docs/guide/B05_B06/groups/server.md @@ -1,3 +1,7 @@ +--- +지문: c9e11c5080 +--- + 서버 창구 · 저장소 · 스키마 — 브라우저 요청을 받아 DB · 정본 파일을 읽고 씀. - 정본 쓰기 = [저장] · [확정] · [초기화] · 저장 밖 셋만. diff --git a/docs/guide/B05_B06/groups/stations.md b/docs/guide/B05_B06/groups/stations.md index bdd9cd15d..4d46f52e2 100644 --- a/docs/guide/B05_B06/groups/stations.md +++ b/docs/guide/B05_B06/groups/stations.md @@ -1,3 +1,7 @@ +--- +지문: 829ee0d82e +--- + 측점 목록 · 열쇠 · 갈아끼움 — 노선 · 시설이 바뀌면 측점을 다시 세움. - 열쇠 = [[common_util_station_key#stationKey]] 한 벌(파이썬 짝 · 거울 시험). diff --git a/docs/guide/B05_B06/groups/structures.md b/docs/guide/B05_B06/groups/structures.md index 697643744..5f5d41816 100644 --- a/docs/guide/B05_B06/groups/structures.md +++ b/docs/guide/B05_B06/groups/structures.md @@ -1,3 +1,7 @@ +--- +지문: e29d73c2ef +--- + 구조물 — 추가 · 옮김 · 지움 · 형상 · 소단 · 시설 줄. - 주인 = 가게 `structures` · 화면 사본은 가게 알림으로 맞춤([[announceDesignStore]]). diff --git a/docs/tools/build.py b/docs/tools/build.py index d57365d4a..d9f94c5e8 100644 --- a/docs/tools/build.py +++ b/docs/tools/build.py @@ -79,7 +79,7 @@ def run_typedoc(ts_files: list[str], out: Path) -> dict[tuple[str, str], str]: "entryPoints": [(ROOT / f).as_posix() for f in ts_files], "tsconfig": (ROOT / "tsconfig.json").as_posix(), "skipErrorChecking": True, - "router": "structure", + "router": "kind-dir", "out": (out / "src" / "ts").as_posix(), "json": (out / "typedoc.json").as_posix(), "readme": "none", @@ -95,20 +95,55 @@ def run_typedoc(ts_files: list[str], out: Path) -> dict[tuple[str, str], str]: return typedoc_pages(out) -def typedoc_pages(out: Path) -> dict[tuple[str, str], str]: +FN_KINDS = {64, 512, 2048, 262144} # TypeDoc 함수 · 생성자 · 메서드 · 접근자 +KIND_DIR = {64: "functions", 32: "variables", 128: "classes"} # router kind-dir 폴더 + + +def typedoc_entries(out: Path) -> list[tuple[str, str, int, str]]: + """TypeDoc JSON → (파일, 이름, 종류, 화면 경로). + + 클래스 칸 = `Class.name` · 다시 내보내기 = 가리키는 것의 종류. + """ project = json.loads((out / "typedoc.json").read_text(encoding="utf-8")) - modules = [m for m in project.get("children", []) if m["kind"] == 2] or [ - {**project, "name": ""} - ] - pages = {} + modules = [m for m in project.get("children", []) if m["kind"] == 2] + by_id: dict[int, dict] = {} + + def index(r: dict) -> None: + by_id[r["id"]] = r + for c in r.get("children", []): + index(c) + + index(project) + rows = [] for mod in modules: - base = f"ts/{mod['name']}/" if mod["name"] else "ts/" + file = mod["sources"][0]["fileName"] if mod.get("sources") else f"{mod['name']}.ts" + slug = mod["name"].replace("/", "_") for c in mod.get("children", []): - if c["kind"] in (64, 32) and c.get("sources"): - rel = f"{base}{c['name']}.html" - if (out / "src" / rel).exists(): - pages[(c["sources"][0]["fileName"], c["name"])] = rel - return pages + folder = KIND_DIR.get(c["kind"]) + page = f"ts/{folder}/{slug}.{c['name']}/index.html" if folder else "" + kind = c["kind"] + if kind == 4194304: + kind = by_id.get(c.get("target"), {}).get("kind", kind) + rows.append((file, c["name"], kind, page)) + if c["kind"] != 128: + continue + for m in c.get("children", []): + if m.get("sources") and not m.get("flags", {}).get("isInherited"): + rows.append( + (file, f"{c['name']}.{m['name']}", m["kind"], f"{page}#{m['name'].lower()}") + ) + return rows + + +def typedoc_pages(out: Path) -> dict[tuple[str, str], str]: + """(파일, 이름) → 화면 경로 · 대소문자만 다른 겹침(Windows 한 파일)은 링크 안 함.""" + rows = [r for r in typedoc_entries(out) if r[3]] + seen = Counter(rel.split("#")[0].lower() for *_, rel in rows if "#" not in rel) + return { + (file, name): rel + for file, name, _, rel in rows + if seen[rel.split("#")[0].lower()] == 1 and (out / "src" / rel.split("#")[0]).exists() + } def py_ident(file: str) -> str: @@ -116,7 +151,7 @@ def py_ident(file: str) -> str: def griffe_names(file: str) -> set[str]: - """griffe 가 보는 함수 이름(모듈 함수 · 클래스 메서드 `Class.name`).""" + """griffe 가 보는 함수 이름(모듈 함수 · 클래스 메서드 · 속성 `Class.name` · 자동 생성 뺌).""" mod = griffe.load(py_ident(file), search_paths=[str(ROOT)], allow_inspection=False) names: set[str] = set() @@ -124,7 +159,7 @@ def griffe_names(file: str) -> set[str]: for name, m in obj.members.items(): if m.is_alias: continue - if m.is_function: + if (m.is_function or "property" in m.labels) and m.lineno: names.add(prefix + name) elif m.is_class: walk(m, f"{prefix}{name}.") @@ -386,9 +421,12 @@ class Site: self.gid.update({f["id"]: gid for gid, fns in groups.items() for f in fns}) nav.append({page["title"]: self.write_page(page, groups)}) home.append(f"- [{page['title']}]({page['id']}/index.md)") - ts_nav = ( - [{"TypeScript": "ts/index.html"}] if (self.src / "ts" / "index.html").exists() else [] - ) + ts_nav = [] + if (self.src / "ts" / "index.html").exists(): + (self.src / "ts.md").write_text( + "# TypeScript 함수 화면\n\n[TypeDoc 열기](ts/index.html)\n", encoding="utf-8" + ) + ts_nav = [{"TypeScript": "ts.md"}] nav.append({"함수 화면": [*ts_nav, {"파이썬": "py/index.md"}]}) (self.src / "index.md").write_text("\n".join(home) + "\n", encoding="utf-8") (self.src / ".nav.json").write_text(json.dumps(nav, ensure_ascii=False), encoding="utf-8") diff --git a/docs/tools/groups.yml b/docs/tools/groups.yml index 9a8a4489e..d44d6e474 100644 --- a/docs/tools/groups.yml +++ b/docs/tools/groups.yml @@ -69,6 +69,7 @@ pages: - design_pipeline_stations - design_pipeline_probe_station - common_util_station_key + - common_util_station - id: ground title: 지반 표본 registry: ["ground.*"] @@ -80,6 +81,7 @@ pages: - B06_Section_Engine_SampleExtend - B06_Section_Router_Widen - common_util_surface_sampler + - common_util_surface_confirmation - id: earthwork title: 토량 · 유토 배분 registry: ["earth.*", "haul.*"] @@ -102,6 +104,7 @@ pages: - B05_Profile_PageSettings - B05_Profile_Api_PageSettings - design_profile* + - common_util_route_profile - id: cross title: 횡단 설계 계산 registry: ["cross.*"] @@ -179,6 +182,8 @@ pages: - B06_Section_Section_* - B06_Section_UI_Page_Persist - common_util_calc_runner + - common_util_derived_store + - common_util_node_bundle - id: save title: 저장 · 확정 · 초기화 · 떠남 files: @@ -216,3 +221,7 @@ pages: - B05_Profile - B06_Section - B05_Profile_Debug + - id: common + title: 공용 도구 + files: + - common_util_* diff --git a/resources/tester/fixtures/478_docs/functions.json b/resources/tester/fixtures/478_docs/functions.json index 3888393b9..86d072b1a 100644 --- a/resources/tester/fixtures/478_docs/functions.json +++ b/resources/tester/fixtures/478_docs/functions.json @@ -17,7 +17,8 @@ "calls": [], "called_by": [ "ts:common_util/common_util_station_key.ts#stationKey" - ] + ], + "kind": "arrow" }, { "id": "ts:common_util/common_util_station_key.ts#stationKey", @@ -43,7 +44,8 @@ ], "called_by": [ "ts:common_util/common_util_station_key.ts#dedupeStationKeys" - ] + ], + "kind": "function" }, { "id": "ts:common_util/common_util_station_key.ts#dedupeStationKeys", @@ -67,7 +69,8 @@ "calls": [ "ts:common_util/common_util_station_key.ts#stationKey" ], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "ts:common_util/common_util_station_key.ts#looseChainage", @@ -85,7 +88,8 @@ ], "returns": "number | null", "calls": [], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "ts:common_util/common_util_station_key.ts#curveMoves", @@ -107,7 +111,8 @@ ], "returns": "Map", "calls": [], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "ts:common_util/common_util_station_key.ts#sameSeat", @@ -131,7 +136,8 @@ "calls": [], "called_by": [ "ts:B05_Profile/logic/B05_Profile_Grade_Seat.ts#seatBornNodes" - ] + ], + "kind": "function" }, { "id": "ts:B05_Profile/logic/B05_Profile_Grade_Seat.ts#median", @@ -151,7 +157,8 @@ "calls": [], "called_by": [ "ts:B05_Profile/logic/B05_Profile_Grade_Seat.ts#seatBornNodes" - ] + ], + "kind": "function" }, { "id": "ts:B05_Profile/logic/B05_Profile_Grade_Seat.ts#seatBornNodes", @@ -180,7 +187,8 @@ "ts:B05_Profile/logic/B05_Profile_Grade_Seat.ts#median", "ts:common_util/common_util_station_key.ts#sameSeat" ], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "py:common_util/common_util_station_key.py#_half_up", @@ -198,7 +206,8 @@ ], "returns": "int", "calls": [], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "py:common_util/common_util_station_key.py#chainage_key", @@ -216,7 +225,8 @@ ], "returns": "str", "calls": [], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "py:common_util/common_util_station_key.py#station_key", @@ -238,7 +248,8 @@ ], "returns": "str", "calls": [], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "py:common_util/common_util_station_key.py#dedupe_station_keys", @@ -260,7 +271,8 @@ ], "returns": "list[str]", "calls": [], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "py:common_util/common_util_station_key.py#loose_chainage", @@ -278,7 +290,8 @@ ], "returns": "float | None", "calls": [], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "py:common_util/common_util_station_key.py#curve_moves", @@ -300,7 +313,8 @@ ], "returns": "dict[str, str]", "calls": [], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "py:common_util/common_util_station_key.py#station_seat", @@ -318,7 +332,8 @@ ], "returns": "tuple | None", "calls": [], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "py:common_util/common_util_station_key.py#same_seat", @@ -340,7 +355,8 @@ ], "returns": "bool", "calls": [], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "py:B05_Profile/B05_Profile_Route_NodeEdits.py#node_edits", @@ -358,7 +374,8 @@ ], "returns": "dict", "calls": [], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "py:common_util/common_util_atomic.py#atomic_write_bytes", @@ -380,7 +397,8 @@ ], "returns": "None", "calls": [], - "called_by": [] + "called_by": [], + "kind": "function" }, { "id": "py:common_util/common_util_atomic.py#atomic_write_npz", @@ -402,6 +420,26 @@ ], "returns": "None", "calls": [], + "called_by": [], + "kind": "function" + }, + { + "id": "py:config/config_system.py#get_project_storage_path", + "lang": "py", + "file": "config/config_system.py", + "line": 216, + "name": "get_project_storage_path", + "kind": "function", + "exported": true, + "doc": "", + "params": [ + { + "name": "company", + "type": "str" + } + ], + "returns": "str", + "calls": [], "called_by": [] } ] diff --git a/resources/tester/test_478_docs.py b/resources/tester/test_478_docs.py index 208fe8d9d..0f213ddbb 100644 --- a/resources/tester/test_478_docs.py +++ b/resources/tester/test_478_docs.py @@ -3,7 +3,6 @@ 가짜 추출(fixtures/478_docs)은 늘 돎 · 진짜 추출(docs/_data)은 있을 때만. """ -import json import re import sys import warnings @@ -31,15 +30,26 @@ def shown_anchors(site: build.Site) -> set[str]: return set(re.findall(r"\{ #(f-[0-9a-f]{10}) \}", text)) -def typedoc_functions(out: Path) -> set[tuple[str, str]]: - project = json.loads((out / "typedoc.json").read_text(encoding="utf-8")) - modules = [m for m in project.get("children", []) if m["kind"] == 2] or [project] - return { - (c["sources"][0]["fileName"], c["name"]) - for m in modules - for c in m.get("children", []) - if c["kind"] == 64 +def ts_mismatch(site: build.Site) -> tuple[list, list]: + """추출 export TS ↔ TypeDoc — (추출만, TypeDoc 함수만).""" + rows = build.typedoc_entries(site.out) + every = {(f, n) for f, n, _, _ in rows} + ts = {(f["file"], f["name"]) for f in site.fns if f["lang"] == "ts" and f["exported"]} + names = {n for _, n in ts} + # 화면 없는 줄 = 다시 내보내기 — `export *` 는 추출이 원본 파일에서만 셈 + funcs = {(f, n) for f, n, k, rel in rows if k in build.FN_KINDS and (rel or n not in names)} + return sorted(ts - every), sorted(funcs - ts) + + +def py_mismatch(site: build.Site) -> tuple[list, list]: + """추출 파이썬(안쪽 함수 뺌) ↔ griffe — (추출만, griffe 만).""" + py = { + (f["file"], f["name"]) + for f in site.fns + if f["lang"] == "py" and (f["kind"] == "method" or "." not in f["name"]) } + got = {(file, n) for file in {f for f, _ in py} for n in build.griffe_names(file)} + return sorted(py - got), sorted(got - py) @pytest.fixture(scope="module") @@ -67,13 +77,14 @@ def test_assign_rules(): assert gid["seatBornNodes"] == "profile" # 등록부 profile.seat assert gid["median"] == "profile" # 파일 B05_Profile_Grade_* assert gid["node_edits"] == "route_edit" # 파일 B05_Profile_Route_NodeEdits - assert gid["atomic_write_bytes"] == group.NONE + assert gid["atomic_write_bytes"] == "common" # 파일 common_util_* 끝 규칙 + assert gid["get_project_storage_path"] == group.NONE def test_fake_site(fake): site, rep = fake assert shown_anchors(site) == {build.anchor(f["id"]) for f in site.fns} - assert rep["ungrouped"] == 2 + assert rep["ungrouped"] == 1 assert rep["session_keys"] == 1 and rep["api"] == 1 assert "stations" in rep["stale_groups"] # 손글 지문 ≠ 가짜 목록 build.build_site(site.out, strict=True) @@ -81,10 +92,8 @@ def test_fake_site(fake): def test_fake_tools_match_extract(fake): site, _ = fake - ts = {(f["file"], f["name"]) for f in site.fns if f["lang"] == "ts" and f["exported"]} - assert typedoc_functions(site.out) == ts - py = {(f["file"], f["name"]) for f in site.fns if f["lang"] == "py"} - assert {(file, n) for file, _ in py for n in build.griffe_names(file)} == py + assert ts_mismatch(site) == ([], []) + assert py_mismatch(site) == ([], []) def test_real_hand_refs(real): @@ -98,20 +107,16 @@ def test_real_every_function_shown(real): def test_real_typedoc_matches_extract(real): - site, _ = real - ts = {(f["file"], f["name"]) for f in site.fns if f["lang"] == "ts" and f["exported"]} - got = typedoc_functions(site.out) - assert not (ts - got) and not (got - ts), ( - f"추출만 {sorted(ts - got)[:10]} · TypeDoc 만 {sorted(got - ts)[:10]}" + only_extract, only_tool = ts_mismatch(real[0]) + assert not only_extract and not only_tool, ( + f"추출만 {only_extract[:10]} · TypeDoc 만 {only_tool[:10]}" ) def test_real_griffe_matches_extract(real): - site, _ = real - py = {(f["file"], f["name"]) for f in site.fns if f["lang"] == "py"} - got = {(file, n) for file in {f for f, _ in py} for n in build.griffe_names(file)} - assert not (py - got) and not (got - py), ( - f"추출만 {sorted(py - got)[:10]} · griffe 만 {sorted(got - py)[:10]}" + only_extract, only_tool = py_mismatch(real[0]) + assert not only_extract and not only_tool, ( + f"추출만 {only_extract[:10]} · griffe 만 {only_tool[:10]}" )