Opalはいかにしてrubyspecをいい感じにアレしているのか
OpalはJavaScriptで書かれたRuby処理系です。OpalではArray#findといった組み込みライブラリもJavaScriptで再実装しているので、テストが膨大な数になりそうですが、そのあたりはどうしているのでしょうか。
ruby/spec
Rubyにはruby/specというテストスイートがあります。これは、CRubyやJRubyなど複数の処理系間で挙動を揃えるために作られたものです。READMEにあるようにもとはRubySpecという名前でしたが、現在はThe Ruby Spec Suiteというのが正式名称になっています(が、カジュアルには今でもrubyspecといえばこのruby/specを指すことが多いようです)。
Opalはこのrubyspecをテストとして使うことで、テストを0から書く手間を省きつつ、他の処理系との互換性を担保しています。
Opalとrubyspec
とはいえrubyspecはCRubyやJRubyをターゲットに作られたものなので、Opalでは動かせないものも含まれています。例えばOpalにないものの一つとして、String#gsub!が挙げられます。Opalでは文字列を使ったプログラムはJavaScriptの文字列をそのまま使うように変換されます(多分速度のため)。しかしJavaScriptの文字列はimmutableなので、gsub!のような破壊的なメソッドはサポートできません。
Opalではspec/filters/unsupported以下にサポートしない機能の一覧があり、ここに書かれたテスト項目については実行がスキップされるようになっています。
bugs
spec/filters以下にはもう一つ、bugsというディレクトリがあります。バグ、というよりは既知の未実装機能がここに含まれており、このコミットのように実装が終わったものは消していくという形になっています。
これにより、未実装の機能でテストが落ちまくるのが回避されており、かつこれから作業が必要なものの一覧を明確にするのにも役立っています。Opalに何かコントリビュートしたいという人は、bugsの中から実装できそうなものを見つけるというのも手です。
まとめ
- Opalはrubyspecを使っている
- rubyspecを全て実装するのは大変だが、「通らないもの」のリストを事前に用意することで「テストが全て通る」状態を維持したまま開発できるようになっている