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:833:in `block 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/gems/ruby-1.9.3-p194/gems/minitest-3.0.1/lib/minitest/unit.rb:961:in `block 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: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 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, 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 then, to see if we can get to the root of this. What’s this? In minitest/unit.rb 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):
RUBYOPT=-debug rake test
/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)
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.
Use minitest rather than test/unit
Yeah, the double running on 1.8.7 was annoying me and I was considering doing this, I think it's a good idea. Let's also update the README, which makes reference to test/unit but that won't be the case after this merge.
Is the comment about JSON on 1.8.7 in the README still applicable? Everything seems to run okay for me.
No, actually - at this point I don't even remember what the problem was, it was a long time ago. Works fine for me too.