Monday, June 1, 2009

A Shocking Discovery

‹prev | My Chain | next›

I made a shocking discovery yesterday: I managed to create a list of meals in a given month without actual links to the meals—even with all of my quality Behavior Driven Development!

Well OK, maybe it was not that shocking, but still something I need to address. Since the meal_by_month Haml template lacks the link to the meal, I add a failing example to meal_by_month.haml_spec.rb:
  it "should link to the meal" do
render("/views/meal_by_month.haml")
response.should have_selector("a", :href => "/meals/2009/05/14")
end
I can get that example to pass by parsing the ISO 8601 date string from the CouchDB JSON document and making a strftime call:
  - @meals["rows"].each do |meal_result|
- meal = meal_result['value'][0]
- date = Date.parse(meal['date'])
= image_link meal, :width => 200, :height => 150
%h2
%span.date= meal['date']
%a.title{:href => date.strftime("/meals/%Y/%m/%d")}= meal['title']
%p= meal['summary']
.menu= wiki(meal['menu'].join(', '))
With that, the new, link-to-meal example is passing and well-documented:
cstrom@jaynestown:~/repos/eee-code$ spec -cfs \
> ./spec/views/meal_by_month.haml_spec.rb

meal_by_month.haml
- should include each meal's title
- should link to the meal
- should include each meal's date in the title
- should include each meal's summary
- should include a thumbnail image of the meal
- should include the menu items
- should include recipe titles in the menu items

Finished in 0.040333 seconds

7 examples, 0 failures
With pretty, passing specs in place, it is time to move back out to the Cucumber scenario:
cstrom@jaynestown:~/repos/eee-code$ cucumber features \
-s "Browsing a meal on a specific date"
Feature: Browse Meals

So that I can find meals made on special occasions
As a person interested in finding meals
I want to browse meals by date

Scenario: Browsing a meal on a specific date # features/browse_meals.feature:36
Given a "Focaccia" recipe from March 3, 2009 # features/step_definitions/recipe_details.rb:137
Given a "Focaccia!" meal with the "Focaccia" recipe on the menu # features/step_definitions/meal_details.rb:22
When I view the "Focaccia!" meal # features/step_definitions/meal_details.rb:52
Then I should see the "Focaccia!" title # features/step_definitions/meal_details.rb:66
And I should see a "Focaccia" recipe link in the menu # features/step_definitions/meal_details.rb:86
When I click the "March" link # features/step_definitions/meal_details.rb:61
Then I should see "Focaccia!" in the list of meals # features/step_definitions/meal_details.rb:98
When I click the "Focaccia" link # features/step_definitions/meal_details.rb:61
And I click the "2009" link # features/step_definitions/meal_details.rb:61
Could not find link with text or title or id "2009" (Webrat::NotFoundError)
features/browse_meals.feature:46:in `And I click the "2009" link'
Then I should see "Focaccia!" in the list of meals # features/step_definitions/meal_details.rb:98
When I click the "Focaccia!" link # features/step_definitions/meal_details.rb:61
And I click the "Focaccia" link # features/step_definitions/meal_details.rb:61
Then I should see the "Focaccia" recipe # features/browse_meals.feature:50

1 scenario
1 failed step
3 skipped steps
1 undefined step
8 passed steps
Hrm.

Tracing through the steps starting from the meal page: I click on the month breadcrumb, verify that the link to the meal is on the list of meals in that month, then click on the meal. All of that passes, but, back on the meal page, I am unable to click through to the list of meals this year. What gives?

To solve this puzzle, I will make use of Webrat's incredibly useful save_and_open_page() method to see what the page looks like:
When /^I click the "([^\"]*)" link$/ do |text|
save_and_open_page()
click_link text
end
The output from this shows:



"Preparation time"? That's a recipe! How did I end up on the recipe page when I clicked the link to the meal?

Oops.

Looking back at the scenario text, I see that I am clicking through the "Foccacia" link, not the "Foccocia!" link. The former is the name of the recipe, the latter is the meal. This mess is certainly one of my own making. Giving the meal and recipe the same title except for an extra exclamation may be all right in real life (they were taken from a meal and recipe from the legacy site). It doesn't work quite as well when testing, where readability is the key.

So I rename the the meal from "Foccacia!" to "Foccacia! The Dinner" and ensure that I am clicking on that in the meals-by-the-month page:
cstrom@jaynestown:~/repos/eee-code$ cucumber features -n \
> -s "Browsing a meal on a specific date"
Feature: Browse Meals

So that I can find meals made on special occasions
As a person interested in finding meals
I want to browse meals by date

Scenario: Browsing a meal on a specific date
Given a "Focaccia" recipe from March 3, 2009
Given a "Focaccia! The Dinner" meal with the "Focaccia" recipe on the menu
When I view the "Focaccia! The Dinner" meal
Then I should see the "Focaccia! The Dinner" title
And I should see a "Focaccia" recipe link in the menu
When I click the "March" link
Then I should see "Focaccia! The Dinner" in the list of meals
When I click the "Focaccia! The Dinner" link
And I click the "2009" link
Then I should see "Focaccia! The Dinner" in the list of meals
When I click the "Focaccia! The Dinner" link
And I click the "Focaccia" link
Then I should see the "Focaccia" recipe

1 scenario
1 undefined step
12 passed steps

You can implement step definitions for missing steps with these snippets:

Then /^I should see the "([^\"]*)" recipe$/ do |arg1|
pending
end
Nice! Now all that is left is the last step, which I implement, based on the suggestion from Cucumber, as:
Then /^I should see the "([^\"]*)" recipe$/ do |title|
response.should have_selector("h1", :content => title)
end
And...



Success! The entire scenario passing. But...

I noticed that, when I viewed the recipe output from save_and_open_page(), it lacked breadcrumbs. So, before I stop for today, I add two more steps at the end of this scenario to remind myself where to pick up tomorrow:
  Scenario: Browsing a meal on a specific date

Given a "Focaccia" recipe from March 3, 2009
Given a "Focaccia! The Dinner" meal with the "Focaccia" recipe on the menu
When I view the "Focaccia! The Dinner" meal
Then I should see the "Focaccia! The Dinner" title
And I should see a "Focaccia" recipe link in the menu
When I click the "March" link
Then I should see "Focaccia! The Dinner" in the list of meals
When I click the "Focaccia! The Dinner" link
And I click the "2009" link
Then I should see "Focaccia! The Dinner" in the list of meals
When I click the "Focaccia! The Dinner" link
When I click the "Focaccia" link
Then I should see the "Focaccia" recipe
When I click the "3" link
Then I should see the "Focaccia! The Dinner" title

No comments:

Post a Comment