Ruby 4.1 のエラーメッセージ変更に対応した比較バリデーションのテスト修正

rails/rails

Ruby 4.1.0dev での比較エラーメッセージの文言変更により壊れていた CI テストを、正規表現マッチングに切り替えることで修正しました。

背景

Rails Nightly CI が Ruby 4.1.0dev 環境で test_validates_comparison_of_incomparables に失敗するようになりました。原因は Ruby 本体のエラーメッセージ変更にあり、Rails 側のテストが特定の文字列に完全一致していたことで、その変更を検知できなくなっていました。

問題のある比較(IntegerString の比較)を実行したとき、Ruby 4.1.0dev では以下のようにメッセージの末尾に詳細な理由が付加されるようになっています。

# Ruby ~4.0
"comparison of Integer with String failed"

# Ruby 4.1.0dev
"comparison of Integer with String failed: coercion was not possible"

このメッセージ変更は ruby/ruby#16321 で導入されました。同 PR では Array#sort などで nil が比較値として返った際に「comparison of String with String failed」という誤解を招くメッセージが出る問題を改善するため、rb_cmperr に理由文字列を付加する仕組みが追加されています。これにより「coercion was not possible」や「comparator returned nil」といった追加情報が末尾に付くようになりました。

技術的な変更

変更は activemodel/test/cases/validations/comparison_validation_test.rb の 2 箇所のみで、完全一致を正規表現の前方一致に置き換えています。

変更前:

assert_invalid_values([12], "comparison of Integer with String failed")

変更後:

assert_invalid_values([12], /\Acomparison of Integer with String failed/)

あわせて、assert_invalid_values ヘルパー内部のアサーションも assert_equal から assert_match に変更されています。

変更前:

assert_equal error, topic.errors[:approved].first if error

変更後:

assert_match error, topic.errors[:approved].first if error

assert_match は引数に文字列を渡すと include? 相当の部分一致、正規表現を渡すと =~ によるマッチを行います。正規表現 /\Acomparison of Integer with String failed/\A は文字列先頭を意味するため、メッセージの書き出しが正しい形式であることを検証しつつ、末尾の追加情報には非依存になります。

設計判断

エラーメッセージの検証を「先頭一致」に緩和する方針 が採用されました。

完全一致から単なる部分一致(include?)に緩和することもできますが、正規表現の \A アンカーを使うことで「正しいエラーの種別を表すプレフィックスで始まる」という意味のある制約を維持しています。また、assert_invalid_values ヘルパーが error 引数として文字列と正規表現の両方を受け取れるよう assert_match に統一されており、将来のテスト追加時にもいずれの型でも渡せる柔軟性が生まれています。

まとめ

この修正は Ruby 本体の改善(エラーメッセージへの理由付加)を Ruby バージョン間で吸収するための最小限の対応です。正規表現の \A アンカーによる前方一致を採用することで、テストの意図(Integer と String の比較失敗を検出すること)を損なわずに Ruby 4.1 以降への追従が実現されています。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
42b93f40

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ OK

Title, Context, Technical Detailの存在と明確さ

カスタムMarkdown構文 ✓ OK

シンタックスハイライト・GitHubリンク記法の正確性

対象読者への適合性 ✓ OK

エンジニア向けの適切な技術レベルと表現

パラグラフ・ライティング ✓ OK

トピックセンテンス・1段落1トピック・段落長

Diff内容との照合 ✓ OK

コードブロックとDiff内容の一致

技術用語の正確性 ✓ OK

技術用語の正確な使用

説明の技術的正確性 ✓ OK

技術的主張の正確性と論理性

事実の突合 ✓ OK

PR情報による主張の裏付け(ハルシネーション検出)

数値・固有名詞の確認 ✓ OK

PR番号・コミットID・バージョン等の正確性

タイトル・説明との一致 ✓ OK

記事タイトル・説明とPR内容の一致

外部知識の正確性 ✓ OK

PRに記載のない外部知識(LTS、サポート状況など)の不使用

時間表現の正確性 ✓ OK

時間表現がPR情報と一致しているか