Yesterday, I created Sinatra helper methods that queried CouchDB views for updated versions of recipes as well as recipes that have been replaced by a more recent recipe in the cookbook. Those helper methods were close to the CouchDB metal. Today I would like to build additional helper methods that can be used directly inside Haml templates.
The first thing that I do is query-replace the previous method names (
recipe_update_of
, recipes_updated_by
) for more CouchDB-centric names (couch_recipe_update_of
, couch_recipes_updated_by
). This a cue for my future self that these methods are closely related to the underlying CouchDB view. It could also be interpreted as a cue to my current self that these methods might be more properly organized in their own class or module. I will table that latter thought for the time being.Right now, I want to drive a helper that will indicate that the current recipe is an update to a previous recipe. On the legacy site, that looked like:
Putting on my BDD hat, I write the following RSpec
example:
describe "recipe_update_of" doThe first time I run this example, I see a failure due to the lack of a helper method named
it "should include links to previous recipes" do
stub!(:couch_recipe_update_of).and_return(['2000-09-07-recipe'])
recipe_update_of('2009-09-07-recipe').
should have_selector('span.update-of a')
end
end
recipe_update_of
:cstrom@jaynestown:~/repos/eee-code$ spec ./spec/eee_helpers_spec.rbSo I define that helper method:
.......................................................................F..
1)
NoMethodError in 'recipe_update_of should include links to previous recipes'
undefined method `recipe_update_of' for #<Test::Unit::TestCase::Subclass_13:0xb6b25d5c>
./spec/eee_helpers_spec.rb:501:
Finished in 0.104805 seconds
74 examples, 1 failure
def recipe_update_ofWhen the examples are run now, I receive a failure for the incorrect arity of the helper method:
end
cstrom@jaynestown:~/repos/eee-code$ spec ./spec/eee_helpers_spec.rbI add a single argument to the helper method as desired by the example:
.......................................................................F..
1)
ArgumentError in 'recipe_update_of should include links to previous recipes'
wrong number of arguments (1 for 0)
./spec/eee_helpers_spec.rb:501:in `recipe_update_of'
./spec/eee_helpers_spec.rb:501:
Finished in 0.112535 seconds
74 examples, 1 failure
def recipe_update_of(permalink)Now I find no errors, but the expectation is not met:
end
cstrom@jaynestown:~/repos/eee-code$ spec ./spec/eee_helpers_spec.rbI work methodically through the change-the-message or make-it-pass cycle to ensure that I check my assumptions with each step. With assumptions successfully checked, I am ready to make it pass. That is a fairly in-depth example—I need the links returned by the
.......................................................................F..
1)
'recipe_update_of should include links to previous recipes' FAILED
expected following output to contain a <span.update-of a href='/recipes/2000-09-07-recipe'/> tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
./spec/eee_helpers_spec.rb:501:
Finished in 0.118594 seconds
74 examples, 1 failure
couch_recipe_update_of
helper method to be embedded in an update <span>
:def recipe_update_of(permalink)With that, I have all of my examples passing:
previous = couch_recipe_update_of(permalink)
links = previous.map do |update_permalink|
%Q|<a href="/recipes/#{update_permalink}"></a>|
end
%Q|<span class="update-of">| +
%Q|This is an update of a previous recipe: | +
links.join(", ") +
%Q|</span>|
end
cstrom@jaynestown:~/repos/eee-code$ spec ./spec/eee_helpers_spec.rbThe links are in place, but there is no content. To drive the link text, I use this example:
..........................................................................
Finished in 0.172632 seconds
74 examples, 0 failures
it "should link to a pretty formatted date" doI get that passing by calculating the date string:
stub!(:couch_recipe_update_of).and_return(['2000-09-07-recipe'])
recipe_update_of('2009-09-07-recipe').
should have_selector('span.update-of a',
:content => "September 7, 2000")
end
def recipe_update_of(permalink)Last up, I write an example that describes the case in which the recipe is not an update to a previous recipe:
previous = couch_recipe_update_of(permalink)
links = previous.map do |update_permalink|
date_str = Date.parse(update_permalink).strftime("%B %e, %Y")
%Q|<a href="/recipes/#{update_permalink}">#{date_str}</a>|
end
%Q|<span class="update-of">| +
%Q|This is an update of a previous recipe: | +
links.join(", ") +
%Q|</span>|
end
it "should do nothing if this is not an update" doI can get that passing with a conditional:
stub!(:couch_recipe_update_of)
recipe_update_of('2009-09-07-recipe').
should be_nil
end
def recipe_update_of(permalink)That gets all of my specs passing:
previous = couch_recipe_update_of(permalink)
if previous
links = previous.map do |update_permalink|
date_str = Date.parse(update_permalink).strftime("%B %e, %Y")
%Q|<a href="/recipes/#{update_permalink}">#{date_str}</a>|
end
%Q|<span class="update-of">| +
%Q|This is an update of a previous recipe: | +
links.join(", ") +
%Q|</span>|
end
end
cstrom@jaynestown:~/repos/eee-code$ spec ./spec/eee_helpers_spec.rbI follow a similar procedure to drive the this-recipe-has-been-updated feature:
............................................................................
Finished in 0.109127 seconds
76 examples, 0 failures
With helper methods in hand, I update my Haml templates to use them:
...That should just about do it for the "inside" code work. Tomorrow I will work my way back out to the Cucumber scenario to verify (hopefully) that I have done it well.
%div
= recipe_updated_by(@recipe['id'])
%div
= recipe_update_of(@recipe['id'])
...
No comments:
Post a Comment