Wednesday, May 20, 2009

Meal Summaries, By Month

‹prev | My Chain | next›

In order to display a list of meals in a month, we need the meal's title, date, summary, list of menu items, and the image. That is pretty much the entire meal, so we might as well pull the entire thing back in the CouchDB view. Thus, the view becomes:
    "by_month": {
"map": "function (doc) {
if (doc['type'] == 'Meal') {
emit(doc['date'].substring(0, 4) + '-' + doc['date'].substring(5, 7), doc);
}
}",
"reduce": "function(keys, values, rereduce) { return values; }"
},
"count_by_month": {
"map": "function (doc) {
if (doc['type'] == 'Meal') {
emit(doc['date'].substring(0, 4) + '-' + doc['date'].substring(5, 7), 1);

}
}",
"reduce": "function(keys, values, rereduce) { return sum(values); }"
}
With that in place, I need to update the before(:each) example code block for the Haml specs:
  before(:each) do
assigns[:meals] = {
'rows' => [
{ "value" => [{"date" => '2009-05-14', "title" => 'Meal 1'}]},
{ "value" => [{"date" => '2009-05-15', "title" => 'Meal 2'}]},

]
}
assigns[:year] = 2009
assigns[:month] = '05'
assigns[:count_by_year] = [{"key" => "2009-04", "value" => 3},
{"key" => "2009-05", "value" => 3}]
end
The bits in bold were changed to look like CouchDB records. With that passing, I specify that the meals-by-month listing should include the meal date and summary:
  it "should include each meal's date in the title" do
render("/views/meal_by_month.haml")
response.should have_selector("h2", :content => "2009-05-14")
end

it "should include each meal's summary" do
render("/views/meal_by_month.haml")
response.should have_selector("p", :content => "Meal 2 Summary")
end
After padding the before(:each) block with data for both of these, I get the examples passing by modifying the Haml view:
%h1= "Meals from #{@year}-#{@month}"

.meals
- @meals["rows"].each do |meal|
%h2
%span.date= meal['value'][0]['date']
%span.title= meal['value'][0]['title']
%p= meal['value'][0]['summary']
I am also going to want to include the menu items and a meal thumbnail. Both of these are going to be tricky, so I'll defer that for another day. So that I do not forget, I add some reminders in the Haml spec:
  it "should include a thumbnail image of the meal"

it "should include the menu items"

it "should include recipe titles in the menu items"
Before calling it a day (or moving on to those pending specs), I work my way back out to the Cucumber senario. I have done enough work that I should be able to check off one or two more steps. This is also a good time to test the complete stack of Sinatra, Haml, and CouchDB. The entire scenario:
  Scenario: Browsing a meal in a given month

Given a "Even Fried, They Won't Eat It" meal enjoyed in May of 2009
And a "Salad. Mmmm." meal enjoyed in April of 2009
When I view the list of meals prepared in May of 2009
Then I should see the "Even Fried, They Won't Eat It" meal among the meals of this month
And I should not see the "Salad. Mmmm." meal among the meals of this month
And I should not see a link to June of 2009
When I follow the link to the list of meals in April of 2009
Then I should not see the "Even Fried, They Won't Eat It" meal among the meals of this month
And I should see the "Salad. Mmmm." meal among the meals of this month
And I should not see a link to February of 2009
And I should see a link to May of 2009
Already done is viewing the list of meals in May of 2009. Now I can verify that the meal from May of 2009 is included and that the meal from April of 2009 is not by implementing the two steps:
Then /^I should see the "([^\"]*)" meal among the meals of this month$/ do |title|
response.should have_selector("h2", :content => title)
end

Then /^I should not see the "([^\"]*)" meal among the meals of this month$/ do |title|
response.should_not have_selector("h2", :content => title)
end
Thankfully, for once, Cucumber proves that I have gotten this assembled correctly.

No comments:

Post a Comment