そこで、Emacs の単体テスト パッケージである ERT に慣れようとしています。を使ったマクロ展開をテストしたいgensym
。gensym が同じnameのシンボルを生成することを確認できますが、それらは同じシンボルではないため、失敗します。以下は、より良いアイデアを提供するためのコードです。
(ert-deftest i-test-repreat ()
"Tests the expansion of i-iterate macro, repeat driver."
(require 'i-iterate)
(should
(equal
(macroexpand '(++ (repeat 100) (message "")))
'(let* ((--0 0)) ;; `--0' is a result of a custom-made `gensym'
(while (< --0 100)
(incf --0)
(message "")) nil))))
失敗メッセージは次のとおりです。
(list-elt 1
(list-elt 0
(list-elt 0
(different-symbols-with-the-same-name --0 --0))))
もちろん、それは別のシンボルですが、そうであると予想されます。どうすればこれを成功させることができますか?
編集
これは私がこれまでに思いついたものです:
(defun i/test-equals-ignore-gensym (a b)
"Tests trees A and B for equality, but considers symbols
equal if their names are equal (this allows symbols generated
by `i-gensym' to pass)."
(or (equal a b)
(cond
((and (null a) (null b)) t)
((and (consp a) (consp b))
(and (i/test-equals-ignore-gensym (car a) (car b))
(i/test-equals-ignore-gensym (cdr a) (cdr b))))
((and (symbolp a) (symbolp b))
(string= (symbol-name a) (symbol-name b)))
((and (atom a) (atom b)) (eql a b))
(t nil))))
(defun i/test-explainer-equal (a b)
"Explains why `i/test-equals-ignore-gensym' failed."
;; TODO: Write our own explanation, this will trigger when
;; necessary, but will not always display the correct message.
(ert--explain-equal-rec a b))
(put 'i/test-equals-ignore-gensym
'ert-explainer 'i/test-explainer-equal)
(ert-deftest i-test-repreat ()
"Tests the expansion of i-iterate macro, repeat driver."
(require 'i-iterate)
(should
(i/test-equals-ignore-gensym
(macroexpand '(++ (repeat 100) (message "")))
'(let* ((--0 0))
(while (< --0 100)
(incf --0)
(message "")) nil))))
でも、もっといい方法があればもっと嬉しいです。