clojure.spec.alpha
允许在定义新规范时使用不可解析的规范:
(s/def :foo/bar (s/or :nope :foo/foo))
在这里,:foo/foo
无法解决,因此 using:foo/bar
将引发使用异常:
(s/valid? :foo/bar 42)
;; Exception Unable to resolve spec: :foo/foo clojure.spec.alpha/reg-resolve! (alpha.clj:69)
这是我的代码中发生的事情,当我输入诸如:my-ns/my-spec
而不是::my-ns/my-spec
. 我想用单元测试来捕捉那些。
深入研究clojure.spec.alpha
源代码,我发现我可以获得所有规格,(keys (s/registry))
因此我的测试如下所示:
(ns my-ns.spec-test
(:require [clojure.test :refer :all]
[clojure.spec.alpha :as s]
;; :require all the relevant namespaces to populate the
;; global spec registry.
[my-ns.spec1]
[my-ns.spec2]))
(deftest resolvable-specs
(doseq [spec (keys (s/registry))]
(is (resolvable? spec))))
;; ^^^^^^^^^^^ placeholder; that’s the function I want
不幸的是,没有像s/resolvable?
in这样的东西clojure.spec.alpha
。到目前为止我发现的唯一解决方案是调用(s/valid? spec 42)
并假设它没有引发异常意味着它是可解决的,但它不会检查所有分支:
(s/def :int/int int?)
(s/def :bool/bool bool?)
(s/def :my/spec (s/or :int :int/int
:other (s/or :bool bool/bool
:nope :idont/exist)))
(s/valid? :my/spec 1) ; <- matches the :int branch
;; => true
(s/valid? :my/spec :foo)
;; Exception Unable to resolve spec: :idont/exist clojure.spec.alpha/reg-resolve! (alpha.clj:69)
我检查了异常堆栈跟踪以及源代码,以查看是否可以找到任何函数来完全解析规范,而无需使用类似42
或:foo
以上的测试值,但找不到任何函数。
有没有办法检查,对于给定的规范,它在其所有分支中引用的所有规范确实存在?