# 機能設計書 86-テストツリー表示

## 概要

本ドキュメントは、clojure-lspのテストツリー表示機能の設計書である。エディタのカスタム拡張機能として、テストファイル内のテスト関数を階層的に表示する。

### 本機能の処理概要

この機能は、LSPプロトコルのカスタム拡張として、テストファイル内の `deftest` と `testing` ブロックを階層的なツリー構造で表示する。テストの構造を視覚化し、テスト実行やナビゲーションを支援する。

**業務上の目的・背景**：テスト駆動開発（TDD）やテストファーストの開発手法において、テスト構造の把握は重要である。本機能により、テストファイル内のテストケースを階層的に表示し、開発者がテストの全体像を把握しやすくする。

**機能の利用シーン**：
- テストファイル内のテストケース一覧の確認
- 特定のテストケースへのナビゲーション
- テスト構造の視覚化と理解
- テスト実行の対象選択（エディタ連携）

**主要な処理内容**：
1. テストファイルの解析
2. deftest と testing ブロックの抽出
3. 階層的なツリー構造の構築
4. クライアントへの通知

**関連システム・外部連携**：
- LSPクライアント: テストツリー表示UI
- clj-kondo: テスト定義の解析

**権限による制御**：権限による制御は行わない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | 該当なし | 該当なし | エディタのサイドパネルとして表示（LSP拡張機能） |

## 機能種別

表示機能 / カスタムLSP拡張

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| uri | String | Yes | テストファイルのURI | 有効なファイルURI |

### 入力データソース

- clj-kondo解析結果（var-definitions, var-usages）
- テストファイルのソースコード

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| uri | String | テストファイルのURI |
| tree | Map | テストツリーのルートノード |
| tree.name | String | 名前空間名 |
| tree.range | Map | 名前空間の範囲 |
| tree.name-range | Map | 名前の範囲 |
| tree.kind | Keyword | ノードの種類 |
| tree.children | Vector | 子ノードのリスト |

### ノード種類

| kind | 説明 |
|------|------|
| :namespace | 名前空間（ルートノード） |
| :deftest | deftest 関数 |
| :testing | testing ブロック |

### 出力先

- LSP通知: clojure/textDocument/testTree

## 処理フロー

### 処理シーケンス

```
1. ファイル変更検知
   └─ did-open または解析完了時

2. テストファイル判定
   └─ deftest の存在を確認

3. テスト要素の抽出
   └─ deftest と testing を抽出

4. ツリー構造の構築
   └─ 階層的な親子関係を構築

5. クライアント通知
   └─ clojure/textDocument/testTree を送信
```

### フローチャート

```mermaid
flowchart TD
    A[ファイル変更検知] --> B{テストあり?}
    B -->|No| C[処理終了]
    B -->|Yes| D[名前空間定義取得]
    D --> E[deftest 抽出]
    E --> F[testing 抽出]
    F --> G[各 deftest に対して]
    G --> H[内部の testing を特定]
    H --> I[ネストした testing を構築]
    I --> J[ツリー構造生成]
    J --> K[クライアント通知]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-86-1 | deftest 判定 | clojure.test/deftest または cljs.test/deftest で定義 | var-definitions の defined-by を確認 |
| BR-86-2 | testing 判定 | clojure.test または cljs.test の testing 呼び出し | var-usages の :to と :name を確認 |
| BR-86-3 | ネスト判定 | shared/inside? で親子関係を判定 | 位置情報に基づく包含判定 |
| BR-86-4 | クライアントサポート | :experimental :test-tree がサポートされている場合のみ送信 | client-capabilities を確認 |

### 計算ロジック

ツリー構築アルゴリズム:
1. 名前空間定義をルートノードとする
2. deftest を第1レベルの子ノードとして追加
3. 各 deftest 内の testing を抽出
4. testing のネスト関係を shared/inside? で判定
5. ルートレベルの testing を特定（他の testing に含まれない）
6. 再帰的に子 testing を構築

## データベース操作仕様

該当なし（ファイルシステムのみ操作）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | テストなし | deftest が存在しない | nil を返却（通知しない） |

### リトライ仕様

リトライは行わない。

## トランザクション仕様

該当なし（読み取り専用処理）

## パフォーマンス要件

- ファイル変更時に非同期でツリーを更新
- async/thread で非同期処理

## セキュリティ考慮事項

- 読み取り専用操作のためセキュリティリスクは低い

## 備考

- この機能はLSPの実験的（experimental）機能として提供される
- クライアントが :experimental :test-tree をサポートしている必要がある
- テストファイルの変更時に自動的にツリーが更新される

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ツリー構造 | `lib/src/clojure_lsp/feature/test_tree.clj` | ツリーノードのデータ構造（name, range, name-range, kind, children） |

**読解のコツ**: ツリーは :namespace -> :deftest -> :testing の階層構造

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | server.clj | `cli/src/clojure_lsp/server.clj` | refresh-test-tree の呼び出し |

**主要処理フロー**:
1. **191-201行目**: `refresh-test-tree` - クライアントへの通知処理
2. **199行目**: `f.test-tree/tree` を呼び出しツリー生成

#### Step 3: Producer を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | producer.clj | `lib/src/clojure_lsp/producer.clj` | IProducer インターフェース |

**主要処理フロー**:
- `refresh-test-tree` メソッドの定義

#### Step 4: 機能実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | test_tree.clj | `lib/src/clojure_lsp/feature/test_tree.clj` | ツリー生成の詳細実装 |

**主要処理フロー**:
- **8-26行目**: `->testings-children` - testing のネスト構造を構築
- **28-34行目**: `deftest->tree` - deftest のツリーノード生成
- **36-54行目**: `tree` - メイン関数、ツリー全体を生成

### プログラム呼び出し階層図

```
producer/refresh-test-tree
    │
    └─ (ClojureLspProducer 実装)
           │
           └─ f.test-tree/tree
                  │
                  ├─ q/find-namespace-definition-by-uri
                  │
                  ├─ filter: deftest 判定
                  │      └─ q/defined-bys
                  │
                  ├─ filter: testing 判定
                  │
                  └─ deftest->tree
                         │
                         └─ ->testings-children
                                │
                                └─ (再帰呼び出し)
```

### データフロー図

```
[入力]                      [処理]                           [出力]

テストファイル URI ──▶ 解析データ取得 ──────▶ local-buckets
                              │
                              ▼
                       deftest フィルタ ────▶ deftests リスト
                              │
                              ▼
                       testing フィルタ ────▶ testings リスト
                              │
                              ▼
                       deftest->tree ───────▶ テストノード
                              │
                              ├─ ->testings-children (再帰)
                              │
                              ▼
                       ツリー構造 ───────────▶ LSP通知
                       {:uri ...
                        :tree {...}}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| test_tree.clj | `lib/src/clojure_lsp/feature/test_tree.clj` | ソース | テストツリー生成 |
| server.clj | `cli/src/clojure_lsp/server.clj` | ソース | LSPサーバー、通知送信 |
| producer.clj | `lib/src/clojure_lsp/producer.clj` | ソース | Producer インターフェース |
| clojure_coercer.clj | `cli/src/clojure_lsp/clojure_coercer.clj` | ソース | 型変換 |
| queries.clj | `lib/src/clojure_lsp/queries.clj` | ソース | データ検索 |
| shared.clj | `lib/src/clojure_lsp/shared.clj` | ソース | inside? などのユーティリティ |
