1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
"Tests of using macros as first-class objects: listing, creating, and
deleting them, and retrieving their docstrings. We also test `get-macro`
(with regular, non-reader macros)."
(import
builtins)
;; * Core macros
(defn test-core []
(assert (in "when" (.keys builtins._hy_macros)))
(assert (not-in "global1" (.keys builtins._hy_macros)))
(assert (not-in "nonexistent" (.keys builtins._hy_macros)))
(assert (is
(get-macro when)
(get-macro "when")
(get builtins._hy_macros "when")))
(setv s (. (get-macro when) __doc__))
(assert s)
(assert (is (type s) str)))
;; * Global macros
;; ** Creation
; There are three ways to define a global macro:
; 1. `defmacro` in global scope
(defmacro global1 []
"global1 docstring"
"from global1")
; 2. `require` in global scope
(require tests.resources.tlib [qplah :as global2])
; 3. Manually updating `_hy_macros`
(eval-and-compile (setv (get _hy_macros "global3") (fn []
"from global3")))
(eval-and-compile (setv (get _hy_macros (hy.mangle "global☘")) (fn []
"global☘ docstring"
"from global☘")))
(defn test-globals []
(assert (not-in "when" (.keys _hy_macros)))
(assert (not-in "nonexistent" (.keys _hy_macros)))
(assert (all (gfor
k ["global1" "global2" "global3" "global☘"]
(in (hy.mangle k) (.keys _hy_macros)))))
(assert (= (global3) "from global3"))
(assert (= (global☘) "from global☘"))
(assert (= (. (get-macro global1) __doc__) "global1 docstring"))
; https://github.com/hylang/hy/issues/1946
(assert (= (. (get-macro global☘) __doc__) "global☘ docstring"))
(assert (= (. (get-macro hyx_globalXshamrockX) __doc__) "global☘ docstring")))
;; ** Deletion
; Try creating and then deleting a global macro.
(defn global4 []
"from global4 function")
(setv global4-f1 (global4)) ; Calls the function
(defmacro global4 []
"from global4 macro")
(setv global4-m (global4)) ; Calls the macro
(eval-when-compile (del (get-macro global4)))
(setv global4-f2 (global4)) ; Calls the function again
(defn test-global-delete []
(assert (= (global4) global4-f1 global4-f2 "from global4 function"))
(assert (= global4-m "from global4 macro")))
;; ** Shadowing a core macro
; Try overriding a core macro, then deleting the override.
(pragma :warn-on-core-shadow False)
(defmacro / [a b]
f"{(int a)}/{(int b)}")
(setv div1 (/ 1 2))
(eval-when-compile (del (get-macro /)))
(setv div2 (/ 1 2))
(defn test-global-shadowing-builtin []
(assert (= div1 "1/2"))
(assert (= div2 0.5)))
;; * Local macros
(defn test-local-get []
(defmacro local1 [] "local1 doc" 1)
(defmacro local2 [] "local2 outer" 2)
(require tests.resources.local-req-example :as LRE)
(assert (= (. (get-macro local1) __doc__) "local1 doc"))
(assert (= (. (get-macro local2) __doc__) "local2 outer"))
(assert (= (. (get-macro LRE.wiz) __doc__) "remote wiz doc"))
(defn inner []
(defmacro local2 [] "local2 inner" 2)
(defmacro local3 [] "local3 doc" 2)
(assert (= (. (get-macro local2) __doc__) "local2 inner"))
(assert (= (. (get-macro local3) __doc__) "local3 doc"))
(assert (= (. (get-macro LRE.wiz) __doc__) "remote wiz doc")))
(inner))
|