This post originated from an RSS feed registered with Ruby Buzz
by James Britt.
Original Post: DATA, Windows, binmode
Feed Title: James Britt: Ruby Development
Feed URL: http://feeds.feedburner.com/JamesBritt-Home
Feed Description: James Britt: Playing with better toys
A handy tool when unit testing Ruby code is to stash some test data at the very end of the test code, after the __END__ marker. You can then use the DATA file handle to grab this data for tests.
But, since DATA behaves as a regular file handle, you need to reset the file pointer prior to each read.
A reasonable, but naive, approach might be to call rewind:
require 'test/unit'
class TC_FOO < Test::Unit::TestCase
def setup
DATA.rewind
end
...
end
But this will set the file pointer all the way to the start of the source code, NOT to the point just after the __END__ marker. (Which, BTW, allows for all sorts of fun.)
A better approach is to record the file pointer before any data are read, and use that value to reset the file before each test method:
require 'test/unit'
class TC_FOO < Test::Unit::TestCase
$pos = DATA.pos
def setup
DATA.pos = $pos
end
...
end
Now each test method starts with DATA pointing to the right place.
Unless, like me, you are developing on Windows.
Text read from DATA was almost, but not quite, starting from the __END__ marker.
Ruby IO access on Windows has an explicit binary mode; if you've ever been burned by writing binary data and ending up with some oddly-sized file of junk, you've probaly learned to open files using the "wb" access mode string.
I had some vague memory of having unexpected binary/nonbinary data issues on Windows before, and recalled that there was a way of telling an existing IO stream to use binary mode. So I added a call to binmode to my test class: