---
generated_at: 2026-03-01 12:00:00
metrics:
  claims_total: 114
  claims_with_evidence: 110
  claims_without_evidence: 4
confidence_derived: 0.96
---

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

## 本レポートについて

### 目的
本レポートは、生成された設計書・ドキュメントの信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

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

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

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**0.96**
  - 根拠あり：110 / 114、根拠なし：4
- 優先レビュー（高）
  1. **C-058 (_getIconSource 絵文字のフォントアイコン生成)**：絵文字判定ロジックがIsLikelyToBeEmojiOrSymbolIcon関数に委譲されており、その内部実装が本モジュール外にある
  2. **C-114 (ResourceString::ProvideValue 存在しないリソースキー)**：ResourceLoader.GetString()の挙動がOS/ランタイム依存であり、コード上からは例外の種類を断定できない
  3. **C-076 (_convertToSoftwareBitmap 不正HICON)**：不正なHICONの具体的な挙動はWICライブラリの実装依存
  4. **C-055 (_getColoredBitmapIcon 不正URI)**：CATCH_LOG()マクロで例外をキャッチしてnullptrを返すが、具体的にどの例外がスローされるかはWinRT Uriクラスの実装依存

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

- E-01: `src/cascadia/UIHelpers/Converters.h` - Convertersクラスのヘッダ定義（静的メソッド宣言）
- E-02: `src/cascadia/UIHelpers/Converters.cpp` - Convertersクラスの実装（各変換ロジック）
- E-03: `src/cascadia/UIHelpers/Converters.idl` - Converters WinRT IDL定義
- E-04: `src/cascadia/UIHelpers/IconPathConverter.h` - IconPathConverterクラスのヘッダ定義
- E-05: `src/cascadia/UIHelpers/IconPathConverter.cpp` - IconPathConverterの実装（アイコンパス変換ロジック、テンプレート関数）
- E-06: `src/cascadia/UIHelpers/IconPathConverter.idl` - IconPathConverter WinRT IDL定義
- E-07: `src/cascadia/UIHelpers/TextMenuFlyout.h` - TextMenuFlyoutクラスのヘッダ定義
- E-08: `src/cascadia/UIHelpers/TextMenuFlyout.cpp` - TextMenuFlyoutの実装（メニューフライアウトロジック）
- E-09: `src/cascadia/UIHelpers/TextMenuFlyout.idl` - TextMenuFlyout WinRT IDL定義
- E-10: `src/cascadia/UIHelpers/ResourceString.h` - ResourceStringクラスのヘッダ定義（プロパティ定義）
- E-11: `src/cascadia/UIHelpers/ResourceString.cpp` - ResourceStringの実装（ProvideValueロジック）
- E-12: `src/cascadia/UIHelpers/ResourceString.idl` - ResourceString WinRT IDL定義
- E-13: `src/cascadia/UIHelpers/IDirectKeyListener.idl` - IDirectKeyListenerインターフェースIDL定義
- E-14: `src/cascadia/UIHelpers/init.cpp` - DLLエントリポイント（DllMain）
- E-15: `src/cascadia/UIHelpers/pch.h` - プリコンパイル済みヘッダ

## 3) Claims と根拠の対応（レビューの主戦場）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-001 | InvertBoolean(true)がfalseを返す | E-02 (L14-17: `return !value;`) | ○ |
| C-002 | InvertBoolean(false)がtrueを返す | E-02 (L14-17: `return !value;`) | ○ |
| C-003 | InvertedBooleanToVisibility(true)がCollapsedを返す | E-02 (L19-22: `value ? Collapsed : Visible`) | ○ |
| C-004 | InvertedBooleanToVisibility(false)がVisibleを返す | E-02 (L19-22: `value ? Collapsed : Visible`) | ○ |
| C-005 | PercentageToPercentageValue(0.5)が50.0を返す | E-02 (L25-28: `value * 100.0`) | ○ |
| C-006 | PercentageToPercentageValue(1.0)が100.0を返す | E-02 (L25-28: `value * 100.0`) | ○ |
| C-007 | PercentageToPercentageValue(0.0)が0.0を返す | E-02 (L25-28: `value * 100.0`) | ○ |
| C-008 | PercentageToPercentageValue(-0.1)が-10.0を返す | E-02 (L25-28: `value * 100.0`) | ○ |
| C-009 | PercentageValueToPercentage(50.0)が0.5を返す | E-02 (L30-33: `value / 100.0`) | ○ |
| C-010 | PercentageValueToPercentage(100.0)が1.0を返す | E-02 (L30-33: `value / 100.0`) | ○ |
| C-011 | PercentageValueToPercentage(0.0)が0.0を返す | E-02 (L30-33: `value / 100.0`) | ○ |
| C-012 | PercentageToPercentageString(0.5)が"50%"を返す | E-02 (L35-38: `FMT_COMPILE(L"{:.0f}%"), value * 100.0`) | ○ |
| C-013 | PercentageToPercentageString(1.0)が"100%"を返す | E-02 (L35-38) | ○ |
| C-014 | PercentageToPercentageString(0.0)が"0%"を返す | E-02 (L35-38) | ○ |
| C-015 | PercentageToPercentageString(0.456)が"46%"を返す | E-02 (L35-38: `{:.0f}` フォーマットで小数部切捨て) | ○ |
| C-016 | StringsAreNotEqual 異なる文字列でtrueが返る | E-02 (L41-44: `expected != actual`) | ○ |
| C-017 | StringsAreNotEqual 同じ文字列でfalseが返る | E-02 (L41-44: `expected != actual`) | ○ |
| C-018 | StringsAreNotEqual 両方空文字列でfalseが返る | E-02 (L41-44: `expected != actual`) | ○ |
| C-019 | StringsAreNotEqual 片方空文字列でtrueが返る | E-02 (L41-44: `expected != actual`) | ○ |
| C-020 | StringNotEmpty 非空文字列でtrueが返る | E-02 (L46-49: `!value.empty()`) | ○ |
| C-021 | StringNotEmpty 空文字列でfalseが返る | E-02 (L46-49: `!value.empty()`) | ○ |
| C-022 | StringNotEmptyToVisibility 非空文字列でVisibleが返る | E-02 (L51-54: `value.empty() ? Collapsed : Visible`) | ○ |
| C-023 | StringNotEmptyToVisibility 空文字列でCollapsedが返る | E-02 (L51-54: `value.empty() ? Collapsed : Visible`) | ○ |
| C-024 | StringOrEmptyIfPlaceholder 値がプレースホルダーと異なる場合にそのまま返る | E-02 (L56-59: `placeholder == value ? hstring{} : value`) | ○ |
| C-025 | StringOrEmptyIfPlaceholder 値がプレースホルダーと同一で空文字列が返る | E-02 (L56-59) | ○ |
| C-026 | StringOrEmptyIfPlaceholder 両方空文字列で空文字列が返る | E-02 (L56-59) | ○ |
| C-027 | DoubleToFontWeight(400.0)がFontWeight{400}を返す | E-02 (L62-72: 範囲1.0-1000.0内でlrint変換) | ○ |
| C-028 | DoubleToFontWeight(700.0)がFontWeight{700}を返す | E-02 (L62-72) | ○ |
| C-029 | DoubleToFontWeight(1.0)がFontWeight{1}を返す | E-02 (L66: `value >= 1.0 && value <= 1000.0`) | ○ |
| C-030 | DoubleToFontWeight(1000.0)がFontWeight{1000}を返す | E-02 (L66: `value >= 1.0 && value <= 1000.0`) | ○ |
| C-031 | DoubleToFontWeight(0.0)がデフォルト値FontWeight{400}を返す | E-02 (L64: `uint16_t val = 400;` L66: 条件不成立) | ○ |
| C-032 | DoubleToFontWeight(1001.0)がデフォルト値FontWeight{400}を返す | E-02 (L64,L66: 条件不成立) | ○ |
| C-033 | DoubleToFontWeight(-1.0)がデフォルト値FontWeight{400}を返す | E-02 (L64,L66: 条件不成立) | ○ |
| C-034 | DoubleToFontWeight(400.7)がlrintで401に丸められる | E-02 (L68: `lrint(value)`) | ○ |
| C-035 | ColorToBrush 有効なColorからSolidColorBrushが生成される | E-02 (L74-77: `SolidColorBrush(color)`) | ○ |
| C-036 | ColorToBrush 透明色でSolidColorBrushが生成される | E-02 (L74-77) | ○ |
| C-037 | FontWeightToDouble(FontWeight{400})が400.0を返す | E-02 (L79-82: `fontWeight.Weight`) | ○ |
| C-038 | FontWeightToDouble(FontWeight{1})が1.0を返す | E-02 (L79-82) | ○ |
| C-039 | FontWeightToDouble(FontWeight{1000})が1000.0を返す | E-02 (L79-82) | ○ |
| C-040 | _expandIconPath 空文字列で空文字列が返る | E-05 (L100-108: `if (iconPath.empty()) return iconPath;`) | ○ |
| C-041 | _expandIconPath 環境変数が展開される | E-05 (L106: `ExpandEnvironmentStringsW`) | ○ |
| C-042 | _expandIconPath 環境変数なしパスがそのまま返る | E-05 (L106: ExpandEnvironmentStringsWは非環境変数をそのまま返す) | ○ |
| C-043 | _getIconIndex exeパスにカンマ+インデックスでインデックスが返る | E-05 (L252-278: commaIndex, `til::parse_signed<int>`) | ○ |
| C-044 | _getIconIndex dllパスにカンマ+インデックスでインデックスが返る | E-05 (L263-265: `.dll`拡張子チェック) | ○ |
| C-045 | _getIconIndex lnkパスにカンマ+インデックスでインデックスが返る | E-05 (L263-265: `.lnk`拡張子チェック) | ○ |
| C-046 | _getIconIndex exeパスにカンマなしでデフォルト0が返る | E-05 (L270-277: `return 0;`) | ○ |
| C-047 | _getIconIndex pngパスでnulloptが返る | E-05 (L263-268: exe/dll/lnk以外は`std::nullopt`) | ○ |
| C-048 | _getIconIndex icoパスでnulloptが返る | E-05 (L263-268) | ○ |
| C-049 | _getIconIndex 負のインデックスが負の値で返る | E-05 (L273: `til::parse_signed<int>`) | ○ |
| C-050 | _getIconIndex 空文字列でnulloptが返る | E-05 (L260,L263-268: 空文字列はexe/dll/lnkに該当しない) | ○ |
| C-051 | _getColoredBitmapIcon 有効URIでBitmapIconSourceが生成される | E-05 (L77-98: URI構築→BitmapIconSource設定) | ○ |
| C-052 | _getColoredBitmapIcon monochrome=trueでShowAsMonochrome(true) | E-05 (L90: `iconSource.ShowAsMonochrome(monochrome)`) | ○ |
| C-053 | _getColoredBitmapIcon 空文字列でnullptrが返る | E-05 (L81: `!path.empty()` 条件不成立→L97: `return nullptr`) | ○ |
| C-054 | _getColoredBitmapIcon 非ASCII先頭文字でnullptrが返る | E-05 (L81: `path.front() < 128` 条件不成立) | ○ |
| C-055 | _getColoredBitmapIcon 不正URIで例外キャッチしnullptrが返る | E-05 (L83-94: try/CATCH_LOG() → L97: `return nullptr`) | △ |
| C-056 | _getIconSource 有効画像パスでBitmapIconSourceが返る | E-05 (L126-178: _getColoredBitmapIcon呼出) | ○ |
| C-057 | _getIconSource MDL2アイコン文字でFontIconSourceが返る | E-05 (L137-161: IsLikelyToBeEmojiOrSymbolIcon → FontIconSource生成) | ○ |
| C-058 | _getIconSource 絵文字でFontIconSource(Segoe UI)が返る | E-05 (L137,L154-155: 非MDL2時は`Segoe UI`設定) | △ |
| C-059 | _getIconSource 空文字列でデフォルトBitmapIconSource(UriSource=null)が返る | E-05 (L164-175: デフォルトアイコン生成コメントに理由記載) | ○ |
| C-060 | _getIconSource MDL2範囲下限(\uE700)で正しいフォントが設定される | E-05 (L147: `ch >= L'\uE700' && ch <= L'\uF8FF'`) | ○ |
| C-061 | _getIconSource MDL2範囲上限(\uF8FF)で正しいフォントが設定される | E-05 (L147) | ○ |
| C-062 | _getIconSource MDL2範囲外直前(\uE6FF)でSegoe UIが設定される | E-05 (L147: 条件不成立→L154-155) | ○ |
| C-063 | IconSourceWUX 画像パスからWUX IconSourceが返る | E-05 (L180-188: `_getIconSource<WUX::IconSource>`) | ○ |
| C-064 | IconSourceWUX シンボルからWUX IconSourceが返る | E-05 (L180-188) | ○ |
| C-065 | IconSourceWUX 空文字列からデフォルトアイコンが返る | E-05 (L180-188) | ○ |
| C-066 | IconSourceMUX 画像パスからMUX IconSourceが返る | E-05 (L300-316) | ○ |
| C-067 | IconSourceMUX exeパス(インデックス付き)からImageIconSourceが返る | E-05 (L300-316: _getIconIndex→_getImageIconSourceForBinary→ImageIconSource) | ○ |
| C-068 | IconSourceMUX dllパス(インデックス付き)からImageIconSourceが返る | E-05 (L300-316) | ○ |
| C-069 | IconSourceMUX monochrome=trueでモノクロアイコンが返る | E-05 (L300-316: monochrome引数を_IconSourceMUXに渡す) | ○ |
| C-070 | IconWUX 画像パスからIconSourceElementが返る | E-05 (L318-337: IconSourceWUX呼出→IconSourceElement生成) | ○ |
| C-071 | IconWUX exeパスからImageIconが返る | E-05 (L318-337: _getIconIndex→_getImageIconSourceForBinary→ImageIcon Width=32,Height=32) | ○ |
| C-072 | IconWUX 空文字列からデフォルトアイコンが返る | E-05 (L318-337) | ○ |
| C-073 | _getBitmapFromIconFileAsync 有効パスからSoftwareBitmapが返る | E-05 (L221-240: SHDefExtractIcon→_convertToSoftwareBitmap) | ○ |
| C-074 | _getBitmapFromIconFileAsync 存在しないファイルでnullptrが返る | E-05 (L226-231: `LOG_IF_FAILED`→`if (!hicon) return nullptr`) | ○ |
| C-075 | _convertToSoftwareBitmap 有効HICONからSoftwareBitmapが生成される | E-05 (L195-219: CreateBitmapFromHICON→SoftwareBitmap) | ○ |
| C-076 | _convertToSoftwareBitmap 不正HICONで例外がスローされる | E-05 (L202: `THROW_IF_FAILED`) | △ |
| C-077 | _getImageIconSourceForBinary 有効パスからSoftwareBitmapSourceが返る | E-05 (L280-298: _getBitmapFromIconFileAsync→SetBitmapAsync) | ○ |
| C-078 | _getImageIconSourceForBinary アイコン抽出失敗でnullptrが返る | E-05 (L289-293: `if (swBitmap == nullptr) return nullptr`) | ○ |
| C-079 | TextMenuFlyoutコンストラクタでOpeningイベント登録 | E-08 (L23-27: `Opening({ this, &TextMenuFlyout::MenuFlyout_Opening })`) | ○ |
| C-080 | MenuFlyout_Opening TextBoxでCut/Copy/Paste/SelectAll生成 | E-08 (L29-86: writable=true時の分岐) | ○ |
| C-081 | MenuFlyout_Opening TextBlockでCopy/SelectAllのみ生成 | E-08 (L48-50: TextBlock→writable=false) | ○ |
| C-082 | MenuFlyout_Opening RichTextBlockでCopy/SelectAllのみ生成 | E-08 (L57-59: RichTextBlock→writable=false) | ○ |
| C-083 | MenuFlyout_Opening NumberBoxでTextBoxとして処理 | E-08 (L42-47: NumberBox→GetTemplateChild("InputBox")→TextBox) | ○ |
| C-084 | MenuFlyout_Opening Targetがnullで即座にreturn | E-08 (L31-35: `if (!target) return`) | ○ |
| C-085 | MenuFlyout_Opening 選択テキストありでCut/Copy Visible | E-08 (L80-85: `visibilityOfItemsRequiringSelection`) | ○ |
| C-086 | MenuFlyout_Opening 選択テキストなしでCut/Copy Collapsed | E-08 (L80-85: `selection.empty() ? Collapsed : Visible`) | ○ |
| C-087 | MenuFlyout_Opening 2回目はメニュー項目再利用 | E-08 (L62: `if (!_copy)` で初回のみ生成) | ○ |
| C-088 | Cut_Click TextBoxでCutSelectionToClipboard呼出 | E-08 (L88-107: TextBox判定→CutSelectionToClipboard()) | ○ |
| C-089 | Cut_Click NumberBoxで内部TextBoxのCut実行 | E-08 (L99-102: NumberBox→GetTemplateChild) | ○ |
| C-090 | Cut_Click Targetがnullで即座にreturn | E-08 (L93-97: `if (!target) return`) | ○ |
| C-091 | Copy_Click TextBlockでCopySelectionToClipboard呼出 | E-08 (L109-133: TextBlock→CopySelectionToClipboard()) | ○ |
| C-092 | Copy_Click TextBoxでCopySelectionToClipboard呼出 | E-08 (L125-128: TextBox→CopySelectionToClipboard()) | ○ |
| C-093 | Copy_Click RichTextBlockでCopySelectionToClipboard呼出 | E-08 (L129-132: RichTextBlock→CopySelectionToClipboard()) | ○ |
| C-094 | Copy_Click NumberBoxで内部TextBoxのCopy実行 | E-08 (L117-119: NumberBox→GetTemplateChild) | ○ |
| C-095 | Copy_Click Targetがnullで即座にreturn | E-08 (L111-115: `if (!target) return`) | ○ |
| C-096 | Paste_Click TextBoxでPasteFromClipboard呼出 | E-08 (L135-151: TextBox→PasteFromClipboard()) | ○ |
| C-097 | Paste_Click NumberBoxで内部TextBoxのPaste実行 | E-08 (L143-145: NumberBox→GetTemplateChild) | ○ |
| C-098 | Paste_Click Targetがnullで即座にreturn | E-08 (L137-141: `if (!target) return`) | ○ |
| C-099 | SelectAll_Click TextBlockでSelectAll呼出 | E-08 (L153-192: TextBlock→SelectAll()) | ○ |
| C-100 | SelectAll_Click TextBoxでSelectAll呼出 | E-08 (L184-187: TextBox→SelectAll()) | ○ |
| C-101 | SelectAll_Click RichTextBlockでSelectAll呼出 | E-08 (L188-191: RichTextBlock→SelectAll()) | ○ |
| C-102 | SelectAll_Click NumberBoxで内部TextBoxのSelectAll実行 | E-08 (L176-179: NumberBox→GetTemplateChild) | ○ |
| C-103 | SelectAll_Click TargetがnullでFocusManagerからフォールバック | E-08 (L160-173: XamlRoot→FocusManager::GetFocusedElement) | ○ |
| C-104 | SelectAll_Click Target/XamlRoot両方nullで即座にreturn | E-08 (L163-167: `if (!root) return`) | ○ |
| C-105 | SelectAll_Click Target/フォーカス要素両方nullで即座にreturn | E-08 (L170-173: `if (!target) return`) | ○ |
| C-106 | _createMenuItem シンボル付きメニュー項目が正しく生成される | E-08 (L194-209: `if (symbol != NullSymbol)` → SymbolIcon設定) | ○ |
| C-107 | _createMenuItem NullSymbolでアイコンなしメニュー項目が生成される | E-08 (L201-203: NullSymbol条件不成立→アイコン未設定) | ○ |
| C-108 | ResourceString::Tree getter | E-10 (L11-14: `return tree_;`) | ○ |
| C-109 | ResourceString::Tree setter | E-10 (L16-19: `tree_ = value;`) | ○ |
| C-110 | ResourceString::Name getter | E-10 (L21-24: `return name_;`) | ○ |
| C-111 | ResourceString::Name setter | E-10 (L25-28: `name_ = value;`) | ○ |
| C-112 | ResourceString::ProvideValue 有効TreeとNameでリソース文字列が返る | E-11 (L7-16: ResourceLoader::GetForCurrentView→GetString) | ○ |
| C-113 | ResourceString::ProvideValue Treeが空でnullptr返却 | E-11 (L9-12: `if (tree_.empty()) return nullptr`) | ○ |
| C-114 | ResourceString::ProvideValue 存在しないキーの挙動 | E-11 (L15: `loader.GetString(name_)`) | △ |

## 4) 不足情報（Unknown / Missing）
- **C-055**: `_getColoredBitmapIcon`内のCATCH_LOG()マクロの具体的な挙動は、WinRT Uriクラスの内部実装に依存する。不正URIがスローする例外の型は`winrt::hresult_error`であるが、具体的なHRESULT値はコード上からは確定できない。
  - 候補：WinRT Uri ドキュメント / CATCH_LOG マクロ定義（wil ライブラリ）
- **C-058**: `IsLikelyToBeEmojiOrSymbolIcon`関数は`../types/inc/utils.hpp`に定義されており、本モジュール外の実装。絵文字とシンボルの判定ロジックの詳細が不明。
  - 候補：`src/types/inc/utils.hpp` / `src/types/utils.cpp`
- **C-076**: 不正なHICONをIWICImagingFactory::CreateBitmapFromHICONに渡した場合の具体的なHRESULT値はWICライブラリの実装依存。
  - 候補：WIC API ドキュメント / Windows SDK ヘッダ
- **C-114**: ResourceLoader::GetString()に存在しないキーを渡した場合の挙動（空文字列を返すか例外をスローするか）はWinRTランタイムバージョンに依存する。
  - 候補：Windows.ApplicationModel.Resources.ResourceLoader ドキュメント

## 5) リスクフラグ（レビュー観点）
- **0 (低リスク)**: Convertersクラスの全テストケース（C-001 - C-039）。純粋な変換ロジックであり、外部依存がなく信頼性が高い。
- **0 (低リスク)**: ResourceStringのgetter/setter（C-108 - C-111）。単純なプロパティアクセス。
- **1 (中リスク)**: IconPathConverterの内部関数（_expandIconPath, _getIconIndex）のテストケース。環境変数展開やファイルパス解析は実行環境に軽度に依存する。
- **1 (中リスク)**: TextMenuFlyoutのメニュー構成テストケース。WinUI/XAMLコントロールのモック化が必要であり、テスト実装の難易度が高い。
- **2 (高リスク)**: IconPathConverterのバイナリアイコン抽出関連テストケース（C-067, C-068, C-071, C-073, C-074）。SHDefExtractIcon, WICイメージング等のOS API依存が大きく、統合テスト的な性質を持つ。

## 6) レビュアーチェックリスト（最小）
- [ ] Convertersクラスの境界値テスト（特にDoubleToFontWeightの範囲外値処理）が仕様と一致しているか確認
- [ ] IconPathConverterの_getIconIndex関数で、パス内にカンマが複数ある場合のテストケースが必要かどうか検討
- [ ] TextMenuFlyoutのSelectAll_ClickにおけるFocusManagerフォールバック（GH#18599対応）の動作が最新のWinUIで変更されていないか確認
- [ ] ResourceString::ProvideValueで存在しないリソースキーに対する挙動を実機で確認し、テストケースC-114の期待結果を確定
- [ ] IsLikelyToBeEmojiOrSymbolIcon関数の判定ロジックを確認し、絵文字テストケース（C-058）の入力値が適切か検証
- [ ] バイナリアイコン抽出（_getBitmapFromIconFileAsync等）のテストケースを単体テストとして実装可能か、統合テストに分類すべきか判断
