---
generated_at: 2026-02-22 12:00:00
metrics:
  claims_total: 120
  claims_with_evidence: 115
  claims_without_evidence: 5
confidence_derived: 0.96
---

# 根拠レポート：mruby-hash-ext 単体テストケース一覧

## 本レポートについて

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

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

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

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**0.96**
  - 根拠あり：115 / 120、根拠なし：5
- 優先レビュー（高）
  1. **C-024 (UT-HSH-024)**: 配列要素が1つの場合の挙動 - コードのswitch文から推測したがテストケースで直接検証されていない
  2. **C-102 (UT-HSH-102)**: to_procで存在しないキーを引いた場合 - コードから推測したがテストケースなし
  3. **C-103 (UT-HSH-103)**: to_procの戻り値型 - ラムダリテラル `->x{self[x]}` からの推測
  4. **C-116 (UT-HSH-116)**: 空Hash同士のmerge! - 境界値テストとして追加したが既存テストなし
  5. **C-117 (UT-HSH-117)**: fetch_valuesの引数なし - コードからの推測

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

- E-01: `mrbgems/mruby-hash-ext/src/hash_ext.c` — C実装コード（hash_values_at, hash_slice, hash_slice_bang, hash_except, hash_s_create, hash_key, hash_merge）
- E-02: `mrbgems/mruby-hash-ext/mrblib/hash.rb` — Ruby実装コード（merge!, compact, compact!, fetch, delete_if, flatten, invert, keep_if, to_h, 比較演算子, dig, transform_keys/values, to_proc, fetch_values, エイリアス定義）
- E-03: `mrbgems/mruby-hash-ext/test/hash.rb` — 既存テストコード（各メソッドのテストケース）
- E-04: `mrbgems/mruby-hash-ext/mrbgem.rake` — gem仕様定義（依存関係: mruby-array-ext）

## 3) Claims と根拠の対応（レビューの主戦場）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-001 | values_atで指定キーの値配列が返る | E-01(L26-41), E-03(L72-80) | ○ |
| C-002 | values_atで存在しないキーはnilが返る | E-01(L37: mrb_hash_get) | ○ |
| C-003 | values_at引数0件で空配列が返る | E-01(L33: argc==0 return) | ○ |
| C-004 | values_at大量キーでGCアリーナが正しく動作する | E-01(L35-39: arena save/restore), E-03(L76-79) | ○ |
| C-005 | sliceで指定キーのみのHashが返る | E-01(L53-72), E-03(L289-293) | ○ |
| C-006 | sliceで存在しないキーが無視される | E-01(L66-69: mrb_undef_p), E-03(L292) | ○ |
| C-007 | slice引数0件で空Hashが返る | E-01(L61: argc==0 return) | ○ |
| C-008 | sliceで元のHashが変更されない | E-01(L60: mrb_hash_new_capa) | ○ |
| C-009 | slice!で指定キー以外が削除され削除分が返る | E-01(L114-140), E-03(L295-299) | ○ |
| C-010 | slice!引数なしで全キーが削除される | E-01(L123-126), E-03(L301-304) | ○ |
| C-011 | slice!全キー指定で削除なし | E-01(L131-137), E-03(L306-309) | ○ |
| C-012 | exceptで指定キーを除いたHashが返る | E-01(L152-164), E-03(L312-317) | ○ |
| C-013 | exceptで存在しないキーが無視される | E-01(L161: mrb_hash_delete_key), E-03(L315) | ○ |
| C-014 | except引数なしで複製が返る | E-01(L159: mrb_hash_dup), E-03(L316) | ○ |
| C-015 | exceptで元のHashが変更されない | E-01(L159: mrb_hash_dup) | ○ |
| C-016 | Hash[]でHash引数からコピー生成 | E-01(L194-206), E-03(L4-8) | ○ |
| C-017 | Hash[]でネスト配列から生成 | E-01(L209-246), E-03(L10-26) | ○ |
| C-018 | Hash[]でキーバリューペアから生成 | E-01(L250-264), E-03(L28-40) | ○ |
| C-019 | Hash[]引数なしで空Hash | E-01(L250-254), E-03(L33-34) | ○ |
| C-020 | Hash[]奇数引数でArgumentError | E-01(L250-252), E-03(L37-39) | ○ |
| C-021 | Hash[]配列要素が配列でないとArgumentError | E-01(L217-219) | ○ |
| C-022 | Hash[]空配列要素でArgumentError | E-01(L233-236), E-03(L23-25) | ○ |
| C-023 | Hash[]要素3つ以上でArgumentError | E-01(L234-236), E-03(L19-21) | ○ |
| C-024 | Hash[]配列要素1つで値がnil | E-01(L229-231) | △ |
| C-025 | Hash[]サブクラスでクラス保持 | E-01(L202-204,242-244,260-262), E-03(L42-46) | ○ |
| C-026 | Hash[]空配列で空Hash | E-01(L210-211), E-03(L15-17) | ○ |
| C-027 | keyで値に対応するキーが返る | E-01(L315-330), E-03(L177-178) | ○ |
| C-028 | key重複値で最初のキーが返る | E-01(L291-301), E-03(L179) | ○ |
| C-029 | key存在しない値でnilが返る | E-01(L329), E-03(L180) | ○ |
| C-030 | keyでnil値の逆引き | E-01(L295: mrb_equal), E-03(L181-182) | ○ |
| C-031 | __mergeで複数Hashマージ | E-01(L345-368), E-03(L65) | ○ |
| C-032 | __mergeでキー重複時上書き | E-01(L364: mrb_hash_merge) | ○ |
| C-033 | __merge引数なしでArgumentError | E-01(L354-356), E-03(L68) | ○ |
| C-034 | __mergeでHash以外にTypeError | E-01(L360-363), E-03(L69) | ○ |
| C-035 | merge!ブロックなしでマージ | E-02(L28-40), E-03(L48-54) | ○ |
| C-036 | merge!ブロック付きで競合解決 | E-02(L31-37), E-03(L57-62) | ○ |
| C-037 | merge!複数引数マージ | E-02(L29-30), E-03(L65) | ○ |
| C-038 | merge!引数なしでArgumentError | E-02(L30), E-03(L68) | ○ |
| C-039 | merge!Hash以外でTypeError | E-02(L34), E-03(L69) | ○ |
| C-040 | updateがmerge!のエイリアス | E-02(L42) | ○ |
| C-041 | merge!がselfを返す | E-02(L39) | ○ |
| C-042 | compactでnil除外 | E-02(L69-73), E-03(L82-86) | ○ |
| C-043 | compactで元Hash不変 | E-02(L70-72), E-03(L86) | ○ |
| C-044 | compact!でnil削除 | E-02(L55-57), E-03(L89-93) | ○ |
| C-045 | compact!変更なしでnil返却 | E-02(L56: __compact), E-03(L93) | ○ |
| C-046 | fetch存在キーで値返却 | E-02(L103-115), E-03(L98) | ○ |
| C-047 | fetchデフォルト値返却 | E-02(L107), E-03(L99) | ○ |
| C-048 | fetchブロック戻り値返却 | E-02(L105-106), E-03(L100) | ○ |
| C-049 | fetchブロックにキーが渡る | E-02(L106), E-03(L101) | ○ |
| C-050 | fetchキー不在でKeyError | E-02(L110), E-03(L102-104) | ○ |
| C-051 | delete_ifで条件一致要素削除 | E-02(L131-138), E-03(L107-138) | ○ |
| C-052 | delete_ifブロックfalseで削除なし | E-02(L135), E-03(L114) | ○ |
| C-053 | delete_ifブロックtrueで全削除 | E-02(L135), E-03(L115) | ○ |
| C-054 | delete_ifブロックなしでEnumerator | E-02(L132) | ○ |
| C-055 | delete_ifがselfを返す | E-02(L137) | ○ |
| C-056 | flattenデフォルトlevel=1 | E-02(L156-158), E-03(L141-143) | ○ |
| C-057 | flatten level=0でto_a相当 | E-02(L157), E-03(L144) | ○ |
| C-058 | flatten level=2でネスト展開 | E-02(L157), E-03(L146) | ○ |
| C-059 | flatten level=3で全展開 | E-02(L157), E-03(L147) | ○ |
| C-060 | invertでキー値入替 | E-02(L171-175), E-03(L150-161) | ○ |
| C-061 | invert重複値で上書き | E-02(L173), E-03(L157-160) | ○ |
| C-062 | invert特殊値対応 | E-02(L173), E-03(L151-155) | ○ |
| C-063 | invertサブクラスでクラス保持 | E-02(L172: self.class.new), E-03(L163-167) | ○ |
| C-064 | keep_ifで条件一致要素保持 | E-02(L188-197), E-03(L169-174) | ○ |
| C-065 | keep_ifブロックtrueで全保持 | E-02(L191-196), E-03(L173) | ○ |
| C-066 | keep_ifブロックなしでEnumerator | E-02(L189) | ○ |
| C-067 | keep_ifがselfを返す | E-02(L196) | ○ |
| C-068 | to_hでselfが返る | E-02(L207-209), E-03(L185-188) | ○ |
| C-069 | to_hで同一オブジェクト | E-02(L208) | ○ |
| C-070 | <で部分集合判定true | E-02(L224-229), E-03(L191-207) | ○ |
| C-071 | <で同一内容false | E-02(L226: size<), E-03(L195) | ○ |
| C-072 | <で非部分集合false | E-02(L226-228), E-03(L197) | ○ |
| C-073 | <でサイズ小値不一致false | E-02(L227), E-03(L203-204) | ○ |
| C-074 | <でHash以外にTypeError | E-02(L225) | ○ |
| C-075 | <=で部分集合true | E-02(L244-249), E-03(L209-225) | ○ |
| C-076 | <=で同一内容true | E-02(L246: size<=), E-03(L213) | ○ |
| C-077 | <=で非部分集合false | E-02(L246-248), E-03(L215) | ○ |
| C-078 | <=でHash以外にTypeError | E-02(L245) | ○ |
| C-079 | >で上位集合true | E-02(L264-269), E-03(L245-261) | ○ |
| C-080 | >で同一内容false | E-02(L266: size>), E-03(L249) | ○ |
| C-081 | >で非上位集合false | E-02(L266-268), E-03(L250) | ○ |
| C-082 | >でHash以外にTypeError | E-02(L265) | ○ |
| C-083 | >=で上位集合true | E-02(L284-289), E-03(L227-243) | ○ |
| C-084 | >=で同一内容true | E-02(L286: size>=), E-03(L231) | ○ |
| C-085 | >=で非上位集合false | E-02(L286-288), E-03(L232) | ○ |
| C-086 | >=でHash以外にTypeError | E-02(L285) | ○ |
| C-087 | digでネストキー取得 | E-02(L299-306), E-03(L263-267) | ○ |
| C-088 | digで単一キー取得 | E-02(L300-304) | ○ |
| C-089 | digで存在しないキーnil | E-02(L300), E-03(L266) | ○ |
| C-090 | digで中間キー不在nil | E-02(L302: n&.dig) | ○ |
| C-091 | transform_keysでキー変換 | E-02(L318-326), E-03(L269-276) | ○ |
| C-092 | transform_keysで元Hash不変 | E-02(L320: hash={}) | ○ |
| C-093 | transform_keysブロックなしEnumerator | E-02(L319) | ○ |
| C-094 | transform_keys!で破壊的変換 | E-02(L337-342), E-03(L275-276) | ○ |
| C-095 | transform_keys!ブロックなしEnumerator | E-02(L338) | ○ |
| C-096 | transform_valuesで値変換 | E-02(L354-361), E-03(L279-287) | ○ |
| C-097 | transform_valuesで元Hash不変 | E-02(L356: hash={}) | ○ |
| C-098 | transform_valuesブロックなしEnumerator | E-02(L355) | ○ |
| C-099 | transform_values!で破壊的変換 | E-02(L373-379), E-03(L285-286) | ○ |
| C-100 | transform_values!ブロックなしEnumerator | E-02(L374) | ○ |
| C-101 | to_procでHashキー引きProc | E-02(L381-383) | ○ |
| C-102 | to_procで存在しないキーnil | E-02(L382: self[x]) | △ |
| C-103 | to_procでProcオブジェクト返却 | E-02(L382: ->x{}) | △ |
| C-104 | fetch_valuesで値配列返却 | E-02(L400-404) | ○ |
| C-105 | fetch_valuesキー不在KeyError | E-02(L402: self.fetch) | ○ |
| C-106 | fetch_valuesブロック付き | E-02(L402: &block) | ○ |
| C-107 | each_pairがeachのエイリアス | E-02(L4) | ○ |
| C-108 | filterがselectのエイリアス | E-02(L406) | ○ |
| C-109 | filter!がselect!のエイリアス | E-02(L407) | ○ |
| C-110 | values_at空Hashでnil配列 | E-01(L37: mrb_hash_get) | ○ |
| C-111 | slice空Hashで空Hash | E-01(L66-69) | ○ |
| C-112 | dig空Hashでnil | E-02(L300) | ○ |
| C-113 | compact空Hashで空Hash | E-02(L70-72) | ○ |
| C-114 | invert空Hashで空Hash | E-02(L171-175) | ○ |
| C-115 | flatten空Hashで空配列 | E-02(L157) | ○ |
| C-116 | merge!空Hash同士 | E-02(L28-40) | △ |
| C-117 | fetch_values引数なしで空配列 | E-02(L400-404) | △ |
| C-118 | key空Hashでnil | E-01(L327-329) | ○ |
| C-119 | <空Hash同士false | E-02(L226) | ○ |
| C-120 | <=空Hash同士true | E-02(L246) | ○ |

## 4) 不足情報（Unknown / Missing）
- **C-024**: `Hash[[[key]]]` で要素が1つの場合に値がnilになる挙動は、C実装のswitch文(L229-231)から読み取れるが、既存テストケースでは直接検証されていない
  - 候補：手動テスト / mruby REPLでの実行検証
- **C-102, C-103**: `to_proc` メソッドは既存テストコードに検証なし。ラムダ式 `->x{self[x]}` の挙動からの推測
  - 候補：Ruby標準仕様ドキュメント / mruby REPLでの実行検証
- **C-116**: 空Hash同士の `merge!` は境界値として追加したが、既存テストで直接検証されていない
  - 候補：手動テスト / mruby REPLでの実行検証
- **C-117**: `fetch_values` の引数なし呼び出しは、Rubyの可変長引数(`*keys`)の挙動からの推測
  - 候補：Ruby標準仕様ドキュメント / mruby REPLでの実行検証

## 5) リスクフラグ（レビュー観点）
- **0 (低リスク)**: 大部分のテストケースはソースコード(C実装/Ruby実装)と既存テストコード(test/hash.rb)に直接的な根拠がある
- **1 (中リスク)**: to_procメソッドのテストケース(C-101〜C-103)は既存テストが存在しないため、実行時の挙動確認が推奨される
- **0 (低リスク)**: 比較演算子(<, <=, >, >=)のTypeError発生テスト(C-074, C-078, C-082, C-086)はコード上の`raise TypeError`から根拠十分だが、既存テストに含まれていないため確認推奨
- **0 (低リスク)**: 境界値テスト(空Hash対応)はコードロジックからの論理的推論に基づく

## 6) レビュアーチェックリスト（最小）
- [ ] C-024: `Hash[[[key]]]` (要素1つの配列)の挙動が実装通りか確認
- [ ] C-101〜C-103: `to_proc` の実行時挙動をmruby REPLで確認
- [ ] C-074, C-078, C-082, C-086: 比較演算子のTypeError発生をmruby REPLで確認
- [ ] C-116: 空Hash同士のmerge!の挙動を確認
- [ ] C-117: fetch_values引数なしの挙動を確認
- [ ] 全体: テストID(UT-HSH-001〜120)の連番に欠番がないことを確認
- [ ] 全体: 対象ファイルパスがリポジトリ内の実際のファイルと一致することを確認
