【问题标题】:Unicode Clojure unit test outputUnicode Clojure 单元测试输出
【发布时间】:2011-01-30 16:28:12
【问题描述】:

在对一些将 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) 中运行它,结果相同。

【问题讨论】:

    标签: unit-testing unicode clojure leiningen


    【解决方案1】:

    原来你可以将选项传递给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"])
    

    【讨论】:

    • 天哪!我爱你这个答案。以为我的代码错了,我快疯了!
    【解决方案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=> 
    

    但是如果我使用这个 sn-p 添加 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>
    

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

    【讨论】:

    • 我已经尝试做类似的事情来看看会发生什么。有趣的是,像在 REPL 上那样运行测试工作正常,但直接从 java 运行相同的测试却不行。所以java -cp lib/clojure-1.2.0.jar:lib/clojure-contrib-1.2.0.jar:lib/fnparse-2.2.7.jar:src/ clojure.main -i test/parse_perseus/test/betacode.clj
    • 这意味着不是 Leiningen 造成了这种情况,也不是 Maven (asaik),但似乎是 clojure.test 在打印到标准输出时打印失败的方式。
    • 也许不会:(打印“αβγ”)也会产生有趣的字符
    • 这是打印失败的代码:(println "expected:" (pr-str (:expected m))) (clojure.test/report)。为什么这会在 REPL 中很好地打印,但在标准输出中却没有我想知道?
    • Mac OS X 默认使用 MacRoman 编码而不是 UTF-8,所以只是平台配置问题。
    猜你喜欢
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 2011-03-26
    • 1970-01-01
    • 2021-08-18
    相关资源
    最近更新 更多