Open bilus opened 9 years ago
UPDATE: Added support for Regex, used protocols to make it extensible.
Example:
(defn xx [a b]
10)
(defn y [s])
(deftest x-test
(mocking [xx y]
(xx 5 10)
(verify-first-call-args-for-p xx __ __) ;; any arguments
(verify-first-call-args-for-p xx 5 10) ;; values
(verify-first-call-args-for-p xx pos? pos?) ;; ifns
(verify-first-call-args-for-p xx string? pos?) ;; failing example
;; Actual arguments do not match expectations
;; Expected: (xx string? pos?)
;; Actual: (xx 5 10)
(y "tata")
(verify-first-call-args-for-p y string?)
(verify-first-call-args-for-p y #"tata") ;; regex
(verify-first-call-args-for-p y #"sasa") ;; failing example
;; Actual arguments do not match expectations
;; Expected: (y #"sasa")
;; Actual: (y "tata")
))
Implementation:
(defprotocol IArgMatcher
(-matches-arg? [this x]))
(extend-type clojure.lang.IFn
IArgMatcher
(-matches-arg? [this x]
(true? (this x))))
(extend-type java.util.regex.Pattern
IArgMatcher
(-matches-arg? [this x]
(some? (re-matches this (str x)))))
(extend-type Object
IArgMatcher
(-matches-arg? [this x]
(= this x)))
(defmacro verify-first-call-args-for-p
"Asserts that the faked function was called at least once, and the first call
was passed the args matching the specified predicates/values"
[fn-name & args]
`(do
(assert-in-fake-context "verify-first-call-args-for-p")
(assert-conjurified-fn "verify-first-call-args-for-p" ~fn-name)
(when-not (pos? (count (get @call-times ~fn-name)))
(do-report {:type :fail, :message "Expected function not invoked"
:expected '(~fn-name ~@args)}))
(let [actual-args# (first (get @conjure.core/call-times ~fn-name))
arg-preds-match# (map -matches-arg? ~(vec args) actual-args#)]
(when-not (every? true? arg-preds-match#)
(do-report {:type :fail, :message "Actual arguments do not match expectations"
:expected '(~fn-name ~@args), :actual (apply list '~fn-name actual-args#)})))))
(def __ (constantly true))
@bilus Where is the do-report
function defined?
Oh never mind https://clojuredocs.org/clojure.test/do-report
:)
Thank you for the little library. Sometimes small is enough. :)
The thing I needed is
verify-first-call-args-for
but with more flexible argument matching. I've updated the macro (below) so while it's backwards-compatible, it adds predicate matching for args:Of course you can mix and match.
If you're interested, I'll be happy to submit a pr.
UPDATE: Updated code below.