Sunday, March 29, 2009

Finishing Working Inside the Recipe Details, Moving Back Out

‹prev | My Chain | next›

Yesterday, I got in the flow of outside-in Behavior Driven Development. I reached a decidedly inside stopping point driving the development of my Haml views—even finding and addressing a boundary condition.

Work today is smoother as I add four more examples describing various display attributes. At this point, my specification describes the recipe.haml template as:
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

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

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

Finished in 0.07205 seconds

7 examples, 0 failures
(commit)

I believe that I have completed all of the necessary implementation for the "Viewing a recipe with several ingredients" scenario. To remind myself of where I left off in the "outside" scenarios:
cstrom@jaynestown:~/repos/eee-code$ cucumber features/recipe_details.feature -n -s "Viewing a recipe with several ingredients"
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 several ingredients
Given a recipe for Buttermilk Chocolate Chip Pancakes
When I view the recipe
Then I should see an ingredient of "1 cup of all-purpose, unbleached flour"
expected the following element's content to include "1 cup of all-purpose, unbleached flour":

Buttermilk Chocolate Chip Pancakes (Spec::Expectations::ExpectationNotMetError)
./features/step_definitions/recipe_details.rb:17:in `Then /^I should see an ingredient of "(.+)"$/'
features/recipe_details.feature:11:in `Then I should see an ingredient of "1 cup of all-purpose, unbleached flour"'
And I should see an ingredient of "¼ teaspoons salt"
And I should see an ingredient of "chocolate chips (Nestle Tollhouse)"

1 scenario
2 steps passed
1 step failed
2 steps skipped
The scenario is failing because it does not build any ingredient preparations. Adding them, and then training the "I should seen an ingredient" step to ignore whitespace, I still get a failing scenario:
cstrom@jaynestown:~/repos/eee-code$ cucumber features/recipe_details.feature -n -s "Viewing a recipe with several ingredients"
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 several ingredients
Given a recipe for Buttermilk Chocolate Chip Pancakes
When I view the recipe
Then I should see an ingredient of "1 cup all-purpose, unbleached flour"
expected the following element's content to match /1\s+cup\s+all-purpose,\s+unbleached\s+flour/:

Buttermilk Chocolate Chip Pancakes
1
cup
flour
all-purpose, unbleached (Spec::Expectations::ExpectationNotMetError)
./features/step_definitions/recipe_details.rb:33:in `Then /^I should see an ingredient of "(.+)"$/'
features/recipe_details.feature:11:in `Then I should see an ingredient of "1 cup all-purpose, unbleached flour"'
And I should see an ingredient of "¼ teaspoons salt"
And I should see an ingredient of "chocolate chips (Nestle Tollhouse)"


1 scenario
2 steps passed
1 step failed
2 steps skipped
This is failing because the conversationally written spec (an ingredient of "1 cup all-purpose, unbleached flour") is not matching up with the order of implementation. As implemented, the ingredient name ("flour") comes before the kind of ingredient ("all-purpose, unbleached"), but the scenario expects them to be reversed. For ease of reading, conversationally written should win.

Back into the view specs...

Although it is not quite xpath, I need to rely on some gnarly CSS3 to specify that ingredient "kind" comes before the "name": .ingredient > .kind + .name. The whole example is:
    it "should read conversationally, with the ingredient kind before the name" do
response.should have_selector(".preparations") do |preparations|
preparations.
should have_selector(".ingredient > .kind + .name",
:content => 'flour')
end
end
Making the spec pass is a simple matter of re-arranging the Haml template.
(commit)

While I was in the view, I also took some time to arrange the brand (e.g. Nestle Tollhouse) in the ingredient listing.
(commit)

Moving back out to the Cucumber scenario (and adding the requisite ingredient preparations), I now have the entire scenario passing:
cstrom@jaynestown:~/repos/eee-code$ cucumber features/recipe_details.feature -n -s "Viewing a recipe with several ingredients"
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 several ingredients
Given a recipe for Buttermilk Chocolate Chip Pancakes
When I view the recipe
Then I should see an ingredient of "1 cup all-purpose, unbleached flour"
And I should see an ingredient of "¼ teaspoons salt"
And I should see an ingredient of "chocolate chips (Nestle Tollhouse)"


1 scenario
5 steps passed
(commit)

No comments:

Post a Comment