2024 年 Clojure 状态调查! 中分享您的想法。

欢迎!请查阅 关于 页面以获取更多关于如何使用此功能的信息。

0
ClojureScript

cljs.core/test 的行为与它的文档字符串描述不一致。

cljs.core/test 的定义是

(defn test
  "test [v] finds fn at key :test in var metadata and calls it,
  presuming failure will throw exception"
  [v]
  (let [f (.-cljs$lang$test v)]
    (if f
      (do (f) :ok)
      :no-test)))

根据我的理解,它应该这样使用(示例从 ClojureDocs 上记录的相同函数的文档版本复制,https://docs.clojure.org/clojure.core/test#example-542692cac026201cdc326b8a )

(defn my-function
  "this function adds two numbers"
  {:test #(do
            (assert (= (my-function 2 3) 5))
            (assert (= (my-function 4 4) 8)))}
  ([x y] (+ x y)))

(test #'my-function)  ;equal to (test (var my-function))
=> :ok

因此,cljs.core/test 通过在 :test 键下提供的测试来使函数能够自我描述其功能。

然而,在 CLJS 环境中重复上述内容会产生不同的结果

(defn my-function
  "this function adds two numbers"
  {:test #(do
            (assert (= (my-function 2 3) 5))
            (assert (= (my-function 4 4) 8)))}
  ([x y] (+ x y)))

(test #'my-function)
=> :no-test

有趣的是,鉴于我在 CLJS REPL 中评估了上述内容, metadata 确实是可用的,据我所知

(meta #'my-function)
=>
{:ns cljs.user,
 :name my-function,
 :file "<cljs repl>",
 :end-column 18,
 :source "my-function",
 :column 1,
 :line 1,
 :end-line 1,
 :arglists ([x y]),
 :doc "this function adds two numbers", 
 :test #object[Function]}

通过用一个关键字替换这个相当模糊的函数,可以使情况更加清晰

(defn my-function
  "this function adds two numbers"
  {:test :just-a-keyword}
  ([x y] (+ x y)))

(meta #'my-function)
=>
{:ns cljs.user,
 :name my-function,
 :file "<cljs repl>",
 :end-column 18,
 :source "my-function",
 :column 1,
 :line 1,
 :end-line 1,
 :arglists ([x y]),
 :doc "this function adds two numbers", 
 :test :just-a-keyword}

我曾在 Clojurians Slack 上与 @theller 和 @hiredman 讨论过这个问题,他们推测 cljs.core/test 已经被重新用于执行 deftest 的体,因为这两者似乎相匹配。观察

(require '[cljs.test :as test])
(test/deftest foo (test/is (= 1 2)))
=> #'cljs.user/foo

(test foo)
FAIL in () (<NO_SOURCE_FILE>:1:28)
expected: (= 1 2)
  actual: (not (= 1 2))

:ok

deftest 的体被执行,并返回了关键字 :ok(无论 is 的结果如何),从阅读 cljs.core/test 的定义中也可以看出。

如果 cljs.core/test 以这种方式被重新用于,那么还有两点也是真实的

A) 如果曾经打算让 cljs.core/test 启用测试 defn:test 声明,那么现在不再是这样了。
B) cljs.core/test 的文档字符串有些误导。

文档字符串的第一部分,"test [v] finds fn at key :test in var metadata and calls it",在技术上可能是正确的,但它没有提到与 deftest 的任何联系,因此有些无帮助。

文档字符串的第二部分,", 假设失败将抛出异常",当用于 deftest 时肯定是不正确的——大多数 deftest 都会使用 cljs.test/is 宏,我认为这是公平的——它捕获异常并报告。我认为原始意图是抛出异常,以使 :ok 不返回,但在这个上下文中,这个结构会失败。

这个文档字符串似乎只是 Clojure 版本的副本,所以可能需要更新。或者,cljs.core/test 到目前为止可能是未使用的并且是冗余的?

1 个回答

0
...