6

在对一些将 ascii 序列转换为 unicode 字符的代码进行单元测试时,我发现 Clojure 测试的输出存在问题。

我已经测试过我的终端可以输出 unicode 字符(通过 cat-ing 测试文件)并且工作正常,所以问题似乎与 leiningen、Clojure 或 clojure.test 有关。

这是一个示例测试(使用 unicode 的希腊语部分 - 我也将使用扩展的希腊语,但我认为同样的问题也会适用):

(deftest bc-string-w-comma
  (is (= "αβγ, ΑΒΓ" (parse "abg,*a*b*g"))))

由于输入中缺少空格,它意味着失败。的输出lein test如下:

Testing parse_perseus.test.betacode
FAIL in (bc-string-w-comma) (betacode.clj:15)
expected: (= "???, ???" (parse "abg,*a*b*g"))
  actual: (not (= "???, ???" "???,???"))
Testing parse_perseus.test.core
Testing parse_perseus.test.pluralise
Ran 10 tests containing 59 assertions.
1 failures, 0 errors.

我在这里做错了什么?这是终端仿真问题还是与 clojure 相关的问题?我在使用 Slime/swank/emacs 的 REPL 中运行代码时遇到了同样的问题。emacs 中的 REPL 只输出 unicode 输出的问号(尽管 emacs 非常有能力理解 unicode)。

我尝试在终端和 iTerm (OS X) 中运行它,结果相同。

4

2 回答 2

6

事实证明,您可以将选项传递给 java 以强制输出编码,*out*以便 unicode 工作,如下所示:

java -Dfile.encoding=utf-8 -cp lib/clojure-1.2.0.jar:lib/clojure-contrib-1.2.0.jar clojure.main -i src/whatever.clj

当我使用 Leiningen 时,我将此属性添加到我的 project.clj 文件中:

(defproject project_name "1.0.0-SNAPSHOT"
  :description "A Clojure Project"
  :dependencies [[org.clojure/clojure "1.2.0"]
                 [org.clojure/clojure-contrib "1.2.0"]]
  :dev-dependencies [[swank-clojure "1.2.0"]]
  :jvm-opts ["-Dfile.encoding=utf-8"])
于 2011-01-30T22:45:51.830 回答
2

Clojure 本身似乎很清楚(这是 Ubuntu 10.10、gnome-terminal、OpenJDK):

john@woc-desktop$ java -cp /home/john/.m2/repository/org/clojure/clojure/1.2.0/clojure-1.2.0.jar:/home/john/.m2/repository/org/clojure/clojure-contrib/1.2.0/clojure-contrib-1.2.0.jar clojure.main
Clojure 1.2.0
user=> (use 'clojure.test)
nil
user=> (defn parse [s] "αβγ,ΑΒΓ")
#'user/parse
user=> (deftest greek (is (= "αβγ, ΑΒΓ" (parse ""))))
#'user/greek
user=> (run-tests)

Testing user

FAIL in (greek) (NO_SOURCE_FILE:3)
expected: (= "αβγ, ΑΒΓ" (parse ""))
  actual: (not (= "αβγ, ΑΒΓ" "αβγ,ΑΒΓ"))

Ran 1 tests containing 1 assertions.
1 failures, 0 errors.
{:type :summary, :test 1, :pass 0, :fail 1, :error 0}
user=> 

但它确实破坏了 emacs/swank/clojure-maven-plugin/maven

在 emacs 中的 REPL:

> (is "αβγ""αβγ")

slime-net-send: Coding system iso-latin-1-unix not suitable for "000052(:emacs-rex (swank:listener-eval \"(is \\\"αβγ\\\"\\\"αβγ\\\")

\") \"user\" :repl-thread 33)
"

如果我使用 maven、下面的简单 pom 文件和 mvn clojure:repl 就可以了:

[INFO] [clojure:repl {execution: default-cli}]
Clojure 1.2.0
user=> (use 'clojure.test) (is "αβγ""αβγ")
nil
"αβγ"
user=> (defn parse [s] "αβγ,ΑΒΓ")
#'user/parse
user=> (deftest greek (is (= "αβγ, ΑΒΓ" (parse ""))))
#'user/greek
user=> (run-tests)

Testing user

FAIL in (greek) (NO_SOURCE_FILE:3)
expected: (= "αβγ, ΑΒΓ" (parse ""))
  actual: (not (= "αβγ, ΑΒΓ" "αβγ,ΑΒΓ"))

Ran 1 tests containing 1 assertions.
1 failures, 0 errors.
{:type :summary, :test 1, :pass 0, :fail 1, :error 0}
user=> 

但是如果我使用这个片段添加 jline 库:

<dependency>
  <groupId>jline</groupId>
  <artifactId>jline</artifactId>
  <version>0.9.94</version>
</dependency>

然后我得到:

[INFO] [clojure:repl {execution: default-cli}]
[INFO] Enabling JLine support
Clojure 1.2.0
user=> (use 'clojure.test) (is "αβγ""αβγ")
nil
"���"
user=> (defn parse [s] "αβγ,ΑΒΓ")
#'user/parse
user=> (deftest greek (is (= "αβγ, ΑΒΓ" (parse ""))))
#'user/greek
user=> (run-tests)

Testing user

FAIL in (greek) (NO_SOURCE_FILE:3)
expected: (= "���, ���" (parse ""))
  actual: (not (= "���, ���" "���,���"))

Ran 1 tests containing 1 assertions.
1 failures, 0 errors.
{:type :summary, :test 1, :pass 0, :fail 1, :error 0}
user=> 

这看起来非常像你的错误。因此,问题可能出在 jLine 或 Leiningen 和 maven 与 jLine 相关的其他一些共同点。

或者当然,可能有两个独立的 unicode 相关故障。

这是我的 maven pom.xml 文件,以防有人尝试调试它。

<project>

  <modelVersion>4.0.0</modelVersion>
  <groupId>com.aspden</groupId>
  <artifactId>maven-clojure-simple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>maven-clojure-simple</name>
  <description>maven, clojure: simple project</description>

  <repositories>

    <repository>
      <id>clojure</id>
      <url>http://build.clojure.org/releases</url>
    </repository>
    <repository>
      <id>central</id>
      <url>http://repo1.maven.org/maven2</url>
    </repository>
  </repositories>

  <dependencies>
    <dependency>
      <groupId>org.clojure</groupId>
      <artifactId>clojure</artifactId>
      <version>1.2.0</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
    <groupId>com.theoryinpractise</groupId>
    <artifactId>clojure-maven-plugin</artifactId>
    <version>1.3.5-SNAPSHOT</version>
      </plugin>
    </plugins>
  </build>

</project>

我很欣赏这不是答案,但我认为它可能会有所帮助。

于 2011-01-30T17:25:58.740 回答