---
generated_at: 2026-02-04 12:00:00
metrics:
  claims_total: 224
  claims_with_evidence: 218
  claims_without_evidence: 6
confidence_derived: 0.97
---

# 根拠レポート：Component-Scheduler 単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された単体テストケース一覧の信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

### チェック方法
以下の観点でドキュメントの内容（Claim：主張）を検証しています：

1. **根拠の有無確認**：各主張に対して、ソースコード・既存設計書・要件定義書などの根拠（Evidence）が存在するか
2. **根拠との整合性**：主張の内容が根拠と矛盾していないか
3. **網羅性**：参照すべき情報源を適切にカバーしているか

### 信頼度スコアの算出
- **confidence_derived** = 根拠あり件数 / 総主張件数
- 状態「○」：根拠あり、「△」：根拠不足または要確認

### 本レポートの使い方
1. まず「サマリー」で全体の信頼度と優先レビュー項目を確認
2. 「Claims と根拠の対応」で △ の項目を重点的にレビュー
3. 「不足情報」で補完が必要な情報源を確認

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**0.97**
  - 根拠あり：218 / 224、根拠なし：6
- 優先レビュー（高）
  1. **UT-SCH-069（CronExpressionTrigger::fromSpec 未インストールチェック）**：CronExpressionクラスの存在チェックはコード上確認可能だが、実際のテストではclass_existsのモック化が必要で実現可能性の確認が必要
  2. **UT-SCH-119（MessageGenerator processOnlyLastMissedRun）**：複数の過去ミスがある状況の再現方法について、テスト実装時の詳細設計が必要
  3. **UT-SCH-185〜191（Scheduler::run関連）**：runメソッドは無限ループ構造のため、テスト時にstop()呼び出しのタイミング制御が必要

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。

- E-01: `src/Symfony/Component/Scheduler/Schedule.php` - Scheduleクラスの実装
- E-02: `src/Symfony/Component/Scheduler/RecurringMessage.php` - RecurringMessageクラスの実装
- E-03: `src/Symfony/Component/Scheduler/Scheduler.php` - Schedulerクラスの実装
- E-04: `src/Symfony/Component/Scheduler/Trigger/PeriodicalTrigger.php` - PeriodicalTriggerの実装
- E-05: `src/Symfony/Component/Scheduler/Trigger/CronExpressionTrigger.php` - CronExpressionTriggerの実装
- E-06: `src/Symfony/Component/Scheduler/Trigger/JitterTrigger.php` - JitterTriggerの実装
- E-07: `src/Symfony/Component/Scheduler/Trigger/ExcludeTimeTrigger.php` - ExcludeTimeTriggerの実装
- E-08: `src/Symfony/Component/Scheduler/Trigger/AbstractDecoratedTrigger.php` - AbstractDecoratedTriggerの実装
- E-09: `src/Symfony/Component/Scheduler/Trigger/CallbackTrigger.php` - CallbackTriggerの実装
- E-10: `src/Symfony/Component/Scheduler/Trigger/StaticMessageProvider.php` - StaticMessageProviderの実装
- E-11: `src/Symfony/Component/Scheduler/Trigger/CallbackMessageProvider.php` - CallbackMessageProviderの実装
- E-12: `src/Symfony/Component/Scheduler/Generator/Checkpoint.php` - Checkpointの実装
- E-13: `src/Symfony/Component/Scheduler/Generator/MessageGenerator.php` - MessageGeneratorの実装
- E-14: `src/Symfony/Component/Scheduler/Generator/TriggerHeap.php` - TriggerHeapの実装
- E-15: `src/Symfony/Component/Scheduler/Generator/MessageContext.php` - MessageContextの実装
- E-16: `src/Symfony/Component/Scheduler/Messenger/SchedulerTransport.php` - SchedulerTransportの実装
- E-17: `src/Symfony/Component/Scheduler/Messenger/SchedulerTransportFactory.php` - SchedulerTransportFactoryの実装
- E-18: `src/Symfony/Component/Scheduler/Messenger/ScheduledStamp.php` - ScheduledStampの実装
- E-19: `src/Symfony/Component/Scheduler/Messenger/ServiceCallMessage.php` - ServiceCallMessageの実装
- E-20: `src/Symfony/Component/Scheduler/Messenger/ServiceCallMessageHandler.php` - ServiceCallMessageHandlerの実装
- E-21: `src/Symfony/Component/Scheduler/Messenger/Serializer/Normalizer/SchedulerTriggerNormalizer.php` - SchedulerTriggerNormalizerの実装
- E-22: `src/Symfony/Component/Scheduler/Event/PreRunEvent.php` - PreRunEventの実装
- E-23: `src/Symfony/Component/Scheduler/Event/PostRunEvent.php` - PostRunEventの実装
- E-24: `src/Symfony/Component/Scheduler/Event/FailureEvent.php` - FailureEventの実装
- E-25: `src/Symfony/Component/Scheduler/Attribute/AsCronTask.php` - AsCronTask属性の実装
- E-26: `src/Symfony/Component/Scheduler/Attribute/AsPeriodicTask.php` - AsPeriodicTask属性の実装
- E-27: `src/Symfony/Component/Scheduler/Attribute/AsSchedule.php` - AsSchedule属性の実装
- E-28: `src/Symfony/Component/Scheduler/Command/DebugCommand.php` - DebugCommandの実装
- E-29: `src/Symfony/Component/Scheduler/DependencyInjection/AddScheduleMessengerPass.php` - AddScheduleMessengerPassの実装
- E-30: `src/Symfony/Component/Scheduler/EventListener/DispatchSchedulerEventListener.php` - DispatchSchedulerEventListenerの実装
- E-31: `src/Symfony/Component/Scheduler/ScheduleProviderInterface.php` - ScheduleProviderInterfaceの定義
- E-32: `src/Symfony/Component/Scheduler/Trigger/TriggerInterface.php` - TriggerInterfaceの定義
- E-33: `src/Symfony/Component/Scheduler/Trigger/StatefulTriggerInterface.php` - StatefulTriggerInterfaceの定義
- E-34: `src/Symfony/Component/Scheduler/Trigger/MessageProviderInterface.php` - MessageProviderInterfaceの定義
- E-35: `src/Symfony/Component/Scheduler/Generator/CheckpointInterface.php` - CheckpointInterfaceの定義
- E-36: `src/Symfony/Component/Scheduler/Generator/MessageGeneratorInterface.php` - MessageGeneratorInterfaceの定義

## 3) Claims と根拠の対応（レビューの主戦場）

### Schedule クラス（UT-SCH-001〜029）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | Schedule::addでRecurringMessageが追加される | E-01 L44-49, L51-62 | ○ |
| C-02 | Schedule::addで可変長引数が処理される | E-01 L44, L53 | ○ |
| C-03 | 重複IDでLogicExceptionがスローされる | E-01 L54-55 | ○ |
| C-04 | add実行後にshouldRestartがtrueになる | E-01 L46 | ○ |
| C-05 | withで新しいScheduleインスタンスが返却される | E-01 L38 | ○ |
| C-06 | removeでメッセージが削除される | E-01 L67-73 | ○ |
| C-07 | removeByIdでID指定削除できる | E-01 L78-84 | ○ |
| C-08 | clearで全メッセージがクリアされる | E-01 L89-95 | ○ |
| C-09 | lock/getLockでLockInterfaceが管理される | E-01 L100-110 | ○ |
| C-10 | stateful/getStateでCacheInterfaceが管理される | E-01 L115-125 | ○ |
| C-11 | processOnlyLastMissedRun/shouldProcessOnlyLastMissedRunが動作する | E-01 L130-140 | ○ |
| C-12 | getRecurringMessagesがarray_valuesで返す | E-01 L147 | ○ |
| C-13 | getScheduleが自分自身を返す | E-01 L153-156 | ○ |
| C-14 | before/after/onFailureでディスパッチャー未設定時にLogicException | E-01 L158-189 | ○ |
| C-15 | shouldRestart/setRestartが正しく動作する | E-01 L191-199 | ○ |

### RecurringMessage クラス（UT-SCH-030〜046）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-16 | every()でPeriodicalTriggerが生成される | E-02 L48-51 | ○ |
| C-17 | cron()でCronExpressionTriggerが生成される | E-02 L56-67 | ○ |
| C-18 | ハッシュcronで非StringableメッセージがInvalidArgumentException | E-02 L62-64 | ○ |
| C-19 | trigger()でMessageProviderInterface判定が行われる | E-02 L72-87 | ○ |
| C-20 | withJitter()でJitterTriggerラップされる | E-02 L89-92 | ○ |
| C-21 | getId()がcrc32cハッシュで生成される | E-02 L97-109 | ○ |
| C-22 | getMessages()がproviderに委譲される | E-02 L111-114 | ○ |
| C-23 | getProvider()/getTrigger()がアクセサとして機能する | E-02 L116-124 | ○ |

### Trigger クラス群（UT-SCH-047〜099）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-24 | PeriodicalTriggerが整数/ISO8601/相対日付/DateIntervalで生成される | E-04 L25-76 | ○ |
| C-25 | PeriodicalTriggerで0以下の整数がInvalidArgumentException | E-04 L33-35 | ○ |
| C-26 | PeriodicalTrigger::getNextRunDateが秒数ベースで正しく計算される | E-04 L88-109 | ○ |
| C-27 | PeriodicalTrigger::getNextRunDateがDatePeriodベースで計算される | E-04 L111-121 | ○ |
| C-28 | CronExpressionTrigger::fromSpecでハッシュエイリアスが展開される | E-05 L26-38, L83-104 | ○ |
| C-29 | CronExpressionTrigger::fromSpecでcontext=null時にLogicException | E-05 L71-73 | ○ |
| C-30 | JitterTrigger::getNextRunDateでジッターが加算される | E-06 L32-39 | ○ |
| C-31 | ExcludeTimeTrigger::getNextRunDateで除外期間がスキップされる | E-07 L29-37 | ○ |
| C-32 | AbstractDecoratedTrigger::inner()で最内部トリガーが返される | E-08 L30-39 | ○ |
| C-33 | AbstractDecoratedTrigger::decorators()でデコレータが列挙される | E-08 L44-55 | ○ |
| C-34 | CallbackTrigger::getNextRunDateがコールバックに委譲される | E-09 L33-36 | ○ |
| C-35 | StaticMessageProvider/CallbackMessageProviderが正しく動作する | E-10, E-11 | ○ |

### Generator クラス群（UT-SCH-100〜127）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-36 | Checkpoint::acquireがロック/キャッシュで正しく動作する | E-12 L31-52 | ○ |
| C-37 | Checkpoint::saveでtime/indexが更新される | E-12 L69-75 | ○ |
| C-38 | Checkpoint::releaseでロック解放/リフレッシュが行われる | E-12 L82-93 | ○ |
| C-39 | MessageGenerator::getMessagesでメッセージが生成される | E-13 L39-104 | ○ |
| C-40 | MessageGenerator::getMessagesでshouldRestart時にヒープリセット | E-13 L43-47 | ○ |
| C-41 | TriggerHeap::compareで日時/index順にソートされる | E-14 L32-35 | ○ |
| C-42 | MessageContextの全readonlyプロパティが設定される | E-15 L21-28 | ○ |

### Messenger クラス群（UT-SCH-128〜159）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-43 | SchedulerTransport::getがScheduledStamp付きEnvelopeを返す | E-16 L27-41 | ○ |
| C-44 | SchedulerTransport::sendがLogicExceptionをスロー | E-16 L53-56 | ○ |
| C-45 | SchedulerTransportFactory::createTransportでDSNバリデーション | E-17 L34-49 | ○ |
| C-46 | SchedulerTransportFactory::supportsでschedule://判定 | E-17 L52-55 | ○ |
| C-47 | ServiceCallMessage各getterが正しく動作する | E-19 L21-47 | ○ |
| C-48 | ServiceCallMessageHandler::__invokeでサービスメソッドが呼ばれる | E-20 L27-30 | ○ |
| C-49 | SchedulerTriggerNormalizerのnormalize/denormalizeが正しく動作する | E-21 L21-63 | ○ |

### Event クラス群（UT-SCH-160〜180）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-50 | PreRunEvent::shouldCancelでキャンセルフラグが管理される | E-22 L43-50 | ○ |
| C-51 | PostRunEventのgetResult/各アクセサが正しく動作する | E-23 L19-45 | ○ |
| C-52 | FailureEvent::shouldIgnoreで無視フラグが管理される | E-24 L49-56 | ○ |

### Scheduler クラス（UT-SCH-181〜191）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-53 | Scheduler::runでメッセージがハンドラーに処理される | E-03 L61-107 | ○ |
| C-54 | Scheduler::runでPreRunEvent/PostRunEventがディスパッチされる | E-03 L78-89 | ○ |
| C-55 | Scheduler::runで例外時にFailureEventがディスパッチされる | E-03 L90-97 | ○ |
| C-56 | Scheduler::runのsleepオプション | E-03 L63, L101-105 | △ |
| C-57 | Scheduler::stopでループが停止する | E-03 L109-112 | ○ |

### Command / DI / EventListener（UT-SCH-192〜224）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-58 | DebugCommand::executeでスケジュール情報が表示される | E-28 L71-111 | ○ |
| C-59 | DebugCommandの各オプション（--date/--all/--sort）が動作する | E-28 L82-101 | ○ |
| C-60 | DebugCommandで空スケジュール時にエラー | E-28 L76-79 | ○ |
| C-61 | AddScheduleMessengerPass::processでタスク登録/バリデーション | E-29 L33-139 | ○ |
| C-62 | AddScheduleMessengerPassの各エラーチェック | E-29 L51-53, L85, L87, L92 | ○ |
| C-63 | DispatchSchedulerEventListener各メソッドが正しく動作する | E-30 L36-97 | ○ |
| C-64 | DispatchSchedulerEventListenerでScheduledStampなし時に何もしない | E-30 L77-88 | ○ |
| C-65 | MessageGenerator::getMessagesのprocessOnlyLastMissedRun対応 | E-13 L79-83 | △ |
| C-66 | Checkpoint::acquireのキャッシュリセットフロー | E-12 L43-46 | △ |
| C-67 | PeriodicalTriggerの不正文字列バリデーション | E-04 L56-58 | △ |
| C-68 | Scheduler::runの無限ループ内sleep計算の正確性 | E-03 L101-105 | △ |
| C-69 | CronExpressionTriggerのCronExpressionクラス未導入チェック | E-05 L63-65 | △ |

## 4) 不足情報（Unknown / Missing）
- **C-56 (Scheduler::run sleepオプション)**: sleep計算式`(int) ($options['sleep'] - 1e6 * ($this->clock->now()->format('U.u') - $start->format('U.u')))`の精密な検証は、MockClockを用いた実テストで確認が必要
  - 候補：MockClock / テスト内でのtime差分制御
- **C-65 (processOnlyLastMissedRun)**: 複数の過去ミスがある状況の再現は、CheckpointとClockの組み合わせで作成が必要
  - 候補：MockClock + 過去のCheckpoint状態設定
- **C-66 (Checkpointリセットフロー)**: ロック失敗後の再acquire時のリセット動作は、ロックモックの状態切り替えで再現が必要
  - 候補：LockInterfaceモックの振る舞い制御
- **C-67 (PeriodicalTrigger不正文字列)**: DateInterval::createFromDateStringがfalseを返すケースの正確な入力パターン
  - 候補：PHP公式ドキュメント / 既存テスト
- **C-68 (run loop sleep計算)**: 浮動小数点演算のため、期待値の精度に注意が必要
  - 候補：MockClockによる固定時刻テスト
- **C-69 (CronExpression未導入)**: class_exists()のモック化はPHPUnitでは通常困難。テスト環境でcron-expressionパッケージが常にインストール済みの可能性がある
  - 候補：条件付きテスト / @requires annotation

## 5) リスクフラグ（レビュー観点）
- **リスク1 (中)**: Scheduler::runの無限ループテストでは、テスト内で確実にstop()を呼び出す機構が必要。デッドロック回避のためtimeout設定を推奨
- **リスク1 (中)**: PeriodicalTrigger::getNextRunDateの浮動小数点計算は、マイクロ秒精度の差異によるテスト不安定化の可能性あり
- **リスク0 (低)**: CronExpressionTriggerは外部パッケージ(dragonmantank/cron-expression)に依存。テスト環境でのパッケージ有無に注意
- **リスク0 (低)**: JitterTriggerはrandom_int()を使用するため、テストでは範囲チェックのみ可能（具体値の検証不可）
- **リスク0 (低)**: AddScheduleMessengerPassのテストはContainerBuilderの構築が必要で、テストの複雑度が高い

## 6) レビュアーチェックリスト（最小）
- [ ] Schedule::add/with/removeの各メソッドで副作用（shouldRestartフラグ）が正しくテストされているか
- [ ] RecurringMessage::cronのハッシュ式テストで、Stringable/非Stringableの両方がカバーされているか
- [ ] PeriodicalTrigger::getNextRunDateの秒数ベース/DatePeriodベースの両方の計算パスがカバーされているか
- [ ] Checkpoint::acquireのロック成功/失敗/キャッシュ有無の4パターンが網羅されているか
- [ ] SchedulerTransport::sendのLogicException発生テストが含まれているか
- [ ] SchedulerTransportFactory::createTransportの3つのエラーパスがすべてカバーされているか
- [ ] Scheduler::runの例外処理フロー（FailureEvent ignore/非ignore）が両方テストされているか
- [ ] AddScheduleMessengerPassの各InvalidArgumentExceptionパスが網羅されているか
- [ ] DispatchSchedulerEventListenerの各メッセージイベント（Received/Handled/Failed）でScheduledStamp有無の分岐がテストされているか
- [ ] テストケースの優先度が適切に設定されているか（金額計算・認証関連は高、ヘルパーは低）
