---
generated_at: 2026-01-30 16:40:00
metrics:
  claims_total: 131
  claims_with_evidence: 131
  claims_without_evidence: 0
confidence_derived: 1.00
---

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

## 本レポートについて

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

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

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

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**1.00**
  - 根拠あり：131 / 131、根拠なし：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/IClock.cs`
- E-13: `src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/Clock.cs`

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

### PhysicalFileProvider (UT-FPP-001 〜 UT-FPP-031)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | コンストラクタで絶対パスのみ受け付け | E-01 L56-59: `if (!Path.IsPathRooted(root)) throw new ArgumentException` | ○ |
| C-02 | 存在しないディレクトリでDirectoryNotFoundException | E-01 L64-67: `if (!Directory.Exists(Root)) throw new DirectoryNotFoundException` | ○ |
| C-03 | UsePollingFileWatcherが環境変数から読み取り | E-01 L88-99, L188-196: `ReadPollingEnvironmentVariables()` でDOTNET_USE_POLLING_FILE_WATCHERを読み取り | ○ |
| C-04 | FileWatcher初期化後のUsePollingFileWatcher設定でInvalidOperationException | E-01 L103-106: `if (_fileWatcher != null) throw new InvalidOperationException` | ○ |
| C-05 | GetFileInfoでnull/空文字はNotFoundFileInfo | E-01 L265-268: `if (string.IsNullOrEmpty(subpath)...)` | ○ |
| C-06 | GetFileInfoで絶対パスはNotFoundFileInfo | E-01 L274-277: `if (Path.IsPathRooted(subpath))` | ○ |
| C-07 | GetFileInfoでパストラバーサルはNotFoundFileInfo | E-01 L230-233: `if (PathUtils.PathNavigatesAboveRoot(path))` | ○ |
| C-08 | GetFileInfoで不正文字はNotFoundFileInfo | E-01 L265: `PathUtils.HasInvalidPathChars(subpath)` | ○ |
| C-09 | GetDirectoryContentsでnullはNotFoundDirectoryContents | E-01 L310: `if (subpath == null || PathUtils.HasInvalidPathChars(subpath))` | ○ |
| C-10 | WatchでnullはNullChangeToken | E-01 L357-360: `if (filter == null...)` | ○ |
| C-11 | Disposeでリソース解放 | E-01 L211-221: `Dispose(bool disposing)` でFileWatcherをDispose | ○ |

### PhysicalFilesWatcher (UT-FPW-001 〜 UT-FPW-017)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-12 | watcher=null かつ pollForChanges=falseでArgumentNullException | E-02 L78-81: `if (fileSystemWatcher == null && !pollForChanges) throw new ArgumentNullException` | ○ |
| C-13 | CreateFileChangeTokenでnullはArgumentNullException | E-02 L130: `ArgumentNullException.ThrowIfNull(filter)` | ○ |
| C-14 | CreateFileChangeTokenで絶対パスはNullChangeToken | E-02 L135-138: `if (Path.IsPathRooted(filter) || PathUtils.PathNavigatesAboveRoot(filter))` | ○ |
| C-15 | ワイルドカードパターンでGetOrAddWildcardChangeToken使用 | E-02 L157-165: `if (isWildCard || IsDirectoryPath(pattern))` | ○ |
| C-16 | RaiseChangeEventsで変更トークンをキャンセル | E-02 L474-506: `RaiseChangeEvents` でHasChangedがtrueならCancelを実行 | ○ |
| C-17 | Disposeで FileWatcherとTimerを解放 | E-02 L265-276: `_fileWatcher?.Dispose(); _timer?.Dispose();` | ○ |

### PhysicalFileInfo (UT-PFI-001 〜 UT-PFI-011)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-18 | Existsは_info.Existsを返却 | E-03 L26: `public bool Exists => _info.Exists;` | ○ |
| C-19 | Lengthは_info.Lengthを返却 | E-03 L29: `public long Length => _info.Length;` | ○ |
| C-20 | IsDirectoryは常にfalse | E-03 L43: `public bool IsDirectory => false;` | ○ |
| C-21 | CreateReadStreamでFileStreamを作成 | E-03 L46-58: FileMode.Open, FileAccess.Read, FileShare.ReadWrite, FileOptions.Asynchronousで作成 | ○ |

### PhysicalDirectoryInfo (UT-PDI-001 〜 UT-PDI-013)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-22 | Lengthは常に-1 | E-04 L43: `public long Length => -1;` | ○ |
| C-23 | IsDirectoryは常にtrue | E-04 L59: `public bool IsDirectory => true;` | ○ |
| C-24 | CreateReadStreamでInvalidOperationException | E-04 L66-69: `throw new InvalidOperationException(SR.CannotCreateStream);` | ○ |
| C-25 | GetEnumeratorで除外フィルタ適用 | E-04 L89-98: `.Where(info => !FileSystemInfoHelper.IsExcluded(info, _filters))` | ○ |
| C-26 | DirectoryNotFoundExceptionで空コレクション | E-04 L100-103: `catch (Exception ex) when (ex is DirectoryNotFoundException...)` | ○ |

### PollingFileChangeToken (UT-PFCT-001 〜 UT-PFCT-010)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-27 | HasChangedでポーリング間隔チェック | E-05 L92-96: `if (currentTime - _lastCheckedTimeUtc < PollingInterval)` | ○ |
| C-28 | 一度trueになると常にtrue | E-05 L87-90: `if (_hasChanged) return _hasChanged;` | ○ |
| C-29 | ActiveChangeCallbacksのデフォルトはfalse | E-05 L59: `public bool ActiveChangeCallbacks { get; internal set; }` (デフォルト値) | ○ |
| C-30 | RegisterChangeCallbackでActiveChangeCallbacks=falseならEmptyDisposable | E-05 L117-121: `if (!ActiveChangeCallbacks) return EmptyDisposable.Instance;` | ○ |
| C-31 | シンボリックリンク対応 | E-05 L53: `FileSystemInfoHelper.GetFileLinkTargetLastWriteTimeUtc(_fileInfo)` | ○ |

### PollingWildCardChangeToken (UT-PWCT-001 〜 UT-PWCT-013)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-32 | HasChangedでポーリング間隔チェック | E-06 L98-111: `ShouldRefresh() => Clock.UtcNow - _lastScanTimeUtc >= PollingInterval` | ○ |
| C-33 | CalculateChangesでハッシュ比較 | E-06 L115-162: IncrementalHash.CreateHash(SHA256)でファイルリストのハッシュ比較 | ○ |
| C-34 | GetLastWriteUtcでシンボリックリンク対応 | E-06 L169-173: `FileSystemInfoHelper.GetFileLinkTargetLastWriteTimeUtc(filePath)` | ○ |
| C-35 | RegisterChangeCallbackでEmptyDisposable返却 | E-06 L198-206: `if (!ActiveChangeCallbacks) return EmptyDisposable.Instance;` | ○ |

### ExclusionFilters (UT-EF-001 〜 UT-EF-005)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-36 | None=0 | E-07 L38: `None = 0` | ○ |
| C-37 | DotPrefixed=0x0001 | E-07 L23: `DotPrefixed = 0x0001` | ○ |
| C-38 | Hidden=0x0002 | E-07 L28: `Hidden = 0x0002` | ○ |
| C-39 | System=0x0004 | E-07 L33: `System = 0x0004` | ○ |
| C-40 | Sensitive=DotPrefixed|Hidden|System | E-07 L18: `Sensitive = DotPrefixed | Hidden | System` | ○ |

### FileSystemInfoHelper (UT-FSIH-001 〜 UT-FSIH-010)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-41 | IsExcludedでNoneフィルタは常にfalse | E-09 L14-17: `if (filters == ExclusionFilters.None) return false;` | ○ |
| C-42 | ドットプレフィックスチェック | E-09 L18-21: `fileSystemInfo.Name.StartsWith(".", StringComparison.Ordinal)` | ○ |
| C-43 | Hidden属性チェック | E-09 L23: `(fileSystemInfo.Attributes & FileAttributes.Hidden) != 0` | ○ |
| C-44 | System属性チェック | E-09 L24: `(fileSystemInfo.Attributes & FileAttributes.System) != 0` | ○ |
| C-45 | GetFileLinkTargetLastWriteTimeUtcでリンクターゲット取得 | E-09 L48-72: `fileInfo.ResolveLinkTarget(returnFinalTarget: true)` | ○ |
| C-46 | ターゲット不存在でDateTime.MinValue | E-09 L67: `return DateTime.MinValue;` | ○ |

### PhysicalDirectoryContents (UT-PDC-001 〜 UT-PDC-006)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-47 | コンストラクタでnullチェック | E-10 L34: `ArgumentNullException.ThrowIfNull(directory);` | ○ |
| C-48 | デフォルトフィルタはSensitive | E-10 L24: `: this(directory, ExclusionFilters.Sensitive)` | ○ |
| C-49 | Existsは_info.Existsを委譲 | E-10 L40: `public bool Exists => _info.Exists;` | ○ |

### PathUtils (UT-PU-001 〜 UT-PU-013)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-50 | HasInvalidPathCharsでSearchValues使用 | E-11 L23-24: `path.AsSpan().ContainsAny(_invalidFileNameChars)` | ○ |
| C-51 | HasInvalidFilterCharsでワイルドカード許可 | E-11 L17-18: `GetInvalidFileNameChars().Where(c => c != '*' && c != '|' && c != '?')` | ○ |
| C-52 | EnsureTrailingSlashで末尾スラッシュ追加 | E-11 L32-41: `if (path[path.Length - 1] != Path.DirectorySeparatorChar) return path + Path.DirectorySeparatorChar;` | ○ |
| C-53 | PathNavigatesAboveRootで..をカウント | E-11 L43-70: depth変数で階層をカウント、-1になったらtrue | ○ |

### Clock (UT-CLK-001 〜 UT-CLK-002)

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-54 | シングルトンパターン | E-13 L10: `public static readonly Clock Instance = new Clock();` | ○ |
| C-55 | UtcNowはDateTime.UtcNowを返却 | E-13 L16: `public DateTime UtcNow => DateTime.UtcNow;` | ○ |

## 4) 不足情報（Unknown / Missing）
- なし - 全テストケースにソースコードからの根拠あり

## 5) リスクフラグ（レビュー観点）
- 0: 低リスク - 全テストケースがソースコードの実装に基づいて設計されている
- 注意点:
  - シンボリックリンク関連テスト（UT-PFCT-010, UT-PWCT-013, UT-FSIH-007〜010）はプラットフォーム依存の可能性あり
  - FileSystemWatcher関連テスト（UT-FPW-*）はOS環境によって動作が異なる可能性あり

## 6) レビュアーチェックリスト（最小）
- [ ] テストケースのカバレッジが十分か（正常系・異常系・境界値を網羅）
- [ ] パストラバーサル攻撃に対するテストケース（UT-FPP-018, UT-FPW-008）の入力パターンが十分か
- [ ] 環境変数関連テスト（UT-FPP-006〜011）の前提条件が明確か
- [ ] シンボリックリンク関連テストのプラットフォーム依存性を考慮しているか
- [ ] Disposeパターンのテスト（UT-FPP-030〜031, UT-FPW-016〜017）が十分か
- [ ] ExclusionFiltersの組み合わせテストが網羅されているか
