## Wednesday, May 13, 2009

### Browsing Meals

‹prev | My Chain | next›

Up next, according to Cucumber (my master), is the "Browse Meals" feature. The first scenario in there is "Browsing a meal in a given year":
Scenario: Browsing a meal in a given year
Given a "Even Fried, They Won't Eat It" meal enjoyed in 2009
When I view the list of meals prepared in 2009
Then "Even Fried, They Won't Eat It" should be included in the list

Given a "Even Fried, They Won't Eat It" meal enjoyed in 2009
And a "Salad. Mmmm." meal enjoyed in 2008
When I view the list of meals prepared in 2009
Then I should be able to follow a link to the list of meals in 2008
And "Salad. Mmmm." should be included in the list
This was one of the first scenarios that I wrote and it shows, I think. I have the same "Given" and the order of the steps reads a bit off. Re-organizing the scenario a bit:
Scenario: Browsing a meal in a given year

Given a "Even Fried, They Won't Eat It" meal enjoyed in 2009
And a "Salad. Mmmm." meal enjoyed in 2008
When I view the list of meals prepared in 2009
Then the "Even Fried, They Won't Eat It" meal should be included in the list
And the "Salad. Mmmm." meal should not be included in the list
When I follow the link to the list of meals in 2008
Then the "Even Fried, They Won't Eat It" meal should not be included in the list
And the "Salad. Mmmm." meal should be included in the list
Much better.

My "Givens" are declared at the outset. There are two paths being followed (one for 2009, one for 2008), both starting with "When" declarations. Best of all, the second "When" flows from the first—clicking a link displayed in the first.

Implementing the first two steps can be accomplished via a single Given block:
Given /^a "([^\"]*)" meal enjoyed in (\d+)\$/ do |title, year|
date = Date.new(year.to_i, 5, 13)

meal = {
:title => title,
:date => date,
:serves => 4,
:summary => "meal summary",
:description => "meal description"
}

meal.to_json,
:content_type => 'application/json'
end
The next step, viewing the list of meals in 2009, can be defined as:
When /^I view the list of meals prepared in 2009\$/ do
visit("/meals/2009")
response.status.should == 200
end
It fails, of course, since I have to define the meals action, so into the code I go...

As with recipes, I write my meal creation / tear down before / after blocks (this ain't no relational DB with fancy transactions):
context "a CouchDB meal" do
before(:each) do
@date = Date.new(2009, 5, 13)
@title = "Meal Title"

meal = {
:title => @title,
:date => @date,
:serves => 4,
:summary => "meal summary",
:description => "meal description"
}

meal.to_json,
:content_type => 'application/json'

end

after(:each) do
meal = JSON.parse(data)

end
end
The first meals action example is a simple one:
describe "GET /meals/YYYY" do
it "should respond OK" do
get "/meals/2009"
response.should be_ok
end
end
This fails, of course since the action has not been defined. Let's define it and call it a night:
get %r{/meals/(\d+)} do |year|
end
(commit)
(commit)

Three steps down, 5 to go in the first meal scenario:

Looks like some fun with map-reduce is in store for tomorrow!