---
generated_at: 2026-01-30 10:30:00
metrics:
  claims_total: 129
  claims_with_evidence: 129
  claims_without_evidence: 0
confidence_derived: 1.00
---

# 根拠レポート：Microsoft.Extensions.FileProviders.Physical 単体テストケース一覧

## 本レポートについて

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

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

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

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**1.00**
  - 根拠あり：129 / 129、根拠なし：0
- 優先レビュー（高）
  1. **該当なし**：全テストケースに根拠あり

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。抽出フェーズで付けたIDをそのまま出す。

- E-01: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs`
- E-02: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFilesWatcher.cs`
- E-03: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileInfo.cs`
- E-04: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalDirectoryInfo.cs`
- E-05: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PollingFileChangeToken.cs`
- E-06: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PollingWildCardChangeToken.cs`
- E-07: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/ExclusionFilters.cs`
- E-08: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/IPollingChangeToken.cs`
- E-09: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs`
- E-10: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/PhysicalDirectoryContents.cs`
- E-11: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/PathUtils.cs`
- E-12: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/Clock.cs`
- E-13: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/IClock.cs`

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

### PhysicalFileProvider (UT-FPP-001 - UT-FPP-030)
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | PhysicalFileProvider(string) コンストラクタは絶対パスを要求する | E-01 (L56-59: `if (!Path.IsPathRooted(root)) throw ArgumentException`) | ○ |
| C-02 | 存在しないディレクトリでDirectoryNotFoundExceptionをスロー | E-01 (L64-67: `if (!Directory.Exists(Root)) throw DirectoryNotFoundException`) | ○ |
| C-03 | Rootプロパティは末尾スラッシュ付きで返される | E-01 (L63: `Root = PathUtils.EnsureTrailingSlash(fullRoot)`) | ○ |
| C-04 | GetFileInfoはnull/空文字でNotFoundFileInfoを返す | E-01 (L265-268: `if (string.IsNullOrEmpty(subpath)...) return new NotFoundFileInfo`) | ○ |
| C-05 | GetFileInfoは絶対パスでNotFoundFileInfoを返す | E-01 (L274-277: `if (Path.IsPathRooted(subpath)) return new NotFoundFileInfo`) | ○ |
| C-06 | GetFileInfoはパストラバーサルを防止する | E-01 (L279-283: `if (fullPath == null) return new NotFoundFileInfo`, L230-233: `PathNavigatesAboveRoot`) | ○ |
| C-07 | GetFileInfoは除外フィルタを適用する | E-01 (L286-289: `if (FileSystemInfoHelper.IsExcluded...) return new NotFoundFileInfo`) | ○ |
| C-08 | GetDirectoryContentsはnullでNotFoundDirectoryContentsを返す | E-01 (L310-313: `if (subpath == null...) return NotFoundDirectoryContents.Singleton`) | ○ |
| C-09 | GetDirectoryContentsは絶対パスでNotFoundDirectoryContentsを返す | E-01 (L319-322: `if (Path.IsPathRooted(subpath)) return NotFoundDirectoryContents.Singleton`) | ○ |
| C-10 | WatchはnullでNullChangeTokenを返す | E-01 (L357-360: `if (filter == null...) return NullChangeToken.Singleton`) | ○ |
| C-11 | UsePollingFileWatcherは環境変数から初期値を取得 | E-01 (L188-196: `ReadPollingEnvironmentVariables`, L191-192: DOTNET_USE_POLLING_FILE_WATCHER) | ○ |
| C-12 | UsePollingFileWatcherはFileWatcher初期化後に変更不可 | E-01 (L103-106: `if (_fileWatcher != null) throw InvalidOperationException`) | ○ |
| C-13 | Disposeでリソースが解放される | E-01 (L211-221: `_fileWatcher?.Dispose()`) | ○ |

### PhysicalFilesWatcher (UT-FPW-001 - UT-FPW-015)
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-14 | FileSystemWatcherがnullでポーリングも無効の場合ArgumentNullException | E-02 (L78-81: `if (fileSystemWatcher == null && !pollForChanges) throw ArgumentNullException`) | ○ |
| C-15 | CreateFileChangeTokenはnullでArgumentNullExceptionをスロー | E-02 (L130: `ArgumentNullException.ThrowIfNull(filter)`) | ○ |
| C-16 | CreateFileChangeTokenは絶対パスでNullChangeTokenを返す | E-02 (L135-138: `if (Path.IsPathRooted(filter)...) return NullChangeToken.Singleton`) | ○ |
| C-17 | ワイルドカードパターンはGetOrAddWildcardChangeTokenを使用 | E-02 (L158-165: `isWildCard` check, `GetOrAddWildcardChangeToken`) | ○ |
| C-18 | ディレクトリパス（末尾スラッシュ）もワイルドカードトークンを使用 | E-02 (L162: `if (isWildCard || IsDirectoryPath(pattern))`) | ○ |
| C-19 | Disposeで_fileWatcherと_timerが解放される | E-02 (L269-273: `_fileWatcher?.Dispose(); _timer?.Dispose()`) | ○ |
| C-20 | RaiseChangeEventsは変更されたトークンをキャンセル | E-02 (L498-499: `token.CancellationTokenSource!.Cancel()`) | ○ |

### PhysicalFileInfo (UT-PFI-001 - UT-PFI-011)
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-21 | ExistsはFileInfo.Existsを返す | E-03 (L26: `public bool Exists => _info.Exists`) | ○ |
| C-22 | LengthはFileInfo.Lengthを返す | E-03 (L29: `public long Length => _info.Length`) | ○ |
| C-23 | PhysicalPathはFileInfo.FullNameを返す | E-03 (L32: `public string PhysicalPath => _info.FullName`) | ○ |
| C-24 | NameはFileInfo.Nameを返す | E-03 (L35: `public string Name => _info.Name`) | ○ |
| C-25 | LastModifiedはFileInfo.LastWriteTimeUtcを返す | E-03 (L38: `public DateTimeOffset LastModified => _info.LastWriteTimeUtc`) | ○ |
| C-26 | IsDirectoryは常にfalse | E-03 (L43: `public bool IsDirectory => false`) | ○ |
| C-27 | CreateReadStreamはFileStreamを返す | E-03 (L46-58: `return new FileStream(...)`) | ○ |

### PhysicalDirectoryInfo (UT-PDI-001 - UT-PDI-013)
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-28 | ExistsはDirectoryInfo.Existsを返す | E-04 (L38: `public bool Exists => _info.Exists`) | ○ |
| C-29 | Lengthは常に-1 | E-04 (L43: `public long Length => -1`) | ○ |
| C-30 | IsDirectoryは常にtrue | E-04 (L59: `public bool IsDirectory => true`) | ○ |
| C-31 | CreateReadStreamはInvalidOperationExceptionをスロー | E-04 (L66-69: `throw new InvalidOperationException(SR.CannotCreateStream)`) | ○ |
| C-32 | GetEnumeratorでファイルとディレクトリが列挙される | E-04 (L89-98: `_info.EnumerateFileSystemInfos()` with filtering and mapping) | ○ |
| C-33 | 存在しないディレクトリで空コレクション | E-04 (L100-103: `catch (DirectoryNotFoundException...) _entries = Enumerable.Empty`) | ○ |

### PollingFileChangeToken (UT-PCT-001 - UT-PCT-010)
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-34 | HasChangedは初期状態でfalse | E-05 (L26: `private bool _hasChanged;` default false) | ○ |
| C-35 | HasChangedはファイル変更で true | E-05 (L99-103: `if (_previousWriteTimeUtc != lastWriteTimeUtc) _hasChanged = true`) | ○ |
| C-36 | HasChangedは一度trueになると常にtrue | E-05 (L87-90: `if (_hasChanged) return _hasChanged`) | ○ |
| C-37 | PollingInterval未経過では前回の結果を返す | E-05 (L93-96: `if (currentTime - _lastCheckedTimeUtc < PollingInterval) return _hasChanged`) | ○ |
| C-38 | ActiveChangeCallbacksのデフォルトはfalse | E-05 (L59: `public bool ActiveChangeCallbacks { get; internal set; }` default false) | ○ |
| C-39 | RegisterChangeCallbackはActiveChangeCallbacks=falseでEmptyDisposable | E-05 (L118-121: `if (!ActiveChangeCallbacks) return EmptyDisposable.Instance`) | ○ |

### PollingWildCardChangeToken (UT-PWC-001 - UT-PWC-011)
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-40 | HasChangedは初期状態でfalse | E-06 (L27: `private bool _changed;` default false) | ○ |
| C-41 | HasChangedはファイル変更でtrue | E-06 (L104: `_changed = CalculateChanges()`, L129: `return true` on file change) | ○ |
| C-42 | ハッシュ計算でファイルリスト変更を検知 | E-06 (L142-144: `if (!_previousHash.AsSpan().SequenceEqual(currentHash)) return true`) | ○ |
| C-43 | GetLastWriteUtcでファイル日時取得 | E-06 (L169-173: `GetLastWriteUtc` implementation) | ○ |
| C-44 | RegisterChangeCallbackはActiveChangeCallbacks=falseでEmptyDisposable | E-06 (L200-203: `if (!ActiveChangeCallbacks) return EmptyDisposable.Instance`) | ○ |

### ExclusionFilters (UT-EXF-001 - UT-EXF-005)
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-45 | Noneは0 | E-07 (L38: `None = 0`) | ○ |
| C-46 | DotPrefixedは0x0001 | E-07 (L23: `DotPrefixed = 0x0001`) | ○ |
| C-47 | Hiddenは0x0002 | E-07 (L28: `Hidden = 0x0002`) | ○ |
| C-48 | Systemは0x0004 | E-07 (L33: `System = 0x0004`) | ○ |
| C-49 | SensitiveはDotPrefixed | Hidden | System | E-07 (L18: `Sensitive = DotPrefixed | Hidden | System`) | ○ |

### FileSystemInfoHelper (UT-FSH-001 - UT-FSH-011)
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-50 | IsExcludedはフィルタがNoneでfalse | E-09 (L14-17: `if (filters == ExclusionFilters.None) return false`) | ○ |
| C-51 | ドットで始まるファイルはDotPrefixedで除外 | E-09 (L18-21: `if (fileSystemInfo.Name.StartsWith(".")...) return true`) | ○ |
| C-52 | 隠し属性はHiddenで除外 | E-09 (L23: `(fileSystemInfo.Attributes & FileAttributes.Hidden) != 0`) | ○ |
| C-53 | システム属性はSystemで除外 | E-09 (L24: `(fileSystemInfo.Attributes & FileAttributes.System) != 0`) | ○ |
| C-54 | GetFileLinkTargetLastWriteTimeUtcはリンクターゲットの日時を返す | E-09 (L56-60: `targetInfo.LastWriteTimeUtc`) | ○ |
| C-55 | リンクターゲットが存在しない場合DateTime.MinValue | E-09 (L67: `return DateTime.MinValue`) | ○ |

### PathUtils (UT-PU-001 - UT-PU-015)
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-56 | EnsureTrailingSlashは末尾スラッシュを追加 | E-11 (L34-38: check and append DirectorySeparatorChar) | ○ |
| C-57 | 既存の末尾スラッシュはそのまま | E-11 (L35: `if (path[path.Length - 1] != Path.DirectorySeparatorChar)`) | ○ |
| C-58 | HasInvalidPathCharsは不正文字を検出 | E-11 (L23-24: `path.AsSpan().ContainsAny(_invalidFileNameChars)`) | ○ |
| C-59 | HasInvalidFilterCharsはワイルドカードを許可 | E-11 (L17-18: exclude `*`, `|`, `?` from invalid chars) | ○ |
| C-60 | PathNavigatesAboveRootはパストラバーサルを検出 | E-11 (L54-61: `depth--` and `if (depth == -1) return true`) | ○ |
| C-61 | ドットセグメント(.)は無視される | E-11 (L50-53: `if (segment.Equals(".")) continue`) | ○ |

### PhysicalDirectoryContents (UT-PDC-001 - UT-PDC-006)
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-62 | nullでArgumentNullExceptionをスロー | E-10 (L34: `ArgumentNullException.ThrowIfNull(directory)`) | ○ |
| C-63 | ExistsはPhysicalDirectoryInfo.Existsを委譲 | E-10 (L40: `public bool Exists => _info.Exists`) | ○ |
| C-64 | GetEnumeratorはPhysicalDirectoryInfoに委譲 | E-10 (L43-44: `return _info.GetEnumerator()`) | ○ |

### Clock (UT-CLK-001 - UT-CLK-002)
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-65 | Instanceはシングルトン | E-12 (L10: `public static readonly Clock Instance = new Clock()`) | ○ |
| C-66 | UtcNowはDateTime.UtcNowを返す | E-12 (L16: `public DateTime UtcNow => DateTime.UtcNow`) | ○ |

## 4) 不足情報（Unknown / Missing）
- 該当なし：全テストケースに対してソースコードから根拠を確認済み

## 5) リスクフラグ（レビュー観点）
- 0: 低リスク - 全てのテストケースがソースコードに基づいて生成されている

## 6) レビュアーチェックリスト（最小）
- [ ] PhysicalFileProviderのパストラバーサル防止テスト（UT-FPP-011, UT-FPP-018）が十分か確認
- [ ] ファイル監視のポーリング関連テスト（UT-PCT-*, UT-PWC-*）のタイミング依存性を確認
- [ ] シンボリックリンク関連テスト（UT-PCT-007, UT-FSH-009, UT-FSH-010）がプラットフォーム依存でないか確認
- [ ] Dispose後の操作に関するテストケースが必要か検討
- [ ] 並行アクセス時のスレッドセーフティテストが必要か検討
