読者です 読者をやめる 読者になる 読者になる

GroovyのPowerAssertにおける空文字の表現がわかりづらい件

groovy

以下のようなPower Assertだと、左辺がStringの内部表現(?)になってしまいます。
""とかで出力してくれればいいのに。

$ groovy -e "assert new String() == 'HOGE'"
Caught: Assertion failed:

assert new String() == 'HOGE'
       |            |
       |            false
       java.lang.String@3fb2d7df

        at script_from_command_line.run(script_from_command_line:1)
$ groovy -e "String left = ''; assert left == 'HOGE'"
Caught: Assertion failed:

assert left == 'HOGE'
       |    |
       |    false
       java.lang.String@4c538974

        at script_from_command_line.run(script_from_command_line:1)


あるテスト中にこれをみたとき、Stringが空であることが直感的に分からず、何が起こったのかを一生懸命デバッグするはめになってしまいました。しかもちょうどテストコードが微妙な実装になっていて、テスト結果がOKになったりNGになったりをしているときで、ものすごくはまりました。


知っていればいいだけの話なので、これをみた人は慌てず騒がず「お、空文字なのか」と思えばOKだと思います。



もちろん直接シングル/ダブルクォートで書いていれば、特に展開されないので以下の通り。

$ groovy -e "assert '' == 'HOGE'"
Caught: Assertion failed:

assert '' == 'HOGE'
          |
          false

        at script_from_command_line.run(script_from_command_line:1)

2010/06/17追記

一応、JIRAに挙げてみました。さて、どうなるか。

2010/06/21追記

コミッタ達が色々案をたたかわせてましたが、Roshan氏の素敵なまとめによって、すっきりとした感じに落ち着きました。

ということで、↓のような仕様になりました。次のGroovy1.7.4で修正される予定です。
やりましたね!

Attaching the consolidated patch here (v2).

Following is the output in various scenarios now:
A)
assert new String() == "xxx"

produces

assert new String() == "xxx"
       |            |
       ""           false

B)
assert new StringBuffer() == "xxx"

produces

assert new StringBuffer() == "xxx"
       |                  |
       ""                 false

C)
assert new StringBuilder() == "xxx"

produces

assert new StringBuilder() == "xxx"
       |                   |
       ""                  false

D)
class EmptyToString {
    String toString(){""}
}
def e = new EmptyToString()
assert e == "xxx"

produces

assert e == "xxx"
       | |
       | false
       EmptyToString@19da4fc (toString() == "")

E)
class NullToString {
    String toString(){null}
}
def n = new NullToString()
assert n == "xxx"

produces

assert n == "xxx"
       | |
       | false
       NullToString@19da4fc (toString() == null)

F)
And as before (no change here), the following

class ExceptionToString {
    String toString(){throw new RuntimeException()}
}
def ex = new ExceptionToString()
assert ex == "xxx"

produces

assert ex == "xxx"
       |  |
       |  false
       ExceptionToString@13c6a22 (toString() threw java.lang.RuntimeException)