Haml と Sass (続々)「スペックとフィーチャ」

前回(Haml と Sass (続き)「unexpected kENSURE, expecting kEND」 - Rubyとか Illustratorとか SFとか折紙とか)、scaffold.cssのSass化、一覧ビューの Haml化まで出来た、何とか。しかし、ビューのスペック(rspec(-rails))とフィーチャ(cucumber)には失敗している。その辺をなんとか。

index.htmlビューのスペック

failureメッセージはこんな感じ

1)
ActionView::MissingTemplate in '/items/index.html.erb renders a list of items'
Missing template items/index.html.erb in view path app/views
./spec/views/items/index.html.erb_spec.rb:21:

テンプレートがないとか。それはそうだ。
取り敢えず describe 行を書き換え。

#describe "/items/index.html.erb" do
describe "/items/index.html.haml" do

で、

36 examples, 0 failures

いいでしょう。ただそれでスペックファイル名が「index.html.erb_spec.rb」というのはなんなので「index.html.haml_spec.rb」に改名しておく。

rake features

フィーチャは「script/generate feature Item name:string description:text」で自動生成した「manage_items.feature」

Feature: Manage items
  In order to [goal]
  [stakeholder]
  wants [behaviour]

  Scenario: Register new item
    Given I am on the new item page
    When I fill in "Name" with "name 1"
    And I fill in "Description" with "description 1"
    And I press "Create"
    Then I should see "name 1"
    And I should see "description 1"

  Scenario: Delete item
    Given the following items:
      |name|description|
      |name 1|description 1|
      |name 2|description 2|
      |name 3|description 3|
      |name 4|description 4|
    When I delete the 3rd item
    Then I should see the following items:
      |Name|Description|
      |name 1|description 1|
      |name 2|description 2|
      |name 4|description 4|

失敗するのはこの二つ目のテーブルを対照するシナリオ

    Then I should see the following items: # features/step_definitions/item_steps.rb:12
      | Name   | Description   |
          Name
           |
          Description
           |
      | name 1 | description 1 |
          name 1
         |
          description 1
         |
      | name 2 | description 2 |
          name 2
         |
          description 2
         |
      | name 4 | description 4 |
          name 4
         |
          description 4
         |
      Tables were not identical (RuntimeError)
      features/manage_items.feature:22:in `Then I should see the following items:'

Failing Scenarios:
cucumber features/manage_items.feature:14 # Scenario: Delete item

2 scenarios (1 failed, 1 passed)
9 steps (1 failed, 8 passed)

どうも改行の違いを見てるらしい。タイトル行「|Name|Description|」を見るとして、

erb

  <tr>
    <th>Name</th>
    <th>Description</th>
  </tr>

がその儘下記

  <tr>
    <th>Name</th>
    <th>Description</th>
  </tr>

一方 haml

  %tr
    %th
      Name
    %th
      Description

が下記になる

      <tr>
        <th>
          Name
        </th>
        <th>
          Description
        </th>
      </tr>

haml化で構造化が進んで改行が増えてる模様。この改行の認識をどうするというのか。

取り敢えず「|Name|Description|」を正規表現で誤魔化してみよう「|\s*Name\s*|\s*Description\s*|」

    Then I should see the following items: # features/step_definitions/item_steps.rb:12
      | \s*Name\s* | \s*Description\s* |
          Name
           |
          Description
           |

いや、変わらない。ちょっと中を見てやる必要がありそうだ。

item_steps.rb

フィーチャの所要のステップ「Then I should see the following items:」は何処にあるんだろう。

features/step_definitions/item_steps.rb を見る、itemはモデルの名前だったね。

Given /^the following items:$/ do |items|
  Item.create!(items.hashes)
end

When /^I delete the (\d+)(?:st|nd|rd|th) item$/ do |pos|
  visit items_url
  within("table > tr:nth-child(#{pos.to_i+1})") do
    click_link "Destroy"
  end
end

Then /^I should see the following items:$/ do |expected_items_table|
  expected_items_table.diff!(table_at('table').to_a)
end

このステップ定義全般にも見所は多いが今は /^I should see the following items:$/ を見る。
「expected_items_table」とか、「table_at()」ってなんなんだろう。

その前に、ここで String#strip すればこのシナリオ(ステップ)は何とかなるんだよね。
さっき試したフィーチャ(シナリオ)文自体の「\s*」は無しにしておいて、こっちを修正

Then /^I should see the following items:$/ do |expected_items_table|
  expected_items_table.diff!(table_at('table').to_a.map{ |cell| cell.strip })
end

いや、駄目だ

    Then I should see the following items: # features/step_definitions/item_steps.rb:12
      | Name   | Description   |
      | name 1 | description 1 |
      | name 2 | description 2 |
      | name 4 | description 4 |
      undefined method `strip' for #<Array:0xb6d9cb58> (NoMethodError)
      ./features/step_definitions/item_steps.rb:13
      ./features/step_definitions/item_steps.rb:13:in `/^I should see the following items:$/'
      features/manage_items.feature:22:in `Then I should see the following items:'

Failing Scenarios:
cucumber features/manage_items.feature:14 # Scenario: Delete item

2 scenarios (1 failed, 1 passed)
9 steps (1 failed, 8 passed)

Array の Array のようだ、ならそうしてみよう

Then /^I should see the following items:$/ do |expected_items_table|
  expected_items_table.diff!(table_at('table').to_a.map{ |row| row.map{ |cell| cell.strip } })
end
    Then I should see the following items: # features/step_definitions/item_steps.rb:12
      | Name   | Description   |
      | name 1 | description 1 |
      | name 2 | description 2 |
      | name 4 | description 4 |

2 scenarios (2 passed)
9 steps (9 passed)

一応フィーチャ通った。通すだけならこれでいいけど、やっぱちょっと無様か。

まあ、今回はここまで。

expected_items_table
Cucumber::Ast::Table
table_at('table')
Webrat::Table

について等さらに続く(つもり)