String フィルターメソッドの境界ケーステストを追加
String クラスのフィルターメソッド (remove, remove!, truncate_words) に対し、未テストだった no‑op と境界入力を検証するテストが追加されました。これにより、期待通りの挙動が保証された状態で将来の変更に備えることができます。
背景
既存のテストは、パターンが一致した場合や正の単語数での truncate_words のみを対象としていました。その結果、パターン未指定や truncate_words に 0・負数を渡した時の挙動はテストされず、潜在的なリグレッションが残っていました。今回の PR は、これらの 境界条件 と no‑op ケース を明示的にテスト対象に加えることで、未検証領域を埋めることを目的としています。
この背景は、activesupport/lib/active_support/core_ext/string/filters.rb に実装されたロジックが既に正しい動作を行っているものの、テストスイートで保証されていなかった点にあります。境界値テストの欠如は、将来的なリファクタリングやバグ修正時に意図しない挙動変化を検出しにくくするリスクがあります。
技術的な変更
テストファイル activesupport/test/core_ext/string_ext_test.rb に 25 行の追加が行われました。主な追加テストは次のとおりです。
def test_truncate_words_with_zero_count
assert_equal "Hello Big World", "Hello Big World".truncate_words(0)
assert_equal "Hello Big World", "Hello Big World".truncate_words(0, omission: "[...]")
end
def test_truncate_words_with_negative_count
assert_equal "Hello Big World", "Hello Big World".truncate_words(-1)
end
これらは 0 または負の単語数 を渡した場合に元文字列がそのまま返ることを確認します。
def test_remove_with_no_patterns_returns_unchanged_copy
original = "This is a good day to die"
result = original.remove
assert_equal original, result
assert_not_same original, result
end
def test_remove_bang_with_no_patterns_returns_self
original = +"This is a good day to die"
result = original.remove!
assert_equal "This is a good day to die", result
assert_same original, result
end
remove はパターン未指定時に コピー を返し、remove! は 同一オブジェクト を返すことを検証します。いずれのテストもプロダクションコードの変更を伴わず、テストスイートの網羅性を高めるだけの追加です。
設計判断
テストだけを追加するという選択は、機能的な変更を避けつつ品質を向上させるという設計方針に沿っています。PR 内の議論は見当たりませんが、既存実装が正しいことを前提に、境界条件のテストだけを導入することで、リファクタリング時の安全性を高める姿勢が伺えます。
このアプローチは、後方互換性に影響を与えず、テストカバレッジを拡張する点でリスクが低く、継続的インテグレーションの信頼性向上に直結します。実装コードの変更が不要なため、デプロイやランタイムへの影響はゼロです。
まとめ
本 PR は、String フィルターメソッドの 境界ケースと no‑op 動作 をテストで明文化し、未検証領域を除去しました。コード自体は変更せず、テストスイートのみ拡張することで、将来の変更に対する安全マージンを提供します。