lib/minitest/unit.rb へのパッチ
ruby 1.9 を利用しており Rake を使用してテストしている。
以下、使用している Rakefile。
require "rake" require "rake/testtask" Rake::TestTask.new do |t| t.libs << "lib" t.libs << "test" t.test_files = FileList["test/**/*_{helper,test}.rb"] end task :default => :test
test ディレクトリ以下に require に失敗するスクリプトがある場合、次のような例外が発生した。
ragdoll$ rake19trunk
(in /Users/kouji/work/s7)
/Users/kouji/local/lib/ruby19trunk/1.9.1/minitest/unit.rb:328:in `block in autorun': unexpected return (LocalJumpError)
/Users/kouji/work/s7/test/s7/secret_generator_test.rb:3:in `require': no such file to load -- s7/secret_generator (LoadError)
from /Users/kouji/work/s7/test/s7/secret_generator_test.rb:3:in `<top (required)>'
from /Users/kouji/local/lib/ruby19trunk/1.9.1/rake/rake_test_loader.rb:5:in `load'
from /Users/kouji/local/lib/ruby19trunk/1.9.1/rake/rake_test_loader.rb:5:in `block in <main>'
from /Users/kouji/local/lib/ruby19trunk/1.9.1/rake/rake_test_loader.rb:5:in `each'
from /Users/kouji/local/lib/ruby19trunk/1.9.1/rake/rake_test_loader.rb:5:in `<main>'
rake aborted!
Command failed with status (1): [/Users/kouji/local/bin/ruby19trunk -Ilib:l...]
(See full trace by running task with --trace)上記のうち、以下が余計だと思う。原因を調べ、解決する。
/Users/kouji/local/lib/ruby19trunk/1.9.1/minitest/unit.rb:328:in `block in autorun': unexpected return (LocalJumpError)
上記の例外が発生したソースは以下。例外が発生した($! が nil でない)場合、処理を中断したいという意図だと思われる。ここは return ではなく、next がよいと思う。
def self.autorun at_exit { return if $! # don't run if there was an exception exit_code = MiniTest::Unit.new.run(ARGV) exit false if exit_code && exit_code != 0 } unless @@installed_at_exit @@installed_at_exit = true end
以下がパッチ。
Index: unit.rb
===================================================================
--- unit.rb (revision 21138)
+++ unit.rb (working copy)
@@ -325,7 +325,7 @@
def self.autorun
at_exit {
- return if $! # don't run if there was an exception
+ next if $! # don't run if there was an exception
exit_code = MiniTest::Unit.new.run(ARGV)
exit false if exit_code && exit_code != 0
} unless @@installed_at_exitこのパッチを適用した結果。
ragdoll$ rake19trunk
(in /Users/kouji/work/s7)
/Users/kouji/work/s7/test/s7/secret_generator_test.rb:3:in `require': no such file to load -- s7/secret_generator (LoadError)
from /Users/kouji/work/s7/test/s7/secret_generator_test.rb:3:in `<top (required)>'
from /Users/kouji/local/lib/ruby19trunk/1.9.1/rake/rake_test_loader.rb:5:in `load'
from /Users/kouji/local/lib/ruby19trunk/1.9.1/rake/rake_test_loader.rb:5:in `block in <main>'
from /Users/kouji/local/lib/ruby19trunk/1.9.1/rake/rake_test_loader.rb:5:in `each'
from /Users/kouji/local/lib/ruby19trunk/1.9.1/rake/rake_test_loader.rb:5:in `<main>'
rake aborted!
Command failed with status (1): [/Users/kouji/local/bin/ruby19trunk -Ilib:l...]
(See full trace by running task with --trace)これで、想定通りに動作するようになった。
あとは、ruby-core にメールを送ろう。
英語の作文をするために、述べたいことをまとめておく。
- test スクリプトの解析時にエラーが発生したときに LocalJump 例外が発生した。
- 原因は、self.autorun で指定している at_exit のブロックの中で return しているからです。
- return を next に修正してはどうか。
- 修正した結果、手元では LocalJump 例外が発生しなくなった。
メールを作成する前に、修正済みかもしれないので、 svn up をしてみよう。最近、Ryan が merge しているようだ。最新のソースでも修正されていないことが分かった。(誰も困っていないのかな?)
以下、作成したメール。(英語でメールを書くことになれていないため、いいたいことが伝わるかどうかが不安です。)
Hi Ryan,
If $! is not nil, returns in the block of the at_exit method in
MiniTest::Unit.autorun. Then raises LocalJump exception.
-----
def self.autorun
at_exit {
return if $! # don't run if there was an exception
exit_code = MiniTest::Unit.new.run(ARGV)
exit false if exit_code && exit_code != 0
} unless @@installed_at_exit
@@installed_at_exit = true
end
-----
The attached patch will fix the problem.
Index: lib/minitest/unit.rb
===================================================================
--- lib/minitest/unit.rb (revision 21508)
+++ lib/minitest/unit.rb (working copy)
@@ -325,7 +325,7 @@
def self.autorun
at_exit {
- return if $! # don't run if there was an exception
+ next if $! # don't run if there was an exception
exit_code = MiniTest::Unit.new.run(ARGV)
exit false if exit_code && exit_code != 0
} unless @@installed_at_exit
Thanks, kouji.