test(spec): state, multimethods, protocols — fix reify, get-method, hierarchies
Add spec suites for stateful refs (atoms/volatiles/delays/promises), multimethods (dispatch + hierarchies), and protocols/types/records. Bugs caught and fixed: - reify with multiple methods registered only the first (stepped i by 2 over one-element specs); now collects every method spec - get-method/methods/remove-method evaluated their arg to the dispatch fn, but a multimethod's methods live on its var — now resolve the var (get-method and methods are special forms; remove-method fixed). get-method/methods added. - no global hierarchy: 2-arg derive modified a throwaway, isa? was hardcoded false, parents missing, ancestors/descendants returned arrays (so contains? failed), and dispatch ignored derive. Now a global hierarchy backs the 1/2-arg derive/isa?/parents/ancestors/descendants (returning sets) and multimethod dispatch falls back to it. Corrected a phase5 port assertion that encoded the old isa? bug. conformance 218/218, jpm test green.
This commit is contained in:
parent
50d63d896f
commit
a24e9bfba0
7 changed files with 174 additions and 29 deletions
36
test/spec/state-spec.janet
Normal file
36
test/spec/state-spec.janet
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# Specification: stateful reference types (atoms, volatiles, delays, promises).
|
||||
(use ../support/harness)
|
||||
|
||||
(defspec "state / atoms"
|
||||
["deref @" "0" "(let [a (atom 0)] @a)"]
|
||||
["deref fn" "0" "(deref (atom 0))"]
|
||||
["reset!" "5" "(let [a (atom 0)] (reset! a 5) @a)"]
|
||||
["reset! returns new" "5" "(let [a (atom 0)] (reset! a 5))"]
|
||||
["swap!" "1" "(let [a (atom 0)] (swap! a inc) @a)"]
|
||||
["swap! with args" "10" "(let [a (atom 1)] (swap! a + 2 3 4) @a)"]
|
||||
["swap! returns new" "1" "(let [a (atom 0)] (swap! a inc))"]
|
||||
["swap-vals!" "[0 1]" "(let [a (atom 0)] (swap-vals! a inc))"]
|
||||
["reset-vals!" "[0 9]" "(let [a (atom 0)] (reset-vals! a 9))"]
|
||||
["compare-and-set! ok" "true" "(let [a (atom 0)] (compare-and-set! a 0 1))"]
|
||||
["compare-and-set! no" "false" "(let [a (atom 0)] (compare-and-set! a 9 1))"]
|
||||
["atom?" "true" "(do (require (quote [clojure.core])) (instance? clojure.lang.Atom (atom 0)))"])
|
||||
|
||||
(defspec "state / watches & validators"
|
||||
["add-watch fires" "1" "(let [a (atom 0) seen (atom 0)] (add-watch a :k (fn [k r o n] (reset! seen 1))) (reset! a 5) @seen)"]
|
||||
["remove-watch" "0" "(let [a (atom 0) seen (atom 0)] (add-watch a :k (fn [k r o n] (swap! seen inc))) (remove-watch a :k) (reset! a 5) @seen)"]
|
||||
["set-validator! ok" "5" "(let [a (atom 0)] (set-validator! a number?) (reset! a 5) @a)"]
|
||||
["set-validator! rejects" :throws "(let [a (atom 0)] (set-validator! a pos?) (reset! a -1))"])
|
||||
|
||||
(defspec "state / volatiles & delays"
|
||||
["volatile! deref" "0" "(let [v (volatile! 0)] @v)"]
|
||||
["vreset!" "5" "(let [v (volatile! 0)] (vreset! v 5) @v)"]
|
||||
["vswap!" "1" "(let [v (volatile! 0)] (vswap! v inc) @v)"]
|
||||
["delay not forced" "0" "(let [c (atom 0) d (delay (swap! c inc))] @c)"]
|
||||
["delay force once" "1" "(let [c (atom 0) d (delay (swap! c inc))] (force d) (force d) @c)"]
|
||||
["delay value" "5" "(let [d (delay 5)] @d)"]
|
||||
["realized? before" "false" "(let [d (delay 5)] (realized? d))"]
|
||||
["realized? after" "true" "(let [d (delay 5)] (force d) (realized? d))"])
|
||||
|
||||
(defspec "state / promises"
|
||||
["promise deliver" "5" "(let [p (promise)] (deliver p 5) @p)"]
|
||||
["promise undelivered" "nil" "(let [p (promise)] @p)"])
|
||||
Loading…
Add table
Add a link
Reference in a new issue