What’s up with Hoe

I just don’t get it. Hoe looks like a convenience library for creating and deploying gems. But it’s not convenient at all. In fact, due to the extremely sparse documentation, it seems more difficult to use that the standard rake tasks that everybody already has installed.

Maybe I’m missing something, but having worked with Hoe on a project for the last few weeks, the most satisfying part was ripping the damn thing out of my project.

Disclaimer: I used newgem to build my project, so it could be their provided templates rather than Hoe itself that are so confounding.

Acts As State Machine

What the heck is a state machine and why should you use one? Wikipedia say:

A finite state machine or finite state automaton or simply a state machine, is a model of behavior composed of a finite number of states, transitions between those states, and actions.

Put simply, a finite state machine (FSM) is a design pattern for handling the progression of an object through a set of arbitrary “states” and the transitions between those states. This is a really useful concept whenever you have some data that moves through a workflow. Let’s look at the example of a comment on a blog entry. The “happy path” steps are as follows:

  • A user posts the comment
  • The comment is run through an spam filter
  • The comment is approved by the moderator
  • The comment is displayed on the blog

Continue reading

Unit Testing Saves the Day

I had been using XMLSimple to parse a bunch of XML input coming from Flex. The client discovered a sequence of events that would cause XMLSimple to stop parsing the CDATA from any XML until the server was restarted. After trying to debug what on Earth could be causing this issue and getting nowhere, I decided to just rip out XMLSimple and use the more battle hardened REXML for my parsing.

Lucky for me, I’d gone to the trouble to write good tests for these actions. It only took me a few minutes to completely change the way the handler was parsing the XML and, because I have a good test suite, I was able to confidently deploy the new version without introducing any new issues. Needless to say, the client was quite pleased. Thank you unit tests!

Testing Rake Tasks

I recently worked on a project where I was essentially building a library of rake tasks. Obviously, I wanted to be a good citizen and unit test them. Here are a few notes on techniques I used.

You’re going to want to create a complete sample project to test against. One tricky thing about creating a library rather than an app is that you need an app to test against. It actually turns out to be really helpful because you can create exactly the application you need to test against and leave anything unrelated out. For example, if your task is going to take a bunch of code and bundle it into a gem, you’ll want to put together a very simple bit of code in the proper structure so you can test against it. Put things in your code that are easy to grep for.

You don’t always need to run your tasks for every test. For example, if you have some file or rule based tasks, use the Task#requirements array to your advantage. If something’s not working as expected, it makes sense to first make sure your rules are choosing the proper files. This goes for any set of task dependencies.

Do something about rake’s output. Rake likes to tell you all about the marvelous things it’s doing. This can make reading your test results really freaking difficult. I found a really sweet module in rake’s own test library called CaptureStdout. It provides a two methods, capture_stdout and capture_stderr. These methods accept a block and silence the output of anything executed within them.

Make yourself some convenience methods. You can execute tasks from within a rake environment using Rake::Task[:task_name].invoke. How many times do you want to type that? If your answer is anything shy of “One million please!”, you probably want to make yourself a helper for that. My recommendation is that you buddy your helper up with capture_stdout in any way you find clever.

Think about any environment conditions that may effect your code. This is especially something to consider if you’re dynamically generating tasks based on some external variable (such as RAILS_ENV). The best way I’ve found to handle this is to create separate test files for each environment that need to be tested specifically. Then, just make sure you set the property before you require your library.

Use your setup method efficiently. Make sure you clean any temporary or generated files to give the next test a clean working environment.

Think about how long tasks will take. If you’re only testing a subset of the functionality of your library, choose to test against the most specific task possible. Otherwise, you will end up waiting a long time for your full stack to run in every test.

Lastly, remember that rake, by default, will remember if a task has been run and keep it from running again in the same execution. This is great for avoiding circular dependencies in a running app, but it makes testing just that much more a pain. Allow me to offer this snippet for your enjoyment:

Rake.application.tasks.each {|t| t.instance_eval{@already_invoked = false}}

Going to Railsconf

I’m going to Railsconf in a few days. I’ve been spending much of my free time and, recently, a good bit of my professional time working with Rails. In preparing for the conference, I’ve been doing a ton of reading and a good bit of rails hacking.

I’ve been mostly silent on here for the last few weeks. This is partially because I’ve been so bummed about being vandalized and partially because I’ve been spending much of my would-be blogging time on building my own blog engine. Sure, WordPress is good enough for what I need, but it’s such a big target for automated hacking. Also, I’m not really learning much by using an out of the box application. I want this site to be a place where I can try things out.

It only took me one night to re-build the presentation engine, custom theme and all, with rails. It’s taking me considerably longer to get things like the MetaWeblog API, Akismet, and various other essential components I hadn’t considered complete. Also, there are some static urls that I cannot break such as the links to my very popular Scrollbox.js library and a few other things, which is where most of my traffic comes from. If I were just creating a new site, I’d be able to launch it today, but since I have so many features I have to keep consistent with the old version, it’s going to take a little while longer.

Anyway, the reason I bring it up in this post is that it’s my project for Railsconf weekend. I hope to get it finished and insert as many bells and whistles as possible while I’m away.

Making the Most of EDGE: SVG

Note: I wrote this post almost a year ago, just as the iPhone was coming out. They’d told us in development talks that the iPhone would support most of the features of the desktop Safari, sans Flash. I never published because I discovered that the iPhone did have canvas features, but did not have SVG support. It’s been announced recently that the next version of the iPhone firmware will support SVG.

Most visual effects on web pages are today created in a graphic editor such as Photoshop and implemented on the page as rendered graphics. This is all well and good for users on speedy DSL connections, but the bandwidth eaten up by these graphics can really effect the load times of your content on our favorite new mobile device.

Luckily, the iPhone supports both canvas and SVG for handling your drawing in the browser. Using these formats will allow you to create much more visually appealing content at a fraction of the bandwidth. Both canvas and SVG are specified using plain text. Instead of supplying the artwork, you supply instructions for generating the artwork.

In the example that follows, I’ll compare using a transparent PNG to create a reflection effect with the same effect in SVG. The SVG version uses only a few lines of code to produce what is a near identical effect.

Continue reading