Rewriting My Competitors
Games: , , , , , , ,
Comments Off on Rewriting My Competitors

It’s really clear that the polls So Play We All are measuring progress. When we have a quiet week, there’s a lot fewer votes. This week, there were 4, evenly split between Luke and I. The SPWA site doesn’t have code to handle ties so it highligted me as winning, which I guess means the bugfix is not my problem. :)

Continue this post

From Fixtures to Factories
Code: , , , , , ,
Comments Off on From Fixtures to Factories

Automated tests need example data, and it’s a pain to have to construct a complete object in every test, especially when there are a lot of non-optional fields.

Continue this post

Small Plans
Biz: , , , , ,
Comments Off on Small Plans

My last day at the Post is Feb 20, and I’m headed to Chicago on the 22nd. I’ll be helping a family member recover from surgery, so my schedule (both day-to-day and how long I’ll be in town) is pretty vague, but I’ll be around at least a few weeks before returning to DC.

Continue this post

Twitter and Ruby’s Open Classes
Code: , , , ,
Comments Off on Twitter and Ruby’s Open Classes

For a few years I’ve been using weird, funny, outrageous, bizarre, or just offensive quotes as IM status messages. They used to appear at the bottom of this site, but the Jabber bot that fetched them has been offline for a while. I hooked them up to a Twitter account with a short Ruby script, and I wanted to talk about it a little.

Continue this post

Caching Dictionaries in Python vs. Ruby
Code: , , ,
Comments Off on Caching Dictionaries in Python vs. Ruby

A while ago I made a slightly-underinformed post (see the corrections in the comments) trying to draw a difference between Python and Ruby. I’ve finally got a decent example and can explain what I’m getting at.

Continue this post

Painless Upgrade to Rails 2.0
Code: , , , , , , , , , , ,
Comments Off on Painless Upgrade to Rails 2.0

I spent a dead-easy 2.5 hours last night updating NearbyGamers to Rails 2.0. My svn commit message read (with links added here for convenience):

Continue this post

Keep Ruby Gems in Your Home Directory
Code: , , , ,
Comments Off on Keep Ruby Gems in Your Home Directory

I like keeping my Ruby Gems in my home directory. I don’t have to type sudo in front of every gem command, it’s easier to remember the path to them when I want to read their source, and I don’t have to worry about a sysadmin on a shared host updating a gem before I test it. Here’s how to make those benefits yours:

Continue this post

Simple Ruby Mocking
Code: , , , , , ,
Comments Off on Simple Ruby Mocking

I mentioned at the end of my last post on testing that I wrote some code to do mocking for my unit tests in Ruby. Writing a small mock library was very much reinventing the wheel, but I needed to do it to earn a deeper understanding of mocks.

I’m writing some code (“Fetcher”) to talk to a POP3 server, fetch mail, and pass it off to another process. One of the tests deals with what happens when the POP3 server is down or otherwise unreachable.

def test_setup_server_down
pop3 =
pop3.expect(:new, [MAIL_SERVER, MAIL_POP3_PORT]){ raise"execution expired") }
f =
# further assertions that f acts correctly

This says that the Mock object expects a call to the new method with the given arguments, and when the call happens it runs the block. The block could return anything, but in this case it raises the same error as Net::Pop3 does when it can’t contact the server. After that the test can go on to make whatever assertions it needs to verify that the exception was handled properly.

The Mock object has a list of calls it expects to see and keeps a list of how it’s been called (yes, this could just be one list with an index but I thought it was mentally simpler this way). The test sets up what calls it should expect to see with what arguments (or blank for any) and block to run (or blank for none). When a method is called on the mock object, method_missing logs the call and executes the given block (raising a fuss if the call didn’t match what it expected).

class Mock
attr_reader :calls, :called

# the stub arg makes it just record all calls
def initialize
@calls = []
@called = []

# Pass nil for args to ignore the actual args in the call.
# Proc is optional; default is empty proc returning nil.
def expect(method, *args, &proc)
@calls << {:method => method, :args => args.first, :proc => (proc or{})}

def method_missing(method, *args)
@called << {:method => method, :args => args}

expect = @calls.shift
raise "Unexpected mock call #{method.to_s}(#{args.join(', ')})" if expect.nil?
raise "Wrong mock call #{method.to_s}(#{args.join(', ')}); expected #{expect[:method]}(#{expect[:args].join(', ')})" if method != expect[:method] or (expect[:args] != nil and args != expect[:args])

It’s a straightforward little object, and I also added some code to raise a fuss if expected calls weren’t made. This does have the downside that any tests defining their own teardown need to call super.

class Mock
def fail_if_not_empty
# Empty the call stack so that this obj doesn't throw errors for
# every later test between now and this object getting gc'd
calls, @calls = @calls, []
raise "Mock calls uncalled: n" + calls.collect { |call| "#{call[:method]}(#{call[:args]} { #{call[:proc] })" }.join(" ") unless calls.empty?

class Test::Unit::TestCase
def teardown

def finish_mocks
ObjectSpace.each_object(Mock) do |m|

This has been a handy piece of code to test the code I’ve written in the last two weeks, but it’s not good enough. I have to use a technique called dependency injection to test, where the outside code passes it a POP3 object instead of its initialize just using Net::POP3. Useful for testing, but my code is badly repetitive when all the instantiation calls have to do this exact same setup. (As an aside, Jacob Proffitt recently started an interesting conversation on dependency injection, took criticism, and responded. Good reading.)

I was pondering how to extend the Mock object to let me mock class methods (eg a call to when I realized I’d gone as far as I should down the do-it-yourself road. I’d heard of Mocha and it took me all of ten minutes to think to look at its cheat sheet where that’s the first example.

After spending two hours or so writing and tweaking this code, the best thing for it is to be thrown away. I’ve learned about mocking by doing it and I’m better-prepared to understand someone else’s larger and better library.

Fixtures in Ruby Unit Tests
Code: , , , ,
Comments Off on Fixtures in Ruby Unit Tests

I’m writing some Ruby scripts that sort and store lots of small files. After a day or two of hacking I had the basic code working, ran through a few thousand files, and a malformed file blew up the sorter. That was OK, the sorter was intentionally naive and lacking in error handling; I wanted it to hack it together and try out a few approaches before committing to serious development.

Now it’s time to treat it as real code, which means getting it under test. Tests are especially useful for ensuring tricky edge cases like malformed input don’t quietly break during other changes. When I started writing unit tests for the sorter I wanted fixtures similar to the Rails fixtures so I could write:

require File.dirname(__FILE__) + '/../test_helper'
require 'message'

class MessageTest < Test::Unit::TestCase fixtures :message def test_initialization f = message(:good) # assert the object was parsed correctly, etc. end end

The basic usage is fixtures :type to load the data and create the named function (in this case, message) for fetching data. First, I wrote some YAML fixtures for my data and put them in test/fixtures/message.yaml. You can see the :good key in use here:

good: |
  [the body of a good message here]
missing_header: |
  [more text]
bad_checksum: |
  [more text]

Because I'm parsing textfiles my fixtures look pretty simple, but the YAML library for Ruby makes serialization of any very easy.

So here's the code I put in test/test_helper.rb to set this up. I really like the [list].flatten.each idiom so the call from the unit test class can cleanly pass one or more types, eg: fixtures :message and fixtures :message, :user.

class Test::Unit::TestCase
@@fixtures = {}
def self.fixtures list
[list].flatten.each do |fixture|
self.class_eval do
# add a method name for this fixture type
define_method(fixture) do |item|
# load and cache the YAML
@@fixtures[fixture] ||= YAML::load_file("test/fixtures/#{fixture.to_s}.yaml")

(Note to Rails coders: I deliberately left out the pluralization, I like having the File class in file.rb with the fixtures in text/fixtures/file.rb and the database table named file and so on. I don't mind Rails' convention of pluralizing to "files" in the latter two examples, but I'd rather have a single identifier.)

Last night at the Rudolph Hering Society meeting Ian Bicking and Atul Varma explained mocking to me. I wrote a (very) little Ruby this morning to do mocking and I'll post that in a day or two when I'm sure I didn't do it too badly.

Discussion URLs: Opaque, Usable, and Readable
Code: , , , , , , , , , ,
Comments Off on Discussion URLs: Opaque, Usable, and Readable

I just wrote about Human-Readable ActiveResource URLs, and now I want to examine one example of them more in-depth. Discussion forum URLs have several conflicting goals:

Continue this post