<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><description>This is the company weblog of thoughtbot, a web development business based in Boston, MA.</description><title>GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS</title><generator>Tumblr (3.0; @thoughtbot-giantrobots)</generator><link>http://robots.thoughtbot.com/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/GiantRobotsSmashingIntoOtherGiantRobots" type="application/rss+xml" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>2 years of hackfests</title><description>&lt;p&gt;On Tuesday, we’ll be hosting &lt;a href="http://bostonrb.org/events/108"&gt;the November Boston.rb hackfest&lt;/a&gt; at the thoughtbot Boston office. This marks two years and about 30 total hackfests we’ve held here.&lt;/p&gt;

&lt;p&gt;If you’ve never attended, please join us &lt;a href="http://bostonrb.org"&gt;the first Tuesday night of every month&lt;/a&gt;. All skill levels and backgrounds are welcome.&lt;/p&gt;

&lt;h2&gt;attendance award&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://technicalpickles.com"&gt;Josh Nichols&lt;/a&gt; deserves special recognition for attendance. He has attended more hackfests than anyone else and had about a year streak of perfect attendance once.&lt;/p&gt;

&lt;p&gt;Thanks, Josh, for keeping the group active and vibrant.&lt;/p&gt;

&lt;h2&gt;celebrating the output&lt;/h2&gt;

&lt;p&gt;While the majority of the fun of the hackfests is meeting other locals interested in similar technologies, there has been an impressive number of open source projects big and small to which Boston Rubyists have contributed patches big and small during these hackfests.&lt;/p&gt;

&lt;p&gt;We’d like to highlight those now and thank all those for contributing.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Hackers" src="https://thoughtbot-training.s3.amazonaws.com/images/hackers.jpg" width="420"/&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note that many of the following were not written at the hackfests, although some were. All of the large projects simply had patches written at the hackfests by Boston Rubyists.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;web application frameworks&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/rails/rails"&gt;Ruby on Rails&lt;/a&gt; is a full stack, Web application framework optimized for sustainable programming productivity, allows writing sound code by favoring convention over configuration.&lt;/p&gt;

&lt;h2&gt;gem management&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/qrush/gemcutter"&gt;Gemcutter&lt;/a&gt; is an open source Sinatra-and-Rails app for hosting Rubygems… awesomely.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/technicalpickles/jeweler"&gt;Jeweler&lt;/a&gt; is a simple and opinionated helper for creating and managing Rubygem projects.&lt;/p&gt;

&lt;h2&gt;testing&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/dchelimsky/rspec"&gt;RSpec&lt;/a&gt; is a Behaviour Driven Development framework for Ruby.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/aslakhellesoy/cucumber"&gt;Cucumber&lt;/a&gt; is a BDD framework that talks to domain experts first and code second.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/dchelimsky/rspec-rails"&gt;rspec-rails&lt;/a&gt; is an RSpec extension that allows you to drive the development of Ruby on Rails applications with RSpec.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/thoughtbot/shoulda"&gt;Shoulda&lt;/a&gt; is a context test framework built on Test::Unit and a set of Rails testing “macros” that can be used in any Ruby testing framework (RSpec, test/spec, etc.).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/thoughtbot/quietbacktrace"&gt;Quiet Backtrace&lt;/a&gt; suppresses the noise in your Test::Unit backtraces.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/jferris/mocha"&gt;jferris/mocha&lt;/a&gt; is a fork of Mocha that adds test spies.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/btakita/rr"&gt;RR&lt;/a&gt; (Double Ruby) is a test double framework that features a rich selection of double techniques and a terse syntax.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/jasonm/greengreen"&gt;greengreen&lt;/a&gt; is a tool for assuring quality metrics of 100% quality.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/thoughtbot/factory_girl"&gt;Factory Girl&lt;/a&gt; is a fixtures replacement with a straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), including factory inheritance.&lt;/p&gt;

&lt;h2&gt;templating things&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/jferris/effigy"&gt;Effigy&lt;/a&gt; is Ruby views without a templating language. (alternative to Mustache, ERb)&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/nakajima/slidedown"&gt;Slidedown&lt;/a&gt; lets you generate slides with Markdown, for display in web browsers.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/mojombo/jekyll"&gt;Jekyll&lt;/a&gt; is a simple, blog aware, static site generator that takes a template directory (representing the raw form of a website), runs it through Textile or Markdown and Liquid converters, and spits out a complete, static website suitable for serving with Apache or your favorite web server.&lt;/p&gt;

&lt;h2&gt;Rails apps&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/bostonrb/bostonrb"&gt;Boston.rb&lt;/a&gt; is the source code for &lt;a href="http://bostonrb.org"&gt;&lt;a href="http://bostonrb.org"&gt;http://bostonrb.org&lt;/a&gt;&lt;/a&gt;, a community site for local Rubyists.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/joshuaclayton/peas"&gt;Peas&lt;/a&gt; is the source code for &lt;a href="http://peas.heroku.com"&gt;&lt;a href="http://peas.heroku.com"&gt;http://peas.heroku.com&lt;/a&gt;&lt;/a&gt;, a URL shortener.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/dmitryame/echowaves"&gt;Echowaves&lt;/a&gt; is the source code for &lt;a href="http://echowaves.com"&gt;&lt;a href="http://echowaves.com"&gt;http://echowaves.com&lt;/a&gt;&lt;/a&gt;, social group chat aimed as an open source alternative to Campfire.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/dmitryame/cleantogether"&gt;Clean Together&lt;/a&gt; is the source code for &lt;a href="http://cleantogether.com"&gt;&lt;a href="http://cleantogether.com"&gt;http://cleantogether.com&lt;/a&gt;&lt;/a&gt;, which lets people post their environmental cleanup experiences.&lt;/p&gt;

&lt;h2&gt;generators&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/dancroak/blitz"&gt;Blitz&lt;/a&gt; is a Rails plugin for feature, view, controller, model, &amp; helper generators meant to be used as part of an “Outside-In” Test-Driven Development cycle.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/dancroak/webster"&gt;Webster&lt;/a&gt; generates random short words good for human-readable confirmation codes.&lt;/p&gt;

&lt;h2&gt;configuration&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/jferris/config_files"&gt;jferris/config_files&lt;/a&gt; is dotfiles for git, vim, zsh, &amp; irb.&lt;/p&gt;

&lt;h2&gt;process management&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/dpickett/under_construction"&gt;Under Construction&lt;/a&gt; is JQuery Utility for hiding or overlaying elements that haven’t been built yet, inspired by &lt;a href="http://github.com/thoughtbot/mile_marker"&gt;Mile Marker&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;search&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/technicalpickles/ambitious-sphinx"&gt;Ambitious Sphinx&lt;/a&gt; is an Ambition adapter for Sphinx.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/eugenebolshakov/search_model"&gt;SearchModel&lt;/a&gt; is a Rails plug-in for building search forms.&lt;/p&gt;

&lt;h2&gt;authentication&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/thoughtbot/clearance"&gt;Clearance&lt;/a&gt; is a Rails engine for authentication with email &amp; password.&lt;/p&gt;

&lt;h2&gt;computer science&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/dgoldhirsch/cs"&gt;CS&lt;/a&gt; is is a gem containing some algorithms useful for computer science and math.&lt;/p&gt;

&lt;h2&gt;command-line interfaces&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/qrush/beardo"&gt;Beardo&lt;/a&gt; is a CLI for &lt;a href="http://coopapp.com"&gt;Co-op&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/dancroak/hello"&gt;Hello&lt;/a&gt; is a Ruby interface to a collection of the word “hello” in many languages and dialects; written for Flickr-style messages after users sign in to a web application.&lt;/p&gt;

&lt;h2&gt;web service API wrappers&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/technicalpickles/le-git/"&gt;Le-Git&lt;/a&gt; is a Ruby wrapper for the Github API.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/technicalpickles/daywalker/"&gt;Daywalker&lt;/a&gt; is a Ruby wrapper around the &lt;a href="http://wiki.sunlightlabs.com/Sunlight_API_Documentation"&gt;Sunlight Labs&lt;/a&gt; API.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/dancroak/twitter-search"&gt;Twitter Search&lt;/a&gt; is a Ruby wrapper around the Twitter API.&lt;/p&gt;

&lt;h2&gt;countless failed and semi-failed experiments, incomplete hacks, forks, &amp; bad ideas&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Daddy Warbucks&lt;/em&gt; was a library idea to find orphaned Ruby code not&lt;br/&gt;
being sent messages from anywhere in your program. We learned a little bit about &lt;code&gt;Kernel#set_trace_func&lt;/code&gt; and called it a night.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Recommendable&lt;/em&gt; was a Rails plugin concept for simple item-to-item collaborative filtering.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/dancroak/nurse"&gt;Nurse&lt;/a&gt; cares for invalid ActiveRecord objects.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/dancroak/rails-templates"&gt;dancroak/rails-templates&lt;/a&gt; contains Rails templates for Suspenders, Heroku, &amp; MongoDB.&lt;/p&gt;

&lt;p&gt;MySpace API Ruby wrapper.&lt;/p&gt;

&lt;p&gt;Wikipedia API Ruby wrapper.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ActiveObject&lt;/em&gt; was an ActiveRecord-like library for persisted serialized Ruby objects.&lt;/p&gt;

&lt;p&gt;Altering Shoulda to use &lt;a href="http://github.com/jeremymcanally/context"&gt;context&lt;/a&gt; as its context/should framework.&lt;/p&gt;

&lt;p&gt;Benchmarking an add-on to &lt;a href="http://github.com/macournoyer/thin"&gt;Thin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;An &lt;a href="http://groups.google.com/group/boston-rubygroup/browse_thread/thread/5f69015e5d1b1e34/5662800484ca8fc4"&gt;early, failed attempt&lt;/a&gt; at what Joe Ferris would later accomplish in Factory Girl.&lt;/p&gt;

&lt;p&gt;Porting apps to Rails 2.1. Porting plugins to gems.&lt;/p&gt;

&lt;p&gt;Videoconferencing in &lt;a href="http://www.workingwithrails.com/person/2244-eloy-duran"&gt;Eloy Duran&lt;/a&gt; at 1am his time in Amsterdam to talk about RubyCocoa.&lt;/p&gt;

&lt;p&gt;Creating the first version of bostonrb.org in Merb, Haml, &amp; DataMapper when none of us had ever used any of those tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/slack12/1816776341/"&gt;&lt;img src="http://farm3.static.flickr.com/2081/1816776341_e1501712bf.jpg" alt="Boston skyline"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;and a lot of pizza &amp; beer…&lt;/h2&gt;

&lt;p&gt;I’m sure I missed a lot. Feel free to add anything to the comments.&lt;/p&gt;

&lt;p&gt;See you Tuesday night!&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/J-QOcYy0Q3k/228155634</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/228155634</guid><pubDate>Fri, 30 Oct 2009 15:10:00 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/228155634</feedburner:origLink></item><item><title>Sharing assertions between Cucumber and Test::Unit</title><description>&lt;p&gt;YO CUCUMBER, imma let you finish but according to &lt;code&gt;rake stats&lt;/code&gt;, my units have the best collection of hand-rolled assertions of ALL TIME.&lt;/p&gt;

&lt;p&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/7k0ZMDwmzHI&amp;hl=en&amp;fs=1&amp;"&gt;
&lt;param name="allowFullScreen" value="true"&gt;
&lt;param name="allowscriptaccess" value="always"&gt;
&lt;embed src="http://www.youtube.com/v/7k0ZMDwmzHI&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Guinea Pigs Battle for Cucumber: a compelling and entertaining short film&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;How to share with Cucumber&lt;/h1&gt;

&lt;p&gt;The gist is this: declare your assertions in a &lt;code&gt;TestSupport::Assertions&lt;/code&gt; module, inside &lt;code&gt;test/support&lt;/code&gt; — feel free to split them up into multiple files, to keep things organized.  Then, both Test::Unit and Cucumber will load those files up and include the modules as appropriate:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[~/dev/app] tail -n 2 features/support/env.rb
Dir[File.join(RAILS_ROOT, 'test', 'support', '*.rb')].each { |f| require f }
World(TestSupport::Assertions)

[~/dev/app] tail -n 4 test/test_helper.rb
Dir[File.join(RAILS_ROOT, 'test', 'support', '*.rb')].each { |f| require f }
class Test::Unit::TestCase
  include TestSupport::Assertions
end

[~/dev/app] cat test/support/stuff_assertions.rb
module TestSupport
  module Assertions
    def assert_stuff(params)
      assert_match /stuff/, params
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ker-DRYed up code!&lt;/p&gt;

&lt;h2&gt;Letters from viewers&lt;/h2&gt;

&lt;p&gt;I hear from &lt;a href="http://robots.thoughtbot.com/post/219216005/fake-it"&gt;people who know about testing&lt;/a&gt; that this approach to sharing between units and Cucumber is de-facto in RSpec.&lt;/p&gt;

&lt;p&gt;So, what do you like to share between Cucumber and your unit tests?&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/dgJ-s8GWg7M/220864386</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/220864386</guid><pubDate>Fri, 23 Oct 2009 08:00:00 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/220864386</feedburner:origLink></item><item><title>Have you ever...faked it?</title><description>&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_krvk95kMJb1qzocnw.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;I’ll admit it - I’ve faked it. Sometimes, you just can’t wait for a service to finish and you just want to fake a satisfactory response. There are lots of techniques for doing this: &lt;a href="http://xunitpatterns.com/Test%20Stub.html"&gt;stubs&lt;/a&gt;, &lt;a href="http://xunitpatterns.com/Mock%20Object.html"&gt;mocks&lt;/a&gt;, &lt;a href="http://xunitpatterns.com/Test%20Spy.html"&gt;spies&lt;/a&gt;, and &lt;a href="http://xunitpatterns.com/Fake%20Object.html"&gt;fakes&lt;/a&gt;. A full fake object will require more up-front effort than a quick stub, but they can be more reusable, reliable, and fail-proof.&lt;/p&gt;

&lt;h2&gt;Keeping your tests local&lt;/h2&gt;

&lt;p&gt;Probably the first reason every developer encounters that drives them to &lt;a href="http://xunitpatterns.com/Test%20Double.html"&gt;test doubles&lt;/a&gt; of any kind is an external service. Writing tests that interact with a live server is bad for a number of reasons: it’s slow, it’s hard to setup your test, and your tests will likely &lt;a href="http://xunitpatterns.com/Erratic%20Test.html#Interacting%20Tests"&gt;interact&lt;/a&gt; with each other (or other developers’ tests). You’ll also eventually run into that frustrating situation where server downtime results in a development blackout.&lt;/p&gt;

&lt;h2&gt;Overriding methods&lt;/h2&gt;

&lt;p&gt;Ruby is extremely flexible with its class definitions, to the point that you’re allowed to reopen and append (or redefine) methods at any point. I’ve seen lots of projects where this is used to simply white out pieces of the application that developers don’t want running in tests:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# The production code
# app/models/event.rb

class Event &lt; ActiveRecord::Base
  before_validation :geocode
  # ...
  private
  def geocode
    geo = GeoKit::Geocoders::MultiGeocoder.geocode(address)
    if geo.success
      self.lat, self.lng = geo.lat, geo.lng
    else
      self.errors.add(:address, 'Unable to identify your location.')
      false
    end
  end
end

# The override
# test/support/geocoding.rb

module GeoKit
  module Geocoders
    class MultiGeocoder &lt; Geocoder
      def self.geocode(location)
        loc = GeoLoc.new
        loc.lat = 1
        loc.lng = 1
        loc.success = true
        loc
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That little snippet lets you hit the ground running. Your tests don’t need to
hit an external server, and you can test that a latitude and longitude is
assigned when the record is created. However, you can’t test the negative
case, and if you want to write tests for geo-spatial search, you’re out of
luck.&lt;/p&gt;

&lt;h2&gt;Using stubs&lt;/h2&gt;

&lt;p&gt;If you need different geocoded results in different tests, a straight-up
override won’t do it for you. At this point, a developer might turn to stubs
and mocks:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe Event do
  it "should geocode a valid location" do
    loc = GeoLoc.new
    loc.lat = 100
    loc.lng = 200
    loc.success = true
    GeoKit::Geocoders::MultiGeocoder.
      stubs(:geocode).
      with('123 Happy Street').
      returns(loc)
    event = Factory.build(:event, :address =&gt; '123 Happy Street')
    event.save
    event.lat.should == loc.lat
    event.lng.should == loc.lng
  end

  it "should add an error message with an invalid location" do
    loc = GeoLoc.new
    loc.success = false
    GeoKit::Geocoders::MultiGeocoder.
      stubs(:geocode).
      with('123 Sad Lane').
      returns(loc)
    event = Factory.build(:event, :address =&gt; '123 Sad Lane')
    event.save
    event.should_not be_valid
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You’ll probably need to stub out geo locations several times throughout the
test suite, so wrapping these up in helper methods helps:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe Event do
  it "should geocode a valid location" do
    loc = build_geoloc(:lat =&gt; 100, :lng =&gt; 200, :success =&gt; true)
    stub_geoloc!('123 Happy Street' =&gt; loc)
    event = Factory.build(:event, :address =&gt; '123 Happy Street')
    event.save
    event.lat.should == loc.lat
    event.lng.should == loc.lng
  end

  it "should add an error message with an invalid location" do
    loc = build_geoloc(:success =&gt; false)
    stub_geoloc!('123 Sad Lane' =&gt; loc)
    event = Factory.build(:event, :address =&gt; '123 Sad Lane')
    event.save
    event.should_not be_valid
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, this leads to a few new problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most of the time you create an Event in a test, you don’t care about geocoding, so you’ll probably still need to add an override.&lt;/li&gt;
&lt;li&gt;Writing stubs like this in Cucumber tests is tricky - you need to make sure your stubs are torn down, and refactoring your implementation will noisily cause scenarios to fail. This isn’t what you want from an integration test.&lt;/li&gt;
&lt;li&gt;You can’t test the stubs themselves, and these methods are difficult to reuse, especially between projects.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Swappable components&lt;/h2&gt;

&lt;p&gt;One of the best pieces of programming advice I’ve ever received is this: “separate the pieces that change from the pieces that don’t.” Logic that doesn’t directly apply to your domain, such as geocoding and credit card processing, are likely to change. Which provider will you use? Do you need failover support? Adding the code (and tests) to your models is likely to increase churn and noise in the essential models of your application. Extracting these other concerns to external components helps reduce this noise. Writing these components so that the implementation can be swapped out will take you even further.&lt;/p&gt;

&lt;p&gt;Luckily, in the case of GeoKit, this has all been done for you. GeoKit supports several Geocoders, and the list of Geocoders that will be used can be configured per-environment. The list of Geocoders is configured via the global “provider_order” setting:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;GeoKit::Geocoders::provider_order = [:fake]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;GeoKit will look for a camelized constant nested under GeoKit::Geocoders for each provider specified, so you can write a fake geocoder like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module GeoKit
  module Geocoders
    class FakeGeocoder &lt; Geocoder
      def self.geocode(location)
        # return a GeoLoc instance
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you maintain a global registry of locations mapped to latitude and longitude, you can write steps like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Given /^the following geolocations:$/ do |table|
  table.hashes.each do |hash|
    location = hash['Location']
    lat = hash['Lat'].to_f
    lng = hash['Lng'].to_f
    GeoKit::Geocoders::FakeGeocoder.locations[location] = [lat, lng]
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Because GeoKit allows you to swap out the geocoder implementation without changing your model code, there’s no test-specific code in your model, no overrides to look for, and no extra churn in your model if you decide to switch providers.&lt;/p&gt;

&lt;h2&gt;Keeping it fresh&lt;/h2&gt;

&lt;p&gt;One potential issue with the above faking strategy is that there are a number of globals involved: the GeoKit provider is specified globally, as is the registry of fake locations. This means that you’ll need a teardown phase to clear the registry. In this case, there’s little reason to swap out implementation at runtime or between tests. However, if you’re faking out something that changes live, these global won’t do.&lt;/p&gt;

&lt;p&gt;When possible, I recommend accepting the external component as a parameter. If Event could take a GeoKit provider as a parameter, you could write tests like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe Event do
  it "should geocode a valid location" do
    fake_geocoder = FakeGeocoder.new('123 Happy Street' =&gt; [100, 200])
    event = Factory.build(:event, :address =&gt; '123 Happy Street',
                                  :geocoder =&gt; fake_geocoder)
    event.save
    event.lat.should == 100
    event.lng.should == 200
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There’s no teardown required. The FakeGeocoder is discarded after the test executes, so the mapped locations don’t live beyond the test.&lt;/p&gt;

&lt;h2&gt;Keeping it real&lt;/h2&gt;

&lt;p&gt;When faking out a component, make sure you adequately reproduce the actual expected behavior. When faking out payment gateways, you’ll need to cover a variety of error responses and so on. When faking out a geocoder backend, you may want to simulate timeout errors and other failures. Make sure you have enough test cases that your application will catch the edge cases that occur when using the real thing.&lt;/p&gt;

&lt;h2&gt;Apply liberally&lt;/h2&gt;

&lt;p&gt;Developers are forced to extract code into external components when it’s just not feasible to use the same code in the tests, as is the case when contacting external services. However, there are many pieces of behavior that can be extracted that don’t need to be: searching, authentication, and so on.&lt;/p&gt;

&lt;p&gt;Although developers usually only use stubs and mocks when they need to, many developers eventually prefer the isolation, speed, and declaritive nature of such doubles. If you start experimenting with fakes in place of mocks for external services, you may find that there are pieces of your code that you could swap out just to keep the churn down in your models, or to keep your tests focused on what they’re testing.&lt;/p&gt;

&lt;p&gt;How about you? Have you ever…faked it?&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/bDiMaZCjXCM/219216005</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/219216005</guid><pubDate>Wed, 21 Oct 2009 13:37:00 -0400</pubDate><category>testing</category><category>doubles</category><category>fakes</category><feedburner:origLink>http://robots.thoughtbot.com/post/219216005</feedburner:origLink></item><item><title>Video: Sinatra at Boston.rb, part 3</title><description>&lt;p&gt;This is the third in a series of short videos. They feature Blake Mizerany discussing Sinatra and Heroku in great technical detail at September’s Boston.rb. Watch &lt;a href="http://robots.thoughtbot.com/post/215005339/sinatra-at-boston-rb-part-1"&gt;Part 1&lt;/a&gt; and &lt;a href="http://robots.thoughtbot.com/post/215237920/sinatra-at-boston-rb-part-2"&gt;Part 2&lt;/a&gt; if you’d like.&lt;/p&gt;

&lt;p&gt;&lt;object width="400" height="300"&gt;&lt;param name="allowfullscreen" value="true"&gt;
&lt;param name="allowscriptaccess" value="always"&gt;
&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=7114267&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1"&gt;
&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=7114267&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;h2&gt;legacy APIs&lt;/h2&gt;

&lt;p&gt;Blake uses “legacy APIs” as a common use case for Sinatra. The reason &lt;code&gt;params[:splat]&lt;/code&gt; and &lt;code&gt;params[:matches]&lt;/code&gt; and super-flexible routing in Sinatra exists is because of work done on an existing non-RESTful, ugly API that sent all the data back in the URL itself (not in JSON or some other format).&lt;/p&gt;

&lt;p&gt;This seems to be consistent with the philosophy of “&lt;a href="http://adam.blog.heroku.com/past/2008/8/12/dont_fear_the_urls/"&gt;Don’t fear the URLs&lt;/a&gt;”.&lt;/p&gt;

&lt;h2&gt;return values must respond to “each”&lt;/h2&gt;

&lt;p&gt;In order to be Rack-compliant, your return values of Sinatra routes should respond to each. Blake mentions the Ruby 1.9 gotcha that the Rack spec also mentions:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The Body must respond to each and must only yield String values. The Body should not be an instance of String, as this will break in Ruby 1.9. If the Body responds to close, it will be called after iteration. If the Body responds to to_path, it must return a String identifying the location of a file whose contents are identical to that produced by calling each. The Body commonly is an Array of Strings, the application instance itself, or a File-like object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;templates&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;get '/' do
  erb(:index)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The file would be named “index.erb”. Sintra doesn’t use the same “name.format.template” convention because the routes are supposed to be “less magical”. You should know what your response format is based on which route you’re already in.&lt;/p&gt;

&lt;h2&gt;begin/rescue vs. throw :halt&lt;/h2&gt;

&lt;p&gt;I hadn’t seen a discussion of these two control structures before. &lt;code&gt;begin/rescue&lt;/code&gt; is meant for exceptions and &lt;a href="http://railsapi.com/doc/sinatra-v0.9.4/classes/Sinatra/Base.html#M000066"&gt;throw :halt&lt;/a&gt; is meant for returning a value and returning to another section of code.&lt;/p&gt;

&lt;p&gt;The promise is that this will come in very handy as we dive deeper into Sinatra.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/' do
  halt(404) unless session[:user]
  # ...
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As Sinatra processes the route, it’s listening for &lt;code&gt;halt&lt;/code&gt;s and &lt;code&gt;pass&lt;/code&gt;es.&lt;/p&gt;

&lt;h2&gt;when Sinatra, when Rails?&lt;/h2&gt;

&lt;p&gt;I cut a section out for space reasons where Blake talks about thanking David Heinemeier Hansson for writing Rails. Blake had been trying to get Ruby into companies for years without much success, then Rails came along and made it acceptable.&lt;/p&gt;

&lt;p&gt;Rails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;get bigger apps going quickly&lt;/li&gt;
&lt;li&gt;less pain to get a CRUD app going&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sinatra:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;more control&lt;/li&gt;
&lt;li&gt;choose your own conventions&lt;/li&gt;
&lt;li&gt;legacy APIs&lt;/li&gt;
&lt;li&gt;small apps going quickly&lt;/li&gt;
&lt;li&gt;take full advantage of Rack, no special magic to be compatible&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;shotgun&lt;/h2&gt;

&lt;p&gt;At the end of this video, I included a section where Blake shows, in response to an audience question, how to append to an existing body via &lt;code&gt;response.body&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I thought his &lt;code&gt;shotgun&lt;/code&gt; command was more interesting, though.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/rtomayko/shotgun"&gt;Shotgun&lt;/a&gt; is “an automatic reloading version of the rackup command that’s shipped with Rack.” It gets you “application-wide reloading of all source files and templates on each request” by forking into a child process, processing, then exiting the child process.&lt;/p&gt;

&lt;p&gt;Note that this is not part of Sinatra at all. This is obviously great for a development environment, but keeps Sinatra clean by being a third party.&lt;/p&gt;

&lt;h2&gt;next&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Moving from “classic Sinatra” to &lt;code&gt;Sinatra::Base&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Why &lt;code&gt;throw :halt&lt;/code&gt; is so cool in practice.&lt;/li&gt;
&lt;/ul&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/z8iCqYznnX4/218275588</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/218275588</guid><pubDate>Tue, 20 Oct 2009 14:16:43 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/218275588</feedburner:origLink></item><item><title>Video: Sinatra at Boston.rb, part 2</title><description>&lt;p&gt;This is the second in a series of short videos. They feature Blake Mizerany discussing Sinatra and Heroku in great technical detail at September’s &lt;a href="http://bostonrb.org"&gt;Boston.rb&lt;/a&gt;. Watch &lt;a href="http://robots.thoughtbot.com/post/215005339/sinatra-at-boston-rb-part-1"&gt;Part 1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;object width="400" height="300"&gt;&lt;param name="allowfullscreen" value="true"&gt;
&lt;param name="allowscriptaccess" value="always"&gt;
&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=7108353&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1"&gt;
&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=7108353&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;In HD this time… watch out, the kid is learning!&lt;/p&gt;

&lt;h2&gt;“use” is built-in&lt;/h2&gt;

&lt;p&gt;In this video, Blake extends his example code using Rack middleware from &lt;a href="http://github.com/rack/rack-contrib"&gt;rack-contrib&lt;/a&gt; called &lt;a href="http://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/accept_format.rb"&gt;&lt;code&gt;Rack::AcceptFormat&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Adds a format extension at the end of the URI when there is none,
  corresponding to the mime-type given in the Accept HTTP header.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example from the docs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;GET /some/resource HTTP/1.1
Accept: application/json

GET /some/resource.json HTTP/1.1
Accept: application/json
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Blake says we can &lt;code&gt;use Rack::AcceptFormat&lt;/code&gt; in our &lt;code&gt;config.ru&lt;/code&gt; or in Sinatra, depending on the situation.&lt;/p&gt;

&lt;p&gt;This middleware will re-write &lt;a href="http://rack.rubyforge.org/doc/classes/Rack/Request.html#M000227"&gt;path_info&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What’s cool about this is Sinatra doesn’t have to know about &lt;code&gt;Rack::AcceptFormat&lt;/code&gt;’s deeds making our work with content types easier. By the time the request gets to Sinatra, “.json” has been added. Call it “just-in-time routing”.&lt;/p&gt;

&lt;h2&gt;Rack Hoptoad&lt;/h2&gt;

&lt;p&gt;On the day Blake spoke at Boston.rb, he and I sat down to get &lt;a href="http://github.com/atmos/rack-hoptoad"&gt;Rack Hoptoad&lt;/a&gt; working on Heroku. Staying true to the philosophy of &lt;a href="http://robots.thoughtbot.com/post/215005339/sinatra-at-boston-rb-part-1#backing-into-patterns"&gt;backing into patterns&lt;/a&gt;, we started with a bare-bones Rack app, then moved to Sinatra.&lt;/p&gt;

&lt;p&gt;In both cases, we need to specify the gem in our &lt;code&gt;.gems&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# &lt;a href="http://docs.heroku.com/gems#overview"&gt;http://docs.heroku.com/gems#overview&lt;/a&gt;
rack_hoptoad
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Rack:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# config.ru
require 'rack_hoptoad'

use Rack::HoptoadNotifier, "123abc"
run lambda { |env| fail "Fail!" }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sinatra:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# config.ru
require 'rack_hoptoad'
require 'example'

use Rack::HoptoadNotifier, "1234"
run Sinatra::Application

# example.rb
require 'sinatra'

configure :production do
  enable :raise_errors
end

get '/boom' do
  fail "Fail from Sinatra!"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;when Rack, when Sinatra?&lt;/h2&gt;

&lt;p&gt;Blake’s rule of thumb is to start with Rack when he knows, when he’s starting, that he’s only going to have one route, maybe two, and there’s nothing special about them.&lt;/p&gt;

&lt;p&gt;In many ways, Sinatra is just a clean DSL around HTTP with lots of delegation to Rack. Without it, you’d have messy conditional statements that are fine for a couple of routes, but get out of hand beyond that.&lt;/p&gt;

&lt;h2&gt;routing tricks&lt;/h2&gt;

&lt;p&gt;Access wildcard operators using block syntax instead of a Rails-style &lt;code&gt;params[:first_name]&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/:first_name/:last_name' do |first, last|
  "Hello, #{first} #{last}"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sinatra allows splats, such as this non-greedy match:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/:name.*?/:last' do
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The returned object will be a normal Ruby &lt;a href="http://www.ruby-doc.org/core/classes/MatchData.html"&gt;MatchData&lt;/a&gt; object, so everything you can do with that applies in your Sinatra code.&lt;/p&gt;

&lt;h2&gt;next&lt;/h2&gt;

&lt;p&gt;Stay tuned next time when our protagonist discusses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;POSTing data to a legacy API&lt;/li&gt;
&lt;li&gt;war stories&lt;/li&gt;
&lt;li&gt;view templates&lt;/li&gt;
&lt;/ul&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/N3VUjsGTPoM/215237920</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/215237920</guid><pubDate>Sat, 17 Oct 2009 00:06:30 -0400</pubDate><category>ruby</category><category>sinatra</category><category>web app</category><category>framework</category><feedburner:origLink>http://robots.thoughtbot.com/post/215237920</feedburner:origLink></item><item><title>Video: Sinatra at Boston.rb, part 1</title><description>&lt;p&gt;This the first in a series of short videos. They feature Blake Mizerany discussing Sinatra and Heroku in great technical detail at September’s &lt;a href="http://bostonrb.org"&gt;Boston.rb&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="437" height="370" id="viddler_tbot_6"&gt;&lt;param name="movie" value="http://www.viddler.com/player/e9e9aaf/"&gt;
&lt;param name="allowScriptAccess" value="always"&gt;
&lt;param name="allowFullScreen" value="true"&gt;
&lt;embed src="http://www.viddler.com/player/e9e9aaf/" wmode="transparent" width="437" height="370" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" name="viddler_tbot_6"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;Blake Mizerany wrote Sinatra in 2006 because he was working on a high traffic site with a lot of POSTs, PUTs, and DELETEs. GETs can be cached but the others cannot.&lt;/p&gt;

&lt;p&gt;In this video, Blake discusses the following concepts as they apply to Sinatra:&lt;/p&gt;

&lt;p&gt;&lt;a name="backing-into-patterns"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;backing into patterns&lt;/h2&gt;



&lt;p&gt;Start with a string, start with a text file, use &lt;code&gt;main&lt;/code&gt; on Ruby. Move up to Factories and Model-View-Controller and ActiveRecord when you need it.&lt;/p&gt;

&lt;p&gt;Rails creates 72 files when you run the &lt;code&gt;rails&lt;/code&gt; command. Blake decided he didn’t need to start with MVC on each new project.&lt;/p&gt;

&lt;h2&gt;clean routing system&lt;/h2&gt;

&lt;p&gt;Blake uses Sinatra often for web services. He compares Rails’ &lt;code&gt;respond_to&lt;/code&gt; with Sinatra’s &lt;code&gt;content_type&lt;/code&gt; declaration. He discusses his feeling that the routing systems in other frameworks are overly complex undesirable.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/users.json' do
  content_type :json
  @user = User.find(params[:id])
  @user.to_json
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;His first example, shown above, highlights Sinatra’s clean content type approach.&lt;/p&gt;

&lt;h2&gt;next&lt;/h2&gt;

&lt;p&gt;In the &lt;a href="http://robots.thoughtbot.com/post/215237920/sinatra-at-boston-rb-part-2"&gt;next video&lt;/a&gt;, Blake discusses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;handling the &lt;code&gt;Accepts&lt;/code&gt; header using Rack middleware&lt;/li&gt;
&lt;li&gt;deciding between Rack and Sinatra&lt;/li&gt;
&lt;li&gt;rack-hoptoad&lt;/li&gt;
&lt;li&gt;routing tricks such as passing wildcard params into block variables and non-greedy matching&lt;/li&gt;
&lt;/ul&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/a6qsa8VgZM4/215005339</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/215005339</guid><pubDate>Fri, 16 Oct 2009 18:03:00 -0400</pubDate><category>sinatra</category><category>heroku</category><category>rack</category><category>ruby</category><category>rails</category><category>patterns</category><feedburner:origLink>http://robots.thoughtbot.com/post/215005339</feedburner:origLink></item><item><title>fundamentals: TDD a date helper</title><description>&lt;p&gt;I want to format a date range in a view for our &lt;a href="http://training.thoughtbot.com/"&gt;training app&lt;/a&gt;. This is a job for helpers. A fundamental skill for Rails developers is writing the helper using TDD. This process takes about 10 minutes and results in a confidence-building regression suite.&lt;/p&gt;

&lt;p&gt;Working outside-in, we start in the interface:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;%= format_date_range(course.date_range) %&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Tests fail, “format_date_range” doesn’t exist.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;script/generate helper date_time
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Produces:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# app/helpers/date_time_helper.rb
module DateTimeHelper
end

# test/unit/helpers/date_time_helper_test.rb
require 'test_helper'

class DateTimeHelperTest &lt; ActionView::TestCase
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Incidentally, former thoughtbot intern &lt;a href="http://taknado.com"&gt;Eugene Bolshakov&lt;/a&gt; wrote &lt;a href="http://github.com/rails/rails/commit/3c9beb3dab73013af83b90983f283b76625052b8"&gt;the Rails patch&lt;/a&gt; that creates the helper test stub generator.&lt;/p&gt;

&lt;p&gt;First case:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;should "format date range on same day" do
  eight_oclock = DateTime.new(2009, 10, 12, 8)
  nine_oclock  = DateTime.new(2009, 10, 12, 9)
  date_range   = eight_oclock..nine_oclock
  expected     = "October 12, 2009"

  assert_equal expected, format_date_range(date_range)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;My style is flat test structure, intention-revealing temporary variables, respect an 80-character line limit.&lt;/p&gt;

&lt;p&gt;Make it pass:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def format_date_range(date_range)
  first = date_range.first
  last  = date_range.last
  if same_day?(first, last)
    "#{first.to_s(:month_day)}, #{first.year}"
  end
end

private

def same_day?(date_one, date_two)
  date_one.day == date_two.day
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;More temporary variables. Simple private method is there for a more expressive question in the conditional.&lt;/p&gt;

&lt;p&gt;Next case:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;should "format date range on different days of same month" do
  monday     = DateTime.new(2009, 10, 12)
  tuesday    = DateTime.new(2009, 10, 13)
  date_range = monday..tuesday
  expected   = "October 12-13, 2009"

  assert_equal expected, format_date_range(date_range)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Same pattern. Make it pass:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def format_date_range(date_range)
  # ...
  elsif same_month?(first, last)
    "#{first.to_s(:month_day)}-#{last.day}, #{last.year}"
  end
end

private

def same_month?(date_one, date_two)
  date_one.month == date_two.month
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Same pattern. Date and time formatting already has a home in &lt;code&gt;config/initializers/time_formats.rb&lt;/code&gt;, so we’re using our existing date format, &lt;code&gt;month_day&lt;/code&gt;. Here’s what my typical initializer looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{ :short_date  =&gt; "%x",                 # 04/13/10
  :long_date   =&gt; "%a, %b %d, %Y",      # Tue, Apr 13, 2010
  :longer_date =&gt; "%B %d, %Y %H:%M %Z", # April 13, 2010 11:20
  :index       =&gt; "%Y/%m/%d %H:%M",     # 2010/04/13 11:20
  :standard    =&gt; "%B %d, %Y",          # April 13, 2010
  :month_day   =&gt; "%B %d",              # April 13
  :abbr_month  =&gt; "%b"                  # Apr
}.each do |key, value|
  ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.update(
    key =&gt; value
  )
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Final case:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;should "format date range on days of different months" do
  october    = DateTime.new(2009, 10, 31)
  november   = DateTime.new(2009, 11, 1)
  date_range = october..november
  expected   = "October 31-November 01, 2009"

  assert_equal expected, format_date_range(date_range)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make it pass:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;else
  "#{first.to_s(:month_day)}-#{last.to_s(:month_day)}, #{last.year}"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There’s room for improvement: that leading zero sucks. We could use &lt;code&gt;%e&lt;/code&gt; instead of &lt;code&gt;%d&lt;/code&gt;, which replaces the leading zero with a space:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;expected   = "October 31-November  1, 2009"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That makes the test look a little ridiculous, but since the output will be HTML, the extra space is fine.&lt;/p&gt;

&lt;p&gt;Make it pass:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:month_day   =&gt; "%B %e"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://gist.github.com/211045"&gt;Complete source code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sneak peak of the app in progress, taking advantage of the date helper:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://thoughtbot-training.s3.amazonaws.com/images/training_app_sneak_peak.png" alt="Sneak peak of training.thoughtbot.com's new date helper"/&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/tGHaqT3KcXo/213842585</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/213842585</guid><pubDate>Thu, 15 Oct 2009 11:57:00 -0400</pubDate><category>testing</category><category>TDD</category><category>date</category><category>time</category><category>format</category><category>strftime</category><feedburner:origLink>http://robots.thoughtbot.com/post/213842585</feedburner:origLink></item><item><title>Slave to the intepreter</title><description>&lt;p&gt;I think of Ruby as the “free love” language. Yet, even Ruby can put the programmer in chains.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Mr. Slave" src="https://dancroak.s3.amazonaws.com/images/mr_slave.png" width="400"/&gt;&lt;/p&gt;

&lt;h2&gt;klass&lt;/h2&gt;

&lt;p&gt;Ever seen code like this?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;klass = Class.new
klass.class_eval do
  def self.xyz
    'xyz'
  end
end
@model = klass.new
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The programmer names the temporary variable “klass” to avoid a collision with the &lt;a href="http://www.ruby-doc.org/docs/keywords/1.9/files/keywords_rb.html#M000012"&gt;class keyword&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Bob Martin uses this as an anti-pattern, extolling programmers to “make meaningful distinctions” in &lt;a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882"&gt;Clean Code&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;misspelling and over-abbreviation&lt;/h2&gt;

&lt;p&gt;I wrote this last week:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;attitudes.each do |tude|
  # something
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cute. I re-wrote it.&lt;/p&gt;

&lt;p&gt;The problem was &lt;code&gt;attitude&lt;/code&gt; was also a method in scope.&lt;/p&gt;

&lt;h2&gt;restricted vocabulary&lt;/h2&gt;

&lt;p&gt;I’ve been working on our &lt;a href="http://training.thoughtbot.com"&gt;training application&lt;/a&gt;. The education domain is full of troublesome terms for software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;classes&lt;/li&gt;
&lt;li&gt;sessions&lt;/li&gt;
&lt;li&gt;forms (British)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We could start talking in terms of “workshops” or “seminars”, which we may have to for the purposes of the application, but it feels like the interpreter is pushing us around.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I’m the human; you’re the computer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I know I’m going to be teaching a &lt;em&gt;class&lt;/em&gt; and say things like “see you at tomorrow’s class.” That’s the most natural vocabulary, but the interpreter has its own ideas.&lt;/p&gt;

&lt;h2&gt;no way out&lt;/h2&gt;

&lt;p&gt;I don’t see a way around these problems, however. Just seems like the hand we’re dealt. Any creative solutions out there?&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/rBonI-c1ats/212191926</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/212191926</guid><pubDate>Tue, 13 Oct 2009 15:57:15 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/212191926</feedburner:origLink></item><item><title>code cowboy</title><description>&lt;p&gt;I’ve written before about &lt;a href="http://robots.thoughtbot.com/post/161233418/analysis-paralysis-access-control"&gt;lightweight access control&lt;/a&gt; using inherited_resource’s &lt;code&gt;begin_of_association_chain&lt;/code&gt; and raising a 404.&lt;/p&gt;

&lt;p&gt;I still prefer this approach in the vast majority of apps I work on, but it doesn’t work in the case where there is no relationship between a user and an object other than access control.&lt;/p&gt;

&lt;p&gt;&lt;img alt="gunshot" src="https://thoughtbot-training.s3.amazonaws.com/images/high_noon_strut.png" width="400"/&gt;&lt;/p&gt;

&lt;h2&gt;custom&lt;/h2&gt;

&lt;p&gt;Last week, I had a need to differentiate access control to some controller actions based on whether a signed in user was a &lt;code&gt;teacher&lt;/code&gt; or &lt;code&gt;student&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is a simple need, and I’m loathe to introduce a large gem into the app for what could just be a custom &lt;code&gt;before_filter&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class CoursesController &lt; InheritedResources::Base
  actions :new, :show, :index

  before_filter :authenticate
  before_filter :deny_student, :only =&gt; [:new]

  protected

  def deny_student
    deny_access if current_user.student?
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, I recently saw &lt;a href="http://github.com/be9/acl9"&gt;acl9&lt;/a&gt; mentioned on a mailing list and &lt;em&gt;really&lt;/em&gt; liked the DSL. Couldn’t we have the best of both worlds?&lt;/p&gt;

&lt;p&gt;So, Josh Clayton and I wrote up a sub-set of acl9’s DSL that would meet my needs.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module AccessControl
  def self.included(controller)
    controller.extend(ClassMethods)
    controller.send(:include, InstanceMethods)
  end

  module ClassMethods
    def access_control(options = {}, &amp;block)
      before_filter(options) do |controller|
        controller.authenticate
      end
      before_filter(options) do |controller|
        controller.instance_eval(&amp;block)
      end
    end
  end

  module InstanceMethods
    def allow(role, opts = {})
      if opts[:to].nil? || opts[:to].include?(action_name.to_sym)
        unless current_user.send("#{role}?")
          deny_access(opts[:flash])
        end
      end
    end

    def deny(role, opts = {})
      if opts[:from].nil? || opts[:from].include?(action_name.to_sym)
        if current_user.send("#{role}?")
          deny_access(opts[:flash])
        end
      end
    end
  end
end

ActionController::Base.send :include, AccessControl&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img alt="Gunshot" src="https://thoughtbot-training.s3.amazonaws.com/images/high_noon_saddlery.png" width="400"/&gt;&lt;/p&gt;

&lt;h2&gt;the DSL&lt;/h2&gt;

&lt;p&gt;In action:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class CoursesController &lt; InheritedResources::Base
  actions :new, :show, :index

  access_control do
    allow :teacher, :to =&gt; [:new]
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Very expressive. Nice work, Oleg Dashevskii!&lt;/p&gt;

&lt;p&gt;&lt;img alt="strut" src="https://thoughtbot-training.s3.amazonaws.com/images/high_noon_gunshot.png" width="400"/&gt;&lt;/p&gt;

&lt;h2&gt;features we cared about&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;optional flash mesage&lt;/li&gt;
&lt;li&gt;natural language (allow/to and deny/from)&lt;/li&gt;
&lt;li&gt;role is just a boolean on &lt;code&gt;User&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;opinions we could have&lt;/h2&gt;

&lt;p&gt;This will usually be included when most actions require a signed in user. Therefore, we call &lt;code&gt;authenticate&lt;/code&gt; and allow an ugly override for edge cases:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class CoursesController &lt; InheritedResources::Base
  actions :new, :show, :index

  access_control(:except =&gt; :show) do
    allow :teacher, :to =&gt; [:new]
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is used with &lt;a href="http://github.com/thoughtbot/clearance"&gt;Clearance&lt;/a&gt; and can therefore rely on &lt;code&gt;authenticate&lt;/code&gt;, &lt;code&gt;current_user&lt;/code&gt;, and &lt;code&gt;deny_access&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Girl, gun, clock" src="https://thoughtbot-training.s3.amazonaws.com/images/high_noon_gun_girl_clock.jpg" width="400"/&gt;&lt;/p&gt;

&lt;h2&gt;instance_eval&lt;/h2&gt;

&lt;p&gt;Writing code with a pretty DSL in mind is exceedingly fun. The one downside seems to be that &lt;em&gt;scope&lt;/em&gt; can become confusing.&lt;/p&gt;

&lt;p&gt;Yesterday I was messing with Rails app templates and read the source for the &lt;a href="http://github.com/rails/rails/blob/2-3-stable/railties/lib/rails_generator/generators/applications/app/template_runner.rb#L26"&gt;2.3 template runner&lt;/a&gt;. It, like this custom access control DSL, also uses &lt;code&gt;instance_eval&lt;/code&gt; as the key line to make things work.&lt;/p&gt;

&lt;p&gt;In the app template example, it was hard to figure out how to get the file path of the original template.&lt;/p&gt;

&lt;p&gt;I simply wanted to &lt;code&gt;require 'helper'&lt;/code&gt;, a separate file in the app template, but because of the scope within which it was &lt;code&gt;instance_eval&lt;/code&gt;‘d, &lt;code&gt;helper&lt;/code&gt; could not be found.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;in_root { self.instance_eval(code) }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The solution in that case was to take advantage of other public methods and mess with the load path, which would probably an atrocious solution for a vendored gem in a Rails app, but acceptable for a one-off script to generate a Rails app:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;here = File.expand_path(File.dirname(template), File.join(root,'..'))
$LOAD_PATH &lt;&lt; here
require 'helper'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the access control example, it was hard to figure out how to have access to &lt;code&gt;flash&lt;/code&gt;, &lt;code&gt;redirect_to&lt;/code&gt;, etc. from a class-level scope.&lt;/p&gt;

&lt;p&gt;Similar to the &lt;code&gt;require 'helper'&lt;/code&gt; example, your tests will fail if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;deny&lt;/code&gt; and &lt;code&gt;access&lt;/code&gt; are defined at the class level&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;instance_eval&lt;/code&gt; is not used to delay evaluation until runtime&lt;/li&gt;
&lt;li&gt;you don’t use &lt;code&gt;before_filter&lt;/code&gt;’s block&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The solution is to use blocks and lazy evaluation to control scope, but it can be confusing to get there:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;before_filter(options) do |controller|
  controller.authenticate
end
before_filter(options) do |controller|
  controller.instance_eval(&amp;block)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;not a code cowboy&lt;/h2&gt;

&lt;p&gt;Every time you decide to roll your own, remind yourself that you may waste time getting lost in something like a scope problem you haven’t seen before. Then, once you get the rhythm down, be careful of a thought like “it won’t take me that long to write.” Re-inventing the wheel has to be balanced with a specific reason in addition to, “it will be fun for me.”&lt;/p&gt;

&lt;p&gt;The third-party ecosystem of gems and plugins is one reason why Rails is awesome. However, writing custom code every now and again is worth it for programmer pleasure, fewer lines of code and dependencies, and staying focused on only what you need.&lt;/p&gt;

&lt;p&gt;Ruby makes great DSLs, though, so don’t be afraid to take inspiration from existing code and try your hand at making beautiful code for a specific purpose.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/O4e_qZGke6c/211268957</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/211268957</guid><pubDate>Mon, 12 Oct 2009 15:24:00 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/211268957</feedburner:origLink></item><item><title>Happy Birthday, Ralph</title><description>&lt;p&gt;&lt;img class="img_right" src="http://media.tumblr.com/tumblr_kquij4gPNt1qz4sb2.jpg"/&gt;&lt;/p&gt;

&lt;p&gt;Please join the celebration.&lt;/p&gt;

&lt;p&gt;Today is the 4th anniversary of the incorporation of thoughtbot, inc. (We previously existed as an MA state partnership - which turned 7 years old in July).  October also marks our 4th anniversary of working almost exclusively with ruby and rails as a web application platform.&lt;/p&gt;

&lt;p&gt;We’d like to thank our current and past employees for their commitment to producing quality software in a productive environment.  We created thoughtbot to make that environment a reality, and we love that it’s still going strong.&lt;/p&gt;

&lt;p&gt;We’d like to thank our current and past customers for hiring us - and give a special thanks to our earliest customers who had to make the case for an “unproven” technology within their organizations by choosing Rails as a platform.&lt;/p&gt;

&lt;p&gt;We’d also like to thank the Ruby community, all the other great Rails-focused companies doing web app development, the Rails core team, Ruby conference organizers, all our training alumni — for making the ruby community such a fun and professional place to exist as a software developer.&lt;/p&gt;

&lt;p&gt;We think our best work is yet to come, and look forward to the future with a sort of crazed, sinister-yet-loving robotic stare.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/CXMNhF_zGGU/201892518</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/201892518</guid><pubDate>Thu, 01 Oct 2009 13:37:45 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/201892518</feedburner:origLink></item><item><title>testing named scopes</title><description>&lt;p&gt;Everyone was psyched when Nick Kallen’s &lt;a href="http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality"&gt;has_finder plugin was added to Rails as named_scope&lt;/a&gt;. They’re powerful, particularly when chaining.&lt;/p&gt;

&lt;p&gt;One disadvantage is that they are so easy to create, people want their tests to be equally concise, which is often impossible.&lt;/p&gt;

&lt;p&gt;Two related “testing named scopes” questions have come up recently on the &lt;a href="http://thoughtbot.com/services/training"&gt;thoughtbot training&lt;/a&gt; mailing list and the &lt;a href="http://groups.google.com/group/shoulda"&gt;shoulda mailing list&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Movie recommendations: InternetFlicks&lt;/h2&gt;

&lt;p&gt;We’re going to create a movie recommendation system called InternetFlicks.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;script/generate model Movie ranking:integer in_stock:boolean
script/generate model Viewing user:belongs_to movie:belongs_to
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;user:belongs_to&lt;/code&gt; syntax is from &lt;a href="http://github.com/dancroak/blitz"&gt;Blitz&lt;/a&gt;. We’ll assume a &lt;code&gt;User&lt;/code&gt; model is already created, perhaps using &lt;a href="http://github.com/thoughtbot/clearance"&gt;Clearance&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Outside-In&lt;/h2&gt;

&lt;p&gt;Say we’re working on the recommendations page for the signed in user. RESTfully, this might be:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/recommendations
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can use a &lt;a href="http://robots.thoughtbot.com/post/161233418/analysis-paralysis-access-control"&gt;simple authorization strategy&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class RecommendationsController &lt; ApplicationController
  before_filter :authenticate
  def index
    @movies = Movie.recommended_for(current_user)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I’m skipping a few steps here, but our goal is to determine what interface the model needs to expose.&lt;/p&gt;

&lt;p&gt;Also note that we’re intentionally crossing resources (“recommendations”) in the RESTful sense with a model of a different name (“Movie”). This is something we’ve started to stress in &lt;a href="http://thoughtbot.com/services/training"&gt;training&lt;/a&gt; as many students have thought REST means they need to match controller names to models (probably because they’ve seen scaffold generation).&lt;/p&gt;

&lt;h2&gt;TDD will guide you to better habits&lt;/h2&gt;

&lt;p&gt;Use &lt;a href="http://robots.thoughtbot.com/post/191132156/role-suggesting-name"&gt;Role Suggesting Name&lt;/a&gt; for the test name, variable names, and method under test to describe the behavior of &lt;code&gt;Movie.recommended_for&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class MovieTest &lt; ActiveSupport::TestCase
  should "recommend 2 highest ranked, in stock movies unwatched by user" do
    user    = Factory(:user)
    top_out = Factory(:movie, :ranking =&gt; 100, :in_stock =&gt; false)
    top_in  = Factory(:movie, :ranking =&gt; 95,  :in_stock =&gt; true)
    next_in = Factory(:movie, :ranking =&gt; 90,  :in_stock =&gt; true)
    watched = Factory(:movie, :ranking =&gt; 100, :in_stock =&gt; true)
    Factory(:viewing, :user =&gt; user, :movie =&gt; watched)

    assert_equal [top_in, next_in], Movie.recommended_for(user, 2)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a state-based test. We create a user and a few movies, have him or her watch a movie, exercise the method, and verify the results match the test name.&lt;/p&gt;

&lt;p&gt;Skipping ahead again, say we’ve gone through a few red, green, refactor cycles, taking into account some edge cases, and the implementation now looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Movie &lt; ActiveRecord::Base
  def self.recommended_for(user, limit = 10)
    highest_ranked.in_stock.unwatched(user).limited(limit)
  end

  private

  named_scope :highest_ranked, :order =&gt; "ranking desc"
  named_scope :in_stock, :conditions =&gt; { :in_stock =&gt; true }
  named_scope :unwatched, lambda { |user|
    { :joins      =&gt; "left outer join viewings
                                   on viewings.movie_id = movies.id
                                  and viewings.user_id  = #{user.id}
                      left outer join users
                                   on users.id = viewings.id",
      :conditions =&gt; "users.id is null" }
  }
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cool, named_scopes helped us make the &lt;code&gt;recommended_for&lt;/code&gt; method expressive. If the specification for it changes, it will be a joy to change.&lt;/p&gt;

&lt;h2&gt;No tests for the private methods&lt;/h2&gt;

&lt;p&gt;We’ll test those private methods &lt;a href="http://archive.patmaddox.com/blog/2008/10/27/testing-protected-and-private-methods-in-ruby"&gt;like this&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If an object outside of &lt;code&gt;Movie&lt;/code&gt; needs &lt;code&gt;highest_ranked&lt;/code&gt; or one of the other private methods, we’ll write a unit test for it, watch it error, and bring it into a public scope piece by piece.&lt;/p&gt;

&lt;h2&gt;Discarded option: should_have_named_scope&lt;/h2&gt;

&lt;p&gt;About a year ago, &lt;a href="http://robots.thoughtbot.com/post/159806857/testing-named-scope"&gt;should_have_named_scope was introduced to Shoulda&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It was later deprecated. We never felt comfortable using it. While there’s something to be said for quick Shoulda one-liners, I don’t think there’s much of an argument for &lt;code&gt;should_have_named_scope&lt;/code&gt; except for simple scopes that are responsible for order or limit.&lt;/p&gt;

&lt;p&gt;Since those are usually taken care of by something like &lt;a href="http://github.com/yfactorial/utility_scopes"&gt;utility_scopes&lt;/a&gt; or &lt;a href="http://github.com/thoughtbot/pacecar"&gt;Pacecar&lt;/a&gt; (and thus do not need to be unit tested) OR are often relegated to private status, that doesn’t leave a niche for &lt;code&gt;should_have_named_scope&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you’re still a &lt;code&gt;should_have_named_scope&lt;/code&gt; fan, please write a test for &lt;code&gt;unwatched&lt;/code&gt; using it. I’ll be surprised if it stands up to peer review.&lt;/p&gt;

&lt;h2&gt;Discarded option: stub_chain&lt;/h2&gt;

&lt;p&gt;Another option I’ve been using this summer, but have recently rejected is &lt;code&gt;stub_chain&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module StubChainMocha
  module Object
    def stub_chain(*methods)
      while methods.length &gt; 1 do
        stubs(methods.shift).returns(self)
      end
      stubs(methods.shift)
    end
  end
end
Object.send(:include, StubChainMocha::Object) 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This approach unit tests each of the named scopes and then stub_chains the class method:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;should "find 10 highest ranked movies in stock that you have not seen" do
  user = Factory(:user)
  Movie.stub_chain(:highest_ranked, :in_stock, :unwatched, :limited)

  Movie.recommended_for(user)

  assert_received(Movie, :highest_ranked)
  assert_received(Movie, :in_stock)
  assert_received(Movie, :unwatched) { |expect| expect.with(user) }
  assert_received(Movie, :limited)   { |expect| expect.with(10) }
end 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is easy to understand, but very tied to implementation, does not test the “integration” of the scopes (dangerous in many situations when the resulting SQL is not combined as expected), and stubs out methods on the same object (usually a smell that something needs to be refactored).&lt;/p&gt;

&lt;p&gt;My suggested approach may often be more lines of code, but will better describe the behavior.&lt;/p&gt;

&lt;h2&gt;No chains in controllers&lt;/h2&gt;

&lt;p&gt;Some of us have started to use a rule of thumb of “no chains in controllers”. This makes the testing decisions easier, and makes the model’s public interfaces and public/private interface distinction cleaner. The end result is usually a class method that wraps (potentially private) named scopes.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/unzycPtHuZY/200254501</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/200254501</guid><pubDate>Tue, 29 Sep 2009 14:30:42 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/200254501</feedburner:origLink></item><item><title>Success story: Big Room consulting</title><description>&lt;p&gt;We like to spotlight our &lt;a href="http://thoughtbot.com/services/training"&gt;thoughtbot training&lt;/a&gt; students’ work.&lt;/p&gt;

&lt;h2&gt;Big Room&lt;/h2&gt;

&lt;p&gt;In this installment, we’re checking in with Mike Breen, a local Bostonian. Mike took one of our very first Boston classes.&lt;/p&gt;

&lt;p&gt;Since last year, he has been doing Rails consulting as an owner of &lt;a href="http://bigroomtechnology.com"&gt;Big Room Technology&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://bigroomtechnology.com"&gt;&lt;img alt="Big Room" src="https://thoughtbot-training.s3.amazonaws.com/images/big_room.png" width="425"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;Since last October I launched a family of products for SEAK.com: &lt;a href="http://seakexperts.com"&gt;Directory of Expert Witnesses&lt;/a&gt;, Directory of Independent Medical Examiners, and Directory of File Review Consultants,&lt;/blockquote&gt;

&lt;blockquote&gt;… converted multiple ol’ school ASP apps to a single Rails app,&lt;/blockquote&gt;

&lt;blockquote&gt;… helped launch &lt;a href="http://iacez.com"&gt;IAC-EZ&lt;/a&gt; with Lark Farm, Inc.,&lt;/blockquote&gt;

&lt;blockquote&gt;… worked with Auburn Quad and now I’m working on their non-profit wing &lt;a href="http://grassrootsgivinggroup.com"&gt;Grassroots Giving Group&lt;/a&gt;,&lt;/blockquote&gt;

&lt;blockquote&gt;… and helping out with the RailsBridge. I lead up &lt;a href="http://builders.railsbridge.org"&gt;the Builders&lt;/a&gt;. We help non-profits build or rehab Rails sites. [thoughtbot developer] Jason Morrison and the &lt;a href="http://www.personalgenomes.org"&gt;Personal Genome Project&lt;/a&gt; signed up recently.&lt;/blockquote&gt;

&lt;h2&gt;Rails is a productivity enhancer&lt;/h2&gt;

&lt;p&gt;As if that wasn’t enough, Mike also volunteered his time to run the inaugural Rails BugMash, which saw over 300 commits to Rails.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://wiki.railsbridge.org/projects/railsbridge/wiki/BugMash"&gt;The next BugMash&lt;/a&gt; is this weekend, September 25th-27th.&lt;/p&gt;

&lt;p&gt;Our own &lt;a href="http://thoughtbot.com/about/people#tristandunn"&gt;Tristan “Bucky” Dunn&lt;/a&gt; finished in the top 5 last time around. You can mash more bugs than Bucky, can’t you?&lt;/p&gt;

&lt;h2&gt;Training&lt;/h2&gt;

&lt;p&gt;We’re always pleased to see the great work that our alumni have produced.&lt;/p&gt;

&lt;p&gt;We think you can strengthen your TDD with Rails skills through hands-on workshops in an intimate setting with thoughtbot developers.&lt;/p&gt;

&lt;p&gt;Early Bird tickets are now available for &lt;a href="http://rubyonrailsoctober.eventbrite.com"&gt;October&lt;/a&gt; and &lt;a href="http://rubyonrailsdecember.eventbrite.com"&gt;December&lt;/a&gt; classes.&lt;/p&gt;

&lt;p&gt;Previous spotlights on our students’ work include open source libraries &lt;a href="http://robots.thoughtbot.com/post/159805581/klang-strongbox"&gt;Klang &amp; strongbox&lt;/a&gt; and beautifully designed Rails app (with 100% test coverage!) &lt;a href="http://robots.thoughtbot.com/post/159805930/yiloveit"&gt;yiloveit&lt;/a&gt;.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/7FYZ_vSGEvM/194358612</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/194358612</guid><pubDate>Tue, 22 Sep 2009 15:33:00 -0400</pubDate><category>expose</category><feedburner:origLink>http://robots.thoughtbot.com/post/194358612</feedburner:origLink></item><item><title>Role Suggesting Name</title><description>&lt;p&gt;There’s an &lt;a href="http://robots.thoughtbot.com/post/185504560/to-self-or-not-to-self#comment-16438350"&gt;excellent discussion&lt;/a&gt; on Josh’s “self” post last week. In it, I argued:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;in my opinion, naming classes, methods, and variables expressively should be the #1 goal of a programmer when writing or refactoring code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;How to write great names&lt;/h2&gt;

&lt;p&gt;The path to great naming involves a few simple rules.&lt;/p&gt;

&lt;p&gt;You can often deduce the scope and type of a variable.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;one thing&lt;/em&gt; you can’t deduce from a variable is its role, or purpose, it plays in the application.&lt;/p&gt;

&lt;h2&gt;Example&lt;/h2&gt;

&lt;p&gt;The following is something I wrote today.&lt;/p&gt;

&lt;p&gt;Let’s consider a &lt;code&gt;CreditCard&lt;/code&gt; class:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class CreditCard &lt; ActiveRecord::Base
  belongs_to :brand_manager, :class_name =&gt; "User"
end

class User &lt; ActiveRecord::Base
  has_many :credit_cards, :foreign_key =&gt; "brand_manager_id"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Why&lt;/h2&gt;

&lt;p&gt;Context.&lt;/p&gt;

&lt;p&gt;What reads better to you when you use these objects?&lt;/p&gt;

&lt;p&gt;This…&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;user.credit_cards
credit_card.user
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;… or this?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;brand_manager.credit_cards
credit_card.brand_manager
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;“User” is too generic. In the real world, credit cards don’t have users.&lt;/p&gt;

&lt;p&gt;In the domain-specific language of this application, the people are referred to as “brand managers”.&lt;/p&gt;

&lt;h2&gt;Why not just name the model BrandManager?&lt;/h2&gt;

&lt;p&gt;In this case, &lt;code&gt;User&lt;/code&gt; is overloaded to handle three different roles using simple flags on the model. This allows us to use &lt;a href="http://rdoc.info/projects/thoughtbot/clearance"&gt;Clearance&lt;/a&gt; normally and keeps authentication and standard &lt;code&gt;user&lt;/code&gt; vocabulary available where it makes sense.&lt;/p&gt;

&lt;h2&gt;Another example&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;class Impression &lt; ActiveRecord::Base
  belongs_to :campaign, :class_name =&gt; "Offer"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;From the same application, we again see a case where the object in question plays two different roles depending on to whom it is being displayed. The object is a &lt;code&gt;campaign&lt;/code&gt; to advertisers and &lt;code&gt;offer&lt;/code&gt; to recipients.&lt;/p&gt;

&lt;p&gt;From the perspective of &lt;code&gt;impressions&lt;/code&gt;, the Role Suggesting Name is &lt;code&gt;campaign&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Reveal refactoring opportunities&lt;/h2&gt;

&lt;p&gt;In this second example, we now intend to rename the &lt;code&gt;Offer&lt;/code&gt; model &lt;code&gt;Campaign&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We were undecided which name would be dominant in the app when we first wrote the model but as we’ve written new features, using Role Suggesting Name has dictated that the model should be renamed as there is only one place where &lt;code&gt;offer&lt;/code&gt; makes sense.&lt;/p&gt;

&lt;p&gt;By caring about naming as we’ve gone, that eventual refactoring will be painless as we have less code to change. We did not let ourselves feel restricted by original name, and let context and purpose drive naming.&lt;/p&gt;

&lt;h2&gt;100% stolen from studying the masters&lt;/h2&gt;

&lt;p&gt;I first heard of this idiom in &lt;a href="http://www.amazon.com/Smalltalk-Best-Practice-Patterns-Kent/dp/013476904X/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1240240751&amp;sr=1-1"&gt;Smalltalk Best Practice Patterns&lt;/a&gt; by Kent Beck.&lt;/p&gt;

&lt;p&gt;I heard it applied to a similar use case in Philippe Hanrigou’s talk, &lt;a href="http://mwrc2009.confreaks.com/14-mar-2009-15-35-what-the-ruby-craftsman-can-learn-from-the-smalltalk-master-philippe-hanrigou.html"&gt;What the Ruby craftsman can learn from the Smalltalk master&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There’s a lot more to great naming but I can’t say it any better than those guys, so watch Philippe’s talk and read the book.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/Jv0i3Hc3Wys/191132156</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/191132156</guid><pubDate>Fri, 18 Sep 2009 14:03:38 -0400</pubDate><category>smalltalk</category><category>ruby</category><category>kent beck</category><feedburner:origLink>http://robots.thoughtbot.com/post/191132156</feedburner:origLink></item><item><title>swallow nil</title><description>&lt;p&gt;I’ve been using this for &lt;a href="http://dancroak.tumblr.com/post/31279957/swallow-nil"&gt;about a year and a half&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Abomination or legitimate tool for the box?&lt;/p&gt;

&lt;h2&gt;Usage&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;two dots or more. nil anywhere in the chain is an acceptable response.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre&gt;&lt;code&gt;campaign = swallow_nil { supporter.politician.campaign }&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Definition&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;def swallow_nil
  yield
rescue NoMethodError
  nil
end&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;try()&lt;/h2&gt;

&lt;p&gt;It’s similar to &lt;a href="http://railsapi.com/doc/rails-v2.3.4/classes/Object.html#M006206"&gt;try&lt;/a&gt; from ActiveSupport except for chains instead of individual methods.&lt;/p&gt;

&lt;h2&gt;Law of Demeter&lt;/h2&gt;

&lt;p&gt;Are you strict about Law of Demeter violations?&lt;/p&gt;

&lt;p&gt;Or, do you find yourself with occasional chains like this that could benefit from &lt;code&gt;swallow_nil()&lt;/code&gt; or &lt;code&gt;try()&lt;/code&gt; or &lt;code&gt;andand()&lt;/code&gt;?&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/Eg5_odKyBgw/190940474</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/190940474</guid><pubDate>Fri, 18 Sep 2009 08:02:00 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/190940474</feedburner:origLink></item><item><title>How to Ruin a jQuery Plug-in: Markup</title><description>&lt;p&gt;&lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt; is one of my favorite libraries, in any language. And one of the greatest advantages of using jQuery is the abundance of third-party plug-ins available. Just about anything you need to do has probably already been done and extracted into a plug-in. That being said there are ways I feel you can completely ruin a jQuery plug-in.&lt;/p&gt;

&lt;h3&gt;Generating or expecting specific markup.&lt;/h3&gt;

&lt;p&gt;&lt;img src="http://thoughtbot.widgetfinger.com/assets/48/original/ruins_ver3.jpg?1253212388" width="200" height="296" class="img_right"/&gt;Recently I needed a content slider for an existing homepage design. The first promising plug-in I found generated the navigation for you, so it was out the door. Several others expected very specific markup and made it difficult to customize. Eventually I found one that at least allowed me to customize the selectors and even though it still expected &lt;code&gt;&lt;li&gt;&lt;/code&gt; elements I managed to easily modify it to work.&lt;/p&gt;

&lt;h3&gt;Proposed Solution&lt;/h3&gt;

&lt;p&gt;If you are going to generate markup from your plug-in, make it customizable. It is trivial to add another string to your default options and makes it a lot easier to find. If you need to act on the markup, which you will, then base it on an ID, or class names, and &lt;em&gt;not&lt;/em&gt; elements.&lt;/p&gt;

&lt;h3&gt;Example Plug-in&lt;/h3&gt;

&lt;p&gt;Here’s a very basic plug-in to give you an idea what I am talking about.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(function($) {
  $.fn.awesomeMagic = function(options) {
    // Overwrite the defaults with any provided options.
    options = $.extend(true, {}, $.fn.awesomeMagic.defaults, options || {});

    return $(this).each(function() {
      // Append the markup.
      $(this).append(options.html);

      // Grab the elements needed.
      var hat    = $(this).find('.awesome-magic-hat');
      var rabbit = $(this).find('.awesome-magic-rabbit');

      // Perform awesome magic here.
    });
  };

  $.fn.awesomeMagic.defaults = {
    wand : true,
    html : '\
    &lt;div class="awesome-magic-hat"&gt; \
      &lt;div class="awesome-magic-rabbit"&gt; \
        Rabbit goes here. \
      &lt;/div&gt; \
    &lt;/div&gt;'
  };
})(jQuery);
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Plug-in Usage&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;$('#content').awesomeMagic({
  html : '\
    &lt;span class="awesome-magic-rabbit"&gt;Rabbit goes here.&lt;/span&gt; \
    &lt;span class="awesome-magic-hat" /&gt;'
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How do you handle custom or expected mark up in your plug-ins? What are other ways you feel a plug-in can be ruined?&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/rPq475p4ri4/190374106</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/190374106</guid><pubDate>Thu, 17 Sep 2009 15:03:20 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/190374106</feedburner:origLink></item><item><title>tiniest of tips</title><description>&lt;p&gt;Every time you find yourself typing something long and repetitive, automate it.  Every time.&lt;/p&gt;

&lt;p&gt;I often hop into &lt;code&gt;script/console&lt;/code&gt;, so aliasing that is a no-brainer.  That is not the point of this post, though; I also often look up my current user when I’m in &lt;code&gt;script/console&lt;/code&gt;, and I get tired of typing my email address every time.  Add a method into your ~/.irbrc to make that painless, too.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[~/dev/railsapp] alias sc
sc=script/console

[~/dev/railsapp] tail -n 3 ~/.irbrc
def me
  User.find_by_email 'jmorrison@thoughtbot.com'
end

[~/dev/railsapp] sc
Loading development environment (Rails 2.3.3)

&gt;&gt; me
  SQL (0.2ms)   SET NAMES 'utf8'
  SQL (0.1ms)   SET SQL_AUTO_IS_NULL=0
  User Columns (2.7ms)   SHOW FIELDS FROM `users`
  User Load (60.1ms)   SELECT * FROM `users` WHERE (`users`.`email` = 'jmorrison@thoughtbot.com') LIMIT 1
=&gt; #&lt;User id: 1, name: "Jason Morrison", email: "jmorrison@thoughtbot.com"&gt;
&lt;/code&gt;&lt;/pre&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/svD4nDr2zfk/189637456</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/189637456</guid><pubDate>Wed, 16 Sep 2009 17:14:47 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/189637456</feedburner:origLink></item><item><title>Five Ridiculously Awesome Cucumber (and Webrat) Features</title><description>&lt;p&gt;&lt;a href="http://cukes.info"&gt;Cucumber&lt;/a&gt;, if you haven’t heard, is the Next Big Thing™.  It affords developers the ability to write human-readable integration tests.  Even though it’s only at version 0.3.101, it’s full-featured with a handful of hidden gems.  Here are five of my favorites.&lt;/p&gt;

&lt;h2&gt;Running Targeted Features with Cucumber Profiles&lt;/h2&gt;

&lt;p&gt;In a Rails application, if a &lt;code&gt;RAILS_ROOT/cucumber.yml&lt;/code&gt; file is present, you can store named &lt;a href="http://wiki.github.com/aslakhellesoy/cucumber/using-rake"&gt;Cucumber&lt;/a&gt; &lt;a href="http://wiki.github.com/aslakhellesoy/cucumber/cucumberyml"&gt;profiles&lt;/a&gt;.  This becomes handy if you’re running your features in different environments (e.g. Selenium or a simulated browser).&lt;/p&gt;

&lt;p&gt;Here’s an example &lt;code&gt;cucumber.yml&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;default: --format pretty -r features/support/env.rb -r features/support/plain.rb -r features/step_definitions features
selenium: -r features/support/env.rb -r features/support/selenium.rb -r features/step_definitions features
html_output: --format html -r features/support/env.rb -r features/support/plain.rb -r features/step_definitions features
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Within your terminal, you can run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cucumber -p html_output
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Tagging Scenarios&lt;/h2&gt;

&lt;p&gt;Another handy Cucumber feature is the ability to tag scenarios.  Tagging a scenario is achieved by simply adding &lt;code&gt;@tagname&lt;/code&gt; above the scenario definition, as such:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@tagname
Scenario: User is not signed up
  Given no user exists with an email of "email@person.com"
  When I go to the sign in page
  And I sign in as "email@person.com/password"
  Then I should see "Bad email or password"
  And I should not be signed in
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To run scenarios with a specific tag:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cucumber --tags @tagname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To exclude scenarios with a certain tag, prefix the tag with a tilde:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cucumber --tags ~@wip
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A common tag name that Cucumber supports out of the box is &lt;code&gt;@wip&lt;/code&gt; (work in progress) and provides rake tasks to accommodate using this pattern:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rake cucumber:wip # runs only scenarios with a wip tag
rake cucumber:ok # runs all scenarios without a wip tag
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One thing to note here is that Cucumber will exit with a status of 1 if your &lt;code&gt;@wip&lt;/code&gt;-tagged scenarios pass (it’s a reminder that they’re not works in progress anymore since they pass).&lt;/p&gt;

&lt;h2&gt;Assigning Data with Tables&lt;/h2&gt;

&lt;p&gt;Cucumber supports the use of tables, which can be handy for any number of things; my favorite uses are populating fields in a form and instantiating an ActiveRecord object with values defined.&lt;/p&gt;

&lt;p&gt;Webrat gives us a step definition for filling in form fields (within &lt;code&gt;features/step_definitions/webrat_steps.rb&lt;/code&gt;) and can be used as such:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;When I fill in the following:
  | First Name            | John                 |
  | Last Name             | Doe                  |
  | Email                 | john.doe@example.com |
  | Password              | password             |
  | Password Confirmation | password             |
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With an ActiveRecord object and FactoryGirl:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# step
Given a customer exists with the following attributes:
  | Name      | Huge Local Company |
  | Code      | HLC                |

# step definition
Factory.factories.each do |name, factory|
  Given /^an? #{name} exists with the following attributes:$/ do |attrs_table|
    attrs = {}
    attrs_table.raw.each do |(attr, value)|
      sanitized_attr = attr.gsub(/\s+/, "-").underscore
      attrs[sanitized_attr.to_sym] = value
    end
    Factory(name, attrs)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Segregating Selenium and Simulated Browser Steps&lt;/h2&gt;

&lt;p&gt;If you’ve been ambitious enough to get your features running with Selenium, you already know that doing so can add a significant amount of time to your tests.  Webrat is kind enough to provide you execution blocks that run in specific modes, which makes for some snappier tests when you do run features with Webrat.&lt;/p&gt;

&lt;p&gt;For example, within a step that outlines signing in:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;webrat.automate do
  When %{I sign in as "#{email}/#{password}"}
end

webrat.simulate do
  visit "/session",
        :post,
        :session =&gt; {:email =&gt; email, :password =&gt; password}
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Webrat will determine if you’re simulating a browser and execute &lt;code&gt;webrat.simulate&lt;/code&gt; if that’s the case; otherwise, it’ll run the code within the &lt;code&gt;webrat.automate&lt;/code&gt; block.  This can be really helpful if you’re testing the ability to delete an item (especially if there’s a confirmation dialog).&lt;/p&gt;

&lt;h2&gt;Displaying Page Responses within a Scenario&lt;/h2&gt;

&lt;p&gt;If you’re having trouble getting a feature to pass and want to view the page, you can add in a step to have it save the result HTML and open the page in your default browser.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Scenario: User is not signed up
  Given no user exists with an email of "email@person.com"
  When I go to the sign in page
  Then show me the page # saves the HTML of that page and opens the file
  And I sign in as "email@person.com/password"
  Then I should see "Bad email or password"
  And I should be signed out
  Then show me the page # more HTML output
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This tends to be much more convenient than adding this into your step definition:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;puts response.body.inspect
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are, as always, a couple of caveats.  The HTML it generates won’t be relative to your public folder so Javascript and CSS probably won’t load correctly.  It also doesn’t persist form values, so if you run it after a step like ‘I fill in “field” with “value”’, it won’t keep that data.  It also creates a timestamped html file within your &lt;code&gt;RAILS_ROOT&lt;/code&gt; folder.  A simple fix to ensure this doesn’t get committed with git would be to add the following line to your &lt;code&gt;.gitignore&lt;/code&gt; file in the project:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;webrat-*.html
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Finally…&lt;/h2&gt;

&lt;p&gt;Don’t forget to &lt;a href="http://wiki.github.com/aslakhellesoy/cucumber"&gt;read the docs&lt;/a&gt;!  They cover everything you’d ever want to know about Cucumber and how to use it effectively.  I’ve listed only a handful of awesome features Cucumber and Webrat have to offer, but each has helped me in one way or another over the course of the past year.  Hopefully they’ll be as much use to you as they were me.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/ZwM0S58yovg/189412598</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/189412598</guid><pubDate>Wed, 16 Sep 2009 11:05:16 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/189412598</feedburner:origLink></item><item><title>To self. or not to self.</title><description>&lt;p&gt;&lt;img src="http://thoughtbot.widgetfinger.com/assets/48/original/caesar-brutus.jpg" title="Et tu, Brute?" alt="Et tu, Brute?" width="400"/&gt;&lt;/p&gt;

&lt;h2&gt;Off with his head!&lt;/h2&gt;

&lt;p&gt;Ruby developers have gone back and forth for ages as to whether to use &lt;code&gt;self.&lt;/code&gt; on their method calls.  Why is everyone bickering?  Can’t we all just get along?&lt;/p&gt;

&lt;p&gt;My guess is that we can’t.&lt;/p&gt;

&lt;p&gt;This argument is similar to that of the use of whitespace.  Some people are picky while others are not; however, almost all have a very strong opinion.&lt;/p&gt;

&lt;h2&gt;This above all: to thine own self be true&lt;/h2&gt;

&lt;p&gt;I prefer to qualify all public instance method calls with &lt;code&gt;self.&lt;/code&gt;.  I’m one to lean towards being explicit versus implicit, and &lt;code&gt;self.&lt;/code&gt; helps me achieve this goal.  This also makes coworkers (or any other individual reading the code) aware of whether the method call is an attribute defined by ActiveRecord or a public instance method on the class.  The reason this is an issue is because local or block-level variables will never be prefixed with &lt;code&gt;self.&lt;/code&gt; - it’s much easier on the eyes to be able to tell immediately whether you’re dealing with one or the other.&lt;/p&gt;

&lt;h2&gt;Tempt not a desperate man&lt;/h2&gt;

&lt;p&gt;The explicitness of &lt;code&gt;self.&lt;/code&gt; may be construed as line noise.  You may also be asked why you don’t use Hungarian notation.  Using &lt;code&gt;self.&lt;/code&gt; isn’t a naming convention; it’s defining the receiver of the message explicitly.  There’s no misconception and you’re relaying intent very plainly by adding five characters.&lt;/p&gt;

&lt;h2&gt;This is the long and short of it&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;class User &lt; ActiveRecord::Base
  before_save :sanitize_names

  def display_name
    return email if first_name.blank?
    [first_name, last_name].compact.join(" ")
  end

  protected

  def sanitize_names
    self.first_name = nil if first_name.blank?
    self.last_name = nil if last_name.blank?
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The result, after everything is said and done, would be:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class User &lt; ActiveRecord::Base
  before_save :sanitize_names

  def display_name
    return self.email if self.first_name.blank?
    [self.first_name, self.last_name].compact.join(" ")
  end

  protected

  def sanitize_names
    self.first_name = nil if self.first_name.blank?
    self.last_name = nil if self.last_name.blank?
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Although there may not me much of a different to the casual reader, the second is, in my mind, worlds easier to comprehend.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/wpmrH997kcM/185504560</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/185504560</guid><pubDate>Fri, 11 Sep 2009 15:24:41 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/185504560</feedburner:origLink></item><item><title>Zsh completion for your tests and specs</title><description>&lt;p&gt;Got zsh?  Loving your &lt;a href="http://smartic.us/2008/8/15/tatft-i-feel-a-revolution-coming-on/"&gt;TATFT&lt;/a&gt; but tired of typing out all those spec commands?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;spec -cfs spec/controllers/application_controller_spec.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or test commands?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby -Itest test/functionals/admin/users_controller_test.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, put away that keyboard oil, because you’ll be saving keystrokes left and right!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[~/dev/railsapp] $ spc a&lt;Tab&gt;
admin/base_controller    application_controller  arrr_pirates_controller

[~/dev/railsapp] $ spc app&lt;Tab&gt;
admin/base_controller    application_controller  arrr_pirates_controller

[~/dev/railsapp] $ spc application_controller&lt;Enter&gt;
admin/base_controller    application_controller  arrr_pirates_controller

spec -cfs spec/controllers/application_controller_spec.rb # ta-da!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can also complete multiple tests or specs in one line.  Download the scripts and find out more in &lt;a href="http://github.com/jasonm/zsh-rails-test-spec-shortcuts/"&gt;the zsh-rails-test-spec-shortcuts repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gardenpartyradio.com/wp/images/Sleeping-Bear.jpg"/&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“I’m so tired of typing &lt;code&gt;ruby -Itest test/&lt;/code&gt;… I’m so glad I installed the zsh completion scripts.  I’ll spend all my saved energy on eating campsites and writing solid code!”&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Bonus links&lt;/h2&gt;

&lt;p&gt;As a bonus, here’s a reminder of an oldie but a goodie, &lt;strong&gt;rake task completion&lt;/strong&gt; for zsh:
&lt;a href="http://weblog.rubyonrails.org/2006/3/9/fast-rake-task-completion-for-zsh"&gt;http://weblog.rubyonrails.org/2006/3/9/fast-rake-task-completion-for-zsh&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And a recent one from the rubygems-developers list, for &lt;strong&gt;gem command completion&lt;/strong&gt; for zsh:
&lt;a href="http://rubyforge.org/pipermail/rubygems-developers/2009-August/004860.html"&gt;http://rubyforge.org/pipermail/rubygems-developers/2009-August/004860.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;What about you?&lt;/h2&gt;

&lt;p&gt;What’s your favorite time saving alias, script, or shell completion?  Let us know in the comments!&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/U6bfdj2tqB0/185265053</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/185265053</guid><pubDate>Fri, 11 Sep 2009 08:00:10 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/185265053</feedburner:origLink></item><item><title>Quacking like an ActiveRecord in Rails 2.3.4</title><description>&lt;p&gt;You know everything about &lt;a href="http://robots.thoughtbot.com/post/159805369/search-by-quacking-like-activerecord"&gt;pretending to be an &lt;code&gt;ActiveRecord::Base&lt;/code&gt; object&lt;/a&gt;, and especially the bit about ActiveRecord::Errors. That part’s really cool.&lt;/p&gt;

&lt;p&gt;What we are doing here is making an object that quacks like an &lt;code&gt;ActiveRecord::Base&lt;/code&gt; object but has no database table backing it. As examples: a search object, a credit card object, or a remote user object. To do this, you need &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;new_record?&lt;/code&gt;, and the attributes must work in a specific fashion. You can also have &lt;code&gt;errors&lt;/code&gt; produce an &lt;code&gt;ActiveRecord::Errors&lt;/code&gt; instance so user errors will show in forms and whatnot.&lt;/p&gt;

&lt;p&gt;However you may not have noticed that Rails 2.3.4 broke API compatibility for &lt;code&gt;ActiveRecord::Errors&lt;/code&gt;. If your &lt;code&gt;ActiveRecord::Base&lt;/code&gt;-like class provides an &lt;code&gt;#errors&lt;/code&gt; instance method, it must now provide these class methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;self_and_descendants_from_active_record&lt;/code&gt;, which produces an array of classes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;human_name&lt;/code&gt;, which takes an optional hash and produces a string.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;human_attribute_name&lt;/code&gt;, which takes a string and optional hash and produces a string.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img class="img_right" src="http://thoughtbot.widgetfinger.com/assets/48/original/rubber_ducky.jpg" alt="A giant inflatable duck" width="250" height="250"/&gt;&lt;/p&gt;

&lt;p&gt;The last two of these methods are useful in your day-to-day Rails knowledge (the first is an internal, undocumented method used by Rails to produce the class itself and its parents, up to and excluding &lt;code&gt;ActiveRecord::Base&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;human_name&lt;/code&gt; is used to produce a humanized string representing the class/table name. If your class is named &lt;code&gt;AuthenticationRecord&lt;/code&gt;, &lt;code&gt;.human_name&lt;/code&gt; will produce &lt;code&gt;"Authenticationrecord"&lt;/code&gt;. Any options you pass to this are normally sent to &lt;code&gt;I18n.translate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;human_attribute_name&lt;/code&gt; is used to map an attribute to a human-readable string. For example, the attribute &lt;code&gt;created_at&lt;/code&gt; is mapped to &lt;code&gt;"Created at"&lt;/code&gt;. Any options passed to this are normally sent to &lt;code&gt;I18n.translate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here are some tests that need to pass now:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class SearchTest &lt; ActiveSupport::TestCase
  should "conform to the ActiveRecord::Errors interface" do
    assert_respond_to Search, :self_and_descendants_from_active_record
    assert_respond_to Search, :human_name
    assert_respond_to Search, :human_attribute_name

    assert_equal [Search], Search.self_and_descendants_from_active_record
    assert_equal "Search", Search.human_name
    assert_equal "Published at", Search.human_attribute_name('published_at')
  end
end&lt;/code&gt;&lt;/pre&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/u6QAQcvObao/184667563</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/184667563</guid><pubDate>Thu, 10 Sep 2009 14:34:46 -0400</pubDate><feedburner:origLink>http://robots.thoughtbot.com/post/184667563</feedburner:origLink></item></channel></rss>
