ruby 1.9 の gem でのインストール時に test を行うとエラーが記録される。
はじめに
ruby 1.9 向けのアプリケーション(Google Code Archive - Long-term storage for Google Code Project Hosting.)を開発している。
そろそろリリースしようと思って、gem を作成してインストールを試した。インストールがうまくいったので、test もやってみようと思ったら、エラーが発生したので、原因を調査し、対応する。
ragdoll$ gem19trunk install --test pkg/s7-0.0.1.gem (以下、実際の実行結果) Successfully installed s7-0.0.1 1 gem installed Installing ri documentation for s7-0.0.1... Updating class cache with 1339 classes... Installing RDoc documentation for s7-0.0.1... :0:Warning: Gem::SourceIndex#search support for String patterns is deprecated Loaded suite /Users/kouji/local/bin/gem19trunk Started ................ Finished in 0.328068 seconds. 16 tests, 1353 assertions, 0 failures, 0 errors, 0 skips ERROR: While executing gem ... (NoMethodError) undefined method `passed?' for #<MiniTest::Unit:0x17a6b78> ragdoll$ gem19trunk install --debug --test pkg/s7-0.0.1.gem --no-ri --no-rdoc (以下、実際の実行結果) Exception `NoMethodError' at /Users/kouji/local/lib/ruby19trunk/1.9.1/rubygems/commands/install_command.rb:136 - undefined method `passed?' for #<MiniTest::Unit:0x77d1fc> ERROR: While executing gem ... (NoMethodError) undefined method `passed?' for #<MiniTest::Unit:0x77d1fc> /Users/kouji/local/lib/ruby19trunk/1.9.1/rubygems/commands/install_command.rb:136:in `block in execute' /Users/kouji/local/lib/ruby19trunk/1.9.1/rubygems/commands/install_command.rb:133:in `each' /Users/kouji/local/lib/ruby19trunk/1.9.1/rubygems/commands/install_command.rb:133:in `execute' /Users/kouji/local/lib/ruby19trunk/1.9.1/rubygems/command.rb:136:in `invoke' /Users/kouji/local/lib/ruby19trunk/1.9.1/rubygems/command_manager.rb:105:in `process_args' /Users/kouji/local/lib/ruby19trunk/1.9.1/rubygems/command_manager.rb:75:in `run' /Users/kouji/local/lib/ruby19trunk/1.9.1/rubygems/gem_runner.rb:39:in `run' /Users/kouji/local/bin/gem19trunk:24:in `<main>'
原因の調査と対応
バックトレースから lib/rubygems/commands/install_command.rb の 136 行目付近で例外が発生していることが分かる。問題は以下の部分である。result は MiniTest::Unit のインスタンスである。MiniTest::Unit には passed? は存在しない。
if result and not result.passed?
MiniTest::Unit#run の戻り値から、MiniTest::Unit の passed? としては以下がふさわしいと思う。
module MiniTest ... class Unit ... def passed? return (failures + errors) == 0 end ... end ... end
なお、この問題の対応方法として、RubyGems を修正し、MiniTest を修正しない方法もあるだろう。しかし、TestUnit で public だったメソッドは MiniTest に追加してもいいのではないかと考えた。
この問題の対象は、ruby 1.9.1-p0 と trunk の r21924。問題が修正されるまでは r21924 以降のリビジョンでも問題は発生する。
不具合の報告
これから Redmine と ruby-core ML に報告する。英語での報告は緊張する。
たぶん、以下の部分をうまく英語にできないだろう。Ryan が 「MiniTest は悪くない。RubyGems をなおせよ!!」って言ってきたらどうしよう。
なお、この問題の対応方法として、RubyGems を修正し、MiniTest を修正しない方法もあるだろう。しかし、TestUnit で public だったメソッドは MiniTest に追加してもいいのではないかと考えた。
まとめ
ruby 1.9.1-p0 と現在(r21924) の trunk において、gem のインストール時に test を行うと、以下のようなエラーメッセージを記録する。
ERROR: While executing gem ... (NoMethodError)
undefined method `passed?' for #
この問題は、以下のパッチで対応できる。
Index: unit.rb =================================================================== --- unit.rb (revision 21924) +++ unit.rb (working copy) @@ -429,6 +429,10 @@ [@test_count, @assertion_count] end + def passed? + return (failures + errors) == 0 + end + class TestCase attr_reader :name
早く対応されることを望む。