---
generated_at: 2026-02-10 13:00:00
metrics:
  claims_total: 128
  claims_with_evidence: 128
  claims_without_evidence: 0
confidence_derived: 1.00
---

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

## 本レポートについて

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

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

1. **根拠の有無確認**：各テストケースに対して、ソースコードの実装が存在するか
2. **根拠との整合性**：テストケースの内容がソースコードの実装と矛盾していないか
3. **網羅性**：対象モジュールのpublicメソッド・関数を適切にカバーしているか

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**1.00**
  - 根拠あり：128 / 128、根拠なし：0
- 優先レビュー（高）
  1. **UT-EFT-001〜003**: SnapshotSourceText.Fromメソッドの基本機能テスト
  2. **UT-EFT-010〜013**: WithChangesメソッドの変更適用テスト
  3. **UT-EFT-028〜038**: TextBufferContainerの基本機能テスト

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

- E-01: `src/EditorFeatures/Text/Extensions.SnapshotSourceText.cs` - SnapshotSourceTextクラスの実装
- E-02: `src/EditorFeatures/Text/Extensions.TextBufferContainer.cs` - TextBufferContainerクラスの実装
- E-03: `src/EditorFeatures/Text/Extensions.cs` - Extensions拡張メソッドの実装
- E-04: `src/EditorFeatures/Text/ITextImageHelpers.cs` - ITextImageHelpersクラスの実装
- E-05: `src/EditorFeatures/Text/Shared/Extensions/SnapshotPointExtensions.cs` - SnapshotPointExtensions拡張メソッドの実装
- E-06: `src/EditorFeatures/Text/Shared/Extensions/TextSpanExtensions.cs` - TextSpanExtensions拡張メソッドの実装
- E-07: `src/EditorFeatures/Text/Shared/Extensions/ITextSnapshotExtensions.cs` - ITextSnapshotExtensions拡張メソッドの実装
- E-08: `src/EditorFeatures/Text/Shared/Extensions/ITextSnapshotLineExtensions.cs` - ITextSnapshotLineExtensions拡張メソッドの実装
- E-09: `src/EditorFeatures/Text/Implementation/TextBufferFactoryService/ITextBufferCloneService.cs` - ITextBufferCloneServiceインターフェースの定義
- E-10: `src/EditorFeatures/Text/Implementation/TextBufferFactoryService/TextBufferCloneServiceFactory.cs` - TextBufferCloneServiceクラスの実装
- E-11: `src/EditorFeatures/Text/ExternalAccess/VSTypeScript/Api/VSTypeScriptTextBufferExtensions.cs` - VSTypeScript用拡張メソッドの実装
- E-12: `src/EditorFeatures/Text/ContentTypeNames.cs` - ContentTypeNames定数クラスの定義

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

### SnapshotSourceTextクラス（E-01）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 (UT-EFT-001) | From(ITextBufferCloneService?, ITextSnapshot)で有効なITextSnapshotからSourceTextが作成される | E-01: 70-89行目 | ○ |
| C-02 (UT-EFT-002) | nullのITextSnapshotでArgumentNullExceptionがスローされる | E-01: 72-75行目 `throw new ArgumentNullException` | ○ |
| C-03 (UT-EFT-003) | 同一Snapshotに対してキャッシュされたインスタンスが返却される | E-01: 77-88行目 `s_textSnapshotMap.GetValue` | ○ |
| C-04 (UT-EFT-004) | Encodingプロパティが正しい値を返却する | E-01: 105-108行目 | ○ |
| C-05 (UT-EFT-005) | Lengthプロパティが正しいテキスト長を返却する | E-01: 121-128行目 | ○ |
| C-06 (UT-EFT-006) | インデクサで指定位置の文字が取得できる | E-01: 130-133行目 | ○ |
| C-07 (UT-EFT-007) | 最終位置の文字が取得できる | E-01: 130-133行目 | ○ |
| C-08 (UT-EFT-008) | ToString()で全テキストが取得できる | E-01: 174-175行目 | ○ |
| C-09 (UT-EFT-009) | ToString(TextSpan)で指定範囲のテキストが取得できる | E-01: 177-182行目 | ○ |
| C-10 (UT-EFT-010) | WithChangesで変更を適用した新しいSourceTextが返却される | E-01: 184-224行目 | ○ |
| C-11 (UT-EFT-011) | nullのchangesでArgumentNullExceptionがスローされる | E-01: 186-189行目 | ○ |
| C-12 (UT-EFT-012) | 空の変更リストで同一インスタンスが返却される | E-01: 191-194行目 | ○ |
| C-13 (UT-EFT-013) | ITextBufferCloneServiceがnullの場合、基底クラスの実装が使用される | E-01: 197-202行目 | ○ |
| C-14 (UT-EFT-014) | CopyToで指定範囲の文字が配列にコピーされる | E-01: 309-310行目 | ○ |
| C-15 (UT-EFT-015) | WriteでTextWriterにテキストが書き込まれる | E-01: 312-313行目 | ○ |
| C-16 (UT-EFT-016) | GetChangeRangesで同一テキストの場合、空の変更リストが返却される | E-01: 324-328行目 | ○ |
| C-17 (UT-EFT-017) | GetChangeRangesでnullのoldTextでArgumentNullExceptionがスローされる | E-01: 319-322行目 | ○ |
| C-18 (UT-EFT-018) | TryFindEditorSnapshotで対応するITextSnapshotが取得できる | E-01: 110-111, 250-259行目 | ○ |
| C-19 (UT-EFT-019) | TryFindEditorSnapshotで対応するSnapshotがない場合nullが返却される | E-01: 250-259行目 | ○ |
| C-20 (UT-EFT-020) | LineInfo.Countで行数が正しく取得できる | E-01: 146-149行目 | ○ |
| C-21 (UT-EFT-021) | LineInfo[int]で指定行番号のTextLineが取得できる | E-01: 151-158行目 | ○ |
| C-22 (UT-EFT-022) | LineInfo.IndexOfで位置から行番号が取得できる | E-01: 160-161行目 | ○ |
| C-23 (UT-EFT-023) | LineInfo.GetLineFromPositionで位置からTextLineが取得できる | E-01: 163-164行目 | ○ |
| C-24 (UT-EFT-024) | LineInfo.GetLinePositionで位置からLinePositionが取得できる | E-01: 166-170行目 | ○ |
| C-25 (UT-EFT-025) | ChangedSourceText.GetChangeRangesで変更元と同一の場合、空の変更リストが返却される | E-01: 294-298行目 | ○ |
| C-26 (UT-EFT-026) | ChangedSourceText.GetChangeRangesで変更元テキストに対して正しい変更範囲が返却される | E-01: 300-306行目 | ○ |
| C-27 (UT-EFT-027) | ChangedSourceText.GetChangeRangesで異なるテキストの場合、全体変更として返却される | E-01: 300-303行目 | ○ |

### TextBufferContainerクラス（E-02）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-28 (UT-EFT-028) | From(ITextBuffer)で有効なITextBufferからTextBufferContainerが作成される | E-02: 42-50行目 | ○ |
| C-29 (UT-EFT-029) | From(ITextBuffer)でnullのbufferでArgumentNullExceptionがスローされる | E-02: 44-47行目 | ○ |
| C-30 (UT-EFT-030) | 同一バッファに対してキャッシュされたインスタンスが返却される | E-02: 49行目 `s_textContainerMap.GetValue` | ○ |
| C-31 (UT-EFT-031) | TryFindEditorTextBufferで元のITextBufferが取得できる | E-02: 52-53行目 | ○ |
| C-32 (UT-EFT-032) | TryFindEditorTextBufferでバッファがGCされた場合nullが返却される | E-02: 52-53行目 `WeakReference.GetTarget` | ○ |
| C-33 (UT-EFT-033) | CurrentTextで現在のSnapshotに対応するSourceTextが取得できる | E-02: 55-64行目 | ○ |
| C-34 (UT-EFT-034) | CurrentTextでバッファがGCされた場合、最後のテキストが返却される | E-02: 60-62行目 | ○ |
| C-35 (UT-EFT-035) | TextChanged addでイベント購読時にバッファのイベントにフックされる | E-02: 67-79行目 | ○ |
| C-36 (UT-EFT-036) | TextChanged removeでイベント解除時にバッファのイベントからフック解除される | E-02: 82-94行目 | ○ |
| C-37 (UT-EFT-037) | OnTextContentChangedでテキスト変更時にTextChangeEventArgsが発火される | E-02: 97-118行目 | ○ |
| C-38 (UT-EFT-038) | OnTextContentChangedでハンドラがnullの場合、何も行われない | E-02: 99-103行目 | ○ |

### Extensions拡張メソッド（E-03）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-39 (UT-EFT-039) | AsTextContainerでITextBufferからSourceTextContainerが取得できる | E-03: 14-15行目 | ○ |
| C-40 (UT-EFT-040) | GetTextBufferでTextBufferContainerからITextBufferが取得できる | E-03: 17-18行目 | ○ |
| C-41 (UT-EFT-041) | GetTextBufferで非TextBufferContainerでArgumentExceptionがスローされる | E-03: 18行目 `throw new ArgumentException` | ○ |
| C-42 (UT-EFT-042) | TryGetTextBufferでTextBufferContainerからITextBufferが取得できる | E-03: 20-21行目 | ○ |
| C-43 (UT-EFT-043) | TryGetTextBufferでnullの場合nullが返却される | E-03: 20-21行目 | ○ |
| C-44 (UT-EFT-044) | TryGetTextBufferで非TextBufferContainerの場合nullが返却される | E-03: 20-21行目 | ○ |
| C-45 (UT-EFT-045) | FindCorrespondingEditorTextSnapshotでSnapshotSourceTextからITextSnapshotが取得できる | E-03: 30-31行目 | ○ |
| C-46 (UT-EFT-046) | FindCorrespondingEditorTextSnapshotで非SnapshotSourceTextの場合nullが返却される | E-03: 30-31行目 | ○ |
| C-47 (UT-EFT-047) | AsTextでITextSnapshotからSourceTextが作成される | E-03: 39-43行目 | ○ |
| C-48 (UT-EFT-048) | GetWorkspaceでITextBufferからWorkspaceが取得できる | E-03: 51-60行目 | ○ |
| C-49 (UT-EFT-049) | GetWorkspaceでWorkspaceがない場合nullが返却される | E-03: 58-59行目 | ○ |
| C-50 (UT-EFT-050) | GetRelatedDocumentsWithChangesで関連ドキュメントが取得できる | E-03: 67-68行目 | ○ |
| C-51 (UT-EFT-051) | GetOpenDocumentInCurrentContextWithChangesで現在コンテキストのドキュメントが取得できる | E-03: 76-77行目 | ○ |
| C-52 (UT-EFT-052) | GetRelatedDocumentsでバッファに関連するドキュメントが取得できる | E-03: 86-87行目 | ○ |
| C-53 (UT-EFT-053) | CanApplyChangeDocumentToWorkspaceで変更適用可能な場合trueが返却される | E-03: 89-91行目 | ○ |
| C-54 (UT-EFT-054) | CanApplyChangeDocumentToWorkspaceで変更適用不可の場合falseが返却される | E-03: 89-91行目 | ○ |
| C-55 (UT-EFT-055) | GetEncodingOrUTF8でITextDocumentのEncodingが取得できる | E-03: 101-104行目 | ○ |
| C-56 (UT-EFT-056) | GetEncodingOrUTF8でITextDocumentがない場合UTF8が返却される | E-03: 104行目 | ○ |

### ITextImageHelpersクラス（E-04）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-57 (UT-EFT-057) | GetChangeRanges(ITextImage, ITextImage)で2つのITextImage間の変更範囲が取得できる | E-04: 21-22行目 | ○ |
| C-58 (UT-EFT-058) | GetChangeRanges(ITextImageVersion, ITextImageVersion)で順方向での変更範囲が正しく取得できる | E-04: 24-63行目 | ○ |
| C-59 (UT-EFT-059) | GetChangeRanges(ITextImageVersion, ITextImageVersion)で逆方向での変更範囲が正しく取得できる | E-04: 26-29行目, 99-100行目 | ○ |
| C-60 (UT-EFT-060) | GetChangeRanges(ITextImageVersion, ITextImageVersion)で変更がない場合空のリストが返却される | E-04: 52-53行目 | ○ |
| C-61 (UT-EFT-061) | GetChangeRanges(ITextImageVersion, ITextImageVersion)で単一バージョンの変更が正しく返却される | E-04: 55-62行目 | ○ |
| C-62 (UT-EFT-062) | GetChangeRanges(ITextImageVersion, ITextImageVersion)で複数バージョンの変更が統合される | E-04: 38-44行目 | ○ |
| C-63 (UT-EFT-063) | CreateTextChangeRangeで順方向でTextChangeRangeが作成される | E-04: 103-108行目 | ○ |
| C-64 (UT-EFT-064) | CreateTextChangeRangeで逆方向でTextChangeRangeが作成される | E-04: 109-112行目 | ○ |

### SnapshotPointExtensions（E-05）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-65 (UT-EFT-065) | DeconstructでSnapshotPointがデコンストラクトできる | E-05: 11-15行目 | ○ |

### TextSpanExtensions（E-06）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-66 (UT-EFT-066) | ToSpanでTextSpanがSpanに変換される | E-06: 15-16行目 | ○ |
| C-67 (UT-EFT-067) | MoveToでTextSpanにオフセットが追加される | E-06: 21-22行目 | ○ |
| C-68 (UT-EFT-068) | MoveToで負のオフセットで正しく移動する | E-06: 21-22行目 | ○ |
| C-69 (UT-EFT-069) | ToSnapshotSpanでTextSpanがSnapshotSpanに変換される | E-06: 27-32行目 | ○ |

### ITextSnapshotExtensions（E-07）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-70 (UT-EFT-070) | GetPointで指定位置のSnapshotPointが取得できる | E-07: 13-14行目 | ○ |
| C-71 (UT-EFT-071) | TryGetPointで有効な行・列でSnapshotPointが取得できる | E-07: 16-27行目 | ○ |
| C-72 (UT-EFT-072) | TryGetPointで無効な行番号でnullが返却される | E-07: 44-47行目 | ○ |
| C-73 (UT-EFT-073) | TryGetPointで行数を超える行番号でnullが返却される | E-07: 44-47行目 | ○ |
| C-74 (UT-EFT-074) | GetTextSpanでLinePositionSpanからTextSpanが取得できる | E-07: 32-37行目 | ○ |
| C-75 (UT-EFT-075) | GetPositionで行・列から位置が取得できる | E-07: 39-40行目 | ○ |
| C-76 (UT-EFT-076) | GetPositionで無効な位置でInvalidOperationExceptionがスローされる | E-07: 39-40行目 | ○ |
| C-77 (UT-EFT-077) | TryGetPosition(int, int)で有効な行・列でintが返却される | E-07: 42-56行目 | ○ |
| C-78 (UT-EFT-078) | TryGetPosition(int, int)で行末を超える列でnullが返却される | E-07: 50-53行目 | ○ |
| C-79 (UT-EFT-079) | TryGetPosition(int, int, out SnapshotPoint)で有効な位置でtrueが返却される | E-07: 58-76行目 | ○ |
| C-80 (UT-EFT-080) | TryGetPosition(int, int, out SnapshotPoint)で無効な行でfalseが返却される | E-07: 62-65行目 | ○ |
| C-81 (UT-EFT-081) | TryGetPosition(int, int, out SnapshotPoint)で無効な列でfalseが返却される | E-07: 68-71行目 | ○ |
| C-82 (UT-EFT-082) | GetSpan(int, int)で開始位置と長さからSnapshotSpanが取得できる | E-07: 78-79行目 | ○ |
| C-83 (UT-EFT-083) | GetSpanFromBoundsで開始・終了位置からSnapshotSpanが取得できる | E-07: 81-82行目 | ○ |
| C-84 (UT-EFT-084) | GetSpan(Span)でSpanからSnapshotSpanが取得できる | E-07: 84-85行目 | ○ |
| C-85 (UT-EFT-085) | GetTagSpanでTagSpanが作成できる | E-07: 87-88行目 | ○ |
| C-86 (UT-EFT-086) | GetSpan(4引数)で行・列指定でSnapshotSpanが取得できる | E-07: 90-91行目 | ○ |
| C-87 (UT-EFT-087) | GetSpan(4引数)で無効な位置でInvalidOperationExceptionがスローされる | E-07: 90-91行目 | ○ |
| C-88 (UT-EFT-088) | TryGetSpanで有効な行・列でSnapshotSpan?が返却される | E-07: 93-103行目 | ○ |
| C-89 (UT-EFT-089) | TryGetSpanで無効な開始位置でnullが返却される | E-07: 97-100行目 | ○ |
| C-90 (UT-EFT-090) | TryGetSpanで無効な終了位置でnullが返却される | E-07: 97-100行目 | ○ |
| C-91 (UT-EFT-091) | GetFullSpanで全体のSnapshotSpanが取得できる | E-07: 105-110行目 | ○ |
| C-92 (UT-EFT-092) | GetFullSpanでnullのsnapshotで例外がスローされる | E-07: 107行目 | ○ |
| C-93 (UT-EFT-093) | GetSnapshotSpanCollectionでNormalizedSnapshotSpanCollectionが取得できる | E-07: 112-117行目 | ○ |
| C-94 (UT-EFT-094) | GetLineAndCharacterで位置から行・文字位置が取得できる | E-07: 119-125行目 | ○ |
| C-95 (UT-EFT-095) | GetLeadingWhitespaceOfLineAtPositionで行の先頭空白が取得できる | E-07: 130-143行目 | ○ |
| C-96 (UT-EFT-096) | GetLeadingWhitespaceOfLineAtPositionで空白のみの行で全体が返却される | E-07: 136-139行目 | ○ |
| C-97 (UT-EFT-097) | AreOnSameLineで同一行の2つの位置でtrueが返却される | E-07: 145-146行目 | ○ |
| C-98 (UT-EFT-098) | AreOnSameLineで異なる行の2つの位置でfalseが返却される | E-07: 145-146行目 | ○ |

### ITextSnapshotLineExtensions（E-08）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-99 (UT-EFT-099) | GetFirstNonWhitespacePositionで最初の非空白文字位置が取得できる | E-08: 19-26行目 | ○ |
| C-100 (UT-EFT-100) | GetFirstNonWhitespacePositionで空白のみの行でnullが返却される | E-08: 33-47行目 | ○ |
| C-101 (UT-EFT-101) | GetFirstNonWhitespacePositionで空行でnullが返却される | E-08: 33-47行目 | ○ |
| C-102 (UT-EFT-102) | GetFirstNonWhitespaceOffsetで最初の非空白文字オフセットが取得できる | E-08: 33-47行目 | ○ |
| C-103 (UT-EFT-103) | GetFirstNonWhitespaceOffsetでnullのlineで例外がスローされる | E-08: 35行目 | ○ |
| C-104 (UT-EFT-104) | GetLastNonWhitespacePositionで最後の非空白文字位置が取得できる | E-08: 53-54行目 | ○ |
| C-105 (UT-EFT-105) | IsEmptyOrWhitespaceで空白のみの行でtrueが返却される | E-08: 59-79行目 | ○ |
| C-106 (UT-EFT-106) | IsEmptyOrWhitespaceで非空白を含む行でfalseが返却される | E-08: 59-79行目 | ○ |
| C-107 (UT-EFT-107) | IsEmptyOrWhitespaceでstartIndex指定で部分判定できる | E-08: 59-79行目 | ○ |
| C-108 (UT-EFT-108) | IsEmptyOrWhitespaceでendIndex指定で部分判定できる | E-08: 59-79行目 | ○ |
| C-109 (UT-EFT-109) | GetPreviousMatchingLineで条件に合う前の行が取得できる | E-08: 81-104行目 | ○ |
| C-110 (UT-EFT-110) | GetPreviousMatchingLineで先頭行でnullが返却される | E-08: 86-89行目 | ○ |
| C-111 (UT-EFT-111) | GetPreviousMatchingLineで条件に合う行がない場合nullが返却される | E-08: 103行目 | ○ |
| C-112 (UT-EFT-112) | GetColumnOfFirstNonWhitespaceCharacterOrEndOfLineで最初の非空白文字の列が取得できる | E-08: 106-110行目 | ○ |
| C-113 (UT-EFT-113) | GetColumnFromLineOffsetで行オフセットから列が計算できる | E-08: 112-113行目 | ○ |
| C-114 (UT-EFT-114) | GetLineOffsetFromColumnで列から行オフセットが計算できる | E-08: 115-116行目 | ○ |
| C-115 (UT-EFT-115) | StartsWithで行が指定文字列で始まる場合trueが返却される | E-08: 121-143行目 | ○ |
| C-116 (UT-EFT-116) | StartsWithで行が指定文字列で始まらない場合falseが返却される | E-08: 121-143行目 | ○ |
| C-117 (UT-EFT-117) | StartsWithでignoreCaseでの大小文字無視比較ができる | E-08: 133-137行目 | ○ |
| C-118 (UT-EFT-118) | StartsWithでvalueが行より長い場合falseが返却される | E-08: 124-125行目 | ○ |
| C-119 (UT-EFT-119) | Containsで行に指定文字列が含まれる場合trueが返却される | E-08: 146-159行目 | ○ |
| C-120 (UT-EFT-120) | Containsで行に指定文字列が含まれない場合falseが返却される | E-08: 146-159行目 | ○ |
| C-121 (UT-EFT-121) | Containsで指定indexから検索できる | E-08: 148行目 | ○ |

### TextBufferCloneService（E-10）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-122 (UT-EFT-122) | CloneWithUnknownContentType(SnapshotSpan)でSnapshotSpanからITextBufferがクローンされる | E-10: 33-34行目 | ○ |
| C-123 (UT-EFT-123) | CloneWithUnknownContentType(ITextImage)でITextImageからITextBufferがクローンされる | E-10: 36-37行目 | ○ |
| C-124 (UT-EFT-124) | CloneWithRoslynContentTypeでSourceTextからRoslynContentTypeのITextBufferがクローンされる | E-10: 39-40行目 | ○ |
| C-125 (UT-EFT-125) | Clone(SourceText, IContentType)でSourceTextとContentTypeからITextBufferがクローンされる | E-10: 42-53行目 | ○ |
| C-126 (UT-EFT-126) | Clone(SourceText, IContentType)でTextImageがある場合、効率的にクローンされる | E-10: 45-49行目 | ○ |
| C-127 (UT-EFT-127) | Clone(SourceText, IContentType)でTextImageがない場合、文字列からクローンされる | E-10: 52行目 | ○ |

### VSTypeScriptTextBufferExtensions（E-11）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-128 (UT-EFT-128) | AsTextContainerでITextBufferからSourceTextContainerが取得できる | E-11: 12-13行目 | ○ |

## 4) 不足情報（Unknown / Missing）
- なし
- すべてのテストケースはソースコードの実装に基づいて生成されており、根拠が存在します

## 5) リスクフラグ（レビュー観点）
- **0: 低リスク** - すべてのテストケースがソースコードに基づいて生成されており、高い信頼性があります
- 以下の点は追加で確認することを推奨:
  - 外部依存（ITextBuffer, ITextSnapshot等）のモック戦略
  - スレッドセーフティに関するテスト（TextBufferContainerのlockセクション）
  - メモリリークに関するテスト（WeakReference, ConditionalWeakTable関連）

## 6) レビュアーチェックリスト（最小）
- [ ] SnapshotSourceTextのキャッシュ機構（ConditionalWeakTable）のテストケースが適切か
- [ ] TextBufferContainerのイベント購読/解除のスレッドセーフティを確認するテストケースが十分か
- [ ] WeakReferenceを使用した参照管理のテストケースでGC動作を適切にシミュレートできるか
- [ ] 境界値テスト（空文字列、Length=0、LineCount=0）が網羅されているか
- [ ] ITextBufferCloneServiceのモック作成が可能か確認
