ちなみに

火曜日の空は僕を押しつぶした。

mini/specがひどい

require 'mini/spec'

Mini::Test.autorun

class Stack
  def empty?
    true
  end
end

describe Stack do
  before do
    @stack = Stack.new
  end

  it 'should be empty' do
    @stack.empty?.must_equal true
  end
end

これ動きません。
何がおかしいか分かりますか?
とりあえずエラーメッセージを見てみましょう。

/opt/local/lib/ruby/site_ruby/1.8/mini/spec.rb:53: warning: already initialized constant Stack
Loaded suite test
Started
E
Finished in 0.001480 seconds.

  1) Error:
test_should_be_empty(Stack):
ArgumentError: wrong number of arguments (0 for 1)
    test.rb:13:in `initialize'
    test.rb:13:in `new'
    test.rb:13:in `setup'
    /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:381:in `run'
    /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:363:in `run_test_suites'
    /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:358:in `each'
    /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:358:in `run_test_suites'
    /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:357:in `each'
    /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:357:in `run_test_suites'
    /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:337:in `run'
    /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:289:in `autorun'
    test.rb:11

1 tests, 0 assertions, 0 failures, 1 errors

これで分かったでしょうか?
僕はわかりませんでした。


実は犯人はdescribeで、Stackという定数を引数に与えていますが、これを内部で

module Kernel
  def describe desc, &block
    cls = Class.new(Mini::Spec)
    Object.const_set desc.to_s.split(/\W+/).map { |s| s.capitalize }.join, cls

    cls.class_eval(&block)
  end
end

という風に、Mini::Specの子クラスにしてしまっている(あってる?)ので、beforeの中ではMini::Spec::Stack.newを呼んでいることになって、上で定義したStackにはinitializeが無いので、superclassであるSpecのinitializeを見に行って、引数が足りないことになるのでエラーになってしまっています。
これは結構致命的なのではないでしょうか?


そもそも以下のコードが動きません。

require 'mini/spec'

Mini::Test.autorun

describe Array do
  it 'I wanna make array....' do
    Array.new
  end
end