First up tonight, I need to link to more human readable text when navigating between meals. So I add the following RSpec example to drive this:
it "should link to easily human readable previous meal" doI can make this example pass with some help from
render("/views/meal.haml")
response.should have_selector("a", :content => "May 15, 2009")
end
Date
's strftime
:%div.navigation(my
‹
=link_to_adjacent_view_date(@meal['date'], @meals_by_date, :previous => true) { |d| Date.parse(d).strftime("%B %e, %Y") }
|
=link_to_adjacent_view_date(@meal['date'], @meals_by_date) { |d| d.strftime("%B %e, %Y") }
›
link_to_adjacent_view_date
takes an optional block argument that produces the link text).With that I have reached the refactor portion of the red-green-refactor cycle. I target these two examples for refactoring:
it "should link to previous meal" doI can combine those into a single, easier to read spec:
render("/views/meal.haml")
response.should have_selector("a", :href => "/meals/2009/05/15")
end
it "should link to easily human readable previous meal" do
render("/views/meal.haml")
response.should have_selector("a", :content => "May 15, 2009")
end
it "should link to previous meal" doSo, is time to move back out to the Cucumber scenario? Not quite, the current failing step is trying to click on the meal name, not the date as I have just implemented.
render("/views/meal.haml")
response.should have_selector("a",
:href => "/meals/2009/05/15",
:content => "May 15, 2009")
end
The difficulty with this is that the
link_to_adjacent_view_date
helper was implemented to yield just the date for presentation. In this case, I need the title as well. That information is in the CouchDB view from last night, which has data that looks like:{"total_rows":7,"offset":0,"rows":[The
{"id":"2002-04-21","key":"2002/04/21","value":["2002-04-21","Sausage Vegetable Grits"]},
{"id":"2002-04-23","key":"2002/04/23","value":["2002-04-23","Black Bean Chili and Fried Grits"]},
{"id":"2002-07-06","key":"2002/07/06","value":["2002-07-06","Mac 'n' Cheese"]},
{"id":"2003-02-09","key":"2003/02/09","value":["2003-02-09","What To Do with Leftover Bubba's"]},
{"id":"2003-05-26","key":"2003/05/26","value":["2003-05-26","Biscuits and Gravy"]},
{"id":"2003-09-24","key":"2003/09/24","value":["2003-09-24","Almost French Onion Soup"]},
{"id":"2006-05-03","key":"2006/05/03","value":["2006-05-03","The Bestest Dinner Ever"]}
]}
key
is the date of meal, the value
is a two element array of the id
and title
. So, yielding both key and value ought to allow me to retain the current date linking behavior (with some modifications), but also support the title linking behavior.Before I implement this, I have to ask, do I really need the meal text? I already have navigation between meals working—the user can click on the date link. The user, eh? Thinking back to the feature that is driving this inside work, the user is described as "a person interested in exploring meals and how they drive certain recipes". I think such a user is much more likely to be engaged in exploration if the meal titles are shown. It is still worthwhile keeping the dates—if nothing else, they provide a clue to the user as to how the between meal links work (i.e. they are date ordered).
Phew! Confident that I am justified in adding this next bit of behavior, I will need to modify the example of the current behavior:
describe "link_to_adjacent_view_date" doThat example reads, given the CouchDB view (
context "couchdb view by_month" do
before(:each) do
@count_by_month = [{"key" => "2009-04", "value" => 3},
{"key" => "2009-05", "value" => 3}]
end
it "should link to block text + date, if block is given" do
link_to_adjacent_view_date("2009-04", @count_by_month) do |date|
"foo #{date} bar"
end.
should have_selector("a",
:href => "/meals/2009/05",
:content => "foo 2009-05 bar")
end
end
end
@count_by_month
), linking to a date adjacent to the supplied date, I should be able to incorporate the date into my own date string (here, surrounding the date with the words "foo" and "bar").Now I need to support two arguments, instead of one, so the example is updated to read:
it "should link to the CouchDB view's key and value, if block is given" doNow, I expect the
link_to_adjacent_view_date("2009-04", @count_by_month) do |date, value|
"foo #{date} bar #{value} baz"
end.
should have_selector("a",
:href => "/meals/2009/05",
:content => "foo 2009-05 bar 3 baz")
end
link_to_adjacent_view_date
helper to yield with the CouchDB value, in addition to the date (key) that it had been yielding. That example verifies that the value ("3" from the context above) is usable as I expect it to be.Running the spec fails now:
cstrom@jaynestown:~/repos/eee-code$ spec ./spec/eee_helpers_spec.rbI can make that pass by changing
...............................F..............
1)
'link_to_adjacent_view_date couchdb view by_month should link to the CouchDB view's key and value, if block is given' FAILED
expected following output to contain a <a href='/meals/2009/05'>foo 2009-05 bar 3 baz</a> tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><a href="/meals/2009/05">foo 2009-05 bar baz</a></body></html>
./spec/eee_helpers_spec.rb:241:
Finished in 0.044204 seconds
46 examples, 1 failure
link_to_adjacent_view_date
to yield the key and value to build the link text:link_text = block_given? ?I have to update all instances of
yield(next_result['key'], next_result['value']) :
next_result['key']
link_to_adjacent_view_date
that use a block to expect two parameters (even if the second one is not used). With all specs passing, it is back to the meal spec to use the meal title in the link text:it "should link to previous meal title" do(where "Foo" is the title a mock CouchDB view, defined in the spec setup)
render("/views/meal.haml")
response.should have_selector("a",
:href => "/meals/2009/05/15",
:content => "Foo")
end
To make that example pass, I change this line in the Haml template:
=link_to_adjacent_view_date(@meal['date'], @meals_by_date, :previous => true) { |d,v| Date.parse(d).strftime("%B %e, %Y") }to read:
=link_to_adjacent_view_date(@meal['date'], @meals_by_date, :previous => true) { |d,v| Date.parse(d).strftime("#{v[1]} (%B %e, %Y)") }OK, now I am ready to work my way back out to the navigation-between-meals Cucumber scenario:
Yay! All passing. I am now assured that quick navigation between meals will work.
(commit)
I currently reside at the following Cucumber milemarker:
26 scenariosTomorrow, I will pick up with another scenario and try to get the number of undefined steps down under 40. I'm getting close.
1 skipped step
42 undefined steps
166 passed steps
No comments:
Post a Comment