---
generated_at: 2026-02-19 10:30:00
metrics:
  claims_total: 119
  claims_with_evidence: 119
  claims_without_evidence: 0
confidence_derived: 1.00
---

# 根拠レポート：vsintegration-FSharp-VS-FSI 単体テストケース一覧

## 本レポートについて

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

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

1. **根拠の有無確認**：各テストケースに対して、ソースコードから対象クラス・関数・メソッドの存在と動作が確認できるか
2. **根拠との整合性**：テストケースの内容がソースコードの実装と矛盾していないか
3. **網羅性**：主要な機能・境界値・異常系が適切にカバーされているか

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**1.00**
  - 根拠あり：119 / 119、根拠なし：0
- 優先レビュー（高）
  1. **高優先度テストケース（35件）**：セッション管理、デバッグ機能、プロセス起動に関するテスト
  2. **境界値テスト（8件）**：履歴バッファ、行取得、空入力に関する境界値テスト
  3. **異常系テスト（12件）**：例外ハンドリング、タイムアウト、null安全に関するテスト

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

- E-01: `vsintegration/src/FSharp.VS.FSI/sessions.fs` - セッション管理、FsiSession、FsiSessions、EventWrapper、timeoutApp等
- E-02: `vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs` - FsiToolWindow、Locals、ITestVFSI、IOleCommandTarget実装
- E-03: `vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs` - FsiLanguageService、FsiDeclarations、FsiMethods、FsiSource、FsiScanner、FsiAuthoringScope、FsiViewFilter
- E-04: `vsintegration/src/FSharp.VS.FSI/fsiBasis.fs` - HistoryBuffer、Util、RegistryHelpers、ArgParsing、Guids
- E-05: `vsintegration/src/FSharp.VS.FSI/fsiTextBufferStream.fs` - TextBufferStream
- E-06: `vsintegration/src/FSharp.VS.FSI/fsiPackageHooks.fs` - Hooks
- E-07: `vsintegration/src/FSharp.VS.FSI/FSharp.VS.FSI.Attributes.fs` - ResourceDisplayNameAttribute、ResourceDescriptionAttribute、ResourceCategoryAttribute
- E-08: `vsintegration/src/FSharp.VS.FSI/AssemblyInfo.fs` - アセンブリ属性（テスト対象外）

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

### sessions.fs 関連テストケース（C-01 〜 C-39）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | EventWrapper.Set - 正常系テスト | E-01: L29-30 `member _.Set() = lock guard (fun () -> if not disposed then waitHandle.Set())` | ○ |
| C-02 | EventWrapper.Set - Dispose後の安全性 | E-01: L30 `if not disposed then waitHandle.Set()` | ○ |
| C-03 | EventWrapper.Dispose - リソース解放 | E-01: L32-33 `member _.Dispose() = lock guard (fun () -> disposed <- true; ...)` | ○ |
| C-04 | EventWrapper.WaitOne - 待機機能 | E-01: L35-36 `member _.WaitOne(timeout : int) = waitHandle.WaitOne(timeout, true)` | ○ |
| C-05 | timeoutApp - 正常完了時Some返却 | E-01: L44-67 `let timeoutApp _descr timeoutMS (f : 'a -> 'b) (arg:'a) = ... f arg |> Some` | ○ |
| C-06 | timeoutApp - タイムアウト時None返却 | E-01: L66 `ev.WaitOne(timeoutMS) |> ignore; r` - タイムアウト時rはNone | ○ |
| C-07 | timeoutApp - 例外時None返却 | E-01: L51-63 `with | e -> ... None` | ○ |
| C-08 | bufferEvent - バッファリング機能 | E-01: L84-128 `let bufferEvent timeMS (w : #IObservable<_>)` | ○ |
| C-09 | flushBuffer - バッファクリア | E-01: L93-95 `let flushBuffer() = lock buffer <| fun () -> buffer.Clear()` | ○ |
| C-10 | determineFsiPath - NetCore時 | E-01: L136-144 `if SessionsProperties.fsiUseNetCore then ... exe, arg, false` | ○ |
| C-11 | determineFsiPath - NetCore非使用時 | E-01: L145-182 `else ... fsiExe, "", true` | ○ |
| C-12 | determineFsiPath - ファイル不存在時例外 | E-01: L142-143, L181 `raise (SessionError ...)` | ○ |
| C-13 | readOutputAsync - 行単位出力 | E-01: L184-237 `let readOutputAsync (reader: StreamReader) trigger = ...` | ○ |
| C-14 | readOutputAsync - 空出力処理 | E-01: L231 `if bytesRead <> 0 then` | ○ |
| C-15 | fsiStartInfo - ProcessStartInfo構成 | E-01: L239-285 `let fsiStartInfo channelName sourceFile = ...` | ○ |
| C-16 | fsiStartInfo - sourceFile null時 | E-01: L277-280 `match sourceFile with | path when path <> null ...` | ○ |
| C-17 | nonNull - 非null判定 | E-01: L288 `let nonNull = function null -> false | (_:string) -> true` | ○ |
| C-18 | nonNull - null判定 | E-01: L288 同上 | ○ |
| C-19 | FsiSession.Interrupt - 成功時true | E-01: L409-412 `member _.Interrupt() = match timeoutApp ... | Some () -> true` | ○ |
| C-20 | FsiSession.Interrupt - タイムアウト時false | E-01: L412 `| None -> false` | ○ |
| C-21 | FsiSession.SendInput - 入力送信 | E-01: L414 `member _.SendInput (str: string) = inputQueue.Post(str)` | ○ |
| C-22 | FsiSession.Output - 出力イベント | E-01: L416 `member _.Output = Observable.filter nonNull fsiOutput.Publish` | ○ |
| C-23 | FsiSession.Alive - 稼働中true | E-01: L422 `member _.Alive = not cmdProcess.HasExited` | ○ |
| C-24 | FsiSession.Alive - 終了時false | E-01: L422 同上 | ○ |
| C-25 | FsiSession.ProcessID - ID取得 | E-01: L426-429 `member _.ProcessID = ...` | ○ |
| C-26 | FsiSession.Kill - 正常終了 | E-01: L437-444 `member _.Kill() = ... cmdProcess.Kill()` | ○ |
| C-27 | FsiSession.Kill - 例外時ログ | E-01: L443-444 `with e -> fsiOutput.Trigger (...)` | ○ |
| C-28 | FsiSession.SupportsInteractivePrompt | E-01: L431-433 `member _.SupportsInteractivePrompt = ... version >= 7.0f` | ○ |
| C-29 | FsiSessions.Interrupt - セッションなし | E-01: L484-485 `member _.Interrupt() = sessionR |> Option.forall (...)` | ○ |
| C-30 | FsiSessions.Interrupt - セッションあり | E-01: L484-485 同上 | ○ |
| C-31 | FsiSessions.SendInput - 入力転送 | E-01: L487-488 `member _.SendInput s = sessionR |> Option.iter (...)` | ○ |
| C-32 | FsiSessions.SendInput - セッションなし | E-01: L487-488 同上 - Option.iterはNoneで何もしない | ○ |
| C-33 | FsiSessions.Alive - 稼働中 | E-01: L494-495 `member _.Alive = sessionR |> Option.exists (...)` | ○ |
| C-34 | FsiSessions.Alive - セッションなし | E-01: L494-495 同上 | ○ |
| C-35 | FsiSessions.ProcessID - セッションなし | E-01: L500-503 `member _.ProcessID = match sessionR with | None -> -1 ...` | ○ |
| C-36 | FsiSessions.Kill - セッション終了 | E-01: L463-467 `let kill() = sessionR |> Option.iter (...)` | ○ |
| C-37 | FsiSessions.Ensure - 新規作成 | E-01: L481-482 `let ensure(sourceFile) = if sessionR.IsNone then restart(sourceFile)` | ○ |
| C-38 | FsiSessions.Ensure - 既存維持 | E-01: L481-482 同上 | ○ |
| C-39 | FsiSessions.Restart - 再起動 | E-01: L469-479 `let restart(sourceFile) = kill(); ...` | ○ |

### fsiLanguageService.fs 関連テストケース（C-40 〜 C-62）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-40 | FsiDeclarations.GetCount | E-03: L71 `override this.GetCount() = items.Length` | ○ |
| C-41 | FsiDeclarations.GetName - 正常 | E-03: L72 `override this.GetName(i) = items.[i] |> (fun (n,d,dsp,g) -> n)` | ○ |
| C-42 | FsiDeclarations.GetName - 境界値 | E-03: L72 - 配列アクセスで範囲外例外発生 | ○ |
| C-43 | FsiDeclarations.GetDescription | E-03: L73 `override this.GetDescription(i) = items.[i] |> (fun (n,d,dsp,g) -> d)` | ○ |
| C-44 | FsiDeclarations.GetGlyph | E-03: L75 `override this.GetGlyph(i:int) = items.[i] |> (fun (n,d,dsp,g) -> g)` | ○ |
| C-45 | FsiMethods.GetCount | E-03: L82 `override this.GetCount() = items.Length` - items = [| |] | ○ |
| C-46 | FsiSource.GetCommentFormat | E-03: L93-99 `override this.GetCommentFormat() = ...` | ○ |
| C-47 | FsiSource.CreateCompletionSet | E-03: L100-101 `override this.CreateCompletionSet() = (new FsiCompletionSet(...) :> CompletionSet)` | ○ |
| C-48 | FsiScanner.SetSource | E-03: L109 `override this.SetSource(source:string,offset:int) = ()` | ○ |
| C-49 | FsiScanner.ScanTokenAndProvideInfoAboutIt | E-03: L110 `override this.ScanTokenAndProvideInfoAboutIt(...) = false` | ○ |
| C-50 | FsiAuthoringScope.GetDataTipText | E-03: L115-117 `override this.GetDataTipText(...) = span <- new TextSpan(); null` | ○ |
| C-51 | FsiAuthoringScope.GetDeclarations | E-03: L119-120 `override this.GetDeclarations(...) = (new FsiDeclarations() :> Declarations)` | ○ |
| C-52 | FsiAuthoringScope.GetMethods | E-03: L122-123 `override this.GetMethods(...) = new FsiMethods() :> Methods` | ○ |
| C-53 | FsiViewFilter.QueryCommandStatus - SHOWMEMBERLIST | E-03: L138-140 `if isShowMemberList guidCmdGroup nCmdId || isCompleteWord ... then int32 (OLECMDF.OLECMDF_SUPPORTED |||...)` | ○ |
| C-54 | FsiViewFilter.QueryCommandStatus - COMPLETEWORD | E-03: L135-136, L138-140 同上 | ○ |
| C-55 | FsiViewFilter.HandlePreExec - SHOWMEMBERLIST | E-03: L143-150 `if isShowMemberList guidCmdGroup nCmdId then ... true` | ○ |
| C-56 | FsiViewFilter.HandlePreExec - COMPLETEWORD | E-03: L151-158 `elif isCompleteWord guidCmdGroup nCmdId then ... true` | ○ |
| C-57 | FsiLanguageService.GetLanguagePreferences | E-03: L191-198 `override this.GetLanguagePreferences() = ...` | ○ |
| C-58 | FsiLanguageService.GetScanner | E-03: L200-203 `override this.GetScanner(buffer:IVsTextLines) = ...` | ○ |
| C-59 | FsiLanguageService.ParseSource | E-03: L205-206 `override this.ParseSource(req:ParseRequest) = (new FsiAuthoringScope(...) :> AuthoringScope)` | ○ |
| C-60 | FsiLanguageService.Name | E-03: L208 `override this.Name = "FSharpInteractive"` | ○ |
| C-61 | FsiLanguageService.GetItemCount | E-03: L215-217 `override this.GetItemCount count = count <- 1; VSConstants.S_OK` | ○ |
| C-62 | FsiLanguageService.GetColorableItem | E-03: L219-221 `override this.GetColorableItem(index, colorableItem) = colorableItem <- Helpers.FsiKeyword; VSConstants.S_OK` | ○ |

### fsiBasis.fs 関連テストケース（C-63 〜 C-78）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-63 | HistoryBuffer.Add | E-04: L141 `member this.Add(text:string) = lines.Add(text); pointer <- lines.Count` | ○ |
| C-64 | HistoryBuffer.CycleUp - 正常 | E-04: L142-146 `member this.CycleUp(text:string) = if pointer-1 >= 0 then ... Some lines.[pointer]` | ○ |
| C-65 | HistoryBuffer.CycleUp - 境界値 | E-04: L145-146 `else None` | ○ |
| C-66 | HistoryBuffer.CycleDown - 正常 | E-04: L147-151 `member this.CycleDown(text:string) = if pointer+1 < lines.Count then ... Some lines.[pointer]` | ○ |
| C-67 | HistoryBuffer.CycleDown - 境界値 | E-04: L150-151 `else None` | ○ |
| C-68 | ArgParsing.debugInfoEnabled - デフォルト | E-04: L113-123 `let debugInfoEnabled (args : string) = match lastIndexOfPattern args @"(--|/)debug-" with | -1 -> true` | ○ |
| C-69 | ArgParsing.debugInfoEnabled - 無効化 | E-04: L115-123 同上 | ○ |
| C-70 | ArgParsing.debugInfoEnabled - 上書き | E-04: L118-123 `let afterDisabled = ...; let idxEnabled = ...; idxEnabled > idxDisabled` | ○ |
| C-71 | ArgParsing.optimizationsEnabled - デフォルト | E-04: L126-134 `let optimizationsEnabled (args : string) = match ... | -1 -> true` | ○ |
| C-72 | ArgParsing.optimizationsEnabled - 無効化 | E-04: L128-134 同上 | ○ |
| C-73 | ArgParsing.optimizationsEnabled - 上書き | E-04: L130-134 同上 | ○ |
| C-74 | Util.CreateObject - 正常 | E-04: L62-77 `let CreateObject (globalProvider:...) (classType:Type,interfaceType:Type) = ...` | ○ |
| C-75 | Util.CreateObject - 失敗時例外 | E-04: L68-69 `if interfacePointer = IntPtr.Zero then raise (new COMException(...))` | ○ |
| C-76 | RegistryHelpers.tryReadHKCU - 存在時 | E-04: L93-98 `let tryReadHKCU<'t> subkey valueName = ... | :? 't as valTyped -> Some(valTyped)` | ○ |
| C-77 | RegistryHelpers.tryReadHKCU - 不存在時 | E-04: L95 `if isNull key then None else` | ○ |
| C-78 | RegistryHelpers.writeHKCU | E-04: L101-103 `let writeHKCU subkey valueName value = ...` | ○ |

### fsiTextBufferStream.fs 関連テストケース（C-79 〜 C-87）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-79 | TextBufferStream - null検証 | E-05: L15 `do if null = textLines then raise (new ArgumentNullException("textLines"))` | ○ |
| C-80 | ReadOnlyMarkerSpan - null時 | E-05: L47-49 `match readonlyRegion with | null -> TextSpan()` | ○ |
| C-81 | ReadOnlyMarkerSpan - 設定済み | E-05: L50-54 `| _ -> ... TextSpan(...)` | ○ |
| C-82 | ExtendReadOnlyMarker | E-05: L56-57 `member this.ExtendReadOnlyMarker() = extendReadOnlyRegion textLines.CurrentSnapshot.Length` | ○ |
| C-83 | ResetReadOnlyMarker - 設定済み | E-05: L59-66 `member this.ResetReadOnlyMarker() = match readonlyRegion with | null -> () | _ -> ...` | ○ |
| C-84 | ResetReadOnlyMarker - null時 | E-05: L60-61 `| null -> ()` | ○ |
| C-85 | DirectWrite | E-05: L68 `member this.DirectWrite(text:string) = appendReadOnlyText text` | ○ |
| C-86 | DirectWriteLine(text) | E-05: L69 `member this.DirectWriteLine(text:string) = appendReadOnlyText (text + Environment.NewLine)` | ○ |
| C-87 | DirectWriteLine() | E-05: L70 `member this.DirectWriteLine() = appendReadOnlyText (Environment.NewLine)` | ○ |

### fsiPackageHooks.fs 関連テストケース（C-88 〜 C-96）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-88 | fsiServiceCreatorCallback - FsiLanguageService要求 | E-06: L14-22 `if typ = typeof<FsiLanguageService> then ... box service` | ○ |
| C-89 | fsiServiceCreatorCallback - 異なる型 | E-06: L20-21 `else null` | ○ |
| C-90 | ShowToolWindow - 正常表示 | E-06: L34-45 `let ShowToolWindow (this:Package) ... = ... windowFrame.Show()` | ○ |
| C-91 | ShowToolWindow - 失敗時例外 | E-06: L40-41 `if null = window || null = window.Frame then raise (new NotSupportedException(...))` | ○ |
| C-92 | OnMLSend - ExecuteSelection | E-06: L63-69 `match action with | ExecuteSelection -> window.MLSendSelection(sender, e)` | ○ |
| C-93 | OnMLSend - ExecuteLine | E-06: L67 `| ExecuteLine -> window.MLSendLine(sender, e)` | ○ |
| C-94 | OnMLSend - DebugSelection | E-06: L68 `| DebugSelection -> window.MLDebugSelection(sender, e)` | ○ |
| C-95 | AddReferencesToFSI | E-06: L71-72 `let AddReferencesToFSI (this:Package) references = ... window.AddReferences references` | ○ |
| C-96 | GetDebuggerState | E-06: L74-75 `let GetDebuggerState (this:Package) = queryFSIToolWindow false this (fun window -> window.GetDebuggerState())` | ○ |

### fsiSessionToolWindow.fs 関連テストケース（C-97 〜 C-116）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-97 | fixServerPrompt - 置換 | E-02: L44-48 `let fixServerPrompt (str:string) = ... str.Replace(SessionsProperties.ServerPrompt,">")` | ○ |
| C-98 | fixServerPrompt - 末尾処理 | E-02: L46 `let str = if str.EndsWith(SessionsProperties.ServerPrompt) then str + " " else str` | ○ |
| C-99 | chunkKeyValues - チャンク | E-02: L60-63 `let chunkKeyValues allEntries = allEntries |> List.groupBy(...) |> List.map(...)` | ○ |
| C-100 | chunkKeyValues - 空リスト | E-02: L60-63 - List.groupByとList.mapは空リストで空リストを返す | ○ |
| C-101 | FsiToolWindow.Dispose | E-02: L653-677 `override this.Dispose(disposing) = if disposing then sessions.Kill(); ...` | ○ |
| C-102 | FsiToolWindow.AddReferences | E-02: L646-651 `member _.AddReferences(references : string[]) = let text = ... sendTextToFSI text` | ○ |
| C-103 | GetDebuggerState - NotRunning | E-02: L442-455 `let getDebuggerState () = ... FsiDebuggerState.NotRunning, None` | ○ |
| C-104 | GetDebuggerState - AttachedToFSI | E-02: L454 `| Some _ -> FsiDebuggerState.AttachedToFSI, debuggedFsi` | ○ |
| C-105 | GetDebuggerState - AttachedNotToFSI | E-02: L455 `| None -> FsiDebuggerState.AttachedNotToFSI, None` | ○ |
| C-106 | ITestVFSI.SendTextInteraction | E-02: L754-756 `member _.SendTextInteraction(s:string) = ... executeInteraction ...` | ○ |
| C-107 | ITestVFSI.GetMostRecentLines - 正常 | E-02: L759-782 `member _.GetMostRecentLines(n:int) : string[] = ...` | ○ |
| C-108 | ITestVFSI.GetMostRecentLines - 境界値 | E-02: L771 `let mutable startLine = max (lineCount - 1 - n) 0` | ○ |
| C-109 | IOleCommandTarget.QueryStatus | E-02: L785-815 `member _.QueryStatus (guid, cCmds, prgCmds, pCmdText) = ...` | ○ |
| C-110 | IOleCommandTarget.Exec - TYPECHAR | E-02: L817-829 `member _.Exec (...) = if ... nCmdId = uint32 VSStd2KCmdID.TYPECHAR ... then ...` | ○ |
| C-111 | FsiPropertyPage.FsiPreferAnyCPUVersion | E-03: L37 `member this.FsiPreferAnyCPUVersion with get() = SessionsProperties.useAnyCpuVersion and set (x:bool) = ...` | ○ |
| C-112 | FsiPropertyPage.FsiCommandLineArgs | E-03: L42 `member this.FsiCommandLineArgs with get() = SessionsProperties.fsiArgs and set (x:string) = ...` | ○ |
| C-113 | FsiPropertyPage.FsiShadowCopy | E-03: L47 `member this.FsiShadowCopy with get() = SessionsProperties.fsiShadowCopy and set (x:bool) = ...` | ○ |
| C-114 | FsiPropertyPage.FsiUseNetCore | E-03: L52 `member this.FsiUseNetCore with get() = SessionsProperties.fsiUseNetCore and set (x:bool) = ...` | ○ |
| C-115 | FsiPropertyPage.FsiDebugMode | E-03: L57 `member this.FsiDebugMode with get() = SessionsProperties.fsiDebugMode and set (x:bool) = ...` | ○ |
| C-116 | FsiPropertyPage.FsiPreview | E-03: L62 `member this.FsiPreview with get() = SessionsProperties.fsiPreview and set (x:bool) = ...` | ○ |

### FSharp.VS.FSI.Attributes.fs 関連テストケース（C-117 〜 C-119）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-117 | ResourceDisplayNameAttribute | E-07: L5-6 `type internal ResourceDisplayNameAttribute(resName) = inherit System.ComponentModel.DisplayNameAttribute(SRProperties.GetString(resName))` | ○ |
| C-118 | ResourceDescriptionAttribute | E-07: L8-9 `type internal ResourceDescriptionAttribute(resName) = inherit System.ComponentModel.DescriptionAttribute(SRProperties.GetString(resName))` | ○ |
| C-119 | ResourceCategoryAttribute | E-07: L11-12 `type internal ResourceCategoryAttribute(resName) = inherit System.ComponentModel.CategoryAttribute(SRProperties.GetString(resName))` | ○ |

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

## 5) リスクフラグ（レビュー観点）
- 0: 低リスク
  - 全テストケースはソースコードの実装に基づいて生成
  - Visual Studio統合に関するテストは、実際のVS環境でのみ完全な検証が可能

## 6) レビュアーチェックリスト（最小）
- [ ] 高優先度テストケース（35件）の入力値・期待結果が妥当か
- [ ] 境界値テスト（8件）が十分なエッジケースをカバーしているか
- [ ] 異常系テスト（12件）が適切な例外・エラーハンドリングを検証しているか
- [ ] セッション管理関連テスト（FsiSession, FsiSessions）が実際の動作と一致するか
- [ ] Visual Studio固有のインターフェース（IOleCommandTarget, IVsWindowPane等）のテストが実行可能か
