Dancer-1.3060のテストがこける


さっきおもむろにコード読もうと思ってcpanmしたところ、当方の環境だとテストがこけます。該当箇所だけ抜き出すと...

[~/.cpanm/latest-build/Dancer-1.3060]% prove -b ./t/11_logger/05_format.t
./t/11_logger/05_format.t .. 1/9
#   Failed test at ./t/11_logger/05_format.t line 35.
#                   '- 16/ 6/2011 01:22:37 2011-06-16 01:22:37
# '
#     doesn't match '(?^ix:- \s
#               \d+/[a-z]+/\d+ \s \d+:\d+:\d+ \s
#               \d+-\d+-\d+ \s \d+:\d+:\d+ )'
# Looks like you failed 1 test of 9.
./t/11_logger/05_format.t .. Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/9 subtests 

Test Summary Report
-------------------
./t/11_logger/05_format.t (Wstat: 256 Tests: 9 Failed: 1)
  Failed test:  7
  Non-zero exit status: 1
Files=1, Tests=9,  0 wallclock secs ( 0.03 usr  0.01 sys +  0.16 cusr  0.02 csys =  0.22 CPU)
Result: FAIL

です。

原因は

# t/11_logger/05_format.t (L33-37)
setting charset => 'UTF-8', logger_format => '%h %t %T';
$str = $l->format_message('debug', 'this is debug');
like $str, qr{- \s
                   \d+/[a-z]+/\d+ \s \d+:\d+:\d+ \s
                   \d+-\d+-\d+ \s \d+:\d+:\d+ }xi;

# lib/Dancer/Logger/Abstract.pm (L93-94)
t => sub { Encode::decode(setting('charset'),
                                          POSIX::strftime( "%d/%b/%Y %H:%M:%S", localtime )) },

からわかるように、POSIX::strftime("%b", localtime)がJunなどの英語表記月名を返すことをテストコードは期待している(正規表現[a-z]+のところ)のですが、ここは一般的にポータブルじゃありません。

# perldoc POSIXから抜粋
strftime
               Convert date and time information to string.  Returns the
               string.

               Synopsis:

                       strftime(fmt, sec, min, hour, mday, mon, year, wday = −1, yday = −1, isdst = −1)

(snip.)
               If you want your code to be portable, your format ("fmt")
               argument should use only the conversion specifiers defined by
               the ANSI C standard (C89, to play safe).  These are
               "aAbBcdHIjmMpSUwWxXyYZ%".  But even then, the results of some
               of the conversion specifiers are non‐portable.  For example,
               the specifiers "aAbBcpZ" change according to the locale
               settings of the user, and both how to set locales (the locale
               names) and what output to expect are non‐standard.  The
               specifier "c" changes according to the timezone settings of the
               user and the timezone computation rules of the operating
               system.  The "Z" specifier is notoriously unportable since the
               names of timezones are non‐standard. Sticking to the numeric
               specifiers is the safest route.

とりまLANG=Cを与えれば

[~]% LANG=C cpanm Dancer
# => ok

テスト通ります。


ちなみに、ざっとgithubを追ってみたところ

  • こけるテストは、Dancer-1.3059_03以降に入った比較的新しいもの
  • 短期間中にFixされたりしてる

な感じなので、ちょっと放っておけば対応が入るかもしれませんね。