APersistentMap test

This commit is contained in:
Michiel Borkent 2021-03-12 20:31:58 +01:00
parent fa92537bdf
commit 5555ea4ede
3 changed files with 81 additions and 2 deletions

View file

@ -253,6 +253,7 @@
:fields [clojure.lang.PersistentQueue]
:instance-checks [clojure.lang.APersistentMap ;; for proxy
clojure.lang.AMapEntry ;; for proxy
clojure.lang.Associative
clojure.lang.Atom
clojure.lang.Cons

View file

@ -12,7 +12,22 @@
(case (.getName ^Class class)
"clojure.lang.APersistentMap"
(proxy [clojure.lang.APersistentMap] []
(seq [] ((method-or-bust methods 'seq)))
(iterator [] (if-let [m (get methods 'iterator)]
(m)
(proxy-super iterator))) ;; TODO: should we call proxy-super as a fallback always?
(containsKey [k] (if-let [m (get methods 'containsKey)]
(m k)
(proxy-super containsKey k)))
(entryAt [k] ((method-or-bust methods 'entryAt) k))
(valAt
([k] ((method-or-bust methods 'valAt) k))
([k default] ((method-or-bust methods 'valAt) k default))))))
([k default] ((method-or-bust methods 'valAt) k default)))
(cons [v] ((method-or-bust methods 'cons) v))
(count [] ((method-or-bust methods 'count)))
(assoc [k v] ((method-or-bust methods 'assoc) k v))
(without [k] ((method-or-bust methods 'without) k))
(seq [] ((method-or-bust methods 'seq))))
"clojure.lang.AMapEntry"
(proxy [clojure.lang.AMapEntry] []
(key [] ((method-or-bust methods 'key)))
(val [] ((method-or-bust methods 'val))))))

View file

@ -0,0 +1,63 @@
(ns babashka.proxy-test
(:require
[babashka.test-utils :as test-utils]
[clojure.edn :as edn]
[clojure.test :as test :refer [deftest is]]))
(defn bb [& args]
(edn/read-string
{:readers *data-readers*
:eof nil}
(apply test-utils/bb nil (map str args))))
(def code
'(do
(defn auto-deref
"If value implements IDeref, deref it, otherwise return original."
[x]
(if (instance? clojure.lang.IDeref x)
@x
x))
(defn proxy-deref-map
{:added "1.0"}
[m]
(proxy [clojure.lang.APersistentMap]
[]
(iterator []
::TODO)
(containsKey [k] (contains? m k))
(entryAt [k] (when (contains? m k) (proxy [clojure.lang.AMapEntry] []
(key [] k)
(val [] (auto-deref(get m k))))))
(valAt ([k] (auto-deref (get m k)))
([k default] (auto-deref (get m k default))))
(cons [v] (proxy-deref-map (conj m v)))
(count [] (count m))
(assoc [k v] (proxy-deref-map (assoc m k v)))
(without [k] (proxy-deref-map (dissoc m k)))
(seq [] (map (fn [[k v]](proxy [clojure.lang.AMapEntry] []
(key [] k)
(val [] (auto-deref (get m k))))) m))))
(let [m (proxy-deref-map
{:a (delay 1)
:b (delay 2)
:c 3})]
[(:a m)
(:b m)
(:c m)
(contains? m :c)
(find m :c)
(-> (conj m [:d (delay 5)])
:d)
(count m)
(-> (assoc m :d (delay 5))
:d)
(-> (dissoc m :a)
(contains? :a))
(seq m)])))
(deftest APersistentMap-proxy-test
(is (= [1 2 3 true [:c 3]
5 3 5 false
'([:a 1] [:b 2] [:c 3])]
(bb code))))