ClojureScript规范断言不会触发异常

时间:2018-03-25 10:45:17

标签: clojure clojurescript leiningen

我有一个实用程序函数,它使用spec来确保传递的map参数完全由整数键入:

的src /项目/ utils.cljs

(ns project.utils
  (:require [cljs.spec.alpha :as s]))

(defn next-int-key
 "Return the next integer key for a integer keyed map."
 [m]
 (if (empty? m) 0
   (+ 1 (apply max (keys m)))))

(s/fdef next-int-key :args (s/cat :m (s/map-of int? some?)) :ret int?)

传递非整数键控映射应触发规范断言异常:

测试/项目/ utils_test.cljs

(ns project.utils-test
  (:require [project.utils :as utils]
            [cljs.test :refer-macros [deftest testing is]]
            [cljs.spec.alpha :as s]))

(deftest test-next-int-key
  (testing "next-int-key util function"
    (testing "with an empty map"
      (is (= 0 (utils/next-int-key {}))))
    (testing "with a populated, integer keyed map"
      (is (= 4 (utils/next-int-key {0 :zero-val 1 :one-val 2 :two-val 3 :three-val}))))
    (testing "with a populated, integer keyed map that has a gap"
      (is (= 5 (utils/next-int-key {0 :zero-val 1 :one-val 2 :two-val 4 :four-val}))))
    (testing "with a non-integer keyed map"
      (is (= 5 (utils/next-int-key {:one "foo"}))))))

但是,不会触发任何异常,而是允许执行效用函数,从而产生错误值。

来自Clojure&CLJS规范文档规范声明默认启用。

我的leiningen :global-vars {*asserts* true}中有project.clj,但我相信这是默认值。

1 个答案:

答案 0 :(得分:1)

您必须致电cljs.spec.test.alpha/instrument以使您的规范具有' d功能。调用断言。没有args调用它将检测已加载的每个spec规范函数:

(stest/instrument)

您可以在测试命名空间中调用它,可以选择传递您想要的特定符号:

(stest/instrument `utils/next-int-key)

更新:未提及其他一些选项,例如使用s/valid?:pre / :post断言:

(defn stringer-bell
  "Prints a string and rings bell."
  [s]
  {:pre [(s/valid? (s/nilable string?) s)]}
  (println s "\007"))

或在功能体中使用s/assert(请记得(s/check-asserts [true|false])切换):

(defn stringer-bell [s]
  (s/assert (s/nilable string?) s)
  (println s "\007"))