仕様が MRI と Rubinius で異なる場合の spec ファイルの書き方

SyntaxError のように仕様が MRI と Rubinius で異なる場合、spec ファイルの書き方には注意が必要である。

一般的には、次のように書いてしまいがちだ。

if defined?(RBX_VERSION)    # Rubinius のとき
  ... test code ...
else                        # そうでないとき
  ... test code ...
end


しかしこれは Rubinius ではしてはいけない。かわりに、次のように書く。

extended_on :rubinius do  # Rubinius のとき
  ... test code ...
end
fails_on :rubinius do     # Rubinis 以外のとき
  ... test code ...
end


extend_on() は、引数に指定されたターゲットのときだけブロックを実行する。fails_on() はその逆で、指定されたターゲット以外のときだけブロックを実行する。ターゲット名は複数指定でき、たとえば「extended_on :ruby, :jruby」と書けば MRIJRuby のときだけブロックが実行される。

これらは mspec/runner/guards.rb で定義されているるので、詳細を知りたい方はどうぞ。