SqlSessionStore now available as a plugin

Posted almost 8 years back at RailsExpress.blog

Rails core team member Rick Olson, the author of many rails plugins, mephisto and techno-weenie, has turned SQLSessionStore into a plugin and sent his code for me to publish. Thanks a lot Rick!

I incorporated the latest changes from my sql session store implementation, most notably postgresql support, and added sql_session_store to my trac installation.

Using sql_session_store is now easier than ever before. Check it out into your vendor/plugins directory:

svn co http://railsexpress.de/svn/plugins/sql_session_store/trunk  \
 sql_session_store

and follow the instructions in the README file.

If you find any problems with the plugin, which would be entirely my own fault, not Rick’s, please use Trac to report them.

BTW, I’d love to get support in for additional database adapters, especially Oracle. I you find the time to write an adapter, please submit the code using Trac, or email me.

RailsConf: Adventures in JavaScript testing by Thomas Fuchs

Posted almost 8 years back at Luke Redpath - Home

I’m currently sitting in the main congress hall awaiting the start of Thomas Fuch’s presentation. As I’m sure many readers of my blog are aware, I’m a huge advocate of testing, or to be specific, good testing. However, one thing that I’ve never managed to get into is unit testing with JavaScript. I’ve never really been aware of the tools available or how well it works.

I’m going to write this post live; hopefully it won’t just come across as a mish-mash of incoherent ramblings.

  • Traditional JavaScript “testing” generally revolves around alert. it can be useful sometimes but it generally doesn’t offer anything interesting. Use it sparingly.
  • There are many common misconceptions or attitudes towards JavaScript: “we don’t need tests for 10 lines of code”; “but you can’t debug JavaScript”. Wrong and wrong again. Enter unit testing for JavaScript.
  • Some options exist already, such as jsunit. These have their problems, such as awkward syntax or problems with Prototype.
  • Scriptaculous has its own unittest.js library. All you need to do is include the unittest.js file and an empty div with a “testlog” HTML ID (defaults). Now you’re ready to roll with Test.Unit.Runner.
  • Test.Unit.Runner looks quite similar to the standard xUnit family of testing libraries. It has the standard setup and teardown methods and a suite of assertions.
  • It has some good testing functionality for dealing with effects, and time-sensitive behaviour (wait function).
  • It has a basic benchmarking system too!
  • Rake integration is provided through a the javascript_test plugin – it allows you to launch browsers and run your javascript unit tests through a single command: rake test:javascripts. It uses a WEBrick server and supports multiple browsers, including Camino, Firefox, Safari and Internet Explorer. It’s fairly trivial to add support for other browsers too. It seems to be missing the functionality to close the browser after the rake test run. Perhaps the browser definition classes could be extended to support a “close” method that is called after the test run?
  • The plugin also provides a generator for generating test stub files (HTML format) in test/javascript.
  • Did I mention the browser-based test runner looks pretty sweet?
  • OK, here’s the killer feature so far: RSpec-style syntax, including should* style expectations and context/spec format. I’m convinced, sign me up!
  • Some other hints and tips: If you aren’t using Firebug already, then start using it! It is awesome and makes debugging AJAX and general JavaScript problems a lot easier. (as an aside, its also great for debugging your behaviours when you are using UJS). There is also a tool for Safari called Drosera.
  • Don’t forget your RJS templates either. RJS has some basic debugging support built-in (although this could really do with being expanded upon).

During the question and answer session, Simon Willison mentioned a tool that was part of the Dojo Toolkit that uses a command-line JavaScript interpreter to run its unit tests. It sounds interesting although I feel its a lot more useful to run the tests in the actual environment they are going to run in (i.e. the browsers). By introducing something like a separate interpreter that end-users aren’t going to be using, you are relying on that interpreter being correct.

All in all, it was a good talk and has really got me interested in unit testing with JavaScript. It’s definately something I should be doing, especially as I am so strict about testing with the rest of my code.

Finally, a word of warning for those who want to try a bit of live blogging: IRC is evil and distracting. Use with caution!

Links and useful information:

Gosling v. Greenspun

Posted almost 8 years back at Ryan Tomayko's Writings

James Gosling, in a weblog entry on the proposal to add closures to the Java language, dubs his Black Hole Theory of Design:

“Lisp is a Black Hole: if you try to design something that’s not Lisp, but like Lisp, you’ll find that the gravitational forces on the design will suck it into the Black Hole, and it will become Lisp”

Compare to Greenspun’s Tenth Rule of Programming (1993):

“Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.”

Which quote you use will depend on your perspective, I suppose.

Here's a Nickel, Kid

Posted almost 8 years back at Ryan Tomayko's Writings

The Dilbert strip referenced in Neil Stephenson’s In The Beginning Was The Command Line:

Here's a Nickel, kid

Huge thanks to Mike Taylor for the original scan and to quickpost for the pointer.

There’s a lively discussion of the section titled, The Hole Hawg of Operating Systems, on reddit.

This strip ran on 06/24/1995 — more than 11 years ago. It is still timely and relevant, although for reasons different from 1995.

It is featured on the front of Advanced Programming in the UNIX® Environment (Addison-Wesley Professional Computing Series):

Advanced Programming in the UNIX Environment

Stephenson actually mis-describes the strip in the essay:

(2) a copy of a Dilbert cartoon in which Dilbert, the long-suffering corporate software engineer, encounters a portly, bearded, hairy man of a certain age—a bit like Santa Claus, but darker, with a certain edge about him. Dilbert recognizes this man, based upon his appearance and affect, as a Unix hacker, and reacts with a certain mixture of nervousness, awe, and hostility. Dilbert jabs weakly at the disturbing interloper for a couple of frames; the Unix hacker listens with a kind of infuriating, beatific calm, then, in the last frame, reaches into his pocket. “Here’s a nickel, kid,” he says, “go buy yourself a real computer.”

It was not the Dilbert character but Wally that had the encounter with the Unix hacker. The hacker quotation is also inaccurate but perhaps better than the original.

Dilbert is by Scott Adams and runs daily on the web and in 2500 newspapers worldwide in 65 countries and 19 languages with over 150 million fans.

Best 500 Page Eva!

Posted almost 8 years back at Ryan Tomayko's Writings

I so wish I could throw this into my boring business software app:

reddit broke

Somehow I don’t think my customers have the same sense of humor.

Speaking of programming.reddit.com, I've been spending a lot of time there. Go for the links, stay for the comments – the discussion is top notch unlike some others we know.

Top.app

Posted almost 8 years back at Ryan Tomayko's Writings

One thing that’s always bothered me about MacOS X’s Terminal.app is that you can’t really run multiple applications. Technically you can but it’s not right having to switch to Terminal and then cycle through the windows to get to the one you want.

And I'm not talking about being able to have multiple shells running so keep your iTerm has tabs bullshit to yourself. I use GNU/Screen for that and am quite happy with it.

There’s a handful of textmode tools I'd like to be able to run as if they were all out Mac applications like Mutt, irssi, elinks, and Vim.

Some of the more popular textmode tools have graphical versions. Mac Vim is solid. AquaEmacs was a little wonky the last time I played with it. MacIrssi sucks because you can’t use plugins and, really, what’s the point of using a shitty textmode anything if you can’t customize the piss out of it?

We need Terminal.app to be a generic container for all of the textmode tools we'd like to pull up to first-class application land. The good news is that, after reading this article, you’ll be able to do just that. The bad news is that it requires quite a bit of work and the technique is pretty nasty. I would even go so far as to call it a big giant hack.

Top.app Dock Icon

To illustrate, we’re going to turn top into a standalone application: Top.app. Yes, even a tool as humble as top ought to have its own bouncy Dock icon and Command+Tab target. We’ll use it as a backup for Activity Monitor the next time it goes all beach-ball on us.

We need another .app

The first thing I don’t like about this approach is that you have to copy Terminal.app in its entirety. I recommend the Applications directory under your $HOME:

$ mkdir -p ~/Applications  # this may already exists
$ cp -r /Applications/Utilities/Terminal.app ~/Applications/Top.app

Without doing anything else, you can run Top.app and get a separate item in The Dock and Command+Tab.

Open it from Finder, or:

$ open ~/Applications/Top.app

Changing The Menu

The menu still says “Terminal”, which is kind of annoying. We can change this without too much hassle by editing the InfoPlist.strings file under your locale’s directory. Check this out:

$ cd ~/Applications/Top.app/Contents/Resources/English.lproj
$ cat InfoPlist.strings
"CFBundleHelpBookName" = "Terminal Help";
"CFBundleName" = "Terminal";
"NSHumanReadableCopyright" = "? Copyright 1995-2003 Apple Compute ...

We need to open the InfoPlist.strings file in an editor that’s UTF-16 aware and change the CFBundleName value from “Terminal” to “Top”. Vim worked swimmingly for this task and OmniOutliner actually has a special graphical mode for strings files. But you can open it in TextEdit if neither of those is available to you:

$ open -a TextEdit InfoPlist.strings

Once saved, you can quit and start Top.app again and you should now see “Top” in the menu instead of Terminal.

Changing The Icon

The hard part about this step is finding an .icns file for the tool you’re running. top is the command-line equivalent of Activity Monitor, so let’s just grab the icon from there:

$ cd ~/Applications/Top.app/Contents/Resources
$ cp icon.icns{,.orig}     # backup original icons file
$ AM=/Applications/Utilities/Activity\ Monitor.app
$ cp "$AM/Contents/Resources/ActivityMonitor.icns" icon.icns

Note that the new icon won’t show up until you restart Finder. In most tutorials, this is where you logoff and back on. Fuck that:

$ killall Finder

TIP: If you have Apple’s Developer Tools installed, you can find more icns files in the wilderness that is /Developer/Applications.

Top Icon

Customization

Now comes the sickest part of the hack.

We’re presented with a bit of a dilemma. We want our Top.app window to be fully customized and we also need a specific command to be executed (/usr/bin/top). That’s not the problem – Terminal.app stores these types of customization in .term files, which are easily created by opening a terminal, customizing it using the inspector (Command+I), and then saving it (File -> Save As or Command+Shift+S). When you save the .term file there’s an option labeled, Open this file when Terminal starts up and this is the problem: the setting applies to all Terminal applications (even copies) because the default .term file is set as a user global preference in ~/Library/Preferences/com.apple.Terminal.plist. So, if we open Top.app as is, customize it, save it and check that box, we’ll end up loading the Top.term file when any terminal is launched.

But it’s okay because Mac applications turn out to be extremely hackable. On most systems, you'd be getting out your hex editor and patching binaries. But not here – changing the preference property list used by an application turns out to be trivial:

$ cd ~/Applications/Top.app/Contents/
$ grep -A1 CFBundleId Info.plist 
      <key>CFBundleIdentifier</key>
      <string>com.apple.Terminal</string>

See that? Rock! All we need to do is change com.apple.Terminal to something else, like com.rtomayko.Top. You can open the file in the nice little Property List Editor.app and change the CFBundleIdentifier property or you can start using your machine as God intended:

$ perl -pi.orig -e 's/com\.apple\.Terminal/com.rtomayko.Top/'
$ grep -A1 CFBundleId Info.plist 
      <key>CFBundleIdentifier</key>
      <string>com.rtomayko.Top</string>

It’s smooth sailing from here on out. Open Top.app and you should get a little white terminal window. Run top -s1 -ocpu at the prompt so we can get a feel for how the window should be dimensioned. Bump the font size up about 5 times using Command + and then resize the window so that the top output fits just right.

Next, hit Command+I to get into the inspector, and customize it as you see fit. Here are the settings I used for each of the customization areas:

  • Shell – When the shell exits, close the window.
  • Processes – Prompt before closing window: never.
  • Buffer – Buffer Size: Disabled (there’s no need for a scrollback buffer in cursors apps).
  • Display – Text: Bitstream Vera Sans Mono, Anti-aliasing, Disable Blinking Text.
  • ColorGreen on Black, Transparency.
  • Window – Title: “Top”, disable everything else.

The Finished Product

Now, hit Command+S to save the .term file. You get a normal Save As dialog with a few extra options. Enter “Top” in the Save As box, you want to save the Main Window, you want to open this file when Terminal starts up, and you want to execute the following command:

exec /usr/bin/top -s1 -ocpu

You also want to check the Execute command in a shell box (it’s the only way I've found that let’s you pass arguments).

Save It

Save it and Quit. If everything went right, you should be right back where you left the next time you open Top.app.

Lather, Rinse, Repeat

To sum up, the basic steps are as follows:

  1. Copy Terminal.app to Foo.app.
  2. Edit Locale.lproj/InfoPlist.strings for the menu and Info.plist for the preference.
  3. Overwrite icon.icns with a distinct .icns file.
  4. Open Foo.app, customize, save .term file as Default.

Issues / Ideas

This approach has drawbacks and limitations:

  • It’s not correct. Terminal.app should provide a mechanism for achieving these results without all the hackery.

  • Updates to Terminal.app will not automatically be picked up. It may be necessary to go through the process after an update.

  • I have not been able to figure out if it’s possible to open files or pass arguments to these applications otherwise.

I'm considering throwing together a quick shell script that’s capable of performing the nitty gritty aspects given a directory containing a few files: the .icns file and maybe some kind of simple config file that contains the values needed for the Info.plist.

New business cards

Posted almost 8 years back at Luke Redpath - Home

Check out our new Agile Evolved business cards which arrived today, just in time for RailsConf.

businesscards

They look really cool. They were printed by Aubergine Print. Our new logo was designed by Tokyo Cube. Mine haven’t arrived yet, but when they do I’ll update the above photo with something a bit more high-quality (theres only so much you can do in Photoshop to improve a camera phone picture).

There will hopefully be many of these being handed out at next week’s European RailsConf.

analogies.google.com

Posted almost 8 years back at Ryan Tomayko's Writings

It’s a bit like a Hefty Bag filled with vegetable soup.


<script type="text/javascript"> function analogize() { var word = document.getElementById('ga-word').value ; var query = document.getElementById('pretentious').checked ? ' is a bit like' : ' is like' ; document.getElementById('ga-query').value = '"' + word + query + '"' ; return true; } </script>

Here’s some ideas to get you started:

  • America
  • God
  • Java (pretentious mode)
  • Perl (pretentious mode)
  • My Girlfriend
  • Your Mom

Web Based Site Monitoring Tools

Posted almost 8 years back at Ryan Tomayko's Writings

A recent upgrade broke an instance of Nagios we use to monitor non-critical stuff. I've always been impressed w/ Nagios' massive feature-set but the web based GUI leaves a lot to be desired. That combined with the fact that I'm beginning to dislike the amount of daemon processes I have running all over the place has led me to consider alternatives.

As all this was unfolding, I just happened to come across a link to Site24x7 so I decided to give it a spin. Site24x7 makes HTTP/ HTTPS requests at regular intervals of time, tracks your website response time, and notifies via email or SMS when your website is down or when the response time has crossed certain limits you have set. That’s exactly no more and no less than what I need so I think these guys found a nice little sweet-spot.

It’s also free and beta.

I've been monitoring six different sites for a week and it pretty much just works. Here’s what lesscode.org’s monitor looks like at the moment:

site24x7

So that’s Site24x7 in a nutshell. Does anyone have experience with any of their competitors?

Decorator Pattern with Ruby in 8 lines

Posted almost 8 years back at Luke Redpath - Home

The Decorator Pattern is a design pattern that enables you to dynamically wrap behaviour around an existing object at runtime. It is especially useful when an object can have many variables that can be combined in different ways, which in turn affect it’s behaviour.

This small, simple implementation of the decorator pattern in Ruby sums up what I love about the hottest dynamic language on the planet.

I’ll borrow a simple example from the excellent Head First Design Patterns book by Eric Freeman, Elisabeth Freeman, Kathy Sierra, and Bert Bates.

Let’s say you want to calculate the cost of a cup of coffee. You have Coffee class, which implements a cost() method. For the purposes of this example, let’s just hardcode a value:

class Coffee
  def cost
    2
  end
end

Great. But what if we want the cost of a coffee with milk? We could have a new class:

class WhiteCoffee
  def cost
    2.4
  end
end

OK. But now we want cream. And sprinkles. Clearly, creating new classes is going to lead to a huge number of classes in our application. It just isn’t realistic to create classes for different combinations of coffee and extras. It could get worse – what if we have different types of coffee? We would then have to have combinations of extras with each different type of coffee. It just isn’t going to work. Enter the decorator pattern. Here’s the the 8 lines of Ruby mentioned in this entry’s title:

module Decorator
  def initialize(decorated)
    @decorated = decorated
  end

  def method_missing(method, *args)
    args.empty? ? @decorated.send(method) : @decorated.send(method, args)
  end
end

And thats all you need. You can include this into any class you want to act as a decorator. You can then use that decorator as if it was the object it is decorating; by default all messages sent to the decorator are forwarded on to the decorated object. You can then decorate the methods you need to extend:

class Milk
  include Decorator

  def cost
    @decorated.cost + 0.4
  end
end

So how does this solve our original problem? The real power of decorators lies in the fact that they can act like the objects they are decorating. By taking this one step further, you can wrap decorators with other decorators as long as they share the same interface. By creating decorators for our different “extras”, we can create coffees using a combination of decorators and get the total cost of the coffee.

class Whip
  include Decorator

  def cost 
    @decorated.cost + 0.2
  end
end

class Sprinkles
  include Decorator

  def cost
    @decorated.cost + 0.3
  end
end

Whip.new(Coffee.new).cost
#=> 2.2
Sprinkles.new(Whip.new(Milk.new(Coffee.new))).cost
#=> 2.9

Of course, there’s nothing stopping us from making life easier with a few factory methods:

class CoffeeFactory
  def self.latte
    SteamedMilk.new(Espresso.new)
  end
  
  def self.cappuccino
    Sprinkles.new(Cream.new(Milk.new(Coffee.new)))
  end
end

order = Order.new
order.add(Coffee.new)
order.add(CoffeeFactory.cappuccino)
puts order.total

Due to Ruby’s highly dynamic nature, the Decorator pattern isn’t the only way of extending class functionality at runtime, however I just love how simple it is to implement the pattern in Ruby. For more information on implementing decorators in Ruby, including generic decorators and alternatives to the traditional decorator pattern, see the DecoratorPattern page at the RubyGarden.

Finally, it would be nice to maintain some kind of identity when using decorators. The RubyGarden page above has one approach. Whilst we aren’t using inheritance, it would be nice to retain one of its features:

CoffeeFactory.cappucino.kind_of? Coffee
#=> true

I can think of a few ways of extending my Decorator class to retain this functionality, but I’m gonna leave this one to the reader. Over to you.

Update: In typical Ruby-fashion, my 8 lines of code has been beaten by, well, zero lines of code by Trevor Squires. Using modules, super and extend, Trevor came up with this alternative solution, which maintains identity as well. Bow down to his Ruby-fu.

Update 2: Never one to step back from a challenge, I see Trevor’s Ruby-fu and raise him with a bit of my own. I still feel my decorator implementation carries some weight, with a nice bit of syntatic sugar:

class Milk
  include Decorator
end

class Whip
  include Decorator
end

class Sprinkles
  include Decorator
end

# normal coffee
Coffee.new

# coffee with milk, whip and sprinkles
Coffee.with :milk, :whip, :sprinkles

The self.with method could do with being extracted into a Decoratable module but here’s a concrete implementation. Trevor’s method still has an advantage in that it maintains object identity, but I have some ideas to solve that. But alas, it is past 1am and bed beckons.

Update 3: Trevor fights back with his own self.with() implementation. Personally I prefer the extend implementation, it eliminates the symbol to class trickery, and still maintains identity. His ’fu is still strong.

However, there is one downside to Trevor’s method: you can only apply a decorator to an object using <filterjscode lang="ruby" inline="true">extend once. But what if you wanted double sprinkles?

Sprinkles.new(Sprinkles.new(Coffee.new))

# or with a bit of sugar (no pun intended)
Coffee.with :sprinkles, :sprinkles
</code></pre>

I Hate This Place

Posted almost 8 years back at Ryan Tomayko's Writings

So I decided to resurrect this weblog. Or, should I say, this giant mess of crap that I've decided I now hate. Everyone always says that rolling your own weblog engine is a stupid idea but I did it anyway because, well, I was stupid. It was stupid when I put it together originally and it was stupid yesterday, when I spent a few hours moving everything from Python w/ a brain-dead file based data store to Ruby, Rails, and MySQL…

Dumb.

I should have grabbed Mephisto instead. No, I should have did wordpress.com and just let this place go.

I should never have gotten out of bed this weekend.

A long time ago, I had a bunch of novel ideas like tagging and bookmark integration, and some other things I never got around to doing. Today, most weblog software has all that stuff but I've decided it doesn’t matter because it’s all stupid. I wanted all my crap (bookmarks, articles, essays, smaller weblog entries, etc) in the same place and tagged so that I could combine tags in the URL, a la del.icio.us, and have these ad-hoc pages filtered using this mini URL based query language. I spent way too much time implementing all this crap and then never used it. Not once.

It’s a stupid idea.

Did I mention you could grab an Atom feed for any combination of tags? How cool is that?

It’s not. I never used it. Not once. It’s been ripped out.

There are exactly three things that matter on a weblog. In order of importance, they are:

  1. “Permalink” / real content pages.
  2. Archives.
  3. The main feed.

Anything else becomes a minor annoyance at best (blogrolls, what’s on your record player, the weather in your zip code, etc). Weblog navigation using tags, on the other hand, is almost entirely annoying and tag clouds as a navigational device is quite possibly the worst of 50 really stupid options.

All of the aforementioned have a place, of course, just not on your weblog. If you want to tag stuff, do it on del.icio.us. Want to broadcast what’s currently on your record player? Do it on last.fm. Blogrolling goes here. What people read on your site can be found on reddit.

Coming into harmony with the web means accepting that each end should do exactly one thing well. The weblog is for writing (or publishing anyway — Emacs is for writing), everything that’s not your weblog is for everything else.

So, should time permit, I'm going to completely redesign this place to be totally bleeding edge. I'm going to attempt to emulate what is quite possibly the greatest technical weblog on the planet: Kragen’s TOL.

The first rule of Barcamp...

Posted almost 8 years back at Luke Redpath - Home

Ongoing updates live (or when I get round to it) from Barcamp London. I’ll be posting notes on the presentations I attend as the weekend goes on.

Yahoo reception photo

4pm: Above is my current view as I sit in the reception of Yahoo’s swanky West End offices, trying to polish off the second part of my BDD/Rails tutorial, whilst panicking about my UJS presentation tomorrow (AKA my first ever presentation).

After arriving fashionably late (ok, 4 hours late) I dropped into Jonathan’s Comet talk, which was followed up by a talk on the Low Pro extension to the Prototype Javascript library by Dan Web.

Jonathan’s talk on Comet gave me some ideas about a forthcoming project we’re gonna be working on here at Agile Evolved. There do seem to be a few implementation issues to resolve first however.

Surprisingly, Dan’s Low Pro talk was a revelation to me. I say surprsing, because you think I’d know all about Low Pro, what with it being the core behind the UJS For Rails plugin however I was only really aware of its improved event handling capabilities. Even cooler was its improved DOM support and the real killer for me, Behaviour classes. Behaviour classes let you build self-contained classes that contain behaviour for a collection of events, which can then be applied to elements in one goal. Dan is going to be blogging about this in full, but here is a small snippet:

var Sortable = Behaviour.create({
  initialize : function() { },
  onclick: function() { },
  onmouseup: function() { }
});

Event.addBehaviour("#todolist li", Sortable);

How awesome is that? It would be a great to see a re-implementation of script.aculo.us behaviours using Behaviour classes. Its also a great way of building and packaing up your own unique behaviours.

6:14pm: Award for most bizarre use of the English language goes to Simon Willison.

“I’m still upset on a theoretical level.”

Sunday, 3pm: OK, here’s some advice. If you are going to do a presentation, don’t leave it until the last minute to put together. I managed to get my slides finished by about half past 1 and was on the train into central London by 2. In the end my presentation seemed to go ok, though I’m still not a fan of public speaking.

Despite arriving so late, I did manage to couple catch a couple of interesting talks. Nick Fitzsimons gave an interesting talk on the correct use of HTTP, which extended nicely from a talk on Saturday regarding REST and Rails (and whether or not to use it). We generally agreed that in an ideal world, content negotiation and a single URL for a resource (with the accept header determining how you want that resource to be presented) is a good thing. However, there were concerns voiced about misconfigured proxy servers that could end up munging with accept headers which would result in some very strange behaviour.

People were more positive about using HTTP verbs to perform different actions on a resource. The issue surrounding proxy servers (which may not allow certain verbs) remained but it was less severe as a proxy server that did not support a particular verb would simply fail, rather than appear to work but actually do something strange.

Thanks to those who did attend my talk on Unobtrusive Javascript with Ruby on Rails. If you weren’t able to attend Barcamp, you can download the slides.

All in all it was a good weekend. It was good to meet some interesting and friendly people. If you haven’t attended a Barcamp before, I suggest you keep an eye out for one in your area, as they are great fun.

Dave Thomas and Mike Clark - Ruby on Rails Podcast

Posted almost 8 years back at Ruby on Rails Podcast

A clarification of what it means for Rails to enter the enteprise, and a preview of the upcoming Rails Edge conferences.
Also mentioned:

Developing a Rails model using BDD and RSpec, Part 1

Posted almost 8 years back at Luke Redpath - Home

Writing Rails testing articles seems to be quite popular at the moment; seeing as I’m often quite vocal about testing on the #caboose and #rubyonrails IRC rooms I felt it was about time I posted one of my own. I have a large series of articles on testing with Rails in the pipeline, but until that is done, here is a nice and simple tutorial for newcomers to BDD and RSpec – the first in a two-part article exploring the development of a typical Rails model, using BDD techniques and the RSpec framework. If you are interested in BDD and RSpec, or new to testing in general and want to learn how to iteratively develop a model test/spec-first, this is the article for you.

Anatomy of a typical Rails-style test

Will Rails developers please raise their hands: how many times have you written a test that looks like this:

class UserTest < Test::Unit::TestCase
  def test_create
    user = User.create(:some => 'params')
    assert user.save
  end
end

Now ask yourself how many times have you sat back and asked yourself why you are writing the above test?

If the concept of unit testing is new to you, then writing tests at all is a great first step. But its also important to have useful tests. Are your tests valuable? Are your tests acceptable?

Avoid meaningless tests

The above test is a good example of a meaningless test. Why is it meaningless? Because you aren’t testing your own code; you are testing the ActiveRecord library, which is pretty well tested already. Let’s take a look at a default Rails model:

class User < ActiveRecord::Base
end

Just those two lines of code give us a whole load of functionality, all of which is provided by the ActiveRecord library. Its fair to assume that the functionality given by those two lines of code will work. If it doesn’t then there is either something wrong with your local setup or something fundamentally wrong with ActiveRecord; in either case, your own tests are the last of your problems.

Test your own code

So if we can safely assume that the built-in ActiveRecord functionality works as advertised, what should you be testing? The simple answer: test any code that you write. Anything that gets added to your model needs test coverage. The aim of this tutorial is to place an emphasis on testing the behaviour of your code in different situations (or contexts). This is the basis of Behaviour Driven Development, the methodology that I will use in this tutorial to iteratively develop a Rails model, test-first spec-first.

For this tutorial, I will be using the excellent RSpec framework, but you could easily apply these principles to TDD using Test::Unit. Before we get started, you’ll need to install RSpec and the RSpec On Rails plugin for your current app:

~/mygreatapp/ $ sudo gem install rspec
~/mygreatapp/ $ ./script/plugin install svn://rubyforge.org/var/svn/rspec/tags/REL_X_Y_Z/vendor/rspec_on_rails/vendor/plugins/rspec
~/mygreatapp/ $ ./script/generate rspec

Replace X, Y and Z in the above with the version of RSpec that you are using. If you have any problems, refer to the full instructions.

Going into RSpec in full detail is outside of the scope of this article, but it should be pretty clear what is going on – this is one of RSpec’s strengths. If you would like to read a more generic RSpec tutorial, the RSpec website has a great tutorial to get you started.

The problem

We’re in the process of writing our fantastic new Web 2.0 application, and we’ve decided that we need people to be able to create accounts and log in to the application. We don’t want to use any of the available Rails authentication plugins; we want to develop our own User model. After a quick whiteboard/CRC session, we come up with a few basic specs for our User model:

  • A user should have a username that they can log in with
  • A user should have a password between 6 and 12 characters in length
  • A user’s password should always be encrypted in the database
  • A user should have an email address
  • A user can optionally have a first name, surname and profile/description

With this in mind, we fire up our favourite text editor and start work on a new Specification. We use the generator that comes with RSpec on Rails to generate a new model, with an accompanying spec file.

$ ./script/generate rspec_model User

This will create a new user.rb file for our model, just like the normal Rails script/generate model command, but it will also create an accompanying spec file in the spec/ directory. If you open up the created user_spec.rb file, you will see a stub context ready and waiting.

Behaviour Driven Development favours the breaking up of specifications into individual “contexts”. A context is an object (or collection of objects, but generally object being specced) in a certain state. As we are going to start our specs from scratch, you can safely remove the stub context in the user_spec.rb file (don’t remove the require line at the top though!).

So what is a good starting point? I tend to favour a more generic starting context: “A user”. We can use this to specify the behaviour of a user in general.

Specifying your model in code

Let start with our first specification: a user should have a username that they can log in with. Its fair to assume that the username is required (otherwise they won’t be able to log in). So what could we specify? How about this:

context "A user (in general)" do
  setup do
    @user = User.new
  end

  specify "must have a username" do

  end
end

That’s not bad, but it could be better. We’ve expressed a requirement in our code but we haven’t said anything about the behaviour of a User object. What about this instead:

context "A user (in general)" do
  setup do
    @user = User.new
  end

  specify "should be invalid without a username" do

  end
end

That’s better. Not only have we expressed that our user must have a username, but we’ve also expressed what behaviour should be expected from the User model if it doesn’t have one; it should be invalid. Let’s fill this spec in, so we have a failing spec:

context "A user (in general)" do
  setup do
    @user = User.new
  end

  specify "should be invalid without a username" do
    @user.should_not_be_valid
    @user.username = 'someusername'
    @user.should_be_valid
  end
end

Now we need to make this pass. The first things we need is our actual User model, and a table in our database. BDD (and TDD) emphasise taking small steps, following the red, green, refactor mantra. However, due to our coupling to the database as a result of using the ActiveRecord pattern, we are going to have to make a slightly larger leap: our users table schema.

We need to write a migration for our users table, but at this stage we aren’t certain exactly what columns we need. We could write a migration every time we want to add a column but that would quickly become tedious. Instead, we’ll make a reasonable guess at our schema based on our written specs – if we get it wrong at this stage it doesn’t matter. Migrations make it easy to modify our schema in the future. Something like this should do the trick:

class AddUsersTable < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.column :first_name, :string
      t.column :last_name, :string
      t.column :email, :string
      t.column :description, :string
      t.column :username, :string
      t.column :encrypted_password, :string
      t.column :salt, :string
    end
  end

  def self.down
    drop_table :users
  end
end

You’ll note that we’ve made a few assumptions regarding our password columns. We already have an idea in mind about how we want to store the password – as a salted hash – so we’ve created columns for the encrypted password and salt. Now we’ve written and run our migration, and created our User model, its time to get the spec to pass:

class User < ActiveRecord::Base
  validates_presence_of :username
end

You’ll notice that we’ve not added a should statement for the error message itself. That is because we know Rails will happily provide us with the default “can’t be blank” message. Remember: only test the code that you write. In this case, we decide we do want a custom message, so lets add a spec and make it pass:

context "A user (in general)" do
  setup do
    @user = User.new
  end

  specify "should be invalid without a username" do
    @user.should_not_be_valid
    @user.errors.on(:username).should_equal "is required"
    @user.username = 'someusername'
    @user.should_be_valid
  end
end

class User < ActiveRecord::Base
  validates_presence_of :username, :message => 'is required'
end

We’ve also specified that our user must have an email address, so lets add a spec for that:

context "A user (in general)" do
  setup do
    @user = User.new
  end

  specify "should be invalid without a username" do
    @user.should_not_be_valid
    @user.errors.on(:username).should_equal "is required"
    @user.username = 'someusername'
    @user.should_be_valid
  end

  specify "should be invalid without an email" do
    @user.should_not_be_valid
    @user.errors.on(:email).should_equal "is required"
    @user.email = 'joe@bloggs.com'
    @user.should_be_valid
  end
end

That’s simple enough to implement:

class User < ActiveRecord::Base
  validates_presence_of :username, :message => 'is required'
  validates_presence_of :email, :message => 'is required'
end

Great, we’re on a roll. But wait a minute, both of our specs are now failing. What gives? Of course, because we’ve now added two validation requirements, we need to add an email address in the first spec to make it pass and a username in the second spec to make that one pass. Hmm, it doesn’t sound very DRY, but lets go with it for now – we want our specs to pass after all!

context "A user (in general)" do
  setup do
    @user = User.new
  end

  specify "should be invalid without a username" do
    @user.email = 'joe@bloggs.com'
    @user.should_not_be_valid
    @user.errors.on(:username).should_equal "is required"
    @user.username = 'someusername'
    @user.should_be_valid
  end

  specify "should be invalid without an email" do
    @user.username = 'joebloggs'
    @user.should_not_be_valid
    @user.errors.on(:email).should_equal "is required"
    @user.email = 'joe@bloggs.com'
    @user.should_be_valid
  end
end

Phew, that was a close one. Finally, lets add the specs for the password. We know a password is required and that it has to be between 6 and 12 characters in length. Because that is actually two specifications, we’ll write two separate specs in our code. Lets start with the required field specification, as that will look similar to our above specs:

context "A user (in general)" do
  setup do
    @user = User.new
  end

  specify "should be invalid without a username" do
    @user.email = 'joe@bloggs.com'
    @user.password = 'abcdefg'
    @user.should_not_be_valid
    @user.errors.on(:username).should_equal "is required"
    @user.username = 'someusername'
    @user.should_be_valid
  end

  specify "should be invalid without an email" do
    @user.username = 'joebloggs'
    @user.password = 'abcdefg'
    @user.should_not_be_valid
    @user.errors.on(:email).should_equal "is required"
    @user.email = 'joe@bloggs.com'
    @user.should_be_valid
  end

  specify "should be invalid without a password" do
    @user.email = 'joe@bloggs.com'
    @user.username = 'joebloggs'
    @user.should_not_be_valid
    @user.password = 'abcdefg'
    @user.should_be_valid
  end
end

Now, we don’t actually have a password column in our users table, but we need somewhere to store the cleartext password before it gets encrypted. A standard Ruby instance variable will do. Here’s the code to make it pass:

class User < ActiveRecord::Base
  attr_accessor :password

  validates_presence_of :username, :message => 'is required'
  validates_presence_of :email, :message => 'is required'
  validates_presence_of :password
end

h3. Refactoring towards cleaner, clearer specifications

Before moving on to the password length specification, lets address our duplication issue here. Its already getting tedious adding all the other required fields in each spec in order to make them pass. It is making our specs bloated, ugly and it will be a nightmare to maintain in the future if our specification changes. Let’s solve this by introducing a small helper module and a neat Hash extension:

module UserSpecHelper
  def valid_user_attributes
    { :email => 'joe@bloggs.com',
      :username => 'joebloggs',
      :password => 'abcdefg' }
  end
end

context "A user (in general)" do
  include UserSpecHelper

  setup do
    @user = User.new
  end

  specify "should be invalid without a username" do
    @user.attributes = valid_user_attributes.except(:username)
    @user.should_not_be_valid
    @user.errors.on(:username).should_equal "is required"
    @user.username = 'someusername'
    @user.should_be_valid
  end

  specify "should be invalid without an email" do
    @user.attributes = valid_user_attributes.except(:email)
    @user.should_not_be_valid
    @user.errors.on(:email).should_equal "is required"
    @user.email = 'joe@bloggs.com'
    @user.should_be_valid
  end

  specify "should be invalid without a password" do
    @user.attributes = valid_user_attributes.except(:password)
    @user.should_not_be_valid
    @user.password = 'abcdefg'
    @user.should_be_valid
  end
end

There, thats much DRYer, more expressive and easier to maintain. If our valid attributes ever change, we only need to change them in one place. However, we haven’t sacrificed readability in the name of DRY, which is very important with any tests/specs.

Finally, lets add a spec for our password length:

specify "should be invalid if password is not between 6 and 12 characters in length" do
  @user.attributes = valid_user_attributes.except(:password)
  @user.password = 'abcdefghijklm'
  @user.should_not_be_valid
  @user.password = 'abcde'
  @user.should_not_be_valid
  @user.password = 'abcdefg'
  @user.should_be_valid
end

And to make it pass:

class User < ActiveRecord::Base
  attr_accessor :password

  validates_presence_of :username, :message => 'is required'
  validates_presence_of :email, :message => 'is required'
  validates_presence_of :password
  validates_length_of :password, :in => 6..12, :allow_nil => :true
end

You’ll notice we’ve added the :allow_nil option to the length validation. This is to avoid a double validation error if we haven’t set a password – the validates_presence_of validation will already handle this and we don’t want an extra error message complaining about the length of the password as well.

There is one last refactoring that we can do at this stage. In each of our validation specs, we’ve checked that the model is invalid, then set the required value and checked that it is now valid, to ensure that the validation is working end to end. We can extract all of these checks into a single specification:

specify "should be valid with a full set of valid attributes" do
    @user.attributes = valid_user_attributes
    @user.should_be_valid
  end
</code></pre>

"Download the full specification.":http://pastie.caboo.se/10720/text

Whats next?

So far we’ve written a basic User model, with an initial schema and a validation of required attributes. We’ve covered the basics of RSpec syntax and we’ve learnt how to DRY up our specs by extracting common code into a helper module.

In the second part of this tutorial, we’ll look at password encryption and authentication. If you have any questions or feedback, do not hesitate to leave a comment; I’ll be happy to answer any queries you may have.

SoundBytes: geddit?

Posted about 8 years back at Luke Redpath - Home

In the style of 37Signals “SunSpots” articles – a small collection of odds and ends not big enough to warrant an entire entry to themselves – I present to you SoundBytes; little bites of information (but bytes, because we are geeks, right?) that are, as any of my Northern friends would say, sound.

Just two small little bite-sized nuggets for this edition…

Automatic stylesheet inclusion with stylesheet_include_tag

First up, stylesheet_include_tag is a small Rails helper that I wrote to help me organise my application stylesheets. I named it _include_tag to distinguish it from Rails’ own stylesheet_link_tag.

First of all, here’s the code:

def stylesheet_include_tag(*sources)
  if sources.include?(:controller)
    sources.delete(:controller)
    sources.push(controller_stylesheet_source) if stylesheet_exists(controller_stylesheet_source)
  end
  if sources.include?(:action)
    sources.delete(:action)
    sources.push(action_stylesheet_source) if stylesheet_exists(action_stylesheet_source)
  end
  if sources.include?(:defaults)
    sources.delete(:defaults)
    sources.unshift('application')
    sources.push(controller_stylesheet_source) if stylesheet_exists(controller_stylesheet_source)
    sources.push(action_stylesheet_source) if stylesheet_exists(action_stylesheet_source)
  end
  sources.collect { |source|
    path = "/stylesheets/#{source}.css"
    tag('link', { 'type' => 'text/css', 'rel' => 'stylesheet', 'href' => path})
  }.join("\n")
end

protected
  def controller_stylesheet_source
    params[:controller]
  end
  
  def action_stylesheet_source
    [ params[:controller], params[:action] ].join("_")
  end
  
  def stylesheet_path(source)
    "#{RAILS_ROOT}/public/stylesheets/#{source}.css"
  end
  
  def stylesheet_exists(source)
    File.exists?(stylesheet_path(source))
  end

So how do you use this little helper? It’s quite simple really – it takes three options:

  • :controller – looks for a stylesheet under /public/stylesheets called controllername.css – if it finds one, it will automatically include it.
  • :action – as above, except it looks for a stylesheet called controllername_actionname.css
  • :defaults – a combination of the two above options, plus it also looks for a stylesheet called application.css – this is the one that I usually use.

So what do you gain? Simply, the ability to break apart your stylesheets into sensible chunks (with global styles in application.css) and not having to worry about adding a link tag for every stylesheet you want to use. Simply drop in a stylesheet under /public/stylesheets using the naming conventions above and it will automatically detect it and add a link tag for you.

Just drop the above code into your ApplicationHelper (or a separate file, and include it) and that is all there is to it. This is one of the many helpers that I’ve written that I just couldn’t live without.

Comment notification for Mephisto

As you might have read, I recently moved my blog over to Mephisto from Wordpress. I’m loving Mephisto, but one of the features I miss is email notification of new comments. You could just use the RSS feed but some people, including myself, prefer email notifications. Implementing email notifications was pretty trivial – it was just a case of hooking up an observer to the Comment class. I’ve packaged up the extension as a normal Rails plugin. As I’m using trunk/tags you probably won’t have much luck installing it with script/plugin, so use svn co instead:

$ svn co http://opensource.agileevolved.com/svn/root/rails_plugins/mephisto_comment_notification/trunk \
  vendor/plugins/mephisto_comment_notification

Please report any problems with the above plugin on the Agile Evolved Open Source Trac.