ClojureScript规范断言未触发异常

ClojureScript规范断言未触发异常,clojure,clojurescript,leiningen,Clojure,Clojurescript,Leiningen,我有一个实用函数,它使用spec确保传递的map参数完全由整数设置键: src/project/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/

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

src/project/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?)
(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"}))))))
传递非整数键控映射应触发规范断言异常:

test/project/utils\u test.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?)
(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
项目.clj
中有
:全局变量{*asserts*true}
,尽管我相信这是默认值。

你必须调用
cljs.spec.test.alpha/instrument
才能断言你的spec'd函数的调用。不带参数调用它将检测已加载的每个规范函数:

(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])
切换):


请注意,
s/fdef
是一个开发时工具。为了执行对函数ARGS/结果的约束,考虑使用<代码>:预:POST < /代码>条件,请参见,谢谢,引用<代码>:预和<代码>:POST <代码>真的很有用!谢谢,我重新阅读了clojure.spec指南,我意识到我需要使用
:pre
:post
条件在运行时检查和强制执行spec。