HashWithIndifferentAccess の未テスト分岐にテストカバーを追加
この PR は HashWithIndifferentAccess の fetch、values_at、dig、except/without に関する未テストのコードパスに対し、テストケースを新たに追加した点が主な変更です。テストのみの追加でプロダクションコードには一切影響しません。
背景
既存のテストスイートは HashWithIndifferentAccess の基本機能を網羅していましたが、ドキュメントで記述されている一部の挙動(fetch のデフォルト値やブロック、values_at の欠損キー処理、dig の欠損キー返却、except/without の不変性)はテストが欠如していました。これにより実装変更時に回帰リスクが見えにくくなるという課題がありました。PR #57689 はそのギャップを埋め、将来の変更がドキュメントと食い違った際に CI が検出できるようにすることを目的としています。
技術的な変更
テストファイル activesupport/test/hash_with_indifferent_access_test.rb に 4 つのテストメソッド が追加されました。各メソッドは対象メソッドの未検証パスを明示的に確認します。
def test_indifferent_fetch_with_default_and_block
hash = HashWithIndifferentAccess.new
hash[:foo] = 1
assert_equal 0, hash.fetch(:bar, 0)
assert_equal 1, hash.fetch(:foo, 99)
assert_equal "bar", hash.fetch(:bar) { |key| key }
end
このテストは fetch が デフォルト値を返す ケース、ブロックが変換された文字列キーを受け取る ケース、そして余分な引数 *extras が透過的に扱われることを検証します。
def test_indifferent_values_at_with_missing_key
hash = HashWithIndifferentAccess.new
hash[:a] = "x"
hash[:b] = "y"
assert_equal ["x", nil, "y"], hash.values_at(:a, :c, "b")
end
ここでは values_at が存在しないキーに対して nil を返す 挙動を確認し、fetch_values との違いを明示します。
def test_indifferent_dig_returns_nil_for_missing_key
data = { foo: { bar: 1 } }.with_indifferent_access
assert_nil data.dig(:zoo)
assert_nil data.dig(:foo, :missing)
end
このテストは dig が第一階層・第二階層ともに欠損キーを指定された場合に nil を返す ことを保証します。
def test_indifferent_except
original = { a: "x", b: "y", c: 10 }.with_indifferent_access
assert_equal({ c: 10 }.with_indifferent_access, original.except(:a, "b"))
assert_instance_of HashWithIndifferentAccess, original.except(:a)
assert_equal({ a: "x", b: "y", c: 10 }.with_indifferent_access, original)
assert_equal({ c: 10 }.with_indifferent_access, original.without(:a, :b))
end
このテストは except とエイリアス without が新しい HashWithIndifferentAccess オブジェクトを返し、元ハッシュを変更しないこと、さらにシンボル・文字列キーの混在を許容することを検証します。
設計判断
PR のアプローチは テストコードのみを追加 する点に特徴があります。実装ロジック自体は変更せず、既存の公開インターフェースをそのまま利用して期待動作を明示的に記述しています。そのため後方互換性への影響はゼロであり、リリース時のリスクは極めて低いです。テストカバレッジの向上という目的に対し、最小限の変更で最大の安全性を確保した設計判断と言えます。
まとめ
この変更により HashWithIndifferentAccess の未テスト領域が 4 つのテスト でカバーされ、ドキュメントに記載された振る舞いが自動的に検証されるようになりました。プロダクションコードはそのままで、将来的な実装変更が期待通りであることを CI が保証できるようになった点が最大の価値です。