RSpecをTest::Baseっぽく使う
RSpecでテストを書いていて単純なテストなんだけど、いろいろなデータで検証させたいといった場合に毎度毎度exampleを書くのがめんどくさいと思い、こんな感じでTest::Baseっぽく使えるやつを作ってみた。
describe Point, "detect_location" do with_fixtures :point => :location do filters({ :point => lambda { |val| Point.new(*val) }, :location => :to_s, }) it "should detect point :point to :location (:msg)" do |point, location| point.detect_location.should == location end set_fixtures([ [ [1, 0] => :right ], [{[-1, 0] => :left }, "border" ], [{[-0.5,0] => :left }, "inner" ], [ [0, 1] => :top ], [ [0, -1] => :bottom ], ]) end end
実行結果はこんな感じになる
Point detect_location - should detect point ( 1, 0 ) to right () (FAILED - 6) - should detect point ( -1, 0 ) to left (border) (FAILED - 7) - should detect point ( -0.5, 0 ) to left (inner) (FAILED - 8) - should detect point ( 0, 1 ) to top () (FAILED - 9) - should detect point ( 0, -1 ) to bottom () (FAILED - 10) 6) 'Point detect_location should detect point ( 1, 0 ) to right ()' FAILED expected: "right", got: "unknown" (using ==) ./examples/detect_location_spec.rb:47: 7) 'Point detect_location should detect point ( -1, 0 ) to left (border)' FAILED expected: "left", got: "unknown" (using ==) ./examples/detect_location_spec.rb:47: 8) 'Point detect_location should detect point ( -0.5, 0 ) to left (inner)' FAILED expected: "left", got: "unknown" (using ==) ./examples/detect_location_spec.rb:47: 9) 'Point detect_location should detect point ( 0, 1 ) to top ()' FAILED expected: "top", got: "unknown" (using ==) ./examples/detect_location_spec.rb:47: 10) 'Point detect_location should detect point ( 0, -1 ) to bottom ()' FAILED expected: "bottom", got: "unknown" (using ==) ./examples/detect_location_spec.rb:47:
with_fixturesの引数は省略すると{ :input => :expected }がデフォルトで使われる。
実はHashである必然性は全然ないのだけど、こう書けた方が視覚的にわかりやすいのでこう書くようにした。
filterは値がProcの場合はそれが実行され、Procじゃない場合は順番に__send__されて適用するようにしてみた。この辺は使ってみてまだ色々変わったりとかしそう。
set_fixturesで渡すデータをTest::Base互換で書けるようにするとか、exampleを複数書けるようにするとか、exampleがinput.should == expectedになるときは省略して書けるようにするとか、まだ色々やろうかなと思うことはあるのでgemにはしてないです。
いつものようにCodereposに入れてあるので色々アドバイスなり、いただけるとありがたいです。
http://coderepos.org/share/browser/lang/ruby/rspec-fixture/trunk