diff --git a/src/malli/core.cljc b/src/malli/core.cljc index c7aa0c9d7..899b8782e 100644 --- a/src/malli/core.cljc +++ b/src/malli/core.cljc @@ -1,5 +1,5 @@ (ns malli.core - (:refer-clojure :exclude [eval type -deref deref -lookup -key]) + (:refer-clojure :exclude [eval type -deref deref -lookup -key assert]) #?(:cljs (:require-macros malli.core)) (:require #?(:clj [clojure.walk :as walk]) [clojure.core :as c] @@ -2230,6 +2230,18 @@ ([?schema value transformer respond raise] (coerce ?schema value transformer respond raise nil)) ([?schema value transformer respond raise options] ((coercer ?schema transformer respond raise options) value))) +(defmacro assert + "Assert that `value` validates against schema `?schema`, or throws ExceptionInfo. + The var clojure.core/*assert* determines whether assertion are checked." + + ([?schema value] + `(assert ~?schema ~value nil)) + + ([?schema value options] + (if *assert* + `(coerce ~?schema ~value nil ~options) + value))) + (defn entries "Returns `EntrySchema` children as a sequence of `clojure.lang/MapEntry`s where the values child schemas wrapped in `:malli.core/val` Schemas, diff --git a/src/malli/dev/virhe.cljc b/src/malli/dev/virhe.cljc index 9945599d6..a40b2070e 100644 --- a/src/malli/dev/virhe.cljc +++ b/src/malli/dev/virhe.cljc @@ -25,7 +25,9 @@ (let [colors (:colors printer -dark-colors) color (get colors color (:error colors))] #?(:cljs [:span body] - :clj [:span [:pass (str "\033[38;5;" color "m")] body [:pass "\u001B[0m"]]))) + :clj (if color + [:span [:pass (str "\033[38;5;" color "m")] body [:pass "\u001B[0m"]] + [:span body])))) ;; ;; EDN diff --git a/test/malli/assert_test.cljc b/test/malli/assert_test.cljc new file mode 100644 index 000000000..0629256a2 --- /dev/null +++ b/test/malli/assert_test.cljc @@ -0,0 +1,29 @@ +(ns malli.assert-test + (:refer-clojure :exclude [assert]) + (:require + [clojure.test :refer [deftest is]] + [malli.core :refer [assert]])) + + +(set! *assert* true) + +(deftest assert-throws-test + (is (thrown? #?(:clj Exception, :cljs js/Error) + (assert :int "42" ))) + (is (thrown? #?(:clj Exception, :cljs js/Error) + (assert int? "42" ))) + (is (thrown? #?(:clj Exception, :cljs js/Error) + (assert string? 42))) + (is (thrown? #?(:clj Exception, :cljs js/Error) + (assert int? nil))) + (is (thrown? #?(:clj Exception, :cljs js/Error) + (assert [:map [:a int?]] {:a "42"}))) + (is (thrown? #?(:clj Exception, :cljs js/Error) + (assert ::invalid-schema 42)))) + +(deftest assert-checked-and-does-not-throw + (is (= 42 (assert :int 42 ))) + (is (= 42 (assert int? 42 ))) + (is (= "42" (assert string? "42"))) + (is (= nil (assert any? nil))) + (is (= {:a 42} (assert [:map [:a int?]] {:a 42}))))