---
generated_at: 2026-02-04 10:00:00
metrics:
  claims_total: 169
  claims_with_evidence: 165
  claims_without_evidence: 4
confidence_derived: 0.98
---

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

## 本レポートについて

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

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

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

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**0.98**
  - 根拠あり：165 / 169、根拠なし：4
- 優先レビュー（高）
  1. **C-009 (RateLimit::wait - 待機不要ケース)**：usleepの呼び出し有無の検証はモック/スパイが必要で、実際の待機動作の確認方法に依存
  2. **C-010 (RateLimit::wait - 待機ケース)**：同上。usleepのモックが必要
  3. **C-016 (Reservation::wait)**：usleep呼び出しの検証方法がテスト環境に依存
  4. **C-082 (Rate::calculateTimeForTokens - tokens=0)**：ceil(0/amount)*interval の計算結果が0になるかは数学的に自明だが、実装上のceil関数の挙動に依存

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

- E-01: `src/Symfony/Component/RateLimiter/RateLimit.php` - RateLimitクラスのソースコード
- E-02: `src/Symfony/Component/RateLimiter/Reservation.php` - Reservationクラスのソースコード
- E-03: `src/Symfony/Component/RateLimiter/CompoundLimiter.php` - CompoundLimiterクラスのソースコード
- E-04: `src/Symfony/Component/RateLimiter/CompoundRateLimiterFactory.php` - CompoundRateLimiterFactoryクラスのソースコード
- E-05: `src/Symfony/Component/RateLimiter/RateLimiterFactory.php` - RateLimiterFactoryクラスのソースコード
- E-06: `src/Symfony/Component/RateLimiter/Policy/FixedWindowLimiter.php` - FixedWindowLimiterクラスのソースコード
- E-07: `src/Symfony/Component/RateLimiter/Policy/SlidingWindowLimiter.php` - SlidingWindowLimiterクラスのソースコード
- E-08: `src/Symfony/Component/RateLimiter/Policy/TokenBucketLimiter.php` - TokenBucketLimiterクラスのソースコード
- E-09: `src/Symfony/Component/RateLimiter/Policy/NoLimiter.php` - NoLimiterクラスのソースコード
- E-10: `src/Symfony/Component/RateLimiter/Policy/Rate.php` - Rateクラスのソースコード
- E-11: `src/Symfony/Component/RateLimiter/Policy/Window.php` - Windowクラスのソースコード
- E-12: `src/Symfony/Component/RateLimiter/Policy/SlidingWindow.php` - SlidingWindowクラスのソースコード
- E-13: `src/Symfony/Component/RateLimiter/Policy/TokenBucket.php` - TokenBucketクラスのソースコード
- E-14: `src/Symfony/Component/RateLimiter/Policy/ResetLimiterTrait.php` - ResetLimiterTraitのソースコード
- E-15: `src/Symfony/Component/RateLimiter/Storage/InMemoryStorage.php` - InMemoryStorageクラスのソースコード
- E-16: `src/Symfony/Component/RateLimiter/Storage/CacheStorage.php` - CacheStorageクラスのソースコード
- E-17: `src/Symfony/Component/RateLimiter/Storage/StorageInterface.php` - StorageInterfaceのソースコード
- E-18: `src/Symfony/Component/RateLimiter/Util/TimeUtil.php` - TimeUtilクラスのソースコード
- E-19: `src/Symfony/Component/RateLimiter/Exception/MaxWaitDurationExceededException.php` - MaxWaitDurationExceededExceptionクラスのソースコード
- E-20: `src/Symfony/Component/RateLimiter/Exception/RateLimitExceededException.php` - RateLimitExceededExceptionクラスのソースコード
- E-21: `src/Symfony/Component/RateLimiter/Exception/ReserveNotSupportedException.php` - ReserveNotSupportedExceptionクラスのソースコード
- E-22: `src/Symfony/Component/RateLimiter/Exception/InvalidIntervalException.php` - InvalidIntervalExceptionクラスのソースコード
- E-23: `src/Symfony/Component/RateLimiter/LimiterInterface.php` - LimiterInterfaceのソースコード
- E-24: `src/Symfony/Component/RateLimiter/LimiterStateInterface.php` - LimiterStateInterfaceのソースコード
- E-25: `src/Symfony/Component/RateLimiter/RateLimiterFactoryInterface.php` - RateLimiterFactoryInterfaceのソースコード

## 3) Claims と根拠の対応（レビューの主戦場）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-001 | RateLimit::__construct - 正常なパラメータで生成 | E-01 | ○ |
| C-002 | RateLimit::isAccepted - accepted=trueでtrue返却 | E-01 | ○ |
| C-003 | RateLimit::isAccepted - accepted=falseでfalse返却 | E-01 | ○ |
| C-004 | RateLimit::ensureAccepted - accepted=trueで$this返却 | E-01 | ○ |
| C-005 | RateLimit::ensureAccepted - accepted=falseで例外スロー | E-01, E-20 | ○ |
| C-006 | RateLimit::getRetryAfter - DateTimeImmutable返却 | E-01 | ○ |
| C-007 | RateLimit::getRemainingTokens - 残トークン数返却 | E-01 | ○ |
| C-008 | RateLimit::getLimit - 制限数返却 | E-01 | ○ |
| C-009 | RateLimit::wait - retryAfterが過去で即座return | E-01 | △ |
| C-010 | RateLimit::wait - retryAfterが未来でusleep実行 | E-01 | △ |
| C-011 | Reservation::__construct - 正常生成 | E-02 | ○ |
| C-012 | Reservation::getTimeToAct - timeToAct返却 | E-02 | ○ |
| C-013 | Reservation::getWaitDuration - 正の待機時間返却 | E-02 | ○ |
| C-014 | Reservation::getWaitDuration - 過去なら0返却 | E-02 | ○ |
| C-015 | Reservation::getRateLimit - RateLimit返却 | E-02 | ○ |
| C-016 | Reservation::wait - 待機時間0で即座return | E-02 | △ |
| C-017 | CompoundLimiter::__construct - 1つ以上のlimiterで生成 | E-03 | ○ |
| C-018 | CompoundLimiter::__construct - 空配列でLogicException | E-03 | ○ |
| C-019 | CompoundLimiter::reserve - ReserveNotSupportedException | E-03, E-21 | ○ |
| C-020 | CompoundLimiter::consume - 最小残トークンのRateLimit返却 | E-03 | ○ |
| C-021 | CompoundLimiter::consume - rejected優先返却 | E-03 | ○ |
| C-022 | CompoundLimiter::consume - 単一リミッターケース | E-03 | ○ |
| C-023 | CompoundLimiter::reset - 全リミッターreset呼出 | E-03 | ○ |
| C-024 | CompoundRateLimiterFactory::create - CompoundLimiter生成 | E-04 | ○ |
| C-025 | CompoundRateLimiterFactory::create - nullキー | E-04 | ○ |
| C-026 | RateLimiterFactory::__construct - token_bucket生成 | E-05 | ○ |
| C-027 | RateLimiterFactory::__construct - fixed_window生成 | E-05 | ○ |
| C-028 | RateLimiterFactory::__construct - sliding_window生成 | E-05 | ○ |
| C-029 | RateLimiterFactory::__construct - no_limit生成 | E-05 | ○ |
| C-030 | RateLimiterFactory::__construct - 不正intervalでLogicException | E-05 | ○ |
| C-031 | RateLimiterFactory::create - TokenBucketLimiter返却 | E-05, E-08 | ○ |
| C-032 | RateLimiterFactory::create - FixedWindowLimiter返却 | E-05, E-06 | ○ |
| C-033 | RateLimiterFactory::create - SlidingWindowLimiter返却 | E-05, E-07 | ○ |
| C-034 | RateLimiterFactory::create - NoLimiter返却 | E-05, E-09 | ○ |
| C-035 | RateLimiterFactory::create - nullキー | E-05 | ○ |
| C-036 | RateLimiterFactory::create - LockFactory連携 | E-05 | ○ |
| C-037 | FixedWindowLimiter::__construct - 正常生成 | E-06 | ○ |
| C-038 | FixedWindowLimiter::__construct - limit=0でInvalidArgumentException | E-06 | ○ |
| C-039 | FixedWindowLimiter::reserve - 十分トークンで即座予約 | E-06 | ○ |
| C-040 | FixedWindowLimiter::reserve - tokens=0で保存なし | E-06 | ○ |
| C-041 | FixedWindowLimiter::reserve - limit超過でInvalidArgumentException | E-06 | ○ |
| C-042 | FixedWindowLimiter::reserve - maxTime超過でMaxWaitDurationExceededException | E-06, E-19 | ○ |
| C-043 | FixedWindowLimiter::reserve - 待機付き予約 | E-06 | ○ |
| C-044 | FixedWindowLimiter::consume - accepted RateLimit返却 | E-06 | ○ |
| C-045 | FixedWindowLimiter::consume - rejected RateLimit返却 | E-06 | ○ |
| C-046 | FixedWindowLimiter::consume - リミット到達 | E-06 | ○ |
| C-047 | FixedWindowLimiter::getAvailableTokens - 残トークン計算 | E-06 | ○ |
| C-048 | FixedWindowLimiter::getAvailableTokens - hitCount=0 | E-06 | ○ |
| C-049 | FixedWindowLimiter::reset - ストレージ削除 | E-06, E-14 | ○ |
| C-050 | SlidingWindowLimiter::__construct - 正常生成 | E-07 | ○ |
| C-051 | SlidingWindowLimiter::reserve - 十分トークンで即座予約 | E-07 | ○ |
| C-052 | SlidingWindowLimiter::reserve - tokens=0で保存なし | E-07 | ○ |
| C-053 | SlidingWindowLimiter::reserve - limit超過でInvalidArgumentException | E-07 | ○ |
| C-054 | SlidingWindowLimiter::reserve - maxTime超過でMaxWaitDurationExceededException | E-07, E-19 | ○ |
| C-055 | SlidingWindowLimiter::reserve - 期限切れウィンドウ再生成 | E-07, E-12 | ○ |
| C-056 | SlidingWindowLimiter::consume - accepted RateLimit返却 | E-07 | ○ |
| C-057 | SlidingWindowLimiter::consume - rejected RateLimit返却 | E-07 | ○ |
| C-058 | SlidingWindowLimiter::reset - ストレージ削除 | E-07, E-14 | ○ |
| C-059 | TokenBucketLimiter::__construct - 正常生成 | E-08 | ○ |
| C-060 | TokenBucketLimiter::reserve - 十分トークンで即座予約 | E-08 | ○ |
| C-061 | TokenBucketLimiter::reserve - tokens=0で保存なし | E-08 | ○ |
| C-062 | TokenBucketLimiter::reserve - maxBurst超過でInvalidArgumentException | E-08 | ○ |
| C-063 | TokenBucketLimiter::reserve - maxTime超過でMaxWaitDurationExceededException | E-08, E-19 | ○ |
| C-064 | TokenBucketLimiter::reserve - 待機付き予約 | E-08 | ○ |
| C-065 | TokenBucketLimiter::consume - accepted RateLimit返却 | E-08 | ○ |
| C-066 | TokenBucketLimiter::consume - rejected RateLimit返却 | E-08 | ○ |
| C-067 | TokenBucketLimiter::reset - ストレージ削除 | E-08, E-14 | ○ |
| C-068 | NoLimiter::reserve - 即座Reservation返却 | E-09 | ○ |
| C-069 | NoLimiter::consume - accepted RateLimit返却 | E-09 | ○ |
| C-070 | NoLimiter::consume - 大量tokens | E-09 | ○ |
| C-071 | NoLimiter::reset - 空実装 | E-09 | ○ |
| C-072 | Rate::__construct - 正常生成 | E-10 | ○ |
| C-073 | Rate::perSecond - 秒単位Rate生成 | E-10 | ○ |
| C-074 | Rate::perMinute - 分単位Rate生成 | E-10 | ○ |
| C-075 | Rate::perHour - 時間単位Rate生成 | E-10 | ○ |
| C-076 | Rate::perDay - 日単位Rate生成 | E-10 | ○ |
| C-077 | Rate::perMonth - 月単位Rate生成 | E-10 | ○ |
| C-078 | Rate::perYear - 年単位Rate生成 | E-10 | ○ |
| C-079 | Rate::perSecond - デフォルト値 | E-10 | ○ |
| C-080 | Rate::fromString - 文字列復元 | E-10 | ○ |
| C-081 | Rate::calculateTimeForTokens - 待機時間計算 | E-10, E-18 | ○ |
| C-082 | Rate::calculateTimeForTokens - tokens=0 | E-10 | △ |
| C-083 | Rate::calculateTimeForTokens - tokens=1 | E-10 | ○ |
| C-084 | Rate::calculateNextTokenAvailability - 次トークン時刻 | E-10 | ○ |
| C-085 | Rate::calculateNewTokensDuringInterval - 期間内新規トークン | E-10, E-18 | ○ |
| C-086 | Rate::calculateNewTokensDuringInterval - 不完全サイクル | E-10 | ○ |
| C-087 | Rate::calculateNewTokensDuringInterval - duration=0 | E-10 | ○ |
| C-088 | Rate::calculateRefillInterval - リフィルインターバル計算 | E-10, E-18 | ○ |
| C-089 | Rate::calculateRefillInterval - 不完全サイクルインターバル | E-10 | ○ |
| C-090 | Rate::__toString - 文字列変換 | E-10 | ○ |
| C-091 | Window::__construct - 正常生成 | E-11 | ○ |
| C-092 | Window::__construct - タイマー指定 | E-11 | ○ |
| C-093 | Window::getId - ID取得 | E-11 | ○ |
| C-094 | Window::getExpirationTime - 有効期限取得 | E-11 | ○ |
| C-095 | Window::add - ヒット追加 | E-11 | ○ |
| C-096 | Window::add - interval超過でリセット | E-11 | ○ |
| C-097 | Window::add - デフォルトhits | E-11 | ○ |
| C-098 | Window::getHitCount - ヒットカウント取得 | E-11 | ○ |
| C-099 | Window::getAvailableTokens - 残トークン計算 | E-11 | ○ |
| C-100 | Window::getAvailableTokens - interval超過で全トークン | E-11 | ○ |
| C-101 | Window::getAvailableTokens - トークン枯渇 | E-11 | ○ |
| C-102 | Window::calculateTimeForTokens - 即時利用可能 | E-11 | ○ |
| C-103 | Window::calculateTimeForTokens - 待機時間計算 | E-11 | ○ |
| C-104 | Window::__serialize - シリアライズ | E-11 | ○ |
| C-105 | Window::__unserialize - デシリアライズ | E-11 | ○ |
| C-106 | Window::__unserialize - BC互換 | E-11 | ○ |
| C-107 | SlidingWindow::__construct - 正常生成 | E-12 | ○ |
| C-108 | SlidingWindow::__construct - interval=0でInvalidIntervalException | E-12, E-22 | ○ |
| C-109 | SlidingWindow::__construct - 負のinterval | E-12, E-22 | ○ |
| C-110 | SlidingWindow::createFromPreviousWindow - ウィンドウ引き継ぎ | E-12 | ○ |
| C-111 | SlidingWindow::createFromPreviousWindow - 古いウィンドウ | E-12 | ○ |
| C-112 | SlidingWindow::getId - ID取得 | E-12 | ○ |
| C-113 | SlidingWindow::getExpirationTime - 有効期限取得 | E-12 | ○ |
| C-114 | SlidingWindow::isExpired - 有効判定 | E-12 | ○ |
| C-115 | SlidingWindow::isExpired - 期限切れ判定 | E-12 | ○ |
| C-116 | SlidingWindow::add - ヒット追加 | E-12 | ○ |
| C-117 | SlidingWindow::add - デフォルトhits | E-12 | ○ |
| C-118 | SlidingWindow::getHitCount - スライディング計算 | E-12 | ○ |
| C-119 | SlidingWindow::getHitCount - 前ウィンドウヒット0 | E-12 | ○ |
| C-120 | SlidingWindow::calculateTimeForTokens - 即時利用可能 | E-12 | ○ |
| C-121 | SlidingWindow::calculateTimeForTokens - 待機時間計算 | E-12 | ○ |
| C-122 | SlidingWindow::__serialize - シリアライズ | E-12 | ○ |
| C-123 | SlidingWindow::__unserialize - デシリアライズ | E-12 | ○ |
| C-124 | SlidingWindow::__unserialize - BC互換 | E-12 | ○ |
| C-125 | TokenBucket::__construct - 正常生成 | E-13 | ○ |
| C-126 | TokenBucket::__construct - initialTokens=0でInvalidArgumentException | E-13 | ○ |
| C-127 | TokenBucket::__construct - タイマー指定 | E-13 | ○ |
| C-128 | TokenBucket::getId - ID取得 | E-13 | ○ |
| C-129 | TokenBucket::setTimer - タイマー設定 | E-13 | ○ |
| C-130 | TokenBucket::getTimer - タイマー取得 | E-13 | ○ |
| C-131 | TokenBucket::setTokens - トークン数設定 | E-13 | ○ |
| C-132 | TokenBucket::getAvailableTokens - トークン補充計算 | E-13, E-10 | ○ |
| C-133 | TokenBucket::getAvailableTokens - 初期状態 | E-13 | ○ |
| C-134 | TokenBucket::getAvailableTokens - burstSize上限 | E-13 | ○ |
| C-135 | TokenBucket::getAvailableTokens - 過去時刻指定 | E-13 | ○ |
| C-136 | TokenBucket::getExpirationTime - 有効期限計算 | E-13, E-10 | ○ |
| C-137 | TokenBucket::__serialize - シリアライズ | E-13 | ○ |
| C-138 | TokenBucket::__unserialize - デシリアライズ | E-13 | ○ |
| C-139 | TokenBucket::__unserialize - BC互換 | E-13 | ○ |
| C-140 | InMemoryStorage::save - 状態保存 | E-15 | ○ |
| C-141 | InMemoryStorage::fetch - 状態取得 | E-15 | ○ |
| C-142 | InMemoryStorage::fetch - 存在しないID | E-15 | ○ |
| C-143 | InMemoryStorage::fetch - 期限切れ状態 | E-15 | ○ |
| C-144 | InMemoryStorage::delete - 状態削除 | E-15 | ○ |
| C-145 | InMemoryStorage::delete - 存在しないID削除 | E-15 | ○ |
| C-146 | CacheStorage::save - キャッシュ保存 | E-16 | ○ |
| C-147 | CacheStorage::save - expiresAfter設定 | E-16 | ○ |
| C-148 | CacheStorage::save - expirationTimeがnull | E-16 | ○ |
| C-149 | CacheStorage::fetch - キャッシュ取得 | E-16 | ○ |
| C-150 | CacheStorage::fetch - 非LimiterState取得 | E-16 | ○ |
| C-151 | CacheStorage::fetch - キャッシュミス | E-16 | ○ |
| C-152 | CacheStorage::delete - キャッシュ削除 | E-16 | ○ |
| C-153 | CacheStorage::save - SHA1キー | E-16 | ○ |
| C-154 | TimeUtil::dateIntervalToSeconds - 1分変換 | E-18 | ○ |
| C-155 | TimeUtil::dateIntervalToSeconds - 1時間変換 | E-18 | ○ |
| C-156 | TimeUtil::dateIntervalToSeconds - 1日変換 | E-18 | ○ |
| C-157 | TimeUtil::dateIntervalToSeconds - 0秒変換 | E-18 | ○ |
| C-158 | TimeUtil::dateIntervalToSeconds - 複合変換 | E-18 | ○ |
| C-159 | MaxWaitDurationExceededException::__construct - 正常生成 | E-19 | ○ |
| C-160 | MaxWaitDurationExceededException::getRateLimit - RateLimit返却 | E-19 | ○ |
| C-161 | RateLimitExceededException::__construct - 正常生成 | E-20 | ○ |
| C-162 | RateLimitExceededException::getRateLimit - RateLimit返却 | E-20 | ○ |
| C-163 | RateLimitExceededException::getRetryAfter - retryAfter返却 | E-20 | ○ |
| C-164 | RateLimitExceededException::getRemainingTokens - 残トークン返却 | E-20 | ○ |
| C-165 | RateLimitExceededException::getLimit - 制限値返却 | E-20 | ○ |
| C-166 | ReserveNotSupportedException::__construct - メッセージ生成 | E-21 | ○ |
| C-167 | ResetLimiterTrait::reset - ロック付きリセット | E-14 | ○ |
| C-168 | ResetLimiterTrait::reset - ロックなしリセット | E-14 | ○ |
| C-169 | ResetLimiterTrait::reset - 例外時ロック解放 | E-14 | ○ |

## 4) 不足情報（Unknown / Missing）
- C-009, C-010, C-016: `usleep()` はPHP組み込み関数であり、実行時の挙動をユニットテストで直接検証することは困難。テスト実装時にはモックライブラリ（php-mock等）やClockインターフェースの導入を検討する必要がある。
  - 候補：php-mock / symfony/clock-mock / uopz拡張
- C-082: `Rate::calculateTimeForTokens(0)` は `ceil(0/refillAmount) * intervalSeconds` となり数学的に0だが、PHPの `ceil(0)` が `0.0` (float) を返すため、戻り値の型が `int` であることの検証が必要。
  - 候補：PHP公式ドキュメント ceil() の仕様確認

## 5) リスクフラグ（レビュー観点）
- 0: 低リスク - 例外クラス群（InvalidIntervalException, ReserveNotSupportedException）は単純なクラスであり、テストケースの信頼性は高い
- 0: 低リスク - ゲッター/セッター系メソッド（getId, getTimer, setTokens等）は自明な動作
- 1: 中リスク - SlidingWindow::getHitCount のスライディング計算は時間に依存するため、テスト実行タイミングにより結果が変動する可能性がある
- 1: 中リスク - TokenBucket::getAvailableTokens のトークン補充計算は Rate クラスとの連携に依存し、時間ベースの計算精度の検証が必要
- 1: 中リスク - シリアライズ/デシリアライズのBC互換テストは旧形式データの正確な再現が必要
- 0: 低リスク - StorageInterface実装クラスのテストは標準的なCRUD操作

## 6) レビュアーチェックリスト（最小）
- [ ] 全169テストケースがCSVに含まれているか
- [ ] テストIDの連番（UT-RLM-001 ~ UT-RLM-169）に欠番がないか
- [ ] 各リミッタークラス（FixedWindow, SlidingWindow, TokenBucket, NoLimiter, CompoundLimiter）のreserve/consume/resetが網羅されているか
- [ ] 異常系テスト（InvalidArgumentException, MaxWaitDurationExceededException, LogicException等）が全分岐に対応しているか
- [ ] 境界値テスト（limit到達、tokens=0、空配列等）が含まれているか
- [ ] ストレージ実装（InMemoryStorage, CacheStorage）のsave/fetch/deleteが網羅されているか
- [ ] シリアライズ/デシリアライズ（Window, SlidingWindow, TokenBucket）のテストが含まれているか
- [ ] BC互換デシリアライズ（旧形式5要素配列）のテストが含まれているか
- [ ] ResetLimiterTraitのfinallyブロック（ロック解放保証）のテストが含まれているか
- [ ] RateLimiterFactoryの全ポリシー（token_bucket, fixed_window, sliding_window, no_limit）のテストが含まれているか
