Monday, March 30, 2009

Implementing Recipe Details, Part 2

‹prev | My Chain | next›

Thanks to the Recipe Details feature, I do no lack for next steps of things to do in my chain. Next up, "Viewing a recipe with non-active prep time":
cstrom@jaynestown:~/repos/eee-code$ cucumber features/recipe_details.feature -n \
-s "Viewing a recipe with non-active prep time"
Feature: Recipe Details

So that I can accurately reproduce a recipe at home
As a web user
I want to be able to easily recognize important details
Scenario: Viewing a recipe with non-active prep time
Given a recipe for Crockpot Lentil Andouille Soup
When I view the recipe
Then I should see 15 minutes of prep time
And I should see that it requires 5 hours of non-active cook time


1 scenario
1 step skipped
3 steps pending (3 with no step definition)

You can use these snippets to implement pending steps which have no step definition:

Given /^a recipe for Crockpot Lentil Andouille Soup$/ do
end

Then /^I should see 15 minutes of prep time$/ do
end

Then /^I should see that it requires 5 hours of non\-active cook time$/ do
end
To implement the Given step, I cut & paste the previous scenario's Given.

Yeah, that's right. I cut&paste. I will almost certainly DRY this up in a little bit, but I prefer repetition and wordiness over indirection in my specs. The easier it is to readily see what is going on in the spec, the better.

In the new Given step, the recipe will need preparation and inactive time:
  recipe = {
:title => @title,
:date => @date,
:inactive_time => 300,
:prep_time => 15
}
(commit)

With the Given and When steps passing (the latter re-using the same When step from the previous scenario), it is time to move back inside to work with view specs.

Implementation of the first several specs goes smoothly:
recipe.haml a recipe with an active and inactive preparation time
- should include preparation time
- should include inactive time

recipe.haml a recipe with no inactive preparation time
- should not include inactive time
I do run into a problem trying to implement the inner workings needed to satisfy the last step, "I should see that it requires 5 hours of non-active cook time". The view specification that I use is:
  context "a recipe with 300 minutes of inactive time" do
before(:each) do
@recipe['inactive_time'] = 300
render("views/recipe.haml")
end
it "should display 5 hours of Inactive Time" do
response.should contain(/Inactive Time: 5 hours/)
end
To convert from 300 minutes to 5 hours, I defined the following helper in the main Sinatra application:
helpers do 
def hours(minutes)
h = minutes.to_i / 60
m = minutes.to_i % 60
h > 0 ? "#{h} hours" : "#{m} minutes"
end
end
I then use that helper in the Haml template as:
.eee-recipe-meta
%div= "Preparation Time: " + hours(@recipe['prep_time'])
- if @recipe['inactive_time']
%div= "Inactive Time: " + hours(@recipe['inactive_time'])
But when I run the view specs, every spec fails with an undefined method `hours' for #<Object:0xb7295de4>.

I am able to get everything working by moving the hours method outside of the helpers block:
cstrom@jaynestown:~/repos/eee-code$ ruby ./spec/views/recipe.haml_spec.rb -cfs 

recipe.haml
- should display the recipe's title

recipe.haml a recipe with no ingredient preparations
- should not render an ingredient preparations

recipe.haml a recipe with 1 egg
- should render ingredient names
- should render ingredient quantities
- should not render a brand

recipe.haml a recipe with 1 cup of all-purpose, unbleached flour
- should include the measurement unit
- should include the specific kind of ingredient
- should read conversationally, with the ingredient kind before the name

recipe.haml a recipe with 1 12 ounce bag of Nestle Tollhouse chocolate chips
- should include the ingredient brand
- should note the brand parenthetically after the name

recipe.haml a recipe with an active and inactive preparation time
- should include preparation time
- should include inactive time

recipe.haml a recipe with no inactive preparation time
- should not include inactive time

recipe.haml a recipe with 300 minutes of inactive time
- should display 5 hours of Inactive Time

Finished in 0.060968 seconds

14 examples, 0 failures
It does not sit well with me to put the helper outside the helper block, so tomorrow, I will likely try to figure out how to make Sinatra helpers available to Haml view specs. But this is a good stopping point for tonight.
(commit)

No comments:

Post a Comment