All right, let's see if I can finish this helper off.
I left myself notes about what was left:
cstrom@jaynestown:~/repos/eee-code$ spec -cfs \The "should show nothing" example is a simple one:
./spec/eee_helpers_spec.rb
...
alternative_preparations
- should retrieve IDs
- should retrieve titles for each alternate ID
- should return nothing if there are no alternate preparations (PENDING: Not Yet Implemented)
- should return a comma separated list of links to recipes (PENDING: Not Yet Implemented)
Pending:
alternative_preparations should return nothing if there are no alternate preparations (Not Yet Implemented)
./spec/eee_helpers_spec.rb:590
alternative_preparations should return a comma separated list of links to recipes (Not Yet Implemented)
./spec/eee_helpers_spec.rb:591
Finished in 0.361926 seconds
85 examples, 0 failures, 2 pending
it "should return nothing if there are no alternate preparations" doIn fact, that example passes right away. It is still a good example to have to ensure that I do not break it with future changes, such as:
alternative_preparations('2009-09-14').
should be_nil
end
it "should return a comma separated list of links to recipes"Before implementing that example, I need yet another helper—this one to pull back a list of titles, given a list of IDs. It should query the "titles" CouchDB view and it should return a list of hashes. In RSpec format:
describe "couch_recipe_titles" doThe POSTs in those examples with the JSON payload are an example of how CouchDB allows lookup by multiple keys in it views (such as the title view that is being used here).
it "should retrieve multiple recipe titles, given IDs" do
RestClient.
should_receive(:post).
with(/titles/, '{"keys":["2008-09-14-recipe","2009-09-14-recipe"]}').
and_return('{"rows": [] }')
couch_recipe_titles(%w{2008-09-14-recipe 2009-09-14-recipe})
end
it "should return a list of recipe IDs and titles" do
RestClient.
stub!(:post).
and_return <<"_JSON"
{"total_rows":578,"offset":175,"rows":[
{"id":"2008-09-14-recipe","key":"2008-09-14-recipe","value":"Recipe #1"},
{"id":"2009-09-14-recipe","key":"2009-09-14-recipe","value":"Recipe #2"}
]}
_JSON
couch_recipe_titles(%w{2008-09-14-recipe 2009-09-14-recipe}).
should == [
{:id => "2008-09-14-recipe", :title => "Recipe #1"},
{:id => "2009-09-14-recipe", :title => "Recipe #2"}
]
end
end
Yes, those examples are very much tied to current implementation. I am not writing good regression tests here (that is what Cucumber will do). I am simply trying to drive implementation. Said implementation is nice and clean—pull back the JSON results and map the results into a list of hashes:
def couch_recipe_titles(ids)With the
data = RestClient.post "#{_db}/_design/recipes/_view/titles",
%Q|{"keys":[#{ids.map{|id| "\"#{id}\""}.join(',')}]}|
JSON.parse(data)['rows'].map do |recipe|
{ :id => recipe["id"], :title => recipe["value"] }
end
end
couch_recipe_titles
helper, together with the couch_alternatives
, I am ready to polish off the alternative_preparations
helper. First up, establishing the context of a recipe with two alternative preparations:context "recipe with two alternate preparations" doThe two CouchDB helpers return two IDs and two recipes in this context. The first aspect of the helper that I would like describe here is that there ought to be two links:
before(:each) do
stub!(:couch_alternatives).
and_return(%w{2007-09-14-recipe 2008-09-14-recipe})
stub!(:couch_recipe_titles).
and_return([
{:id => "2007-09-14-recipe", :title => "Recipe #1"},
{:id => "2008-09-14-recipe", :title => "Recipe #2"}
])
end
it "should have two links" doTo make that example pass, while still ensuring that the no-alternatives case pass, I add a conditional on the return value of the alternate preparations lookup, and then map the recipes associated with those IDs to
alternative_preparations('2009-09-14').
should have_selector("a", :count => 2)
end
<a>
tags:def alternative_preparations(permalink)The last thing that I need this helper to do is to include a label:
ids = couch_alternatives(permalink)
if ids && ids.size > 0
couch_recipe_titles(ids).
map{ |recipe| %Q|<a href="/recipes/#{recipe[:id]}">#{recipe[:title]}</a>|}.
join(", ")
end
end
it "should label the alternate preparations as such" doMaking that pass is a simple matter of adding the label:
alternative_preparations('2009-09-14').
should contain("Alternate Preparations:")
end
def alternative_preparations(permalink)Phew! That combination of helpers ended up taking me much longer than I originally anticipated, but I think that I finally have it done. Not satisfied with "thinking" that I am done, I will verify that I am done by working my way back out to the Cucumber scenario. Tomorrow.
ids = couch_alternatives(permalink)
if ids && ids.size > 0
%Q|<span class="label">Alternate Preparations:</span> | +
couch_recipe_titles(ids).
map{ |recipe| %Q|<a href="/recipes/#{recipe[:id]}">#{recipe[:title]}</a>|}.
join(", ")
end
end
No comments:
Post a Comment