Shouldaのテストヘルパーって、モデルの宣言とまったく同じような書き方で、身も蓋も無い。

テスト:

class PrefectureTest > ActiveSupport::TestCase
should_belong_to :region
should_have_many :graves
should_have_many :inquiries
should_have_many :request_for_publishings
should_require_attributes :name, :reading, :roman
should_require_unique_attributes :roman
end

モデル:

class Prefecture > ActiveRecord::Base
belongs_to :region
has_many :graves
has_many :inquiries
has_many :request_for_publishings
validates_presence_of :name, :reading, :roman
validates_uniqueness_of :roman
end

こんなん書いて意味あんのかな?ってちょっと思ったんですが、モデルに少し変更があってそれに気付かず、速攻でテストが通らなくなった。

あー、「強い型付けより強いテスト」ってこれのことか!?

テストがまるで静的型付け言語の型定義みたいだ。

テストを書きまくってる人にとっては、「テストがこれだけなんて心配だ」とそわそわするかもしれない。「強い型付け」なんてこんな程度のもんだ。

「強いテスト」はここからshould … do …と強記していける。

なるほどなー、と今頃思った。

BEST SOFTWARE WRITING
  • BEST SOFTWARE WRITING
  • 翔泳社(2008-02-21)
  • 翔泳社
  • (編集)Joel Spolsky
  • (翻訳)青木 靖
  • 定価:¥ 3,129
  • 新品価格:¥ 3,129
  • 中古価格:¥ 2,464
  • ASIN:4798115819

追記:最近ではshould have_many(:foos).throughみたいな書き方が主流っぽいです。汎用性を考えると仕方ないけど、個人的には上記の様なまるで型のように見える古い書き方のほうが好き・・・。

この間書いた、簡単テストライブラリShouldaのARマクロを(gettextの)日本語で使うプラグインshoulda_jaを下記に置いときます。

ruby script/plugin install http://svn.komagata.org/rails/plugins/shoulda_ja/

参照: 今日のハマリ – shouldaとgettext

twister_iitaidake

言いたいだけ – Twister Alternative

長年探していた「言いたいだけ」にフィットするサービス発見。Twister。

言いたいんだろ?いっちゃえよ!

飲み会。

日本人の祖先を中国、春秋時代の呉に求める説があるらしい。

ということは、俺たちは臥薪嘗胆のどっちの子孫になるんだ?

「呉は確か臥薪だ!」 「いや、それは南の越だろう。」

激論。

・・・・・・・・・。

今年、僕らも項羽と同い年になりました・・・。

kouu

くそっ!くそう・・・・。

おれは、、、おれはだだ

結婚式披露宴余興芸能人ショー演出のアネット

このリンクをブログに張ってエスパー伊東ステッカーが欲しいだけなのに・・・

もう、MTがむずすぎる・・・ウィジェットとかウィジェットセットとか・・・よくわかんない・・・。

簡単テストライブラリShouldaを使うと、RailsのModelのテストが楽だ。

class RegionTest < ActiveSupport::TestCase
  should_require_attributes :name
  should_require_unique_attributes :roman
end

豊富なマクロのおかげでこんな感じに宣言的にテストが書ける。

でも単体でテストを実行したとき(ruby test/units/region_test.rb)はOKなのにrakeで実行すると(rake test:units)エラーになる。

 33) Failure:
test: Region should require name to be set. (RegionTest)
(略)
/blank/ not found in ["名前を入力してください。"] when set to nil.
<nil> is not true.

 34) Failure:
test: Region should require unique value for roman. (RegionTest)
(略)
/taken/ not found in ["ローマ字はすでに存在します。"] when set to "hokkaidou-touhoku".
<nil> is not true.

うーん・・・。

def should_require_attributes(*attributes)
  message = get_options!(attributes, :message)
  message ||= <strong>/blank/</strong>
  (略)
  end
end

ソースを見てみると、should_require_attributesメソッドはエラーメッセージを/blank/という正規表現で決め打ち比較してるみたい。(validates_presence_ofのデフォルトが”“can‘t be blank”“だから)

そういういい加減なの、嫌いじゃない。

environments読み込むとgettextがエラーメッセージを日本語化するのでエラーになっちゃうのか。

でも、

class RegionTest &lt; ActiveSupport::TestCase
  should_require_attributes :name, 
    :message =&gt; "名前を入力してください。" 
  should_require_unique_attributes :roman, 
    :message =&gt; "ローマ字はすでに存在します。" 
end

いちいちこんな風にテスト書かなきゃいけないんでは面倒過ぎてアメリカに亡命したくなる。

プラグインより後に何かを読み込むにはどうすりゃいいんだろう?

% tree vendor/plugins/shoulda_ja
vendor/plugins/shoulda_ja
|-- init.rb
`-- lib
    `-- shoulda
        `-- active_record_helpers.rb

良い方法とは思えないけど、プラグインはアルファベット順に読まれるはずなのでshoulda_jaというプラグインを置いて上書きしてみた。

init.rb:

require 'shoulda'
require File.dirname(__FILE__) + '/lib/shoulda/active_record_helpers'

lib/shoulda/active_record_helpers.rb:

module ThoughtBot
  module Shoulda
    module ActiveRecord
      def should_require_attributes(*attributes)
        message = get_options!(attributes, :message)
        message ||= <strong>/入力してください/</strong>
    (略)
      end

      def should_require_unique_attributes(*attributes)
        message, scope = get_options!(attributes, :message, :scoped_to)
        scope = [*scope].compact
        message ||= <strong>/すでに存在します/</strong>
        (略)
      end
    end
  end
end

うほ、動いた。

・・・・・・・・・アドホック!!!

WebでFIGletなんて使うところないよなあ、と思ってたら。

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;!--    
                                              88           88              
      ,d                                      88           88              
      88                                      88           88              
    MM88MMM  88       88  88,dPYba,,adPYba,   88,dPPYba,   88  8b,dPPYba,  
      88     88       88  88P'   "88"    "8a  88P'    "8a  88  88P'   "Y8  
      88     88       88  88      88      88  88       d8  88  88          
      88,    "8a,   ,a88  88      88      88  88b,   ,a8"  88  88          
      "Y888   `"YbbdP'Y8  88      88      88  8Y"Ybbd8"'   88  88

--&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;

TumblrのソースにはFIGletが!

Googleマップのリファレンスによれば、GoogleマップはまだSSLに対応してないらしい。(SSLでのGoogleマップ

google_maps_alert

うぜぇっ。

Proxy作るもの面倒だしなあ・・・。

・・・・・・・・・っっっ!?

&lt;script type="text/javascript"&gt;var _alert = alert; <strong>alert = function(){}</strong>&lt;/script>
&lt;%= javascript_include_tag "http://maps.google.com/maps?file=api&v="+GOOGLE_MAPS_API_VERSION+"&key="+GOOGLE_MAPS_API_KEY %&gt;
&lt;script type="text/javascript">alert = _alert&lt;/script&gt;

これでよしと・・・。

・・・最低だ。

大体の画像系と同じようにnilとかを入れるだけでOK。

% ./script/console
Loading development environment (Rails 2.1.0)
>> grave = Grave.first
=> (略)
>> grave.overview.url
=> "/system/graves/overviews/1/normal/test_picture_large.gif" 
>> grave.overview = nil
=> nil
>> grave.save
=> true
>> grave.overview.url
=> "/overviews/normal/missing.png"

しかも、削除した場合のURLが自動的にmissing.pngに変わってる。

この勝手な挙動が嫌いな人もいるかもしれないけど面倒臭がりの俺としては嬉しい。

画像があるかどうかは、grave.overview.exists? で分かる。

thoughtbot: Paperclip File Attachments

Requirements

Only ImageMagick, which you can install quite easily install via apt, yum, or port, or the package manager of your choice.

あとやっぱりRMagick無くても動く!そういやImageMagick自体が問題なんじゃなくて、殆どの場合、パッケージのImageMagickが言語バインディングと合わないことが問題だったんだよね。PureRubyで再実装しかないと思ってた。頭良いな作者。

Helperはrails2.xからApplicationControllerにhelper :allとか書いてあって、こちらに書かれてるように優先順位があってハマった。(名前がかぶってたので)

パフォーマンスが厳しいアプリはhelper :allを外して、俺の様にそういうアプリがめったに無い場合はどうせ全部読まれるんだったらApplicationHelperに全部書いた方が見通しがいいと思った(実際個別のHelperに書いたのを何度も見失った)。そうなると、コントローラー名Helperがなければいけないという制約がうざい。