Skip to content

test: preload API type key と実装 key の同期を vitest で lock (#209 ①)#280

Merged
ymnao merged 3 commits into
mainfrom
refactor/preload-sync-209-1
Jul 5, 2026
Merged

test: preload API type key と実装 key の同期を vitest で lock (#209 ①)#280
ymnao merged 3 commits into
mainfrom
refactor/preload-sync-209-1

Conversation

@ymnao

@ymnao ymnao commented Jul 5, 2026

Copy link
Copy Markdown
Owner

概要

electron/preload/api.ts (Api type、現在 55 method) と electron/preload/index.ts (api Object.freeze 実装、55 method) の hardcode 同期を CI で lock する vitest テストを追加。preload API 追加時に片方の更新漏れがあると本テストが fail するので、drift risk を防ぐ。

  • 追加依存なし(ts-morph 等を使わず、level 1 indent の regex 抽出のみで完結)
  • 順序込みで完全一致検証(expect(implKeys).toEqual(typeKeys)
  • non-empty guard test は将来 extract 経路が silent empty 化した場合の防衛として保持

関連 Issue

#209 項目 ①(v0.7.0 milestone 最終項目)。#209 parent issue は既に closed のため Closes は付与しない。

移行 Stage

  • (移行 Stage 対象外)内部品質改善 refactor

変更内容

  • electron/preload/api-sync.test.ts を新規追加(43 行、2 test case)
    • extractKeys(source, openMarker, closeMarker)\t\w+\??: にマッチする level 1 indent identifier を抽出
    • api.ts の export type Api = Readonly<{ ... }>; block と、index.ts の const api: Api = Object.freeze({ ... }); block を対象
    • 内側 block(tab 2 個以上)は無視するので onWindowCloseRequested のような multi-line 実装があっても top-level method 名だけが取れる

動作確認

  • vitest main project 全体 694 pass(本 test は 2 case pass)
  • biome check pass
  • tsc typecheck (node / web 両方) pass
  • drift 検出 verify: api.ts から 1 key を意図的に削除 → toEqual test が期待通り fail、restore で復帰

セッション内で実施した review flow

3 commit 構成:

  1. test: — 初期実装(3 test case / 63 行)
  2. refactor: /simplify — 2 wrapper unify + redundant count test 削除(2 test case / 51 行)
  3. refactor: /code-review medium — header comment 短縮 + readPreloadFile inline 化(43 行)
検証エビデンス

リスク分類

tier: medium(classify-risk.sh の判定)
理由: 具体的 reason なしのデフォルト分類。ただし新規 test file 1 個追加のみで実 production code の変更なし・security 表面積ほぼゼロ・test suite は 694 pass 済み。

実行した検証

種別 コマンド 結果
ユニットテスト ./node_modules/.bin/vitest run --project main PASS (33 files / 694 tests)
ユニットテスト(該当 file) ./node_modules/.bin/vitest run --project main electron/preload/api-sync.test.ts PASS (2 tests)
Lint ./node_modules/.bin/biome check electron/preload/api-sync.test.ts PASS (no fixes applied)
Typecheck (node) ./node_modules/.bin/tsc --noEmit -p tsconfig.node.json PASS
Typecheck (web) ./node_modules/.bin/tsc --noEmit -p tsconfig.web.json PASS
Drift 検出 verify api.ts から settingsSave key を一時削除 → vitest 実行 → restore PASS (期待通り toEqual test が fail、restore で復帰)
セッション内 review 1 /simplify (4 agent parallel: reuse / simplification / efficiency / altitude) 2 finding 採用 (2 wrapper unify + count test 削除)、2 finding skip
セッション内 review 2 /code-review medium (8 agent parallel: 3 correctness + 3 cleanup + altitude + conventions) correctness bug 0 件、cleanup 2 finding 採用 (header 短縮 + inline)、他 skip
実 e2e (renderer-only) 未実施 ローカル sandbox 内は listen EPERM のため CI で確認
実 e2e (Electron) 未実施 ローカル不可、CI で確認
codex-review security bash ~/.claude/skills/codex-review/scripts/run-review.sh security 未実施(codex CLI v0.142.5 は installed だが sandbox 内で failed to initialize in-process app-server client: Operation not permitted により起動不可)

レビュー指摘と対応

セッション内 /simplify + /code-review medium で以下を対応:

# 指摘内容 対応 理由
1 2 wrapper extractApiTypeKeys / extractApiObjectKeys が near-identical 修正済み (29d3ce1) marker string のみ異なる wrapper を extractKeys(source, open, close) に unify
2 count test は toEqual で cover される redundant 修正済み (29d3ce1) vitest diff で count / order 両方が見えるので独立 test 不要
3 14 行 header comment が excessive 修正済み (516aa67) 重複説明を排除して 4 行に短縮
4 readPreloadFile trivial wrapper 修正済み (516aa67) 呼び出し 2 箇所、extractKeys の第一引数へ inline
5 non-empty guard を toEqual で cover 判定 対応しない 将来 extract 経路が silent empty 化した場合の防衛として保持(cost 4 行のみ)
6 imperative for-of loop → functional 化 対応しない 提案 code に typo あり + RegExpMatchArray narrowing 事情から現状維持
7 Altitude: type-to-impl 未 check 対応しない toEqual は array 完全一致で両方向 cover される
8 Altitude: length > 50 magic number sanity 対応しない method 追加毎に update 必要になる spec 化リスク
9 Altitude: production code に runtime assert 対応しない test を production に漏らす altitude 悪化
10 JSON.stringify を template literal に 対応しない marker に { などの記号あるので visual quoting 保持
11 Angle A 6 correctness finding 全 REFUTED 全て hypothetical / regex 制約で refuted (\t\w+// にマッチしない)

ymnao and others added 3 commits July 5, 2026 12:27
- electron/preload/api.ts の Api type key と electron/preload/index.ts の
  api Object.freeze() 内 method key を正規表現で level 1 indent ベースに
  抽出し、count と順序の完全一致を検証する。
- 新規 preload API 追加時に両ファイルの更新漏れがあると本テストが fail する
  ため、2 ファイル hardcode 構造の drift risk を CI で lock できる。
- 追加依存なし(ts-morph や TypeScript Compiler API を使わず読み取り + 正規
  表現のみで完結)。
- #209 項目 ①「preload 53 メソッド hardcode の 2 ファイル同期 lint rule」の
  実装(現在は 55 メソッド)。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- extractApiTypeKeys / extractApiObjectKeys の 2 wrapper が marker string
  のみ異なる near-identical だったため extractKeys(source, open, close) に
  unify。呼び出し場所で marker 文字列を渡す形にして DRY 化。
- `type key count equals impl key count` テストは
  `expect(implKeys).toEqual(typeKeys)` で必ず cover されるため redundant
  として削除(vitest の diff で count / order 両方のずれが表示される)。
- non-empty guard test は将来 extract 経路が silent empty 化した場合の
  防衛として保持。imperative for-of loop は agent 提案 code の typo と
  RegExpMatchArray の narrowing 事情から現状維持。
- 3 test → 2 test / 63 行 → 51 行。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…nline

- /code-review medium (8 agent parallel) 実行結果:
  - correctness bug 0 件 (Angle A/B/C 全 clean)
  - Conventions 違反 0 件 (CLAUDE.md 全 rule 準拠)
  - Reuse / Efficiency no issues
  - Altitude 提案 3 件全 skip (toEqual は既に両方向 cover、magic
    number 化、production への test 漏出は altitude 悪化)
- 採用した 2 finding:
  - S1: 14 行の header comment を 4 行に短縮 (重複説明を排除)
  - S2: readPreloadFile trivial wrapper を削除、extractKeys の第一引数へ
    readFileSync を inline
- 51 行 → 43 行。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@ymnao ymnao merged commit fb40478 into main Jul 5, 2026
9 checks passed
@ymnao ymnao deleted the refactor/preload-sync-209-1 branch July 5, 2026 03:53
@ymnao ymnao mentioned this pull request Jul 5, 2026
7 tasks
ymnao added a commit that referenced this pull request Jul 5, 2026
- package.json の version を 0.6.0 → 0.7.0 に bump
- CHANGELOG.md に v0.7.0 エントリを追加 (#243#280)
  - Fixed: FileTree scroll regression (#276)、electron e2e launch teardown timeout 拡大 (#247)
  - Internal: #209 3 項目 (drift-lock 系 refactor #278/#279/#280)、settings setter 集約 (#273#277)、search/workspace/backlink 系 helper 抽出 15 件
  - Dependencies: electron 43.0.0 / p-limit 7.3.0 major bump (#275)、Dependabot 7 件 combine (#274)、pnpm-workspace.yaml overrides で @codemirror dual copy を恒久防止

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant