WindowsPowerShell+Test::Moreでテストの時の文字化けを解消する方法

@nqounetです.

ここのところ,MacでもリロードするのにF5を押したり(もちろん動きません)しています.

変更したのはprintの部分で,encodeの処理を加えただけです.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
use utf8;
use strict;
use warnings;
use Test::More;
use Encode;
use Term::Encoding qw(term_encoding);
my $charset = term_encoding;

{
  no warnings 'redefine';
  sub Test::Builder::_print_to_fh {
      my( $self, $fh, @msgs ) = @_;

      # Prevent printing headers when only compiling.  Mostly for when
      # tests are deparsed with B::Deparse
      return if $^C;

      my $msg = join '', @msgs;
      my $indent = $self->_indent;

      local( $\, $", $, ) = ( undef, ' ', '' );

      # Escape each line after the first with a # so we don't
      # confuse Test::Harness.
      $msg =~ s{\n(?!\z)}{\n$indent# }sg;

      # Stick a newline on the end if it needs it.
      $msg .= "\n" unless $msg =~ /\n\z/;

      return print $fh $indent, encode($charset, $msg);
  }
}

... # テストを書く

いろいろ試しているうちにfind_encodingを消してしまったのすが,これだったらfind_encodingを使ったほうが速そうです.

実際のスクリプトは,Test::Mojoを継承してゴニョゴニョしているものなので,この状態で動くかどうかはわかりません.

いずれにしろ,プライベートな関数を再定義しているので行儀が良いわけではありません.

意図的に出力する分については,以前の記事で文字化けを解消できたのですが,テストが失敗した時に自動的に出してくれる出力が文字化けのままでした.

どうにかしたいな〜と思いながらTest::Moreのドキュメントを読んでいて,今更ですがWide character in printについて書いてあるのを発見しました.

これは良さそうです,ということで試したのですが,どうもうまく行きませんでした.

1
2
3
4
my $builder = Test::More->builder;
binmode $builder->output,         ":encoding($charset)";
binmode $builder->failure_output, ":encoding($charset)";
binmode $builder->todo_output,    ":encoding($charset)";

どこかで変なミスをしたのかもしれないのですが,cp932にマッピングされていない文字がある!,というふうに文字ごとに警告がでました.

正確な文字コードは忘れましたが,すべての文字に何かがくっついていた感じです.

もしかすると,変数をやめてcp932を直打ちしたかもしれませんが,結果は同じだったと思います.

メモってなくて記憶で書いているのでアレですが.

念のためBEGINを使ってみましたが,同じだったような気がします.

メモってなくて(以下略

そこにあったのが,Test::Builder::_print_to_fhでした.

前後を見てみましたが,printしているのはここだけっぽいので,それじゃあって感じでencodeして出力するように再定義してみました.

嫌なエラーも消え,文字化けも解消されました.

めでたしめでたし.

Windowsも内部的にはUTF-8を使ってるんじゃないんですかね?

Comments

comments powered by Disqus