Is there a tool / function that can be used to compare form macro templates?

I use the gensym function in some of my macros, which then make testing difficult:

therefore, the extension of some macro can be:

 '(let [G__10458 (js-obj)] (aset G__10458 "a" (fn [] (? G__10458.val))) (aset G__10458 "val" 3) G__10458) 

I want to check that it matches this type of patten:

 '(let [%1 (js-obj)] (aset %1 "a" (fn [] (? %1.val))) (aset %1 "val" 3) %1) 

Is there anything in the clojure.core.match library or another pattern matching library that does this?

+3
clojure
source share
2 answers

I rode on my own. Its template matches vectors, lists, and hash card validations (matching patterns by sets and hash cards is too complicated for me right now).

 (defn match-sym? [v] (and (symbol? v) (re-find #"^%" (str v)))) (defn match ([f1 f2] (match f1 f2 (atom {}))) ([v1 v2 dict] (cond (or (and (list? v1) (list? v2)) (and (vector? v1) (vector? v2))) (and (= (count v1) (count v2)) (->> (map #(match %1 %2 dict) v1 v2) (every? true?))) (and (hash-map? v1) (hash-map? v2)) (and (= (keys v1) (keys v2)) (->> (map #(match %1 %2 dict) (vals v1) (vals v2)) (every? true))) (match-sym? v2) (if-let [vd (@dict v2)] (match v1 vd dict) (do (swap! dict assoc v2 v1) true)) :else (= v1 v2)))) 

and its use:

 > (match '(1 1) '(1 1)) ;=> true > (match '(1 1) '(%1 %1)) ;=> true > (match '(1 2) '(%1 %1)) ;=> false > (match '(let [x 1] (+ x 2)) '(let [%x 1] (+ %x 2))) ;=> true > (match '(let [G__42879 (js-obj)] (aset G__42879 "a" (fn [] (? G__42879.val))) (aset G__42879 "val" 3) G__42879) '(let [%x (js-obj)] (aset %x "a" (fn [] (? %x.val))) (aset %x "val" 3) %x)) ;=> true 
+1
source share

Realistic testing of your macro extensions is extremely fragile. If you go down this path, any small change in your macro will cause your tests to fail, even if your macro does the same anyway!

The best approach - IMO is to check what your macro should do. We can safely assume that calling your macro has an observed side effect - in your example, it sets the properties in the JS object.

In this case, instead of testing the extension, I would write a test that ensures that the state of the JS object is what you expect from it after calling your macro.

This separates the test from the implementation, giving you the freedom to reorganize your macro as you see fit, as the test is much more reliable and will fail if your macro does the wrong thing.

Generally, I would never test a macro extension.

+7
source share

All Articles