Thursday, October 18, 2007

Rails: How to unit test the formatting of model fields in the views.

In our Rails applications we often use Textile/RedCloth or some other libraries to have things like Post's content nicely formatted in the view. I use acts_as_textiled. This plugin simplifies the code a lot. All that is needed in order to make a certain field 'textilized' is this line:

class Post < ActiveRecord::Base
acts_as_textiled :content
end

The question that I want to focus on here is:

How to unit test that a certain field will be nicely formatted in the views?

lolcat - this not so hard
more funny pictures

As Jay Fields has already explained (he focused on testing validations in his article) there are two approaches:
The first one is based on listing all the cases that are important, like whether paragraph tags are correctly inserted or whether bold tags are correct. It may be sometimes useful but for me it's a code smell that for testing a single line in your codebase you need so many test lines of code. Additionally, the acts_as_textiled plugin is nicely tested/specified so why duplicate the code? I'd rather test some of those cases in my Selenium tests or functional tests and choose the second approach:

def test_content_is_nicely_formatted
Post.expects(:acts_as_textiled).with(:content)
load "#{RAILS_ROOT}/app/models/post.rb"
end

I'm using mocha here for setting an expectation that a class method called acts_as_textiled will be called (passing the field name argument) during the load time of the class file. This solution is not ideal. I don't like hardcoding the path here but I still find it simpler that the first approach.
This way testing of things like validations and acts_as_* calls becomes much simpler.

Tuesday, October 16, 2007

How to parse a chess PGN file using JRuby and Chesspresso

I have a lot of chess PGN files with many chess games inside. What I want, is to have some way of filtering this collection e.g. by player names or by opening. Ideally, I'd like to use either Ruby or Python to do that.

My first approach was to find a pure Ruby library and use it. Unfortunately, I couldn't find any good one. No luck with any Python module either. I didn't want to use .Net platform in this case, but I did a quick google search with no good results...

The last hope was the Java platform. This time I was lucky and found Chesspresso. A quick test proved that the library is mature, exposes a very nice API and is actually very fast.
Even though I have a lot of experience with Java language, I don't fancy implementing my projects in statically typed languages. I find Ruby or Python much more readable and testable.

My choice is now clear - JRuby.
include Java
require 'Chesspresso-lib'
include_class 'chesspresso.pgn.PGNReader'

pgn_reader = PGNReader.new 'twic675.pgn'

while game = pgn_reader.parse_game do
if game.white.include?('Shirov')
puts game
end
end
  • The output in my case is:
Shirov,A - Naiditsch,A 1/2-1/2 (2007.10.08)
Shirov,A - Almasi,Z 1-0 (2007.10.09)


deliverhappy.jpg
more funny pictures