# 機能設計書 41-テスト作成

## 概要

本ドキュメントは、clojure-lspの「テスト作成」機能（create-test コマンド）の設計を詳細に記載する。この機能は、関数定義からテスト関数を自動生成するコードアクション機能である。

### 本機能の処理概要

**業務上の目的・背景**：Clojure開発において、関数に対するテストを書くことは品質保証の基本である。しかし、テストファイルの作成、名前空間の設定、テスト関数のボイラープレート記述は反復的な作業である。この機能は、これらの作業を自動化することで、開発者がテストロジックの記述に集中できるようにする。

**機能の利用シーン**：開発者が新しい関数を定義した後、その関数に対するユニットテストを作成したい場合に使用する。カーソルを関数定義に置き、コードアクションメニューから「Create test for 'function-name'」を選択する。

**主要な処理内容**：
1. カーソル位置から関数定義を検出する
2. テスト用ソースパスを決定する（複数ある場合はユーザーに選択させる）
3. テストファイルが存在しない場合は新規作成する
4. テストファイルに対応するテスト関数を追加する
5. テストファイルを開いてフォーカスを移動する

**関連システム・外部連携**：LSPプロトコルのコードアクション機能と連携し、エディタのUI経由でユーザーに操作を提供する。

**権限による制御**：特になし。ファイル書き込み権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | エディタ | 主画面 | コードアクションメニューから実行 |

## 機能種別

コード生成 / ファイル操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| uri | String | Yes | 現在のファイルURI | 有効なファイルURI |
| line | Number | Yes | カーソル行（0始まり） | 非負整数 |
| character | Number | Yes | カーソル列（0始まり） | 非負整数 |

### 入力データソース

- エディタから送信されるカーソル位置情報
- プロジェクトのソースパス設定（settings.clj または .lsp/config.edn）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| resource-changes | Array | 新規ファイル作成指示（テストファイルが存在しない場合） |
| changes-by-uri | Map | URI毎のテキスト編集内容 |
| show-document-after-edit | Map | 編集後に開くドキュメント情報 |

### 出力先

- テストファイル（例: `test/sample_test-test.clj`）
- エディタへのワークスペース編集応答

## 処理フロー

### 処理シーケンス

```
1. カーソル位置から関数定義名を検出
   └─ edit/find-var-definition-name-loc を使用
2. テスト可能かチェック
   └─ can-create-test? 関数で source-paths を確認
3. テスト用ソースパスを決定
   └─ 複数ある場合は producer/show-message-request でユーザーに選択させる
4. テストファイルパスを算出
   └─ namespace-test + source-path からファイル名を生成
5. テストファイルの存在確認
   └─ 存在する場合: 末尾にテスト関数を追加
   └─ 存在しない場合: ns宣言とテスト関数を含む新規ファイル作成
6. 編集結果を返却
   └─ show-document-after-edit でテストファイルを開く
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{関数定義名を検出}
    B -->|検出失敗| Z[nil返却]
    B -->|検出成功| C{ソースパス確認}
    C -->|テストパスなし| E[エラー返却]
    C -->|単一テストパス| F[テストパス決定]
    C -->|複数テストパス| G[ユーザー選択]
    G --> F
    F --> H{テストファイル存在?}
    H -->|存在する| I[既存ファイルに追加]
    H -->|存在しない| J[新規ファイル作成]
    I --> K[編集結果返却]
    J --> K
    K --> L[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | テストファイル命名 | 名前空間名に "-test" を付加 | 常時 |
| BR-02 | テスト関数命名 | 関数名に "-test" を付加 | 常時 |
| BR-03 | ソースパス除外 | "test" を含むソースパスは除外対象 | ソースパス選択時 |

### 計算ロジック

- テスト名前空間: `(str namespace "-test")`
- テスト関数名: `(str function-name "-test")`
- テストファイルパス: `(shared/namespace+source-path->filename namespace-test source-path file-type)`

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

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| :invalid-params | パラメータエラー | カーソル位置に関数定義がない | カーソル位置を関数定義に移動 |
| :invalid-params | パラメータエラー | テスト用ソースパスが見つからない | source-paths設定を確認 |

### リトライ仕様

リトライ不要（ユーザー操作起点のため）

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

ファイル操作のみのため、トランザクション管理なし。

## パフォーマンス要件

- 応答時間: 1秒以内
- ユーザー選択を伴う場合は選択後1秒以内

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

- ファイル書き込み権限の確認
- プロジェクト外へのファイル作成防止（source-paths内のみ）

## 備考

- CLJSファイルの場合、テスト名前空間で `cljs.test` を require する
- Clojureファイルの場合、`clojure.test` を require する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | transform.clj | `lib/src/clojure_lsp/refactor/transform.clj` | create-test 関数の戻り値構造を理解 |

**読解のコツ**: 戻り値の `:changes-by-uri`、`:resource-changes`、`:show-document-after-edit` キーの意味を把握する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | command.clj | `lib/src/clojure_lsp/feature/command.clj` | run-command :create-test メソッドがエントリーポイント |

**主要処理フロー**:
1. **155-156行目**: `:create-test` コマンドのディスパッチ定義
2. **156行目**: `r.transform/create-test` 関数呼び出し

#### Step 3: メイン処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | transform.clj | `lib/src/clojure_lsp/refactor/transform.clj` | create-test, can-create-test?, create-test-for-source-path 関数 |

**主要処理フロー**:
- **1422-1430行目**: `can-create-test?` - テスト作成可否のチェック
- **1432-1448行目**: `create-test` - メイン処理、ソースパス選択と分岐
- **1389-1420行目**: `create-test-for-source-path` - 実際のテストファイル生成

#### Step 4: コードアクション表示を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | code_actions.clj | `lib/src/clojure_lsp/feature/code_actions.clj` | create-test-action 関数とall関数でのコードアクション登録 |

**主要処理フロー**:
- **328-333行目**: `create-test-action` - コードアクションの定義
- **527-529行目**: コードアクション一覧への追加条件

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

```
handlers/code-actions
    │
    └─ f.code-actions/all
           │
           ├─ r.transform/can-create-test?
           │      └─ edit/find-var-definition-name-loc
           │
           └─ create-test-action (コードアクション生成)

handlers/execute-command
    │
    └─ f.command/call-command
           │
           └─ run-command :create-test
                  │
                  └─ r.transform/create-test
                         │
                         ├─ can-create-test?
                         │
                         └─ create-test-for-source-path
                                │
                                ├─ shared/uri->namespace
                                ├─ shared/namespace+source-path->filename
                                └─ z/of-string (テストコード生成)
```

### データフロー図

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

URI, Line, Col ───▶ find-var-definition-name-loc ───▶ function-name-loc
                           │
                    ┌──────┴──────┐
                    │             │
             テストファイル存在?
                    │             │
              Yes   │             │   No
                    ▼             ▼
         既存ファイル末尾    新規ファイル作成
           にテスト追加       + ns宣言 + テスト
                    │             │
                    └──────┬──────┘
                           ▼
                    changes-by-uri ───▶ LSP WorkspaceEdit
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| transform.clj | `lib/src/clojure_lsp/refactor/transform.clj` | ソース | テスト作成のメインロジック |
| command.clj | `lib/src/clojure_lsp/feature/command.clj` | ソース | コマンドディスパッチ |
| code_actions.clj | `lib/src/clojure_lsp/feature/code_actions.clj` | ソース | コードアクション定義 |
| edit.clj | `lib/src/clojure_lsp/refactor/edit.clj` | ソース | 編集ユーティリティ |
| shared.clj | `lib/src/clojure_lsp/shared.clj` | ソース | 共通ユーティリティ |
| producer.clj | `lib/src/clojure_lsp/producer.clj` | ソース | クライアント通信 |
