# 画面設計書 31-testament cat

## 概要

本ドキュメントは、Nimコンパイラプロジェクトのテストフレームワーク「Testament」における「cat」サブコマンドの画面設計書である。testament catは指定されたカテゴリのテストを実行するためのCLIインターフェースを提供する。

### 本画面の処理概要

testament catコマンドは、Nimコンパイラのテストスイートにおいて、特定のカテゴリに属するテストケースのみを選択的に実行する機能を提供する。

**業務上の目的・背景**：Nimコンパイラの開発において、テストスイートは非常に大規模であり、全テストを毎回実行すると時間がかかりすぎる。特定の機能やモジュールに関連するテストのみを実行したい場合、カテゴリ別にテストを分類し、必要なカテゴリだけを実行することで開発効率を向上させる。例えば、GCのテストのみ、JavaScript生成のテストのみなど、焦点を絞ったテスト実行が可能となる。

**画面へのアクセス方法**：コマンドラインから`testament cat <category>`または`testament category <category>`、`testament c <category>`の形式で実行する。categoryには「gc」「js」「dll」「threads」などの事前定義されたカテゴリ名、またはtestsディレクトリ配下のサブディレクトリ名を指定する。

**主要な操作・処理内容**：
1. コマンドライン引数からカテゴリ名を取得
2. skipsファイルから除外するテストを読み込み
3. 指定カテゴリに対応する処理関数（processCategory）を呼び出し
4. カテゴリがspecialCategoriesに含まれる場合は専用のテスト処理を実行
5. それ以外の場合はディレクトリを再帰的に走査してテストファイルを収集
6. 各テストファイルに対してテストスペックを解析し、テストを実行
7. テスト結果を集計し、成功/失敗/スキップの統計を出力

**画面遷移**：
- 遷移元：testament メイン画面（コマンドライン引数に「cat」を指定）
- 遷移先：なし（テスト結果を標準出力に表示して終了）

**権限による表示制御**：特になし。CLIツールとして実行権限があれば使用可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 27 | Testament | 主機能 | 指定カテゴリのテスト実行処理 |
| 1 | Nimコンパイラ本体 | 遷移先機能 | テスト実行時のコンパイラ呼び出し |

## 画面種別

CLIコマンド実行画面（カテゴリ指定テスト実行）

## URL/ルーティング

```
testament cat <category> [options]
testament category <category> [options]
testament c <category> [options]
```

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 | 例 |
|--------|-----|------|------|-----|
| category | string | Yes | テストカテゴリ名 | gc, js, dll, threads |
| --print | flag | No | 結果をコンソールに出力 | - |
| --verbose | flag | No | 詳細な実行コマンドを表示 | - |
| --simulate | flag | No | 実際には実行せず、対象テストを表示 | - |
| --targets | string | No | 実行対象のターゲット | "c cpp js objc" |
| --nim | path | No | 使用するnimコンパイラのパス | /usr/local/bin/nim |
| --directory | path | No | テストディレクトリの変更 | ./tests |
| --colors | on/off | No | 出力の色付け制御 | on |
| --backendLogging | on/off | No | バックエンドログの有効/無効 | on |
| --megatest | on/off | No | megatestの有効/無効 | on |
| --valgrind | on/off | No | valgrindサポートの有効/無効 | on |
| --skipFrom | file | No | スキップするテストを記載したファイル | skip.txt |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| テスト名 | string | 実行されたテストの名前 |
| 結果 | enum | PASS/FAIL/SKIP/JOINED |
| 実行時間 | float | テスト実行にかかった秒数 |
| 期待値 | string | 失敗時の期待される出力 |
| 実際の値 | string | 失敗時の実際の出力 |
| 統計情報 | string | 最終的な成功/失敗/スキップ数 |

## 表示項目

### テスト実行結果表示

| 項目 | 表示形式 | 説明 |
|------|----------|------|
| PASS | 緑色で"PASS:"表示 | テスト成功 |
| FAIL | 赤色で"FAIL:"表示 | テスト失敗 |
| SKIP | 黄色で"SKIP:"表示 | テストスキップ |
| JOINED | 薄い表示で"JOINED:"表示 | megatestに統合済み |

## イベント仕様

### 1-カテゴリテスト実行

ユーザーが`testament cat <category>`を実行すると以下の処理が行われる：

1. main()関数でコマンドライン引数を解析
2. `action`が"c", "cat", "category"の場合、processCategoryを呼び出し
3. skipsファイルが指定されていれば読み込み
4. カテゴリに応じた処理関数を実行：
   - "gc": gcTests()
   - "js": jsTests()
   - "dll": dllTests()
   - "threads": threadTests()
   - "io": ioTests()
   - その他: ディレクトリ走査によるテスト実行
5. 各テストファイルに対してtestSpec()を呼び出し
6. 結果を集計してTResults構造体に格納
7. optPrintResultsがtrueの場合、結果を出力

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| テスト結果記録 | testresults/*.json | INSERT | テスト実行結果をJSONファイルに保存 |

### テーブル別更新項目詳細

#### testresults/*.json

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | テスト名 | ファイルパスとオプション |
| INSERT | category | カテゴリ名 | 引数で指定されたカテゴリ |
| INSERT | target | ターゲット | c/cpp/js/objc |
| INSERT | action | アクション | run/compile/reject |
| INSERT | result | 結果 | reSuccess/reDisabled等 |
| INSERT | expected | 期待値 | テストスペックから |
| INSERT | given | 実際の値 | 実行結果から |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 情報 | "PASS: {テスト名}" | テスト成功時 |
| MSG002 | エラー | "FAIL: {テスト名}" | テスト失敗時 |
| MSG003 | 警告 | "SKIP: {テスト名}" | テストスキップ時 |
| MSG004 | 情報 | "JOINED: {テスト名}" | megatestに統合済み |
| MSG005 | 情報 | "Tests passed or allowed to fail: X / Y" | 実行完了時 |
| MSG006 | エラー | "FAILURE! total: X passed: Y skipped: Z failed: W" | 失敗ありで終了時 |

## 例外処理

| 例外条件 | 処理内容 | エラーメッセージ |
|----------|----------|-----------------|
| 無効なカテゴリ | プログラム終了 | "Invalid category specified: 'X' not in whitelist" |
| コンパイラが見つからない | パス検索 | PATHからnimを検索、見つからなければエラー |
| テストファイルが見つからない | スキップ | "no tests were found for pattern: X" |
| スペック解析エラー | 無効スペックとして記録 | parseErrors内容を表示 |

## 備考

- specialCategoriesには以下が含まれる：assert, async, debugger, dll, examples, gc, io, js, ic, ic_disabled, lib, manyloc, nimble-packages, niminaction, threads, untestable, testdata, nimcache, coroutines, osproc, shouldfail, destructor
- runJoinableTestsパラメータがtrueの場合、joinable（megatestに統合可能）なテストも個別に実行される
- pcatコマンドは並列実行用で、joinableテストを除外して実行する

---

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

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

### 推奨読解順序

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

まず、テストスペック（TSpec）とテスト結果（TResults）の構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | specs.nim | `testament/specs.nim` | TSpec型（75-106行目）でテストの仕様を定義。TResultEnum（41-59行目）で結果種別を定義 |
| 1-2 | testament.nim | `testament/testament.nim` | TResults型（88-91行目）でテスト結果の集計構造を定義。TTest型（92-99行目）で個別テスト情報を定義 |

**読解のコツ**: TSpecは各テストファイルの先頭にあるdiscard """..."""ブロックを解析した結果を格納する。action, targets, outputなどのフィールドを把握することでテストの挙動が理解できる。

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

処理の起点となるmain()関数とコマンドライン解析を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | testament.nim | `testament/testament.nim` | main()関数（684-841行目）がエントリーポイント。オプション解析と"cat"コマンドの分岐処理を確認 |

**主要処理フロー**:
1. **694-756行目**: コマンドラインオプションの解析（targets, nim, colors等）
2. **757-759行目**: コマンド引数の取得とaction変数への格納
3. **804-807行目**: "c", "cat", "category"の場合、processCategoryを呼び出し
4. **805行目**: skipsファイルの読み込み
5. **807行目**: processCategory()の呼び出し

#### Step 3: カテゴリ処理を理解する

processCategoryとspecialCategoriesの処理を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | categories.nim | `testament/categories.nim` | processCategory()関数（653-728行目）でカテゴリ別の処理分岐を実装 |
| 3-2 | categories.nim | `testament/categories.nim` | specialCategories定数（20-43行目）で特別扱いするカテゴリを定義 |

**主要処理フロー**:
- **661-702行目**: specialCategoriesに対する個別処理（gcTests, jsTests等）
- **704-728行目**: 通常カテゴリのディレクトリ走査とテスト実行

#### Step 4: テスト実行を理解する

個別テストの実行とスペック解析を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | specs.nim | `testament/specs.nim` | parseSpec()関数（320-526行目）でテストスペックを解析 |
| 4-2 | testament.nim | `testament/testament.nim` | testSpec()関数（603-619行目）で個別テストを実行 |
| 4-3 | testament.nim | `testament/testament.nim` | testSpecHelper()関数（489-570行目）で実際のコンパイル・実行を処理 |

**主要処理フロー**:
- **603-619行目**: ターゲット別にテストを実行
- **507行目**: callNimCompiler()でコンパイラを呼び出し
- **508-569行目**: actionに応じた結果検証（actionCompile/actionRun/actionReject）

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

```
main()
    │
    ├─ initOptParser() / オプション解析
    │
    ├─ loadSkipFrom() / スキップリスト読み込み
    │
    └─ processCategory()
           │
           ├─ [specialCategory] gcTests() / jsTests() / dllTests() 等
           │       └─ testSpec()
           │
           └─ [normalCategory] walkDirRec()
                   │
                   ├─ makeTest()
                   │       └─ parseSpec()
                   │
                   └─ testSpec()
                           │
                           └─ testSpecHelper()
                                   │
                                   ├─ callNimCompiler()
                                   │
                                   └─ compilerOutputTests() / cmpMsgs()
                                           │
                                           └─ finishTestRetryable() / addResult()
```

### データフロー図

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

コマンドライン引数 ───▶ main() ───▶ 引数解析
       │                                │
       ▼                                ▼
カテゴリ名 ────────▶ processCategory() ───▶ カテゴリ判定
       │                                │
       ▼                                ▼
テストファイル ────▶ parseSpec() ───▶ TSpec構造体
       │                                │
       ▼                                ▼
nimコンパイラ ─────▶ callNimCompiler() ───▶ コンパイル結果
       │                                │
       ▼                                ▼
実行結果 ─────────▶ compilerOutputTests() ───▶ 結果判定
       │                                │
       ▼                                ▼
                   addResult() ───▶ 標準出力 / testresults/*.json
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| testament.nim | `testament/testament.nim` | ソース | メインプログラム、コマンドライン解析、テスト実行制御 |
| specs.nim | `testament/specs.nim` | ソース | テストスペックの定義と解析 |
| categories.nim | `testament/categories.nim` | ソース | カテゴリ別テスト処理（includeファイル） |
| backend.nim | `testament/backend.nim` | ソース | テスト結果のJSON出力 |
| htmlgen.nim | `testament/htmlgen.nim` | ソース | HTMLレポート生成 |
| azure.nim | `testament/azure.nim` | ソース | Azure Pipelines連携 |
| important_packages.nim | `testament/important_packages.nim` | ソース | nimble-packagesテスト用パッケージリスト |
| testament.nim.cfg | `testament/testament.nim.cfg` | 設定 | コンパイル設定 |
