dev(rtc): some test helpers & mock utils for rtc

This commit is contained in:
rcmerci
2023-10-27 23:05:03 +08:00
parent e8d411b837
commit 7ba2811e11
6 changed files with 128 additions and 22 deletions

View File

@@ -40,14 +40,17 @@
:extra-deps {org.clojure/clojurescript {:mvn/version "1.11.54"}
org.clojure/tools.namespace {:mvn/version "0.2.11"}
cider/cider-nrepl {:mvn/version "0.30.0"}
org.clojars.knubie/cljs-run-test {:mvn/version "1.0.1"}}
org.clojars.knubie/cljs-run-test {:mvn/version "1.0.1"}
tortue/spy {:mvn/version "2.14.0"}}
:main-opts ["-m" "shadow.cljs.devtools.cli"]}
:test {:extra-paths ["src/test/"]
:extra-deps {org.clojure/clojurescript {:mvn/version "1.11.54"}
org.clojure/test.check {:mvn/version "1.1.1"}
pjstadig/humane-test-output {:mvn/version "0.11.0"}
org.clojars.knubie/cljs-run-test {:mvn/version "1.0.1"}}
org.clojars.knubie/cljs-run-test {:mvn/version "1.0.1"}
tortue/spy {:mvn/version "2.14.0"}
cider/cider-nrepl {:mvn/version "0.30.0"}}
:main-opts ["-m" "shadow.cljs.devtools.cli"]}
:bench {:extra-paths ["src/bench/"]

View File

@@ -77,48 +77,31 @@
(def transit-w (transit/writer :json))
(def transit-r (transit/reader :json))
(def ^{:private true :dynamic true} *RUNNING-TESTS* "true when running tests" false)
(defmulti transact-db! (fn [action & _args]
(keyword (str (name action) (when *RUNNING-TESTS* "-for-test")))))
(defmulti transact-db! (fn [action & _args] action))
(defmethod transact-db! :delete-blocks [_ & args]
(outliner-tx/transact!
{:persist-op? false}
(apply outliner-core/delete-blocks! args)))
(defmethod transact-db! :delete-blocks-for-test [_ & args]
(prn ::delete-block-for-test args))
(defmethod transact-db! :move-blocks [_ & args]
(outliner-tx/transact!
{:persist-op? false}
(apply outliner-core/move-blocks! args)))
(defmethod transact-db! :move-blocks-for-test [_ & args]
(prn ::move-blocks-for-test args))
(defmethod transact-db! :insert-blocks [_ & args]
(outliner-tx/transact!
{:persist-op? false}
(apply outliner-core/insert-blocks! args)))
(defmethod transact-db! :insert-blocks-for-test [_ & args]
(prn ::insert-blocks-for-test args))
(defmethod transact-db! :save-block [_ & args]
(outliner-tx/transact!
{:persist-op? false}
(apply outliner-core/save-block! args)))
(defmethod transact-db! :save-block-for-test [_ & args]
(prn ::save-block-for-test args))
(defmethod transact-db! :raw [_ & args]
(apply db/transact! args))
(defmethod transact-db! :raw-for-test [_ & args]
(prn ::raw-for-test args))
(defn apply-remote-remove-ops
[repo remove-ops]
(prn :remove-ops remove-ops)
@@ -641,7 +624,7 @@
true))))
(defn <loop-for-rtc
[state graph-uuid repo]
[state graph-uuid repo & {:keys [loop-started-ch]}]
{:pre [(state-validator state)
(some? graph-uuid)
(some? repo)]}
@@ -662,6 +645,7 @@
(<! (get-result-ch)))
(async/sub data-from-ws-pub "push-updates" push-data-from-ws-ch)
(when loop-started-ch (async/close! loop-started-ch))
(<! (go-loop [push-client-ops-ch
(make-push-client-ops-timeout-ch repo (not @*auto-push-client-ops?))]
(let [{:keys [push-data-from-ws client-op-update stop continue]}
@@ -736,7 +720,7 @@
versions))))))
(defn- init-state
(defn init-state
[ws data-from-ws-chan]
;; {:post [(m/validate state-schema %)]}
{:*rtc-state (atom :closed :validator rtc-state-validator)

View File

@@ -0,0 +1,43 @@
(ns frontend.db.rtc.fixture
(:require [cljs.test :as t]
[cljs.core.async :as async :refer [<! >! chan go go-loop]]
[frontend.db.rtc.mock :as rtc-mock]
[frontend.db.rtc.core :as rtc-core]
[frontend.test.helper :as test-helper]))
(def *test-rtc-state (atom nil))
(defn- init-state-helper
[]
(let [data-from-ws-chan (chan (async/sliding-buffer 100))
ws (rtc-mock/mock-websocket data-from-ws-chan)]
(assoc (rtc-core/init-state ws data-from-ws-chan)
:*auto-push-client-ops? (atom false))))
(defn- <start-rtc-loop
[]
(go
(let [graph-uuid "e56287f0-44de-487d-8b9f-02e91ec57d98" ; just random generated
repo test-helper/test-db
state (init-state-helper)
loop-started-ch (chan)]
(reset! *test-rtc-state state)
(rtc-core/<loop-for-rtc state graph-uuid repo :loop-started-ch loop-started-ch)
(<! loop-started-ch))))
(def start-and-stop-rtc-loop-fixture
{:before
#(t/async done
(go
(<! (<start-rtc-loop))
(prn :<started-rtc-loop)
(done)))
:after
#(t/async done
(go
(when-let [stop-rtc-loop-chan (some-> (:*stop-rtc-loop-chan @*test-rtc-state) deref)]
(prn :stopping-rtc-loop)
(>! stop-rtc-loop-chan true))
(reset! *test-rtc-state nil)
(done)))})

View File

@@ -0,0 +1,55 @@
(ns frontend.db.rtc.mock
(:require [spy.core :as spy]
[frontend.db.rtc.const :as rtc-const]
[clojure.core.async :as async :refer [<!]]))
(defrecord Mock-WebSocket [onopen onmessage onclose onerror readyState push-data-chan ^:mutable push-data-fn]
Object
(close [_]
(prn :mock-ws :closed)
(when (fn? onclose) (onclose)))
(send [_ s]
(let [msg (-> s
js/JSON.parse
(js->clj :keywordize-keys true)
rtc-const/data-to-ws-decoder)]
(prn :got-ws-msg msg)
(async/put! onmessage msg)))
(set-push-data-fn [_ f]
(set! push-data-fn f)))
(defn default-push-data-fn
[msg push-data-chan]
(case (:action msg)
"register-graph-updates"
(async/offer! push-data-chan (select-keys msg [:req-id]))
;; default
nil))
(defn mock-websocket
[data-from-ws-chan]
(let [stop-push-data-loop-ch (async/chan)
ws (->Mock-WebSocket nil (async/chan 10) nil nil js/WebSocket.OPEN data-from-ws-chan default-push-data-fn)]
(async/go-loop []
(let [{:keys [stop msg]}
(async/alt!
stop-push-data-loop-ch {:stop true}
(.-onmessage ws) ([msg] {:msg msg}))]
(cond
(or stop (nil? msg))
(do (prn :mock-ws-loop-stop) nil)
msg
(do (when-let [push-data-fn (.-push-data-fn ws)]
(push-data-fn msg (.-push-data-chan ws)))
(recur)))))
ws))
(defn mock-ws-push-data-fn
[ws f]
(.set-push-data-fn ws f))

View File

@@ -0,0 +1,13 @@
(ns frontend.db.rtc-test
(:require [clojure.test :as t :refer [deftest is use-fixtures]]
[frontend.db.rtc.fixture :as rtc-fixture]
[frontend.test.helper :as test-helper]))
(use-fixtures :each
test-helper/start-and-destroy-db-map-fixture
rtc-fixture/start-and-stop-rtc-loop-fixture)
(deftest rtc-loop-test
(prn :*test-rtc-state @rtc-fixture/*test-rtc-state)
(is true))

View File

@@ -205,3 +205,11 @@ This can be called in synchronous contexts as no async fns should be invoked"
(f)
(state/set-current-repo! nil)
(destroy-test-db!))
(def start-and-destroy-db-map-fixture
"To avoid 'Fixtures may not be of mixed types' error
when use together with other map-type fixtures"
{:before #(do (state/set-current-repo! test-db)
(start-test-db!))
:after #(do (state/set-current-repo! nil)
(destroy-test-db!))})