2015-07-26 23:19:10 +02:00
|
|
|
(import [functools [wraps]])
|
|
|
|
|
|
|
|
|
2013-12-15 17:47:24 +01:00
|
|
|
(defn test-reader-macro []
|
2015-12-08 14:43:47 +01:00
|
|
|
"Test a basic reader macro"
|
2013-12-15 17:47:24 +01:00
|
|
|
(defreader ^ [expr]
|
|
|
|
expr)
|
|
|
|
|
|
|
|
(assert (= #^"works" "works")))
|
|
|
|
|
|
|
|
|
|
|
|
(defn test-reader-macro-expr []
|
|
|
|
"Test basic exprs like lists and arrays"
|
|
|
|
(defreader n [expr]
|
|
|
|
(get expr 1))
|
|
|
|
|
|
|
|
(assert (= #n[1 2] 2))
|
|
|
|
(assert (= #n(1 2) 2)))
|
|
|
|
|
|
|
|
|
|
|
|
(defn test-reader-macro-override []
|
|
|
|
"Test if we can override function symbols"
|
|
|
|
(defreader + [n]
|
|
|
|
(+ n 1))
|
|
|
|
|
|
|
|
(assert (= #+2 3)))
|
|
|
|
|
|
|
|
|
2014-01-14 02:38:16 +01:00
|
|
|
(defn test-reader-macros-macros []
|
|
|
|
"Test if defreader is actually a macro"
|
|
|
|
(defreader t [expr]
|
|
|
|
`(, ~@expr))
|
|
|
|
|
|
|
|
(def a #t[1 2 3])
|
|
|
|
|
|
|
|
(assert (= (type a) tuple))
|
|
|
|
(assert (= (, 1 2 3) a)))
|
|
|
|
|
|
|
|
|
2015-12-17 12:59:33 +01:00
|
|
|
(defn test-reader-macro-string-name []
|
|
|
|
"Test if defreader accepts a string as a macro name."
|
|
|
|
|
|
|
|
(defreader "." [expr]
|
|
|
|
expr)
|
|
|
|
|
|
|
|
(assert (= #."works" "works")))
|
|
|
|
|
|
|
|
|
2015-07-26 23:19:10 +02:00
|
|
|
(defn test-builtin-decorator-reader []
|
|
|
|
(defn increment-arguments [func]
|
|
|
|
"Increments each argument passed to the decorated function."
|
|
|
|
#@((wraps func)
|
|
|
|
(defn wrapper [&rest args &kwargs kwargs]
|
|
|
|
(apply func
|
|
|
|
(map inc args)
|
|
|
|
(dict-comp k (inc v) [[k v] (.items kwargs)])))))
|
|
|
|
|
|
|
|
#@(increment-arguments
|
|
|
|
(defn foo [&rest args &kwargs kwargs]
|
|
|
|
"Bar."
|
|
|
|
(, args kwargs)))
|
|
|
|
|
|
|
|
;; The decorator did what it was supposed to
|
|
|
|
(assert (= (, (, 2 3 4) {"quux" 5 "baz" 6})
|
|
|
|
(foo 1 2 3 :quux 4 :baz 5)))
|
|
|
|
|
2015-12-08 14:43:47 +01:00
|
|
|
;; @wraps preserved the docstring and __name__
|
2015-07-26 23:19:10 +02:00
|
|
|
(assert (= "foo" (. foo --name--)))
|
|
|
|
(assert (= "Bar." (. foo --doc--)))
|
|
|
|
|
|
|
|
;; We can use the #@ reader macro to apply more than one decorator
|
|
|
|
#@(increment-arguments
|
|
|
|
increment-arguments
|
|
|
|
(defn double-foo [&rest args &kwargs kwargs]
|
|
|
|
"Bar."
|
|
|
|
(, args kwargs)))
|
|
|
|
|
|
|
|
(assert (= (, (, 3 4 5) {"quux" 6 "baz" 7})
|
|
|
|
(double-foo 1 2 3 :quux 4 :baz 5))))
|