# バッチ設計書 29-GenerateTests.ps1

## 概要

CSVファイルからUiaTextRangeのムーブメントテストコード（C++）を自動生成するPowerShellスクリプトの設計書。テストケースの管理をCSV形式で行い、テストコードへの変換を自動化する。

### 本バッチの処理概要

本スクリプトは、UiaTextRange（UIオートメーション テキスト範囲）のムーブメントテストを記述したCSVファイル（`UiaTests.csv`）を読み込み、C++のテストコードファイル（`GeneratedUiaTextRangeMovementTests.g.cpp`）を自動生成するコードジェネレータである。

**業務上の目的・背景**：UIオートメーションのテキスト範囲操作（Move）は多数のエッジケースを持ち、テストケースの管理が煩雑になる。CSVファイルでテストケースを一元管理し、C++テストコードを自動生成することで、テストの追加・修正を効率化し、人為的なミスを防止する。GH#6986（テキスト範囲ムーブメントの問題）に対する十分なテストカバレッジを確保するために導入された。

**バッチの実行タイミング**：`UiaTests.csv` にテストケースを追加・変更した際に随時手動で実行する。

**主要な処理内容**：
1. ヘッダーコメントと基本変数定義（バッファサイズ、座標定数）を生成する
2. CSVファイル（`UiaTests.csv`）をインポートし、使用される変数名を抽出する
3. 変数名のヒューリスティックに基づいて追加の座標変数を定義する
   - `segment` を含む変数: テキストセグメントの開始位置
   - 数字を含む変数: 文字（C）または行（L）単位のオフセット計算
   - `Left` を含む変数: 行の左端位置
4. テスト構造体（`GeneratedMovementTestInput`, `GeneratedMovementTestExpected`, `GeneratedMovementTest`）を定義する
5. CSVの各行からテストケースのC++コード（配列要素）を生成する
6. 生成されたC++コードを出力ファイルに書き出す

**前後の処理との関連**：生成後は対象プロジェクト（`Conhost.Interactivity.Win32.Unit.Tests`）をビルドしてテストを実行する。テスト通過後にCSVファイルと生成されたC++ファイルの両方をコミットする。コードフォーマッター（`runformat.cmd`、No.30）の実行が推奨される。

**影響範囲**：`src/interactivity/win32/ut_interactivity_win32/GeneratedUiaTextRangeMovementTests.g.cpp` が上書き生成される。

## バッチ種別

コード生成（テストコード自動生成）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時 |
| 実行時刻 | 任意 |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | 手動（UiaTests.csv 変更時） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| PowerShell | PowerShell が利用可能であること |
| CSV入力ファイル | `UiaTests.csv` が存在すること（デフォルトパスまたは引数で指定） |

### 実行可否判定

特別な実行可否判定ロジックはない。CSV ファイルが存在しない場合は Import-Csv でエラーとなる。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| TestPath | string | No | `$PSScriptRoot/../../tools/TestTableWriter/UiaTests.csv` | テストケースCSVファイルのパス |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| UiaTests.csv | CSV | テストケース定義。列: Degenerate, Position, TextUnit, MoveAmount, Start, End, Result_MoveAmount, Result_Start, Result_End, Skip |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| `src/interactivity/win32/ut_interactivity_win32/GeneratedUiaTextRangeMovementTests.g.cpp` | C++ソースファイル | 自動生成されたテストコード |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | GeneratedUiaTextRangeMovementTests.g.cpp |
| 出力先 | `$PSScriptRoot/../../src/interactivity/win32/ut_interactivity_win32/` |
| 文字コード | UTF-8（PowerShellデフォルト） |
| 区切り文字 | N/A（C++ソースコード） |

## 処理フロー

### 処理シーケンス

```
1. ヘッダー・定数定義の生成
   ├─ 著作権コメント・警告コメントを生成
   └─ バッファサイズ・座標定数（origin, midTop, midHistory等）を定義
2. CSVインポートと変数抽出
   ├─ Import-Csv でテストケースを読み込み
   └─ Start, End, Result_Start, Result_End から変数名をSortedSetに収集
3. 変数定義の生成
   ├─ 既知の標準変数を除外
   └─ ヒューリスティックに基づいて追加変数を定義
      ├─ segment系: テキストセグメント開始位置
      ├─ 数字系: point_offset_by_char/line によるオフセット計算
      └─ Left系: 行の左端位置
4. テスト構造体の定義
   └─ GeneratedMovementTestInput/Expected/Test 構造体を出力
5. テストケースの生成
   ├─ CSVの各行をC++テスト配列要素に変換
   └─ テスト名、入力パラメータ、期待値、スキップフラグを生成
6. ファイル出力
   └─ 生成されたコードを .g.cpp ファイルに書き出し
```

### フローチャート

```mermaid
flowchart TD
    A[GenerateTests.ps1 起動] --> B["ヘッダー・定数定義を生成"]
    B --> C["UiaTests.csv をインポート"]
    C --> D["変数名を抽出・収集"]
    D --> E{"各変数のヒューリスティック判定"}
    E -->|segment系| F["セグメント開始位置を定義"]
    E -->|数字系| G["オフセット計算式を定義"]
    E -->|Left系| H["行左端位置を定義"]
    F --> I["テスト構造体を定義"]
    G --> I
    H --> I
    I --> J["CSVの各行をテストコードに変換"]
    J --> K["GeneratedUiaTextRangeMovementTests.g.cpp に出力"]
    K --> L[スクリプト終了]
```

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

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

データベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | ファイル未検出 | UiaTests.csv が指定パスに存在しない | パスを確認するか、-TestPath パラメータで正しいパスを指定する |
| N/A | CSV形式エラー | CSVファイルの形式が不正な場合 | CSVファイルの列名・データ形式を確認する |
| N/A | 不明な変数型 | 変数名ヒューリスティックに一致しない場合 | "Error: unknown variable movement type" が赤字で表示される |
| N/A | 出力先書き込み失敗 | 出力先ディレクトリが存在しないか書き込み権限がない | ディレクトリの存在と権限を確認する |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

エラー発生時は、CSVファイルの内容と形式を確認する。不明な変数型エラーの場合は、変数命名規則（README.md参照）に従って修正する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（ファイル出力は上書き方式） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | CSVのテストケース数に依存 |
| 目標処理時間 | 数秒以内 |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

排他制御は行わない。出力ファイルは上書きされるため、同時実行は避けること。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| エラーログ | 不明な変数型検出時 | "Error: unknown variable movement type"（赤字） |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| N/A | N/A | N/A |

## 備考

- ソースファイルパス: `tools/TestTableWriter/GenerateTests.ps1`
- 詳細な使い方は `tools/TestTableWriter/README.md` を参照
- CSV列定義:
  - Degenerate: テキスト範囲がdegenerateか（TRUE/FALSE）
  - Position: テスト位置
  - TextUnit: 移動単位（TextUnit_Character, TextUnit_Word, TextUnit_Line）
  - MoveAmount: 移動量
  - Start/End: テキスト範囲の開始/終了位置（変数名）
  - Result_MoveAmount: 期待される移動量
  - Result_Start/Result_End: 期待される結果位置（変数名）
  - Skip: テストをスキップするか（TRUE/FALSE）
- 変数命名規則のヒューリスティック:
  - `segment#L<name>`: テキストセグメントの開始位置
  - `<name>P<number>C`: 文字単位の前方移動
  - `<name>M<number>C`: 文字単位の後方移動
  - `<name>P<number>L`: 行単位の前方移動
  - `<name>M<number>L`: 行単位の後方移動
  - `<name>Left`: 同じ行の左端
- GH#6986 のテストカバレッジ確保が主目的
