Thursday, March 26, 2009

Oragnization for RSpec, HAML, and Sinatra

‹prev | My Chain | next›

Since I am learning during my chain, I may as well give a new templating system a try—specifically HAML. While doing do, I am going to follow the advice of the RSpec book and spec my views.

First up, though I need to do a little house cleaning from last night. I had added my RSpec configuration into my main Sinatra spec file. To keep my specs organized, I need a spec/spec_helper.rb file:
ENV['RACK_ENV'] = 'test'

require 'eee'
require 'spec'
require 'spec/interop/test'
require 'sinatra/test'

require 'webrat'

Spec::Runner.configure do |config|
config.include Webrat::Matchers, :type => :views
end
(commit, commit)

Next up, I replace the raw HTML in the get '/recipes/:permalink' Sinatra block with HAML:
get '/recipes/:permalink' do
data = RestClient.get "#{@@db}/#{params[:permalink]}"
result = JSON.parse(data)

haml "%h1 #{result['title']}"
end
Re-running my specs verifies that all is OK.

Lastly, it is time to move the inline HAML into a standalone template. Since this application is read-only, I will name the view views/recipe.haml (as opposed to something with "show" in the filename) with the following contents:
%h1
= @recipe['title']
To set the @recipe instance variable and call the new template, update the get '/recipes/:permalink' Sinatra block to read:
get '/recipes/:permalink' do
data = RestClient.get "#{@@db}/#{params[:permalink]}"
@recipe = JSON.parse(data)

haml :recipe
end
Re-running last night's spec verifies that the changes have not broken the limited functionality that we have so far (good time to commit).

At this point, I realize that I was specifying view behavior in my previous RSpec test:
  it "should include a title" do
get "/recipes/#{@permalink}"
response.should be_ok
response.should have_selector("h1", :content => @title)
end
So I will pull the have_selector matcher into a view spec instead, something like:
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper' )

describe "recipe.haml" do
before(:each) do
@title = "Recipe Title"
@recipe = { :title => @title }
assigns[:recipe] = @recipe
end

it "should display the recipe's title" do
render "recipe.haml"
response.should have_selector("h1", :content => @title)
end
end
Unfortunately, this does not work:
cstrom@jaynestown:~/repos/eee-code$ ruby ./spec/views/recipe.haml_spec.rb
F

1)
NameError in 'recipe.haml should display the recipe's title'
undefined local variable or method `assigns' for #
./spec/views/recipe.haml_spec.rb:7:
./spec/views/recipe.haml_spec.rb:3:

Finished in 0.023361 seconds

1 example, 1 failure
I believe that the assigns method (and the render method) are part of rspec-on-rails rather than rspec proper. So I will have to figure out some way to render HAML templates directly inside RSpec tests. Tomorrow.

No comments:

Post a Comment