OCamlでBDDを行うライブラリを作ってみた

社会人になって早7年目、やっと昇給という事象を経験できそうです。こんだけやって給料上がらんかったら転職した方がいいよ、と言われてますが、万が一上がらんかったらまた転職活動しないとならんのかな・・・。しんどいな。

さて、そんな身の回りのことはどうでもいいのですが、OCamlでちまちま色々なものを作ったりしています。ちまちますぎて何もできあがってないのが悲しいです。
そんな中で、とりあえず利用できるかなー、というくらいまできて、自分で利用したりしてみているライブラリがあります。

https://github.com/derui/simplespec

名前は気にしないでください。

作った動機

ぶっちゃけると
https://github.com/andrenth/ospec

これをめっちゃ参考にしています。というか基本的なコード部分はかなりクローンしていますが・・・。

ただし、個人的にインデントとかtuaregで上手い具合になってくれないと困る場面が多々あったので、文面を変えてあるのと、specのrunnerに、ocamlfindの機能を取り込んで、packageを利用している場合でもちゃんと実行できるようにしたりしています。
現在の機能としては非常に少なく、以下の機能しかないです。

  • describe/itでのテスト記述
  • before/afterやbeforeEach/afterEachとかでセットアップとかクリーンアップとかの処理ができるように
  • pendingとして、あとで書くテストを明示できるように
  • そこそこのパターンのmatcherを用意
  • コンパイルしないと動作が難しいようなものでも、コンパイルさせて動作させられるように
    • この辺はもうちょっとなんとかしたいです。

ospecでは、こんなものは当然、という感じで、さらにHaskellでいうQuickCheck相当の機能まで取り込んでいるようです。

作っている間に学んだこと

Camlp4は(慣れれば)よくわからないなりになんとかなる。

なんじゃそりゃ、という感じではありますが、実際そんな感じです。どうしてもわかんなかったら、やたらと複雑なCamlp4のソースを眺めてれば、何となくな書き方はわかった気になります。

それとToplevelは面白いです。こういうもの以外での用途が私の頭では思い浮かびませんが、もっと便利な利用方法はあるんでしょう、多分。

実際どんな感じになるのか

shouldの一部機能を使うとこんな感じ。

describe "The number one" begin
  it "shoud to be implement late" pending;
  it "should equal 2 when added to itself" begin
    (1 + 1) should = 2;
    let eq = (=) in
    (1 + 1) should eq 2;
    let eq x = (=) 2 x in
    (1 + 1) should eq;
  end;

  it "should equal 0 when subtract to itself" begin
    (1 - 1) should = 0;
    1 should (fun x y -> (1 - x) = y) 0;
    1 should (fun x -> (1 - x) = 0);
  end
end

shouldにはパターンマッチを書いて、そのパターンにマッチしなかったらアウト、とかもできます(ちょっと怪しいですが)。

まとめ

Camlp4の可能性は半端ない。そして難易度も半端無い。

でもOCamlDSLを書きたい人とか、メタプログラミングしたかったら必携なので、そういう場合はあきらめて格闘しましょう。