Add tests from reagent-cursor

This commit is contained in:
Dan Holmsand 2015-01-31 11:01:35 +01:00
parent c64cab83a4
commit 00b5c1d330
2 changed files with 82 additions and 17 deletions

View File

@ -88,13 +88,9 @@
([x] (RAtom. x nil nil nil))
([x & {:keys [meta validator]}] (RAtom. x meta validator nil)))
(declare make-reaction)
(defn peek-at [a path]
(binding [*ratom-context* nil]
(get-in @a path)))
(deftype RCursor [path ratom setf ^:mutable reaction]
IAtom
@ -108,34 +104,37 @@
Object
(_reaction [this]
(if (nil? reaction)
(set! reaction (make-reaction
#(get-in @ratom path)
:on-set (if setf
#(setf %2)
#(swap! ratom assoc-in path %2))))
(set! reaction
(make-reaction
#(get-in @ratom path)
:on-set (if setf
#(setf %2)
(if (= path [])
#(reset! ratom %2)
#(swap! ratom assoc-in path %2)))))
reaction))
(_peek [this]
(binding [*ratom-context* nil]
(deref (._reaction this))))
(-deref (._reaction this))))
IDeref
(-deref [this]
(deref (._reaction this)))
(-deref (._reaction this)))
IReset
(-reset! [this new-value]
(reset! (._reaction this) new-value))
(-reset! (._reaction this) new-value))
ISwap
(-swap! [a f]
(-reset! a (f (._peek a))))
(-swap! (._reaction a) f))
(-swap! [a f x]
(-reset! a (f (._peek a) x)))
(-swap! (._reaction a) f x))
(-swap! [a f x y]
(-reset! a (f (._peek a) x y)))
(-swap! (._reaction a) f x y))
(-swap! [a f x y more]
(-reset! a (apply f (._peek a) x y more)))
(-swap! (._reaction a) f x y more))
IPrintWithWriter
(-pr-writer [a writer opts]

View File

@ -304,3 +304,69 @@
(is (= @a {:foo "foobar"}))
(is (not= w (r/wrap "bar" swap! a assoc :foo)))
(is (not= w (r/wrap "foobar" swap! a assoc :foo)))))
(deftest cursor-values
(let [test-atom (atom {:a {:b {:c {:d 1}}}})
test-cursor (r/cursor [:a :b :c :d] test-atom)
test-cursor2 (r/cursor [] test-atom)] ;; nasty edge case
;; get the initial values
(is (= (get-in @test-atom [:a :b :c :d])
@test-cursor))
(is (= (get-in @test-atom [])
@test-cursor2))
;; now we update the cursor with a reset
(reset! test-cursor 2)
(is (= @test-cursor 2))
(is (= (get-in @test-atom [:a :b :c :d]) 2))
(reset! test-cursor2 3)
(is (= @test-cursor2 3))
(is (= @test-atom 3))
(reset! test-atom {:a {:b {:c {:d 1}}}}) ;; restore test-atom
;; swap
(reset! test-cursor {}) ;; empty map
(swap! test-cursor assoc :z 3)
(is (= @test-cursor {:z 3}))
(is (= (get-in @test-atom [:a :b :c :d])
{:z 3}))
(reset! test-cursor2 {}) ;; empty map
(swap! test-cursor2 assoc :z 3)
(is (= @test-cursor2 {:z 3}))
(is (= (get-in @test-atom [])
{:z 3}))))
(deftest atom-behaviors
(let [test-atom (atom {:a {:b {:c {:d 1}}}})
test-cursor (r/cursor [:a :b :c :d] test-atom)
witness (atom nil)]
;; per the description, reset! should return the new values
(is (= {}
(reset! test-cursor {})))
;; per the description, swap! should return the new values
(is (= {:z [1 2 3]}
(swap! test-cursor assoc :z [1 2 3])))
;; watches should behave like with a normal atom
(reset! test-cursor "old")
(add-watch test-cursor :w #(reset! witness
{:key %1 :ref %2 :old %3 :new %4}))
(reset! test-cursor "new") ;; this should trigger the watch function
(is (= (:key @witness) :w))
;; cursor reports that the reaction is the current atom,
;; but I guess that's ok
(is (= @(:ref @witness) @test-cursor))
(is (= (:old @witness) "old"))
(is (= (:new @witness) "new"))
;; can we remove the watch?
(remove-watch test-cursor :w)
(reset! test-cursor "removed")
(is (= (:new @witness) "new")) ;; shouldn't have changed
))