ActiveSupport::Duration のエッジケースに対するテストカバレッジ追加
このPRは、ActiveSupport::Duration の未テストだった挙動を網羅する新しいテストを追加し、既存ドキュメントと実装の整合性を保証します。テストのみの追加で本番コードに変更はなく、将来的なリグレッション防止が期待されます。
背景
既存テストでは ActiveSupport::Duration の主要機能は網羅されていたものの、いくつかのエッジケースが未確認でした。具体的には、単項マイナス演算子 -@、build メソッドの秒数分解、parts の戻り値の独立性、比較演算子 <=> の非数値オブジェクトへの挙動、coerce の Duration 引数処理がテストされていませんでした。これらは公式 RDoc に記載されているが、テストで裏付けられていないため、実装変更時に壊れやすい箇所です。PR はこれらのギャップを埋め、仕様の明示的な保証を提供します。
技術的な変更
activesupport/test/core_ext/duration_test.rb に 34 行のテストケースが追加されました。新たに導入されたテストは以下のシナリオを検証します。
-
test_unary_minus_negates_value_and_partsは-@がvalueとpartsの全要素を符号反転させることを確認します。 -
test_build_decomposes_seconds_into_partsはActiveSupport::Duration.buildが秒数を年・月・日などの部品に正しく分解することを検証します。 -
test_parts_returns_an_independent_copyは#partsが内部ハッシュのコピーを返し、外部で変更しても元の Duration が変化しないことを保証します。 -
test_compare_returns_nil_for_an_incomparable_objectは#<=>が Duration でも数値でもないオブジェクトに対してnilを返すことを確認します。 -
test_coerce_with_a_durationは#coerceが Duration 引数に対してScalarインスタンスと元の Duration を返すことをテストします。
def test_unary_minus_negates_value_and_parts
assert_equal(-86400, (-1.day).value)
assert_equal({ days: -1 }, (-1.day).parts)
assert_equal({ years: -1, days: -1 }, (-(1.year + 1.day)).parts)
assert_instance_of ActiveSupport::Duration, -1.day
end
def test_build_decomposes_seconds_into_parts
assert_equal({ years: 1 }, ActiveSupport::Duration.build(31556952).parts)
assert_equal({ months: 1, days: 1 }, ActiveSupport::Duration.build(2716146).parts)
assert_equal 2716146, ActiveSupport::Duration.build(2716146).value
end
def test_parts_returns_an_independent_copy
duration = 5.minutes
parts = duration.parts
parts[:minutes] = 99
assert_equal({ minutes: 5 }, duration.parts)
end
def test_compare_returns_nil_for_an_incomparable_object
assert_nil(1.day <=> "foo")
end
def test_coerce_with_a_duration
one_minute = 1.minute
scalar, duration = one_minute.coerce(2.hours)
assert_instance_of ActiveSupport::Duration::Scalar, scalar
assert_equal 7200, scalar.value
assert_same one_minute, duration
end
テスト追加に伴う本番コードの変更はありません。既存のテストスイートに新しいケースが組み込まれ、CI 上で自動的に検証されます。これにより、ActiveSupport::Duration の振る舞いがドキュメント通りであることが継続的に保証されます。
設計判断
テストのみを追加する方針は、既存実装の意図を変更せずに信頼性を向上させることを目的としています。PR の議論では実装の修正や API の拡張は不要と判断され、まずは未カバーの仕様をテストで固める方針が取られました。これは Rails コアチームが「テストで仕様を明文化」する慣行に沿った選択であり、将来的なリファクタリングやパフォーマンス改善時に安全な基準を提供します。エッジケースをテストで保護することで、コードベース全体の回帰リスクが低減します。
まとめ
ActiveSupport::Duration の未テストだったエッジケースに対するテストが追加され、ドキュメントと実装の整合性が検証可能となりました。テストのみの変更でありながら、今後の開発における品質保証の基盤を強化しています。