haml/haml-spec — pull request #6 by mattwildig (2012-06-13 03:02:22+00:00)
Title: Use minitest rather than test/unit

Whilst trying to track down the cause of a warning that’s crept into the Haml tests (with Gemfiles for Rails 3.0 and 3.1), I started looking at the backtraces of the test involved (`TemplateTest#test_form_builder_label_with_block`), where I noticed something rather odd:

```
/Users/matt/.rvm/gems/ruby-1.9.3-p194/gems/minitest-3.0.1/lib/minitest/unit.rb:1068:in `run'
/Users/matt/.rvm/gems/ruby-1.9.3-p194/gems/minitest-3.0.1/lib/minitest/unit.rb:833:in `block in _run_suite'
/Users/matt/.rvm/gems/ruby-1.9.3-p194/gems/minitest-3.0.1/lib/minitest/unit.rb:825:in `map'
/Users/matt/.rvm/gems/ruby-1.9.3-p194/gems/minitest-3.0.1/lib/minitest/unit.rb:825:in `_run_suite'
/Users/matt/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/test/unit.rb:565:in `block in _run_suites'
/Users/matt/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/test/unit.rb:563:in `each'
/Users/matt/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/test/unit.rb:563:in `_run_suites'
/Users/matt/.rvm/gems/ruby-1.9.3-p194/gems/minitest-3.0.1/lib/minitest/unit.rb:785:in `_run_anything'
/Users/matt/.rvm/gems/ruby-1.9.3-p194/gems/minitest-3.0.1/lib/minitest/unit.rb:974:in `run_tests'
/Users/matt/.rvm/gems/ruby-1.9.3-p194/gems/minitest-3.0.1/lib/minitest/unit.rb:961:in `block in _run'
/Users/matt/.rvm/gems/ruby-1.9.3-p194/gems/minitest-3.0.1/lib/minitest/unit.rb:960:in `each'
/Users/matt/.rvm/gems/ruby-1.9.3-p194/gems/minitest-3.0.1/lib/minitest/unit.rb:960:in `_run'
/Users/matt/.rvm/gems/ruby-1.9.3-p194/gems/minitest-3.0.1/lib/minitest/unit.rb:949:in `run'
/Users/matt/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/test/unit.rb:21:in `run'
/Users/matt/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/test/unit.rb:326:in `block (2 levels) in autorun'
/Users/matt/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/test/unit.rb:27:in `run_once'
/Users/matt/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/test/unit.rb:325:in `block in autorun'
```

Hmm, I thought, control shouldn’t be passing back and forth between the minitest gem and the standard library like this, what could be happening. A little further investigation, I found [this rather suspicious looking line](https://github.com/haml/haml/commit/ea8b22f250c2a93a5474aee18746ce54df8e52ea#diff-5) in `test_helper.rb`:

require 'test/unit' # On JRuby, tests won't run unless we include this. WTF?

WFT indeed. Surely we’re using minitest, and we don’t need test/unit at all, JRuby or not? Since test/unit on Ruby 1.9.3 actually _is_ minitest (in a clever disguise), perhaps this could explain the promiscuous switching between the minitest gem and the standard library.

Now something occurred to me — I don’t use JRuby, but isn’t it by default 1.8.7 compatible, and only pretends to be 1.9 if you explicitly tell it to do so? A quick bit of RVM-ing confirmed my hunch — it’s not only JRuby where the tests don’t run, but MRI Ruby 1.8.7 too. And of course, test/unit in 1.8.7 is completely different from minitest. Aha! Now we’re getting somewhere.

This would also explain that odd feature when running the Haml tests under 1.8.7 where it [looks like there are _two_ test suites being run](https://gist.github.com/2921460), because of course there _are_ two suites being run, a minitest one and a test/unit one. Until now I had put it down to a quirk of minitest on 1.8.7, and thought it odd but hadn’t really looked into it.

Let’s have [a look at minitest](https://github.com/seattlerb/minitest) then, to see if we can get to the root of this. What’s this? In [`minitest/unit.rb`](https://github.com/seattlerb/minitest/blob/2edf3f33b6e382bc0adb75a88bdbf2880f29f8ee/lib/minitest/unit.rb#L1306-1317) there’s a little bit of code that checks for test/unit and minitest being loaded at the same time. Sure enough, `RUBYOPT=-debug rake test` produces (along with a bunch of other stuff):

/Users/matt/.rvm/gems/ruby-1.8.7-p358/gems/minitest-3.0.1/lib/minitest/unit.rb:1322:in `inherited': Using minitest and test/unit in the same process: HamlTest (RuntimeError)
from /Users/matt/projects/haml/test/haml-spec/ruby_haml_test.rb:6

So, it’s haml-spec that’s the culprit! The cad! His requiring of test/unit appears to be making `at_exit` handlers step all over each other. Time to put a stop to his antics.

And so here we are, bringing an unruly submodule into line by making it use minitest like the rest of Haml. After this we can delete the `require 'test/unit'` line from `test_helper.rb` in Haml itself.

(Alternatively we could separate the haml-spec tests in Haml itself from the other tests and run them as an explicitly separate test run if you want to keep the dependencies down in haml-spec.)

(commit message below)

Ruby Haml uses minitest as its test runner, and incorporates haml-spec
into its tests. Combining test/unit and minitest in the same process
is problematic and causes several problems.