symfony1.2でDoctrine1.1使ってJobeetチュートリアル8日目

テストもプログラムしよう回

Adding Tests for new Features

テスト項目増やすなら、lime_testへの引数の数字も増やす。

// 第一引数(この場合7)は、テスト項目数と合わせる。
$t = new lime_test(7, new lime_output_color());

Adding Tests because of a Bug

$text = preg_replace('~[^\\pL\d]+~u', '-', $text);

この~(チルダ)何だ?と思ったら、デリミタか。

私は日本人です

フランス語よりは、日本語通して欲しいなぁ。

<?php
// lib/Jobeet.class.php
class Jobeet
{
  static public function slugify($text)
  {
    // replace non letter or digits by -
    $text = preg_replace('~[^\\pL\d]+~u', '-', $text);

    // trim
    $text = trim($text, '-');

    // lowercase
    // urlencode後の英字が小文字にならないように先にこっち実行
    $text = strtolower($text);

    // transliterate
    // GETで渡すので、urlencodeかける
    $text = urlencode($text);

    // remove unwanted characters
    // urlencodeかけると、"%E3%81%82"と%英数字になるので、置換除外文字に%も追加
    $text = preg_replace('~[^-%\w]+~', '', $text);

    if (empty($text))
    {
      return 'n-a';
    }

    return $text;
  }
}


これで、日本語でも渡せるようになったが、
link_to関数通すと、"%"が"%25"にエスケープされてしまいアドレスバーに日本語出ない(T_T)
こんな感じ

http://colinux/~takitake/jobeet/frontend_dev.php/job/%E3%83%9C%E3%83%BC%E3%83%80%E3%83%BC%E5%95%86%E4%BA%8B/%E5%B9%BB%E6%83%B3%E9%83%B7-%E8%BF%B7%E3%81%84%E5%AE%B6/2/%E5%BC%8F%E7%A5%9E
// apps/frontend/modules/job/templates/_list.php
<table class="jobs">
  <?php foreach ($jobs as $i => $job): ?>
    <tr class="<?php echo fmod($i, 2) ? 'even' : 'odd' ?>">
      <td class="location"><?php echo $job->getLocation() ?></td>
      <td class="position"><?php echo preg_replace('~%25~', '%', link_to($job->getPosition(), 'job_show_user', $job)) ?></td>
      <td class="company"><?php echo $job->getCompany() ?></td>
    </tr>
  <?php endforeach; ?>
</table>

と、preg_replaceでエスケープ後の"%25"を"%"に置換すれば

http://colinux/~takitake/jobeet/frontend_dev.php/job/ボーダー商事/幻想郷-迷い家/2/式神

と、期待通りにはなるけれど、力業過ぎる。
どうしたもんかなぁ。

Unit Tests Harness

JobeetTest...........................................................ok
model/JobeetJobTest..................................................dubious
    Test returned status 255
Failed Test                     Stat  Total   Fail  List of Failed
------------------------------------------------------------------
model/JobeetJobTest              255      0      0
Failed 1/2 test scripts, 50.00% okay. 0/10 subtests failed, 100.00% okay.

初めから通るなんて思ってないさ!

symfony test:unit model/JobeetJob

で、JobeetJobTest.phpだけテストして詳細情報得る。

変更後
<?php
include(dirname(__FILE__).'/../../bootstrap/Doctrine.php');

// 比較回数3回なんで、第一引数は3
$t = new lime_test(3, new lime_output_color());

$t->comment('->getCompanySlug()');
$job = Doctrine::getTable('JobeetJob')->createQuery()->fetchOne();
$t->is($job->getCompanySlug(), Jobeet::slugify($job->getCompany()), '->getCompanySlug() return the slug for the company');

$t->comment('->save()');
$job = create_job();
$job->save();

// 'Y-m-d h:i:s'形式じゃないとバリデーションエラー
$expiresAt = date('Y-m-d h:i:s', time() + 86400 * sfConfig::get('app_active_days'));
$t->is(date('Y-m-d h:i:s', strtotime($job->getExpiresAt())), $expiresAt, '->save() updates expires_at if not set');

// 'Y-m-d h:i:s'形式じゃないとバリデーションエラー
$job = create_job(array('expires_at' => '2008-08-08 00:00:00'));
$job->save();

// 比較は'Y-m-d'形式でおk
$t->is(date('Y-m-d', strtotime($job->getExpiresAt())), '2008-08-08', '->save() does not update expires_at if set');

function create_job($defaults = array())
{
  static $category = null;

  if (is_null($category))
  {
    // Doctrine式な書き方に変更
    $category = Doctrine::getTable('JobeetCategory')->createQuery()->fetchOne();
  }

  $job = new JobeetJob();
  $job->fromArray(array_merge(array(
    'category_id'  => $category->getId(),
    'company'      => 'Sensio Labs',
    'position'     => 'Senior Tester',
    'location'     => 'Paris, France',
    'description'  => 'Testing is fun',
    'how_to_apply' => 'Send e-Mail',
    'email'        => 'job@example.com',
    'token'        => rand(1111, 9999),
    'is_activated' => true
  ), $defaults));

  return $job;
}