Bacon さん before/after 問題を解決するパッチを送りました

以前書きました「Bacon さん before/after」の問題を解決するパッチを作者さんに送ってみました。なんだか微妙にごちゃごちゃした修正になってしまったのですが、一応RSpecと動作を同じにしようと思ったらこうなってしまったので仕方ないかなぁ、と思います。もっと良い書き方があるかなぁ。

diff -rN old-bacon/lib/bacon.rb new-bacon/lib/bacon.rb
142,144c142,155
<           @before.each { |block| instance_eval(&block) }
<           instance_eval(&spec)
<           @after.each { |block| instance_eval(&block) }
---
>           begin
>             @rescued = false
>             @before.each { |block| instance_eval(&block) }
>             instance_eval(&spec)
>           rescue Object => e
>             @rescued = true
>             raise e
>           ensure
>             begin
>               @after.each { |block| instance_eval(&block) }
>             rescue Object => e
>               raise e unless @rescued
>             end
>           end

動作例

describe "fail in before" do
  before do
     puts "\n*** before ***"
     raise "before"
  end

  after do
     puts "*** after ***"
  end

  it "should be true" do
     true.should.be.true
  end
end

describe "fail in spec" do
  before do
     puts "\n*** before ***"
  end

  after do
     puts "*** after ***"
  end

  it "should fail" do
     true.should.be.false
  end
end

以上のspecファイルを例とします。

まず、Bacon-0.9では次のような結果になり、afterが呼び出されていないのが分かります。

fail in before
- should be true
*** before ***
 [ERROR: RuntimeError]

fail in spec
- should fail
*** before ***
 [FAILED]

パッチを適用した場合は次のような結果になり、afterが呼び出されているのが分かります。

fail in before
- should be true
*** before ***
*** after ***
 [ERROR: RuntimeError]

fail in spec
- should fail
*** before ***
*** after ***
 [FAILED]

てな感じで、いかがでしょうか。

追記

取り込まれました、でも修正あり。@rescued はダメだよね確かに。うーん気をつけよう。