瀏覽代碼

Improve query dsl tests

- Each dsl test can load its own test data
- Refactored property and page-property tests to test accuracy
  of each
- Also added humane-test-output to make diff easier to read when tests
  fail
- Also fixed weird behavior of test runner that runs all tests when no
  tests selected
Gabriel Horner 3 年之前
父節點
當前提交
ce618443bf
共有 3 個文件被更改,包括 279 次插入265 次删除
  1. 1 0
      deps.edn
  2. 268 259
      src/test/frontend/db/query_dsl_test.cljs
  3. 10 6
      src/test/frontend/node_test_runner.cljs

+ 1 - 0
deps.edn

@@ -43,6 +43,7 @@
            :test {:extra-paths ["src/test/"]
            :test {:extra-paths ["src/test/"]
                   :extra-deps  {org.clojure/clojurescript        {:mvn/version "1.10.891"}
                   :extra-deps  {org.clojure/clojurescript        {:mvn/version "1.10.891"}
                                 org.clojure/test.check           {:mvn/version "1.1.1"}
                                 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"}}
                   :main-opts   ["-m" "shadow.cljs.devtools.cli"]}
                   :main-opts   ["-m" "shadow.cljs.devtools.cli"]}
 
 

+ 268 - 259
src/test/frontend/db/query_dsl_test.cljs

@@ -1,10 +1,10 @@
 (ns frontend.db.query-dsl-test
 (ns frontend.db.query-dsl-test
-  (:require [cljs.test :refer [are async deftest testing use-fixtures]]
+  (:require [cljs.test :refer [are deftest testing use-fixtures is]]
+            [clojure.string :as str]
             [frontend.db :as db]
             [frontend.db :as db]
             [frontend.db.config :refer [test-db] :as config]
             [frontend.db.config :refer [test-db] :as config]
             [frontend.db.query-dsl :as dsl]
             [frontend.db.query-dsl :as dsl]
-            [frontend.handler.repo :as repo-handler]
-            [promesa.core :as p]))
+            [frontend.handler.repo :as repo-handler]))
 
 
 ;; TODO: quickcheck
 ;; TODO: quickcheck
 ;; 1. generate query filters
 ;; 1. generate query filters
@@ -17,20 +17,13 @@
                 :file/content "---
                 :file/content "---
 title: Dec 26th, 2020
 title: Dec 26th, 2020
 tags: [[page-tag-1]], page-tag-2
 tags: [[page-tag-1]], page-tag-2
-parent: [[child page 1]], [[child-no-space]]
 ---
 ---
 - DONE 26-b1 [[page 1]]
 - DONE 26-b1 [[page 1]]
 created-at:: 1608968448113
 created-at:: 1608968448113
 last-modified-at:: 1608968448113
 last-modified-at:: 1608968448113
-prop-a:: val-a
-prop-c:: [[page a]], [[page b]], [[page c]]
-prop-num:: 2000
-prop-linked-num:: [[3000]]
-prop-d:: [[no-space-link]]
 - LATER 26-b2-modified-later [[page 2]] #tag1
 - LATER 26-b2-modified-later [[page 2]] #tag1
 created-at:: 1608968448114
 created-at:: 1608968448114
 last-modified-at:: 1608968448120
 last-modified-at:: 1608968448120
-prop-b:: val-b
 - DONE [#A] 26-b3 [[page 1]]
 - DONE [#A] 26-b3 [[page 1]]
 created-at:: 1608968448115
 created-at:: 1608968448115
 last-modified-at:: 1608968448115
 last-modified-at:: 1608968448115
@@ -39,7 +32,6 @@ last-modified-at:: 1608968448115
                 :file/content "---
                 :file/content "---
 title: Dec 27th, 2020
 title: Dec 27th, 2020
 tags: page-tag-2, [[page-tag-3]]
 tags: page-tag-2, [[page-tag-3]]
-parent: [[child page 1]], child page 2
 ---
 ---
 - NOW [#A] b1 [[page 1]]
 - NOW [#A] b1 [[page 1]]
 created-at:: 1609052958714
 created-at:: 1609052958714
@@ -50,7 +42,6 @@ last-modified-at:: 1609052974285
 - b3 [[page 1]]
 - b3 [[page 1]]
 created-at:: 1609052959954
 created-at:: 1609052959954
 last-modified-at:: 1609052959954
 last-modified-at:: 1609052959954
-prop-a:: val-a
 - b4 [[page 2]]
 - b4 [[page 2]]
 created-at:: 1609052961569
 created-at:: 1609052961569
 last-modified-at:: 1609052961569
 last-modified-at:: 1609052961569
@@ -60,7 +51,6 @@ last-modified-at:: 1609052963089"}
                {:file/path "journals/2020_12_28.md"
                {:file/path "journals/2020_12_28.md"
                 :file/content "---
                 :file/content "---
 title: Dec 28th, 2020
 title: Dec 28th, 2020
-parent: child page 2
 ---
 ---
 - 28-b1 [[page 1]]
 - 28-b1 [[page 1]]
 created-at:: 1609084800000
 created-at:: 1609084800000
@@ -73,6 +63,16 @@ created-at:: 1609084800002
 last-modified-at:: 1609084800002"}]]
 last-modified-at:: 1609084800002"}]]
     (repo-handler/parse-files-and-load-to-db! test-db files {:re-render? false})))
     (repo-handler/parse-files-and-load-to-db! test-db files {:re-render? false})))
 
 
+;; Test helpers
+;; ============
+(defn- load-test-files [files]
+  (repo-handler/parse-files-and-load-to-db! test-db files {:re-render? false}))
+
+(defn- dsl-query
+  [s]
+  (db/clear-query-state!)
+  (map first (deref (dsl/query test-db s))))
+
 (def parse (partial dsl/parse test-db))
 (def parse (partial dsl/parse test-db))
 
 
 (defn- q
 (defn- q
@@ -97,292 +97,305 @@ last-modified-at:: 1609084800002"}]]
 
 
 (defonce empty-result {:query nil :result nil})
 (defonce empty-result {:query nil :result nil})
 
 
+;; Tests
+;; =====
+
 (deftest block-property-queries
 (deftest block-property-queries
-  (are [x y] (= (q-count x) y)
-       "(property prop-a val-a)"
-       {:query (dsl/->property-query "prop-a" "val-a")
-        :count 2}
-
-       "(property prop-b val-b)"
-       {:query (dsl/->property-query "prop-b" "val-b")
-        :count 1}
-
-       "(and (property prop-b val-b))"
-       {:query '([?b :block/properties ?prop]
-                 [(missing? $ ?b :block/name)]
-                 [(get ?prop :prop-b) ?v]
-                 (or [(= ?v "val-b")] [(contains? ?v "val-b")] [(contains? ?v "val-b")]))
-        :count 1}
-
-       "(and (property prop-c \"page c\"))"
-       {:query (dsl/->property-query "prop-c" "page c")
-        :count 1}
-
-       ;; TODO: optimize
-       "(and (property prop-c \"page c\") (property prop-c \"page b\"))"
-       {:query '[[?b :block/properties ?prop]
-                 [(missing? $ ?b :block/name)]
-                 [(get ?prop :prop-c) ?v]
-                 (or [(= ?v "page c")] [(contains? ?v "page c")] [(contains? ?v "page c")])
-                 [(get ?prop :prop-c) ?v1]
-                 (or [(= ?v1 "page b")] [(contains? ?v1 "page b")] [(contains? ?v1 "page b")])]
-        :count 1}
-
-       "(or (property prop-c \"page c\") (property prop-b val-b))"
-       {:query '[[?b :block/content ?content]
-                 (or
-                  (and [?b :block/properties ?prop] [(missing? $ ?b :block/name)] [(get ?prop :prop-c) ?v] (or [(= ?v "page c")] [(contains? ?v "page c")] [(contains? ?v "page c")]))
-                  (and [?b :block/properties ?prop] [(missing? $ ?b :block/name)] [(get ?prop :prop-b) ?v] (or [(= ?v "val-b")] [(contains? ?v "val-b")] [(contains? ?v "val-b")])))]
-        :count 2}
-
-       "(property prop-num 2000)"
-       {:query (dsl/->property-query "prop-num" 2000)
-        :count 1}
-
-       "(property prop-linked-num 3000)"
-       {:query (dsl/->property-query "prop-linked-num" 3000)
-        :count 1}
-
-       "(property prop-d no-space-link)"
-       {:query (dsl/->property-query "prop-d" "no-space-link")
-        :count 1}))
+  (load-test-files [{:file/path "journals/2022_02_28.md"
+                     :file/content "a:: b
+- b1
+prop-a:: val-a
+prop-num:: 2000
+- b2
+prop-a:: val-a
+prop-b:: val-b
+- b3
+prop-c:: [[page a]], [[page b]], [[page c]]
+prop-linked-num:: [[3000]]
+prop-d:: [[no-space-link]]
+- b4
+prop-d:: nada"}])
+
+  (testing "Blocks have given property value"
+    (is (= ["b1" "b2"]
+           (map (comp first str/split-lines :block/content)
+                (dsl-query "(property prop-a val-a)"))))
+
+    (is (= ["b2"]
+           (map (comp first str/split-lines :block/content)
+                (dsl-query "(property prop-b val-b)")))))
+
+  (is (= ["b2"]
+         (map (comp first str/split-lines :block/content)
+              (dsl-query "(and (property prop-b val-b))")))
+      "Blocks have property value with empty AND")
+
+  (is (= ["b3"]
+         (map (comp first str/split-lines :block/content)
+              (dsl-query "(and (property prop-c \"page c\"))")))
+      "Blocks have property value from a set of values")
+
+  ;; TODO: optimize
+  (is (= ["b3"]
+         (map (comp first str/split-lines :block/content)
+              (dsl-query "(and (property prop-c \"page c\") (property prop-c \"page b\"))")))
+      "Blocks have ANDed property values")
+
+  (is (= #{"b2" "b3"}
+         (set
+          (map (comp first str/split-lines :block/content)
+               (dsl-query "(or (property prop-c \"page c\") (property prop-b val-b))"))))
+      "Blocks have ORed property values")
+
+  (is (= ["b1"]
+         (map (comp first str/split-lines :block/content)
+              (dsl-query "(property prop-num 2000)")))
+      "Blocks have integer property value")
+
+  (is (= ["b3"]
+         (map (comp first str/split-lines :block/content)
+              (dsl-query "(property prop-linked-num 3000)")))
+      "Blocks have property with integer page value")
+
+  (is (= ["b3"]
+         (map (comp first str/split-lines :block/content)
+              (dsl-query "(property prop-d no-space-link)")))
+      "Blocks have property value with no space"))
 
 
 (deftest page-property-queries
 (deftest page-property-queries
-  (are [x y] (= (q-count x) y)
-       "(page-property parent)"
-       {:query '[[?p :block/name]
-                 [?p :block/properties ?prop]
-                 [(get ?prop :parent) ?prop-v]
-                 [true]], :count 3}
-
-       "(page-property parent [[child page 1]])"
-       {:query (dsl/->page-property-query "parent" "child page 1")
-        :count 2}
-
-       "(page-property parent [[child-no-space]])"
-       {:query (dsl/->page-property-query "parent" "child-no-space")
-        :count 1}
-
-       "(page-property parent \"child page 1\")"
-       {:query (dsl/->page-property-query "parent" "child page 1")
-        :count 2}
-
-       "(and (page-property parent [[child page 1]]) (page-property parent [[child page 2]]))"
-       {:query '([?p :block/name]
-                 [?p :block/properties ?prop]
-                 [(get ?prop :parent) ?v]
-                 (or [(= ?v "child page 1")] [(contains? ?v "child page 1")])
-                 (or [(= ?v "child page 2")] [(contains? ?v "child page 2")]))
-        :count 1}
-
-       "(or (page-property parent [[child page 1]]) (page-property parent [[child page 2]]))"
-       {:query '(or (and
-                     [?p :block/name]
-                     [?p :block/properties ?prop]
-                     [(get ?prop :parent) ?v]
-                     (or [(= ?v "child page 1")] [(contains? ?v "child page 1")]))
-                    (and
-                     [?p :block/name]
-                     [?p :block/properties ?prop]
-                     [(get ?prop :parent) ?v]
-                     (or [(= ?v "child page 2")] [(contains? ?v "child page 2")])))
-        :count 3}))
+  (load-test-files [{:file/path "pages/page1.md"
+                     :file/content "parent:: [[child page 1]], [[child-no-space]]"}
+                    {:file/path "pages/page2.md"
+                     :file/content "foo:: bar"}
+                    {:file/path "pages/page3.md"
+                     :file/content "parent:: [[child page 1]], child page 2"}
+                    {:file/path "pages/page4.md"
+                     :file/content "parent:: child page 2"}])
+  (is (= ["page1" "page3" "page4"]
+         (map :block/name (dsl-query "(page-property parent)")))
+      "Pages have given property")
+
+  (is (= ["page1" "page3"]
+         (map :block/name (dsl-query "(page-property parent [[child page 1]])")))
+      "Pages have property value that is a page and query is a page")
+
+  (is (= ["page1" "page3"]
+         (map :block/name (dsl-query "(page-property parent \"child page 1\")")))
+      "Pages have property value that is a page and query is a string")
+
+  (is (= ["page1"]
+         (map :block/name (dsl-query "(page-property parent [[child-no-space]])")))
+      "Pages have property value that is a page with no spaces")
+
+  (is (= ["page3"]
+         (map
+          :block/name
+          (dsl-query "(and (page-property parent [[child page 1]]) (page-property parent [[child page 2]]))")))
+      "Page property queries ANDed")
+
+  (is (= ["page1" "page3" "page4"]
+         (map
+          :block/name
+          (dsl-query "(or (page-property parent [[child page 1]]) (page-property parent [[child page 2]]))")))
+      "Page property queries ORed"))
 
 
 (deftest ^:large-vars/cleanup-todo test-parse
 (deftest ^:large-vars/cleanup-todo test-parse
   []
   []
+  (import-test-data!)
+
   (testing "nil or blank strings should be ignored"
   (testing "nil or blank strings should be ignored"
     (are [x y] (= (q x) y)
     (are [x y] (= (q x) y)
-      nil empty-result
-      "" empty-result
-      " " empty-result))
+         nil empty-result
+         "" empty-result
+         " " empty-result))
 
 
   (testing "Non exists page should be ignored"
   (testing "Non exists page should be ignored"
     (are [x y] (nil? (:result (q x)))
     (are [x y] (nil? (:result (q x)))
-      "[[page-not-exist]]" empty-result
-      "[[another-page-not-exist]]" empty-result))
+         "[[page-not-exist]]" empty-result
+         "[[another-page-not-exist]]" empty-result))
 
 
   (testing "Single page query"
   (testing "Single page query"
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "[[page 1]]"
-      {:query '[[?b :block/path-refs [:block/name "page 1"]]]
-       :count 6}
+         "[[page 1]]"
+         {:query '[[?b :block/path-refs [:block/name "page 1"]]]
+          :count 6}
 
 
-      "[[page 2]]"
-      {:query '[[?b :block/path-refs [:block/name "page 2"]]]
-       :count 4}))
+         "[[page 2]]"
+         {:query '[[?b :block/path-refs [:block/name "page 2"]]]
+          :count 4}))
 
 
 
 
 
 
   (testing "task queries"
   (testing "task queries"
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "(task now)"
-      {:query '[[?b :block/marker ?marker]
-                [(contains? #{"NOW"} ?marker)]]
-       :count 1}
-
-      "(task NOW)"
-      {:query '[[?b :block/marker ?marker]
-                [(contains? #{"NOW"} ?marker)]]
-       :count 1}
-
-      "(task later)"
-      {:query '[[?b :block/marker ?marker]
-                [(contains? #{"LATER"} ?marker)]]
-       :count 2}
-
-      "(task now later)"
-      {:query '[[?b :block/marker ?marker]
-                [(contains? #{"NOW" "LATER"} ?marker)]]
-       :count 3}
-
-      "(task [now later])"
-      {:query '[[?b :block/marker ?marker]
-                [(contains? #{"NOW" "LATER"} ?marker)]]
-       :count 3}))
+         "(task now)"
+         {:query '[[?b :block/marker ?marker]
+                   [(contains? #{"NOW"} ?marker)]]
+          :count 1}
+
+         "(task NOW)"
+         {:query '[[?b :block/marker ?marker]
+                   [(contains? #{"NOW"} ?marker)]]
+          :count 1}
+
+         "(task later)"
+         {:query '[[?b :block/marker ?marker]
+                   [(contains? #{"LATER"} ?marker)]]
+          :count 2}
+
+         "(task now later)"
+         {:query '[[?b :block/marker ?marker]
+                   [(contains? #{"NOW" "LATER"} ?marker)]]
+          :count 3}
+
+         "(task [now later])"
+         {:query '[[?b :block/marker ?marker]
+                   [(contains? #{"NOW" "LATER"} ?marker)]]
+          :count 3}))
 
 
   (testing "Priority queries"
   (testing "Priority queries"
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "(priority A)"
-      {:query '[[?b :block/priority ?priority]
-                [(contains? #{"A"} ?priority)]]
-       :count 2}
-
-      "(priority a)"
-      {:query '[[?b :block/priority ?priority]
-                [(contains? #{"A"} ?priority)]]
-       :count 2}
-
-      "(priority a b)"
-      {:query '[[?b :block/priority ?priority]
-                [(contains? #{"A" "B"} ?priority)]]
-       :count 3}
-
-      "(priority [a b])"
-      {:query '[[?b :block/priority ?priority]
-                [(contains? #{"A" "B"} ?priority)]]
-       :count 3}
-
-      "(priority a b c)"
-      {:query '[[?b :block/priority ?priority]
-                [(contains? #{"A" "B" "C"} ?priority)]]
-       :count 3}))
+         "(priority A)"
+         {:query '[[?b :block/priority ?priority]
+                   [(contains? #{"A"} ?priority)]]
+          :count 2}
+
+         "(priority a)"
+         {:query '[[?b :block/priority ?priority]
+                   [(contains? #{"A"} ?priority)]]
+          :count 2}
+
+         "(priority a b)"
+         {:query '[[?b :block/priority ?priority]
+                   [(contains? #{"A" "B"} ?priority)]]
+          :count 3}
+
+         "(priority [a b])"
+         {:query '[[?b :block/priority ?priority]
+                   [(contains? #{"A" "B"} ?priority)]]
+          :count 3}
+
+         "(priority a b c)"
+         {:query '[[?b :block/priority ?priority]
+                   [(contains? #{"A" "B" "C"} ?priority)]]
+          :count 3}))
 
 
   (testing "all-page-tags queries"
   (testing "all-page-tags queries"
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "(all-page-tags)"
-      {:query '[[?e :block/tags ?p]]
-       :count 3}))
+         "(all-page-tags)"
+         {:query '[[?e :block/tags ?p]]
+          :count 3}))
 
 
   (testing "page-tags queries"
   (testing "page-tags queries"
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "(page-tags [[page-tag-1]])"
-      {:query '[[?p :block/tags ?t]
-                [?t :block/name ?tag1]
-                [(contains? #{"page-tag-1"} ?tag1)]]
-       :count 1}
-
-      "(page-tags page-tag-2)"
-      {:query '[[?p :block/tags ?t]
-                [?t :block/name ?tag1]
-                [(contains? #{"page-tag-2"} ?tag1)]]
-       :count 2}
-
-      "(page-tags page-tag-1 page-tag-2)"
-      {:query '[[?p :block/tags ?t]
-                [?t :block/name ?tag1]
-                [(contains? #{"page-tag-1" "page-tag-2"} ?tag1)]]
-       :count 2}
-
-      "(page-tags page-TAG-1 page-tag-2)"
-      {:query '[[?p :block/tags ?t]
-                [?t :block/name ?tag1]
-                [(contains? #{"page-tag-1" "page-tag-2"} ?tag1)]]
-       :count 2}
-
-      "(page-tags [page-tag-1 page-tag-2])"
-      {:query '[[?p :block/tags ?t]
-                [?t :block/name ?tag1]
-                [(contains? #{"page-tag-1" "page-tag-2"} ?tag1)]]
-       :count 2}))
+         "(page-tags [[page-tag-1]])"
+         {:query '[[?p :block/tags ?t]
+                   [?t :block/name ?tag1]
+                   [(contains? #{"page-tag-1"} ?tag1)]]
+          :count 1}
+
+         "(page-tags page-tag-2)"
+         {:query '[[?p :block/tags ?t]
+                   [?t :block/name ?tag1]
+                   [(contains? #{"page-tag-2"} ?tag1)]]
+          :count 2}
+
+         "(page-tags page-tag-1 page-tag-2)"
+         {:query '[[?p :block/tags ?t]
+                   [?t :block/name ?tag1]
+                   [(contains? #{"page-tag-1" "page-tag-2"} ?tag1)]]
+          :count 2}
+
+         "(page-tags page-TAG-1 page-tag-2)"
+         {:query '[[?p :block/tags ?t]
+                   [?t :block/name ?tag1]
+                   [(contains? #{"page-tag-1" "page-tag-2"} ?tag1)]]
+          :count 2}
+
+         "(page-tags [page-tag-1 page-tag-2])"
+         {:query '[[?p :block/tags ?t]
+                   [?t :block/name ?tag1]
+                   [(contains? #{"page-tag-1" "page-tag-2"} ?tag1)]]
+          :count 2}))
 
 
 
 
 
 
   ;; boolean queries
   ;; boolean queries
   (testing "AND queries"
   (testing "AND queries"
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "(and [[tag1]] [[page 2]])"
-      {:query '([?b :block/path-refs [:block/name "tag1"]]
-                [?b :block/path-refs [:block/name "page 2"]])
-       :count 1})
+         "(and [[tag1]] [[page 2]])"
+         {:query '([?b :block/path-refs [:block/name "tag1"]]
+                   [?b :block/path-refs [:block/name "page 2"]])
+          :count 1})
 
 
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "(and [[tag1]] [[page 2]])"
-      {:query '([?b :block/path-refs [:block/name "tag1"]]
-                [?b :block/path-refs [:block/name "page 2"]])
-       :count 1}))
+         "(and [[tag1]] [[page 2]])"
+         {:query '([?b :block/path-refs [:block/name "tag1"]]
+                   [?b :block/path-refs [:block/name "page 2"]])
+          :count 1}))
 
 
   (testing "OR queries"
   (testing "OR queries"
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "(or [[tag1]] [[page 2]])"
-      {:query '(or
-                (and [?b :block/path-refs [:block/name "tag1"]])
-                (and [?b :block/path-refs [:block/name "page 2"]]))
-       :count 4}))
+         "(or [[tag1]] [[page 2]])"
+         {:query '(or
+                   (and [?b :block/path-refs [:block/name "tag1"]])
+                   (and [?b :block/path-refs [:block/name "page 2"]]))
+          :count 4}))
 
 
   (testing "NOT queries"
   (testing "NOT queries"
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "(not [[page 1]])"
-      {:query '([?b :block/uuid]
-                (not [?b :block/path-refs [:block/name "page 1"]]))
-       :count 39}))
+         "(not [[page 1]])"
+         {:query '([?b :block/uuid]
+                   (not [?b :block/path-refs [:block/name "page 1"]]))
+          :count 31}))
 
 
   (testing "Between query"
   (testing "Between query"
     (are [x y] (= (count-only x) y)
     (are [x y] (= (count-only x) y)
-      "(and (task now later done) (between [[Dec 26th, 2020]] tomorrow))"
-      5
+         "(and (task now later done) (between [[Dec 26th, 2020]] tomorrow))"
+         5
 
 
-      ;; between with journal pages
-      "(and (task now later done) (between [[Dec 27th, 2020]] [[Dec 28th, 2020]]))"
-      2
+         ;; between with journal pages
+         "(and (task now later done) (between [[Dec 27th, 2020]] [[Dec 28th, 2020]]))"
+         2
 
 
-      ;; ;; between with created-at
-      ;; "(and (task now later done) (between created-at [[Dec 26th, 2020]] tomorrow))"
-      ;; 5
+         ;; ;; between with created-at
+         ;; "(and (task now later done) (between created-at [[Dec 26th, 2020]] tomorrow))"
+         ;; 5
 
 
-      ;; ;; between with last-modified-at
-      ;; "(and (task now later done) (between last-modified-at [[Dec 26th, 2020]] tomorrow))"
-      ;; 5
-      ))
+         ;; ;; between with last-modified-at
+         ;; "(and (task now later done) (between last-modified-at [[Dec 26th, 2020]] tomorrow))"
+         ;; 5
+         ))
 
 
   (testing "Nested boolean queries"
   (testing "Nested boolean queries"
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "(and (todo done) (not [[page 1]]))"
-      {:query '([?b :block/uuid]
-                [?b :block/marker ?marker]
-                [(contains? #{"DONE"} ?marker)]
-                (not [?b :block/path-refs [:block/name "page 1"]]))
-       :count 0})
+         "(and (todo done) (not [[page 1]]))"
+         {:query '([?b :block/uuid]
+                   [?b :block/marker ?marker]
+                   [(contains? #{"DONE"} ?marker)]
+                   (not [?b :block/path-refs [:block/name "page 1"]]))
+          :count 0})
 
 
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "(and (todo now later) (or [[page 1]] [[page 2]]))"
-      {:query '([?b :block/marker ?marker]
-                [(contains? #{"NOW" "LATER"} ?marker)]
-                (or (and [?b :block/path-refs [:block/name "page 1"]])
-                    (and [?b :block/path-refs [:block/name "page 2"]])
-                    [?b]))
-       :count 3})
+         "(and (todo now later) (or [[page 1]] [[page 2]]))"
+         {:query '([?b :block/marker ?marker]
+                   [(contains? #{"NOW" "LATER"} ?marker)]
+                   (or (and [?b :block/path-refs [:block/name "page 1"]])
+                       (and [?b :block/path-refs [:block/name "page 2"]])
+                       [?b]))
+          :count 3})
 
 
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "(not (and (todo now later) (or [[page 1]] [[page 2]])))"
-      {:query '([?b :block/uuid]
-                (not
-                 [?b :block/marker ?marker]
-                 [(contains? #{"NOW" "LATER"} ?marker)]
-                 (or
-                  (and [?b :block/path-refs [:block/name "page 1"]])
-                  (and [?b :block/path-refs [:block/name "page 2"]])
-                  [?b])))
-       :count 42})
+         "(not (and (todo now later) (or [[page 1]] [[page 2]])))"
+         {:query '([?b :block/uuid]
+                   (not
+                    [?b :block/marker ?marker]
+                    [(contains? #{"NOW" "LATER"} ?marker)]
+                    (or
+                     (and [?b :block/path-refs [:block/name "page 1"]])
+                     (and [?b :block/path-refs [:block/name "page 2"]])
+                     [?b])))
+          :count 34})
 
 
     ;; FIXME: not working
     ;; FIXME: not working
     ;; (are [x y] (= (q-count x) y)
     ;; (are [x y] (= (q-count x) y)
@@ -397,15 +410,15 @@ last-modified-at:: 1609084800002"}]]
     ;;    :count 5})
     ;;    :count 5})
 
 
     (are [x y] (= (q-count x) y)
     (are [x y] (= (q-count x) y)
-      "(and (todo now later done) (or [[page 1]] (not [[page 1]])))"
-      {:query '([?b :block/uuid]
-                [?b :block/marker ?marker]
-                [(contains? #{"NOW" "LATER" "DONE"} ?marker)]
-                (or
-                 (and [?b :block/path-refs [:block/name "page 1"]])
-                 (and (not [?b :block/path-refs [:block/name "page 1"]]))
-                 [?b]))
-       :count 5}))
+         "(and (todo now later done) (or [[page 1]] (not [[page 1]])))"
+         {:query '([?b :block/uuid]
+                   [?b :block/marker ?marker]
+                   [(contains? #{"NOW" "LATER" "DONE"} ?marker)]
+                   (or
+                    (and [?b :block/path-refs [:block/name "page 1"]])
+                    (and (not [?b :block/path-refs [:block/name "page 1"]]))
+                    [?b]))
+          :count 5}))
 
 
   ;; (testing "sort-by (created-at defaults to desc)"
   ;; (testing "sort-by (created-at defaults to desc)"
   ;;   (db/clear-query-state!)
   ;;   (db/clear-query-state!)
@@ -468,13 +481,9 @@ last-modified-at:: 1609084800002"}]]
   ;;            '(1608968448113 1608968448115 1608968448120 1609052958714 1609052974285)))))
   ;;            '(1608968448113 1608968448115 1608968448120 1609052958714 1609052974285)))))
   )
   )
 
 
-(use-fixtures :once
-  {:before (fn []
-             (async done
-                    (config/start-test-db!)
-                    (p/let [_ (import-test-data!)]
-                      (done))))
-   :after config/destroy-test-db!})
+(use-fixtures :each
+              {:before config/start-test-db!
+               :after config/destroy-test-db!})
 
 
 #_(cljs.test/run-tests)
 #_(cljs.test/run-tests)
 
 

+ 10 - 6
src/test/frontend/node_test_runner.cljs

@@ -11,7 +11,9 @@
             [shadow.test.node :as node]
             [shadow.test.node :as node]
             [clojure.string :as str]
             [clojure.string :as str]
             [clojure.set :as set]
             [clojure.set :as set]
-            ["util" :as util]))
+            ["util" :as util]
+            ;; activate humane test output for all tests
+            [pjstadig.humane-test-output]))
 
 
 (defn- print-summary
 (defn- print-summary
   "Print help summary given args and opts strings"
   "Print help summary given args and opts strings"
@@ -54,9 +56,6 @@ returns run options for selected tests to run"
                     [namespace]
                     [namespace]
                     namespace-regex
                     namespace-regex
                     (filter #(re-find namespace-regex (str %)) namespaces))]
                     (filter #(re-find namespace-regex (str %)) namespaces))]
-    ;; NOTE: If include points to a nonexistent metadata flag, this results in test-syms being '().
-    ;; We would expect no tests to run but instead the node test runner runs all tests.
-    ;; We may want to workaround this
     (cond-> {}
     (cond-> {}
             (some? test-syms)
             (some? test-syms)
             (assoc :test-syms test-syms))))
             (assoc :test-syms test-syms))))
@@ -116,5 +115,10 @@ returns run options for selected tests to run"
                        "\n\nNone of these options can be composed. Defaults to running all tests")
                        "\n\nNone of these options can be composed. Defaults to running all tests")
         (js/process.exit 0))
         (js/process.exit 0))
       (with-redefs [node/find-matching-test-vars find-matching-test-vars]
       (with-redefs [node/find-matching-test-vars find-matching-test-vars]
-        (node/execute-cli
-         (run-test-options (keys (env/get-tests)) (env/get-test-vars) options))))))
+        (let [opts (run-test-options (keys (env/get-tests)) (env/get-test-vars) options)]
+          ;; If :test-syms is specified but empty, skip execute-cli because the
+          ;; user has specified an empty test selection
+          (if (and (seq opts) (empty? (:test-syms opts)))
+            (do (println "No tests found.")
+              (js/process.exit 0))
+            (node/execute-cli opts)))))))