## 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)  permalink = "id-#{date.to_s}"  meal = {    :title       => title,    :date        => date,    :serves      => 4,    :summary     => "meal summary",    :description => "meal description"  }  RestClient.put "#{@@db}/#{permalink}",    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 == 200end`
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"      @permalink = "id-#{@date.to_s}"      meal = {        :title       => @title,        :date        => @date,        :serves      => 4,        :summary     => "meal summary",        :description => "meal description"      }      RestClient.put "#{@@db}/#{@permalink}",        meal.to_json,        :content_type => 'application/json'    end    after(:each) do      data = RestClient.get "#{@@db}/#{@permalink}"      meal = JSON.parse(data)      RestClient.delete "#{@@db}/#{@permalink}?rev=#{meal['_rev']}"    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!