From 00b5c1d3307714548009b43b2c840ef41cba00ec Mon Sep 17 00:00:00 2001 From: Dan Holmsand Date: Sat, 31 Jan 2015 11:01:35 +0100 Subject: [PATCH] Add tests from reagent-cursor --- src/reagent/ratom.cljs | 33 ++++++++++----------- test/testcursor.cljs | 66 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 17 deletions(-) diff --git a/src/reagent/ratom.cljs b/src/reagent/ratom.cljs index 81a3627..63940eb 100644 --- a/src/reagent/ratom.cljs +++ b/src/reagent/ratom.cljs @@ -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] diff --git a/test/testcursor.cljs b/test/testcursor.cljs index ef21db4..3b7046a 100644 --- a/test/testcursor.cljs +++ b/test/testcursor.cljs @@ -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 + ))