mirror of
https://github.com/penpot/penpot.git
synced 2025-03-11 23:31:21 -05:00
🎉 Add function instrumentation helper and improve assertion exceptions.
This commit is contained in:
parent
f57941fd7c
commit
5876927505
1 changed files with 48 additions and 5 deletions
|
@ -12,11 +12,16 @@
|
|||
(:refer-clojure :exclude [assert])
|
||||
#?(:cljs (:require-macros [app.common.spec :refer [assert]]))
|
||||
(:require
|
||||
#?(:clj [clojure.spec.alpha :as s]
|
||||
#?(:clj [clojure.spec.alpha :as s]
|
||||
:cljs [cljs.spec.alpha :as s])
|
||||
|
||||
#?(:clj [clojure.spec.test.alpha :as stest]
|
||||
:cljs [cljs.spec.test.alpha :as stest])
|
||||
|
||||
[expound.alpha :as expound]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.geom.point :as gpt]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(s/check-asserts true)
|
||||
|
@ -113,27 +118,54 @@
|
|||
(s/def ::not-empty-string (s/and string? #(not (str/empty? %))))
|
||||
(s/def ::url string?)
|
||||
(s/def ::fn fn?)
|
||||
(s/def ::point gpt/point?)
|
||||
|
||||
;; --- Macros
|
||||
|
||||
(defn spec-assert
|
||||
[spec x]
|
||||
[spec x message]
|
||||
(if (s/valid? spec x)
|
||||
x
|
||||
(ex/raise :type :assertion
|
||||
:data (s/explain-data spec x)
|
||||
#?@(:cljs [:stack (.-stack (ex-info "assertion" {}))]))))
|
||||
:message message
|
||||
#?@(:cljs [:stack (.-stack (ex-info message {}))]))))
|
||||
|
||||
(defn spec-assert*
|
||||
[spec x message context]
|
||||
(if (s/valid? spec x)
|
||||
x
|
||||
(ex/raise :type :assertion
|
||||
:data (s/explain-data spec x)
|
||||
:context context
|
||||
:message message
|
||||
#?@(:cljs [:stack (.-stack (ex-info message {}))]))))
|
||||
|
||||
|
||||
(defmacro assert
|
||||
"Development only assertion macro."
|
||||
[spec x]
|
||||
(when *assert*
|
||||
`(spec-assert ~spec ~x)))
|
||||
(let [nsdata (:ns &env)
|
||||
context (when nsdata
|
||||
{:ns (str (:name nsdata))
|
||||
:name (pr-str spec)
|
||||
:line (:line &env)
|
||||
:file (:file (:meta nsdata))})
|
||||
message (str "Spec Assertion: '" (pr-str spec) "'")]
|
||||
`(spec-assert* ~spec ~x ~message ~context))))
|
||||
|
||||
(defmacro verify
|
||||
"Always active assertion macro (does not obey to :elide-asserts)"
|
||||
[spec x]
|
||||
`(spec-assert ~spec ~x))
|
||||
(let [nsdata (:ns &env)
|
||||
context (when nsdata
|
||||
{:ns (str (:name nsdata))
|
||||
:name (pr-str spec)
|
||||
:line (:line &env)
|
||||
:file (:file (:meta nsdata))})
|
||||
message (str "Spec Assertion: '" (pr-str spec) "'")]
|
||||
`(spec-assert* ~spec ~x ~message ~context)))
|
||||
|
||||
;; --- Public Api
|
||||
|
||||
|
@ -148,3 +180,14 @@
|
|||
(expound/printer edata))
|
||||
:data (::s/problems edata)))))
|
||||
result))
|
||||
|
||||
(defmacro instrument!
|
||||
[& {:keys [sym spec]}]
|
||||
(when *assert*
|
||||
(let [message (str "Spec failed on: " sym)]
|
||||
`(let [origf# ~sym
|
||||
mdata# (meta (var ~sym))]
|
||||
(set! ~sym (fn [& params#]
|
||||
(spec-assert* ~spec params# ~message mdata#)
|
||||
(apply origf# params#)))))))
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue