我正在使用
unicode-show
包来进行通过 hspec 测试:
代码:
...(show . Data.List.NonEmpty.head $ infiles2, outFile2) `shouldBe` ("\"/foo/bar/baz - :.ogg\"", outFile1))...
expected: ("\"/foo/bar/baz - :.ogg\"", "/foo/bar/fee.m4a")
but got: ("\"/foo/bar/baz - \\65306.ogg\"", "/foo/bar/fee.m4a")
但是这段代码通过了:
...(Text.Show.Unicode.ushow . Data.List.NonEmpty.head $ infiles2, outFile2) `shouldBe` ("\"/foo/bar/baz - :.ogg\"", outFile1))...
Test suite spec: RUNNING...
.........
Finished in 0.0115 seconds
9 examples, 0 failures, 2 pending
Test suite spec: PASS
为什么这是必要的?为什么
show
在这里不做正确的事?
您不应该使用show
来检查两个字符串的等价性。事实上,如果你使用:
"/foo/bar/baz - :.ogg" == "/foo/bar/baz - \65306.ogg"
这会返回 True
,因为两个字符串都包含 20 个字符,并且每个字符都是相同的。所以你的测试(可能)可以与:
(Data.List.NonEmpty.head infiles2, outFile2) `shouldBe` ("/foo/bar/baz - :.ogg", outFile1))
但是你在这里使用show
。
show :: Show a => a -> String
是什么意思?它通常用于将对象 a
转换为字符串,该字符串是包含构造
a
的代码的 string。因此,对于像
Int
这样的
5
,它会生成
"5"
,如果您在终端中写入
5
,那么您就构造了
Int
5
。但是构造
5
的方法有多种,例如
1 + 4
也是
5
,但是
"5"
和
"1 + 4"
不是相同的String
。这是两个产生
5
的表达式,但是在字符串级别检查时,它们是不同的字符串。这就是字符串
show
的作用,它将生成一个类似
"\"/foo/bar/baz - \\65306.ogg\""
的字符串,其中content
"/foo/bar/baz - \65306.ogg"
,请注意,该字符串包含 27 个字符。事实上,特殊的冒号字符被转义为
\65306
,其中包含六个 字符,以及引号字符为
\"
,因此每个引号包含两个字符。unicode字符本身不需要转义,所以如果转义方式不同,你会得到两个不同的结果,因此字符串不同,因此测试失败。