Refactor - wip

This commit is contained in:
Nicholas Kariniemi 2014-09-16 23:27:10 +03:00
parent 5a66361746
commit fe5bd00427
2 changed files with 84 additions and 0 deletions

View file

@ -5,6 +5,33 @@
[clojure.core.async :as a :refer [<! >! chan go]]
[hasch.core :as hasch]))
(def initial-state {:hash (hasch/uuid cs/empty-state)
:state cs/empty-state})
(def states (atom [initial-state]))
(defn get-history-state [states hash]
(:state (first (filter #(= (:hash %) hash) states))))
(defn add-history-state [current new-state]
(let [{:keys [state hash]} (first current)
new-hash (hasch/uuid new-state)]
(if (= hash new-hash)
current
(conj current {:hash hash :state state}))))
(defn receive-diff [states diff shadow-hash]
(let [state (:state (first states))
shadow (get-history-state states shadow-hash)]
(if shadow
{:new-state (diff/patch-state state diff)
:new-shadow (diff/patch-state shadow diff)
:full-sync? false}
{:new-state state
:new-shadow state
:full-sync? true})))
(def state (atom cs/empty-state))
(def to-db (atom nil))
(def to-all (chan))
@ -26,6 +53,7 @@
{:grubs (util/map-by-key :id grubs)
:recipes (util/map-by-key :id recipes)})
(defn sync-new-client! [to from]
(let [client-id (java.util.UUID/randomUUID)
client-state (atom cs/empty-state)

View file

@ -0,0 +1,56 @@
(ns grub.test.unit.state
(:require [grub.state :as s]
[grub.common-state :as cs]
[clojure.test :refer :all]
[hasch.core :as hasch]))
(deftest apply-diff-normally
;; Apply changes and return ACK for in sync client/server
(let [state {:grubs {"1" {:text "2 apples" :completed false}}
:recipes {}}
hash (hasch/uuid state)
states [{:hash hash :state state}]
diff {:grubs {:updated {"1" {:completed true}} :deleted #{}}}
shadow-hash hash
{:keys [new-state new-shadow full-sync?]} (s/receive-diff states diff shadow-hash)]
(do
(is (= {:grubs {"1" {:text "2 apples" :completed true}}
:recipes {}}
new-state))
(is (= {:grubs {"1" {:text "2 apples" :completed true}}
:recipes {}}
new-shadow))
(is (not full-sync?)))))
(deftest server-state-changed
;; Send differences back if server state changed
(let [state {:grubs {"1" {:text "3 apples" :completed false}} :recipes {}}
prev {:grubs {"1" {:text "2 apples" :completed false}} :recipes {}}
states [{:hash (hasch/uuid state) :state state}
{:hash (hasch/uuid prev) :state prev}]
diff {:grubs {:updated {"1" {:completed true}} :deleted #{}}}
shadow-hash (hasch/uuid prev)
{:keys [new-state new-shadow full-sync?]} (s/receive-diff states diff shadow-hash)]
(do
(is (= {:grubs {"1" {:text "3 apples" :completed true}}
:recipes {}}
new-state))
(is (= {:grubs {"1" {:text "2 apples" :completed true}}
:recipes {}}
new-shadow))
(is (not full-sync?)))))
(deftest full-sync-if-client-too-far-out-of-sync
;; Shadow hash not in history means client has fallen too far
;; out of sync. Send a full sync
(let [state {:grubs {"1" {:text "2 apples" :completed false}} :recipes {}}
prev {:grubs {"1" {:text "2 apples" :completed false}} :recipes {}}
states [{:hash (hasch/uuid state) :state state}
{:hash (hasch/uuid prev) :state prev}]
shadow-hash (hasch/uuid {:grubs {} :recipes {}})
diff {:grubs {:updated {"1" {:completed true}} :deleted #{}}}
{:keys [new-state new-shadow full-sync?]} (s/receive-diff states diff shadow-hash)]
(do
(is (= state new-state))
(is (= state new-shadow))
(is full-sync?))))