Browse Source

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

rcmerci 2 năm trước cách đây
mục cha
commit
7ba2811e11

+ 5 - 2
deps.edn

@@ -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/"]

+ 4 - 20
src/main/frontend/db/rtc/core.cljs

@@ -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)

+ 43 - 0
src/test/frontend/db/rtc/fixture.cljs

@@ -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)))})

+ 55 - 0
src/test/frontend/db/rtc/mock.cljs

@@ -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))

+ 13 - 0
src/test/frontend/db/rtc_test.cljs

@@ -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))

+ 8 - 0
src/test/frontend/test/helper.cljs

@@ -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!))})