Mine the phase* port batteries into the spec layer and delete them (their
behavior is now covered by spec): phase5 (hierarchies), phase6 (tagged
literals/reader-conditionals), phase7 (lazy/sets), phase8+phase12 (protocols;
phase12 was a duplicate of phase8), phase10 (strings/set), phase13
(reify/walk). Unique cases mined into spec: reader #inst/#uuid/#?@ splice,
(Type. args) dot constructor, lazy-seq body-runs-once, keywordize-keys/
stringify-keys, custom :default key and explicit :hierarchy dispatch.
phase6-final tested the COMPILE-MODE path ({:compile? true}), distinct from the
interpreter-based spec — kept and renamed integration/compile-mode-test.
jpm test green, conformance 218/218.
32 lines
2 KiB
Text
32 lines
2 KiB
Text
# Specification: multimethods & hierarchies.
|
|
(use ../support/harness)
|
|
|
|
(defspec "multimethods / dispatch"
|
|
["dispatch on value" "\"two\""
|
|
"(do (defmulti f identity) (defmethod f 1 [_] \"one\") (defmethod f 2 [_] \"two\") (f 2))"]
|
|
["dispatch on keyword fn" "\"circle\""
|
|
"(do (defmulti area :shape) (defmethod area :circle [_] \"circle\") (area {:shape :circle}))"]
|
|
[":default method" "\"other\""
|
|
"(do (defmulti f identity) (defmethod f 1 [_] \"one\") (defmethod f :default [_] \"other\") (f 99))"]
|
|
["no match throws" :throws
|
|
"(do (defmulti f identity) (defmethod f 1 [_] \"one\") (f 99))"]
|
|
["multiple args" "5"
|
|
"(do (defmulti g (fn [a b] a)) (defmethod g :add [_ b] b) (g :add 5))"]
|
|
["get-method" "\"one\""
|
|
"(do (defmulti f identity) (defmethod f 1 [_] \"one\") ((get-method f 1) 1))"]
|
|
["remove-method" :throws
|
|
"(do (defmulti f identity) (defmethod f 1 [_] \"one\") (remove-method f 1) (f 1))"])
|
|
|
|
(defspec "multimethods / hierarchies"
|
|
["derive + isa?" "true" "(do (derive ::child ::parent) (isa? ::child ::parent))"]
|
|
["isa? reflexive" "true" "(isa? ::x ::x)"]
|
|
["isa? unrelated" "false" "(do (derive ::a ::b) (isa? ::a ::c))"]
|
|
["parents" "true" "(do (derive ::c ::p) (contains? (parents ::c) ::p))"]
|
|
["ancestors" "true" "(do (derive ::c ::p) (derive ::p ::g) (contains? (ancestors ::c) ::g))"]
|
|
["descendants" "true" "(do (derive ::c ::p) (contains? (descendants ::p) ::c))"]
|
|
["dispatch via hierarchy" "\"animal\""
|
|
"(do (derive ::dog ::animal) (defmulti speak identity) (defmethod speak ::animal [_] \"animal\") (speak ::dog))"]
|
|
["custom :default key" ":unknown"
|
|
"(do (defmulti classify :type :default :other) (defmethod classify :a [_] :alpha) (defmethod classify :other [_] :unknown) (classify {:type :zzz}))"]
|
|
["explicit :hierarchy" "\"a\""
|
|
"(do (def h (derive (make-hierarchy) ::dog ::animal)) (defmulti snd identity :hierarchy h) (defmethod snd ::animal [_] \"a\") (snd ::dog))"])
|