refactor: 한계에 걸친 함수·파일 분할 (makeStatusMenu, 테스트 하네스)#106
Merged
Conversation
한 함수가 권한 상태(진단) · DEBUG 전용 도구 · 일반 앱 동작 세 가지를 조립하고 있었고, 실코드 60줄로 function_body_length 한계(60)에 정확히 걸쳐 있었다. 상태바 메뉴에 항목을 하나만 추가해도 make lint가 깨지는 상태였다. 구획별 빌더로 나눈다: addPermissionSection / addDebugSection / addAppSection. DEBUG 명령 서브메뉴 조립(중첩 루프)은 makeDebugCommandsItem으로 한 번 더 뺐다. makeStatusMenu는 8줄이 되고 가장 큰 헬퍼도 24줄이다. 메뉴 항목 순서와 구분선 위치는 그대로다. Release에서는 addDebugSection이 통째로 비어 기존과 동일한 메뉴가 나온다 — Debug/Release 양쪽 빌드로 확인했다.
단일 파일이 테스트 함수 25개로 커져 있었다. Tests/는 SwiftLint 대상이 아니라 (included: [Azimuth]) 프로덕션에 적용되는 file_length 한계를 넘긴 채 계속 자라고 있었다. @main·공유 상태·expect* 헬퍼만 CommandEngineTests.swift에 남기고, 테스트는 도메인별 확장 파일로 나눈다: +Frames(기하 배치·이동·상대 축소), +Displays(스냅·던지기·디스플레이 선택), +Apply(앵커·적용 판정·결과 커밋 정책), +Model(명령 모델·그룹·식별자). Swift의 private은 파일 스코프라 다른 파일의 extension에서 안 보이므로, 옮긴 함수와 공유 헬퍼의 private을 뗐다(단일 실행 파일로 컴파일되는 테스트 하네스라 영향 없음). 새 파일 4개를 scripts/test.sh·coverage.sh 양쪽 소스 목록에 추가했다. 검사 수는 분할 전후 모두 208개로 동일하고(테스트 손실 없음), 순수 로직 커버리지도 100%를 유지한다.
pignuante
added a commit
that referenced
this pull request
Jul 23, 2026
* fix(window): abort resolution when AX messaging-timeout config fails setMessagingTimeout 실패를 로그만 남기고 기본 6초 경로로 계속 진행하던 것을, 즉시 해석 중단으로 바꾼다. 타임아웃 값은 상수 2.0이라 SDK가 실패를 반환하는 경우는 무효 element뿐인데, 그 element로는 이후 AX 읽기·쓰기도 성공할 근거가 없다. WindowResolutionError에 messagingTimeoutConfigurationFailed(code:)를 추가하고 userFacingMessage를 붙였다. 두 호출부(app·window element)가 실패를 전파한다. Shared·WindowAccess AGENTS.md에 이 동작을 반영했다. * docs(agents): bring AGENTS.md current with CommandOutcomePolicy and test split 이미 머지된 변경을 per-directory 문서에 반영한다. - CommandOutcomePolicy(순수 상태 커밋 정책, #103)를 데이터 흐름과 Commands 목록에 추가 - 테스트 파일이 도메인별 CommandEngineTests*.swift 5개로 분할된 것(#106)을 반영 * docs: record isolated-build and stacked-PR gotchas in CLAUDE.md 이번 세션에서 겪은 두 함정을 남긴다. - 실행 중인 서명 앱을 건드리지 않고 컴파일 검증하려면 별도 -derivedDataPath로 빌드한다. #if DEBUG는 구성별로 다르므로 그 블록을 건드릴 땐 Debug·Release 양쪽을 확인한다. - squash-merge가 head 브랜치를 지우므로 그 위에 스택된 PR은 머지 시 자동으로 닫히고 재개설·base 변경이 불가하다 — main 대상으로 재개설한다. 한 PR이 다른 PR이 수정하는 코드를 옮기면(테스트 파일 분할 등) 내용 변경을 먼저, 이동을 마지막에 머지한다.
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
전체 코드베이스를 SwiftLint의 실제 기준(주석·빈 줄 제외, 선언줄/닫는 괄호 제외)으로 측정해
한계를 넘거나 한계에 걸친 두 곳만 분할했다. 동작 변경 0.
측정 결과 — 나머지는 전부 여유가 있다
StatusBarController.makeStatusMenuTests/CommandEngineTests.swiftAzimuth/49개 파일 중 위 한 곳 외에는 분할이 필요한 함수·파일·타입이 없다.1.
makeStatusMenu(60 → 8줄)한 함수가 권한 상태(진단) · DEBUG 전용 도구 · 일반 앱 동작 세 가지를 조립하고 있었고,
실코드 60줄로
function_body_length한계에 정확히 걸쳐 있었다 — 상태바에 항목을 하나만추가해도
make lint가 깨지는 상태였다.구획별 빌더로 분리:
addPermissionSection/addDebugSection/addAppSection.DEBUG 명령 서브메뉴 조립(중첩 루프)은
makeDebugCommandsItem으로 한 번 더 뺐다.가장 큰 헬퍼가 24줄이다.
메뉴 항목 순서와 구분선 위치는 그대로다. Release에서는
addDebugSection이 통째로 비어기존과 동일한 메뉴가 나온다 — Debug/Release 양쪽 구성으로 빌드해 확인했다(
#if DEBUG분기가 구성별로 다르므로 한쪽만 빌드하면 검증이 안 된다).
2. 테스트 하네스 분할 (최대 247줄)
Tests/는included: [Azimuth]라 SwiftLint가 보지 않는다. 그래서 프로덕션이라면 warn을넘겼을 크기로 계속 자라고 있었다.
Swift의
private은 파일 스코프라 다른 파일의extension에서 보이지 않는다. 옮긴 함수와공유 헬퍼의
private을 뗐다(단일 실행 파일로 컴파일되는 하네스라 캡슐화 손실 없음).Type
Checklist
make lintclean — 0 violations / 49 filesmake test— 208 checks (분할 전 main과 동일)make coverage— 100% 유지BUILD SUCCEEDEDscripts/test.sh·scripts/coverage.sh양쪽에 추가.docs/not stagedNotes / risk
테스트 손실이 없다는 근거: 검사 수가 분할 전
main과 208개로 동일하다. 추가로정의된 테스트 함수 25개 /
main()호출 25개 / 중복 정의 0 / 미호출(고아) 0을 확인했다.리뷰어가 볼 곳: 테스트 파일이 1개 → 5개가 되면서 "새 파일을 두 스크립트에 손으로 추가"
해야 하는 기존 함정의 노출면이 커졌다(CLAUDE.md에 기록된 규칙). 이번 PR에서는 4개 모두
추가했고
make test/make coverage로 확인했지만, 앞으로 테스트 파일을 늘릴 때 같은 실수가나기 쉽다는 점은 남는다.