|
35 | 35 | (when raw# (set! ~s raw#)) |
36 | 36 | '~(:name v))))) |
37 | 37 |
|
| 38 | +(defmacro instrument |
| 39 | + "Instruments the vars named by sym-or-syms, a symbol or collection |
| 40 | +of symbols, or all instrumentable vars if sym-or-syms is not |
| 41 | +specified. |
| 42 | +
|
| 43 | +If a var has an :args fn-spec, sets the var's root binding to a |
| 44 | +fn that checks arg conformance (throwing an exception on failure) |
| 45 | +before delegating to the original fn. |
| 46 | +
|
| 47 | +The opts map can be used to override registered specs, and/or to |
| 48 | +replace fn implementations entirely. Opts for symbols not included |
| 49 | +in sym-or-syms are ignored. This facilitates sharing a common |
| 50 | +options map across many different calls to instrument. |
| 51 | +
|
| 52 | +The opts map may have the following keys: |
| 53 | +
|
| 54 | + :spec a map from var-name symbols to override specs |
| 55 | + :stub a set of var-name symbols to be replaced by stubs |
| 56 | + :gen a map from spec names to generator overrides |
| 57 | + :replace a map from var-name symbols to replacement fns |
| 58 | +
|
| 59 | +:spec overrides registered fn-specs with specs your provide. Use |
| 60 | +:spec overrides to provide specs for libraries that do not have |
| 61 | +them, or to constrain your own use of a fn to a subset of its |
| 62 | +spec'ed contract. |
| 63 | +
|
| 64 | +:stub replaces a fn with a stub that checks :args, then uses the |
| 65 | +:ret spec to generate a return value. |
| 66 | +
|
| 67 | +:gen overrides are used only for :stub generation. |
| 68 | +
|
| 69 | +:replace replaces a fn with a fn that checks args conformance, then |
| 70 | +invokes the fn you provide, enabling arbitrary stubbing and mocking. |
| 71 | +
|
| 72 | +:spec can be used in combination with :stub or :replace. |
| 73 | +
|
| 74 | +Returns a collection of syms naming the vars instrumented." |
| 75 | + ([] |
| 76 | + `(instrument (instrumentable-syms))) |
| 77 | + ([sym-or-syms] |
| 78 | + `(instrument ~sym-or-syms nil)) |
| 79 | + ([sym-or-syms opts] |
| 80 | + `(into |
| 81 | + [] |
| 82 | + (comp (filter (instrumentable-syms opts)) |
| 83 | + (distinct) |
| 84 | + (map #(instrument-1* % opts)) |
| 85 | + (remove nil?)) |
| 86 | + (collectionize sym-or-syms)))) |
| 87 | + |
| 88 | +(defmacro unstrument |
| 89 | + "Undoes instrument on the vars named by sym-or-syms, specified |
| 90 | +as in instrument. With no args, unstruments all instrumented vars. |
| 91 | +Returns a collection of syms naming the vars unstrumented." |
| 92 | + ([] |
| 93 | + `(unstrument (map ->sym (keys @instrumented-vars)))) |
| 94 | + ([sym-or-syms] |
| 95 | + `(into |
| 96 | + [] |
| 97 | + (comp (filter symbol?) |
| 98 | + (map unstrument-1*) |
| 99 | + (remove nil?)) |
| 100 | + (collectionize sym-or-syms)))) |
| 101 | + |
38 | 102 | (defmacro run-tests |
39 | 103 | "Like run-all-tests, but scoped to specific namespaces, or to |
40 | 104 | *ns* if no ns-sym are specified." |
|
0 commit comments