mirror of
https://github.com/logseq/logseq.git
synced 2026-04-30 00:46:23 +00:00
chore: convert query-dsl tests to db graphs
Able to remove some dead code and add :build.test/title which is reusable for future tests
This commit is contained in:
@@ -5,15 +5,14 @@
|
||||
[frontend.db.query-dsl :as query-dsl]
|
||||
[frontend.db.react :as react]
|
||||
[frontend.test.helper :as test-helper :include-macros true :refer [load-test-files load-test-files-for-db-graph]]
|
||||
[frontend.util :as util]
|
||||
[logseq.common.util.page-ref :as page-ref]))
|
||||
[frontend.util :as util]))
|
||||
|
||||
;; TODO: quickcheck
|
||||
;; 1. generate query filters
|
||||
;; 2. find illegal queries which can't be executed by datascript
|
||||
;; 3. find filters combinations which might break the current query implementation
|
||||
|
||||
(use-fixtures :each {:before test-helper/start-test-db!
|
||||
(use-fixtures :each {:before #(test-helper/start-test-db! {:db-graph? true})
|
||||
:after test-helper/destroy-test-db!})
|
||||
|
||||
;; Test helpers
|
||||
@@ -63,25 +62,17 @@
|
||||
(with-redefs [query-dsl/db-block-attrs db-block-attrs]
|
||||
(apply query-dsl/query args)))))
|
||||
|
||||
(defn- ->smart-query
|
||||
"Updates to file version if js/process.env.DB_GRAPH is not set"
|
||||
[query]
|
||||
(if js/process.env.DB_GRAPH
|
||||
(some-> query
|
||||
(string/replace "(page-tags" "(tags"))
|
||||
query))
|
||||
|
||||
(defn- dsl-query
|
||||
[s]
|
||||
(react/clear-query-state!)
|
||||
(when-let [result (dsl-query* test-helper/test-db (->smart-query s))]
|
||||
(when-let [result (dsl-query* test-helper/test-db-name-db-version s)]
|
||||
(map first (deref result))))
|
||||
|
||||
(defn- custom-query
|
||||
[query]
|
||||
(react/clear-query-state!)
|
||||
(when-let [result (with-redefs [query-dsl/db-block-attrs db-block-attrs]
|
||||
(query-dsl/custom-query test-helper/test-db query {}))]
|
||||
(query-dsl/custom-query test-helper/test-db-name-db-version query {}))]
|
||||
(map first (deref result))))
|
||||
|
||||
;; Tests
|
||||
@@ -120,20 +111,15 @@
|
||||
|
||||
(defn- block-property-queries-test
|
||||
[]
|
||||
(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-d:: [[no-space-link]]
|
||||
prop-c:: [[page a]], [[page b]], [[page c]]
|
||||
prop-linked-num:: [[3000]]
|
||||
- b4
|
||||
prop-d:: [[nada]]"}])
|
||||
(load-test-files
|
||||
[{:page {:build/journal 20220228, :build/properties {:a "b"}}
|
||||
:blocks [{:block/title "b1", :build/properties {:prop-a "val-a", :prop-num 2000}}
|
||||
{:block/title "b2", :build/properties {:prop-a "val-a", :prop-b "val-b"}}
|
||||
{:block/title "b3"
|
||||
:build/properties {:prop-d #{[:build/page {:block/title "no-space-link"}]}
|
||||
:prop-c #{[:build/page {:block/title "page a"}] [:build/page {:block/title "page b"}] [:build/page {:block/title "page c"}]}
|
||||
:prop-linked-num #{[:build/page {:block/title "3000"}]}}}
|
||||
{:block/title "b4", :build/properties {:prop-d #{[:build/page {:block/title "nada"}]}}}]}])
|
||||
|
||||
(testing "Blocks have given property value"
|
||||
(is (= #{"b1" "b2"}
|
||||
@@ -190,32 +176,31 @@ prop-d:: [[nada]]"}])
|
||||
(test-helper/with-config {}
|
||||
(block-property-queries-test))))
|
||||
|
||||
(when js/process.env.DB_GRAPH
|
||||
(deftest db-only-block-property-queries
|
||||
(load-test-files-for-db-graph
|
||||
{:properties
|
||||
{:zzz {:logseq.property/type :default
|
||||
:block/title "zzz name!"}}
|
||||
:pages-and-blocks
|
||||
[{:page {:block/title "page1"}
|
||||
:blocks [{:block/title "b1"
|
||||
:build/properties {:Foo "bar"}}
|
||||
{:block/title "b2"
|
||||
:build/properties {:foo "bar"}}
|
||||
{:block/title "b3"
|
||||
:build/properties {:zzz "bar"}}]}]})
|
||||
(deftest db-only-block-property-queries
|
||||
(load-test-files-for-db-graph
|
||||
{:properties
|
||||
{:zzz {:logseq.property/type :default
|
||||
:block/title "zzz name!"}}
|
||||
:pages-and-blocks
|
||||
[{:page {:block/title "page1"}
|
||||
:blocks [{:block/title "b1"
|
||||
:build/properties {:Foo "bar"}}
|
||||
{:block/title "b2"
|
||||
:build/properties {:foo "bar"}}
|
||||
{:block/title "b3"
|
||||
:build/properties {:zzz "bar"}}]}]})
|
||||
|
||||
(is (= ["b1"]
|
||||
(map :block/title (dsl-query "(property Foo)")))
|
||||
"filter is case sensitive")
|
||||
(is (= ["b2"]
|
||||
(map :block/title (dsl-query "(property :user.property/foo)")))
|
||||
"filter can handle qualified keyword properties")
|
||||
(is (= ["b3"]
|
||||
(map :block/title (dsl-query "(property \"zzz name!\")")))
|
||||
"filter can handle property name")))
|
||||
(is (= ["b1"]
|
||||
(map :block/title (dsl-query "(property Foo)")))
|
||||
"filter is case sensitive")
|
||||
(is (= ["b2"]
|
||||
(map :block/title (dsl-query "(property :user.property/foo)")))
|
||||
"filter can handle qualified keyword properties")
|
||||
(is (= ["b3"]
|
||||
(map :block/title (dsl-query "(property \"zzz name!\")")))
|
||||
"filter can handle property name"))
|
||||
|
||||
(when (and js/process.env.DB_GRAPH (not js/process.env.DB_QUERY_TYPE))
|
||||
(when (not js/process.env.DB_QUERY_TYPE)
|
||||
(deftest property-default-type-default-value-queries
|
||||
(load-test-files-for-db-graph
|
||||
{:properties
|
||||
@@ -304,11 +289,11 @@ prop-d:: [[nada]]"}])
|
||||
(deftest block-property-query-performance
|
||||
(let [pages (->> (repeat 10 {:tags ["tag1" "tag2"]})
|
||||
(map-indexed (fn [idx {:keys [tags]}]
|
||||
{:file/path (str "pages/page" idx ".md")
|
||||
:file/content (if (seq tags)
|
||||
(str "page-prop:: b\n- block for page" idx
|
||||
"\ntagz:: " (string/join ", " (map page-ref/->page-ref tags)))
|
||||
"")})))
|
||||
{:page {:block/title (str "page" idx)
|
||||
:build/properties {:page-prop "b"}}
|
||||
:blocks [{:block/title (str "block for page" idx)
|
||||
:build/properties {:tagz (set (map #(vector :build/page {:block/title %}) tags))}}]}))
|
||||
vec)
|
||||
_ (load-test-files pages)
|
||||
{:keys [result time]}
|
||||
(util/with-time (dsl-query "(and (property tagz tag1) (property tagz tag2))"))]
|
||||
@@ -319,209 +304,197 @@ prop-d:: [[nada]]"}])
|
||||
|
||||
(defn- page-property-queries-test
|
||||
[]
|
||||
(load-test-files [{:file/path "pages/page1.md"
|
||||
:file/content "parent:: [[child page 1]], [[child-no-space]]\ninteresting:: true\nfoo:: baz"}
|
||||
{:file/path "pages/page2.md"
|
||||
:file/content "foo:: bar\ninteresting:: false"}
|
||||
{:file/path "pages/page3.md"
|
||||
:file/content "parent:: [[child page 1]], [[child page 2]]\nfoo:: bar\ninteresting:: false"}
|
||||
{:file/path "pages/page4.md"
|
||||
:file/content "parent:: [[child page 2]]\nfoo:: baz"}])
|
||||
(load-test-files
|
||||
[{:page {:block/title "page1"
|
||||
:build/properties {:parent #{[:build/page {:block/title "child page 1"}] [:build/page {:block/title "child-no-space"}]}, :interesting true, :foo "baz"}}}
|
||||
{:page {:block/title "page2", :build/properties {:foo "bar", :interesting false}}}
|
||||
{:page {:block/title "page3"
|
||||
:build/properties {:parent #{[:build/page {:block/title "child page 1"}] [:build/page {:block/title "child page 2"}]}, :foo "bar", :interesting false}}}
|
||||
{:page {:block/title "page4"
|
||||
:build/properties {:parent #{[:build/page {:block/title "child page 2"}]}, :foo "baz"}}}])
|
||||
(is (= ["page1" "page3" "page4"]
|
||||
(map :block/name (dsl-query "(page-property parent)")))
|
||||
(map :block/name (dsl-query "(property parent)")))
|
||||
"Pages have given property")
|
||||
|
||||
(is (= #{"page1" "page3"}
|
||||
(set (map :block/name (dsl-query "(page-property parent [[child page 1]])"))))
|
||||
(set (map :block/name (dsl-query "(property parent [[child page 1]])"))))
|
||||
"Pages have property value that is a page and query is a page")
|
||||
|
||||
(is (= #{"page1" "page3"}
|
||||
(set (map :block/name (dsl-query "(page-property parent \"child page 1\")"))))
|
||||
(set (map :block/name (dsl-query "(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]])")))
|
||||
(map :block/name (dsl-query "(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]]))")))
|
||||
(dsl-query "(and (property parent [[child page 1]]) (property parent [[child page 2]]))")))
|
||||
"Page property queries ANDed")
|
||||
|
||||
(is (= #{"page1" "page3" "page4"}
|
||||
(set
|
||||
(map
|
||||
:block/name
|
||||
(dsl-query "(or (page-property parent [[child page 1]]) (page-property parent [[child page 2]]))"))))
|
||||
(dsl-query "(or (property parent [[child page 1]]) (property parent [[child page 2]]))"))))
|
||||
"Page property queries ORed")
|
||||
|
||||
(is (= ["page1" "page3"]
|
||||
(map :block/name
|
||||
(dsl-query "(and (page-property parent [[child page 1]]) (or (page-property foo baz) (page-property parent [[child page 2]])))"))))
|
||||
(dsl-query "(and (property parent [[child page 1]]) (or (property foo baz) (property parent [[child page 2]])))"))))
|
||||
|
||||
(is (= ["page4"]
|
||||
(map
|
||||
:block/name
|
||||
(dsl-query "(and (page-property parent [[child page 2]]) (not (page-property foo bar)))")))
|
||||
(dsl-query "(and (property parent [[child page 2]]) (not (property foo bar)))")))
|
||||
"Page property queries nested NOT in second clause")
|
||||
|
||||
(is (= ["page4"]
|
||||
(map
|
||||
:block/name
|
||||
(dsl-query "(and (not (page-property foo bar)) (page-property parent [[child page 2]]))")))
|
||||
(dsl-query "(and (not (property foo bar)) (property parent [[child page 2]]))")))
|
||||
"Page property queries nested NOT in first clause")
|
||||
|
||||
(testing "boolean values"
|
||||
(is (= ["page1"]
|
||||
(map :block/name (dsl-query "(page-property interesting true)")))
|
||||
(map :block/name (dsl-query "(property interesting true)")))
|
||||
"Boolean true")
|
||||
|
||||
(is (= #{"page2" "page3"}
|
||||
(set (map :block/name (dsl-query "(page-property interesting false)"))))
|
||||
(set (map :block/name (dsl-query "(property interesting false)"))))
|
||||
"Boolean false")))
|
||||
|
||||
(when-not js/process.env.DB_GRAPH
|
||||
(deftest page-property-queries
|
||||
(testing "page property tests with default config"
|
||||
(test-helper/with-config {}
|
||||
(page-property-queries-test)))))
|
||||
(deftest page-property-queries
|
||||
(testing "page property tests with default config"
|
||||
(test-helper/with-config {}
|
||||
(page-property-queries-test))))
|
||||
|
||||
(deftest task-queries
|
||||
(load-test-files [{:file/path "pages/page1.md"
|
||||
:file/content "foo:: bar
|
||||
- DONE b1
|
||||
- TODO b2
|
||||
- DOING b3
|
||||
- DOING b4 [[A]]
|
||||
- DOING b5 [[B]]"}])
|
||||
(load-test-files
|
||||
[{:page {:block/title "page1"}
|
||||
:blocks [{:build.test/title "DONE b1"}
|
||||
{:build.test/title "TODO b2"}
|
||||
{:build.test/title "DOING b3"}
|
||||
{:build.test/title "DOING b4 [[A]]"}
|
||||
{:build.test/title "DOING b5 [[B]]"}]}])
|
||||
|
||||
(testing "Lowercase query"
|
||||
(is (= ["DONE b1"]
|
||||
(is (= ["b1"]
|
||||
(map testable-content (dsl-query "(task done)"))))
|
||||
|
||||
(is (= #{"DOING b3" "DOING b4" "DOING b5"}
|
||||
(is (= #{"b3" "b4" "b5"}
|
||||
(set (map testable-content (dsl-query "(task doing)"))))))
|
||||
|
||||
(is (= #{"DOING b3" "DOING b4" "DOING b5"}
|
||||
(is (= #{"b3" "b4" "b5"}
|
||||
(set (map testable-content (dsl-query "(task DOING)"))))
|
||||
"Uppercase query")
|
||||
|
||||
(testing "Multiple specified tasks results in ORed results"
|
||||
(is (= #{"DONE b1" "DOING b3" "DOING b4" "DOING b5"}
|
||||
(is (= #{"b1" "b3" "b4" "b5"}
|
||||
(set (map testable-content (dsl-query "(task done doing)")))))
|
||||
|
||||
(is (= #{"DONE b1" "DOING b3" "DOING b4" "DOING b5"}
|
||||
(is (= #{"b1" "b3" "b4" "b5"}
|
||||
(set (map testable-content (dsl-query "(task [done doing])"))))
|
||||
"Multiple arguments specified with vector notation"))
|
||||
|
||||
(is (= ["DONE b1" "DOING b4"]
|
||||
(is (= ["b1" "b4"]
|
||||
(map testable-content
|
||||
(dsl-query "(or (task done) (and (task doing) [[A]]))")))
|
||||
"Multiple boolean operators with todo and priority operators")
|
||||
|
||||
(is (= ["DOING b4" "DOING b5"]
|
||||
(is (= ["b4" "b5"]
|
||||
(map testable-content
|
||||
(dsl-query "(and (task doing) (or [[A]] [[B]]))")))))
|
||||
|
||||
(when js/process.env.DB_GRAPH
|
||||
|
||||
;; Ensure some filters work when no data with relevant properties exist
|
||||
(deftest queries-with-no-data
|
||||
(load-test-files [])
|
||||
(is (= [] (dsl-query "(task todo)")))
|
||||
(is (= [] (dsl-query "(priority high)")))))
|
||||
;; Ensure some filters work when no data with relevant properties exist
|
||||
(deftest queries-with-no-data
|
||||
(load-test-files {:pages-and-blocks []})
|
||||
(is (= [] (dsl-query "(task todo)")))
|
||||
(is (= [] (dsl-query "(priority high)"))))
|
||||
|
||||
(deftest sample-queries
|
||||
(load-test-files [{:file/path "pages/page1.md"
|
||||
:file/content "foo:: bar
|
||||
- TODO b1
|
||||
- TODO b2"}])
|
||||
(load-test-files
|
||||
[{:page {:block/title "page1", :build/properties {:foo "bar"}}
|
||||
:blocks [{:build.test/title "TODO b1"}
|
||||
{:build.test/title "TODO b2"}]}])
|
||||
(is (= 1
|
||||
(count (dsl-query "(and (task todo) (sample 1))")))
|
||||
"Correctly limits block results")
|
||||
(is (= 1
|
||||
(count (dsl-query (if js/process.env.DB_GRAPH "(and (property foo) (sample 1))" "(and (page-property foo) (sample 1))"))))
|
||||
(count (dsl-query "(and (property foo) (sample 1))")))
|
||||
"Correctly limits page results"))
|
||||
|
||||
(deftest priority-queries
|
||||
(load-test-files (if js/process.env.DB_GRAPH
|
||||
[{:page {:block/title "page1"}
|
||||
:blocks [{:block/title "[#A] b1"
|
||||
:build/properties {:logseq.property/priority :logseq.property/priority.high}}
|
||||
{:block/title "[#B] b2"
|
||||
:build/properties {:logseq.property/priority :logseq.property/priority.medium}}
|
||||
{:block/title "[#A] b3"
|
||||
:build/properties {:logseq.property/priority :logseq.property/priority.high}}]}]
|
||||
|
||||
[{:file/path "pages/page1.md"
|
||||
:file/content "foo:: bar
|
||||
- [#A] b1
|
||||
- [#B] b2
|
||||
- [#A] b3"}]))
|
||||
(load-test-files [{:page {:block/title "page1"}
|
||||
:blocks [{:block/title "[#A] b1"
|
||||
:build/properties {:logseq.property/priority :logseq.property/priority.high}}
|
||||
{:block/title "[#B] b2"
|
||||
:build/properties {:logseq.property/priority :logseq.property/priority.medium}}
|
||||
{:block/title "[#A] b3"
|
||||
:build/properties {:logseq.property/priority :logseq.property/priority.high}}]}])
|
||||
|
||||
(testing "one arg queries"
|
||||
(is (= #{"[#A] b1" "[#A] b3"}
|
||||
(set (map :block/title
|
||||
(dsl-query (if js/process.env.DB_GRAPH "(priority high)" "(priority a)"))))))
|
||||
(dsl-query "(priority high)")))))
|
||||
(is (= #{"[#A] b1" "[#A] b3"}
|
||||
(set (map :block/title
|
||||
(dsl-query (if js/process.env.DB_GRAPH "(priority high)" "(priority a)")))))))
|
||||
(dsl-query "(priority high)"))))))
|
||||
|
||||
(testing "two arg queries"
|
||||
(is (= #{"[#A] b1" "[#B] b2" "[#A] b3"}
|
||||
(set (map :block/title
|
||||
(dsl-query (if js/process.env.DB_GRAPH "(priority high medium)" "(priority a b)"))))))
|
||||
(dsl-query "(priority high medium)")))))
|
||||
(is (= #{"[#A] b1" "[#B] b2" "[#A] b3"}
|
||||
(set (map :block/title
|
||||
(dsl-query (if js/process.env.DB_GRAPH "(priority [high medium])" "(priority [a b])")))))
|
||||
(dsl-query "(priority [high medium])"))))
|
||||
"Arguments with vector notation"))
|
||||
|
||||
(is (= #{"[#A] b1" "[#B] b2" "[#A] b3"}
|
||||
(set (map :block/title
|
||||
(dsl-query (if js/process.env.DB_GRAPH "(priority high medium low)" "(priority a b c)")))))
|
||||
(dsl-query "(priority high medium low)"))))
|
||||
"Three arg queries and args that have no match"))
|
||||
|
||||
(deftest nested-boolean-queries
|
||||
(load-test-files [{:file/path "pages/page1.md"
|
||||
:file/content "foo:: bar
|
||||
- DONE b1 [[page 1]] [[page 3]]
|
||||
- DONE b2Z [[page 1]]"}
|
||||
{:file/path "pages/page2.md"
|
||||
:file/content "foo:: bar
|
||||
- NOW b3 [[page 1]]
|
||||
- LATER b4Z [[page 2]]
|
||||
"}])
|
||||
(load-test-files
|
||||
[{:page {:block/title "page1", :build/properties {:foo "bar"}}
|
||||
:blocks [{:build.test/title "DONE b1 [[page 1]] [[page 3]]"}
|
||||
{:build.test/title "DONE b2Z [[page 1]]"}]}
|
||||
{:page {:block/title "page2", :build/properties {:foo "bar"}}
|
||||
:blocks [{:build.test/title "NOW b3 [[page 1]]"}
|
||||
{:build.test/title "LATER b4Z [[page 2]]"}]}])
|
||||
|
||||
(let [task-filter (if js/process.env.DB_GRAPH "(task doing todo)" "(task now later)")]
|
||||
(let [task-filter "(task doing todo)"]
|
||||
(is (= []
|
||||
(dsl-query "(and (task done) (not [[page 1]]))")))
|
||||
|
||||
(is (= ["DONE b1"]
|
||||
(is (= ["b1"]
|
||||
(map testable-content
|
||||
(dsl-query "(and [[page 1]] (and [[page 3]] (not (task todo))))")))
|
||||
"Nested not")
|
||||
|
||||
(is (= ["NOW b3" "LATER b4Z"]
|
||||
(is (= ["b3" "b4Z"]
|
||||
(map testable-content
|
||||
(dsl-query (str "(and " task-filter " (or [[page 1]] [[page 2]]))")))))
|
||||
|
||||
(is (= #{"NOW b3"
|
||||
"LATER b4Z"
|
||||
"DONE b1"
|
||||
"DONE b2Z"}
|
||||
(is (= #{"b3"
|
||||
"b4Z"
|
||||
"b1"
|
||||
"b2Z"}
|
||||
(set (map testable-content
|
||||
(dsl-query (str "(and "
|
||||
(if js/process.env.DB_GRAPH "(task doing todo done)" "(task now later done)")
|
||||
"(task doing todo done)"
|
||||
" (or [[page 1]] (not [[page 1]])))"))))))
|
||||
|
||||
(is (= (if js/process.env.DB_GRAPH #{"bar" "DONE b1" "DONE b2Z"} #{"foo:: bar" "DONE b1" "DONE b2Z"})
|
||||
(is (= #{"bar" "b1" "b2Z"}
|
||||
(->> (dsl-query (str "(not (and " task-filter " (or [[page 1]] [[page 2]])))"))
|
||||
(keep testable-content)
|
||||
(remove (fn [s] (db/page? (db/get-page s))))
|
||||
set)))
|
||||
|
||||
(is (= #{"DONE b2Z" "LATER b4Z"}
|
||||
(is (= #{"b2Z" "b4Z"}
|
||||
(->> (dsl-query "(and \"Z\" (or \"b2\" \"b4\"))")
|
||||
(keep testable-content)
|
||||
set))
|
||||
@@ -535,33 +508,31 @@ prop-d:: [[nada]]"}])
|
||||
|
||||
(deftest tags-queries
|
||||
(load-test-files
|
||||
[{:file/path "pages/page1.md"
|
||||
:file/content "tags:: [[page-tag-1]], [[page-tag-2]]"}
|
||||
{:file/path "pages/page2.md"
|
||||
:file/content "tags:: [[page-tag-2]], [[page-tag-3]]"}
|
||||
{:file/path "pages/page3.md"
|
||||
:file/content "tags:: [[other]]"}])
|
||||
[{:page {:block/title "page1" :build/tags [:page-tag-1 :page-tag-2]}}
|
||||
{:page {:block/title "page2" :build/tags [:page-tag-2 :page-tag-3]}}
|
||||
{:page {:block/title "page3" :build/tags [:other]}}])
|
||||
|
||||
(are [x y] (= (set y) (set (map :block/name (dsl-query x))))
|
||||
|
||||
"(page-tags [[page-tag-1]])"
|
||||
"(tags [[page-tag-1]])"
|
||||
["page1"]
|
||||
|
||||
"(page-tags page-tag-2)"
|
||||
"(tags page-tag-2)"
|
||||
["page1" "page2"]
|
||||
|
||||
"(page-tags page-tag-1 page-tag-2)"
|
||||
"(tags page-tag-1 page-tag-2)"
|
||||
["page1" "page2"]
|
||||
|
||||
"(page-tags page-TAG-1 page-tag-2)"
|
||||
"(tags page-TAG-1 page-tag-2)"
|
||||
["page1" "page2"]
|
||||
|
||||
"(page-tags [page-tag-1 page-tag-2])"
|
||||
"(tags [page-tag-1 page-tag-2])"
|
||||
["page1" "page2"]))
|
||||
|
||||
(deftest block-content-query
|
||||
(load-test-files [{:file/path "pages/page1.md"
|
||||
:file/content "- b1 Hit\n- b2 Another"}])
|
||||
(load-test-files [{:page {:block/title "page1"}
|
||||
:blocks [{:block/title "b1 Hit"}
|
||||
{:block/title "b2 Another"}]}])
|
||||
|
||||
(is (= ["b1 Hit"]
|
||||
(map :block/title (dsl-query "\"Hit\""))))
|
||||
@@ -571,10 +542,10 @@ prop-d:: [[nada]]"}])
|
||||
"Correctly returns no results"))
|
||||
|
||||
(deftest page-queries
|
||||
(load-test-files [{:file/path "pages/page1.md"
|
||||
:file/content "foo"}
|
||||
{:file/path "pages/page2.md"
|
||||
:file/content "bar"}])
|
||||
(load-test-files [{:page {:block/title "page1"}
|
||||
:blocks [{:block/title "foo"}]}
|
||||
{:page {:block/title "page2"}
|
||||
:blocks [{:block/title "bar"}]}])
|
||||
|
||||
(is (= ["page1"]
|
||||
(map (fn [result]
|
||||
@@ -596,12 +567,11 @@ prop-d:: [[nada]]"}])
|
||||
"\"\"")))
|
||||
|
||||
(deftest page-ref-and-boolean-queries
|
||||
(load-test-files [{:file/path "pages/page1.md"
|
||||
:file/content "foo:: bar
|
||||
- b1 [[page 1]] [[tag2]]
|
||||
- b2 [[page 2]] [[tag1]]
|
||||
- b4 [[page 4]] [[tag4]]
|
||||
- b3"}])
|
||||
(load-test-files
|
||||
[{:page {:block/title "page1", :build/properties {:foo "bar"}}
|
||||
:blocks [{:block/title "b1 [[page 1]] [[tag2]]"}
|
||||
{:block/title "b2 [[page 2]] [[tag1]]"}
|
||||
{:block/title "b3"}]}])
|
||||
|
||||
(testing "page-ref queries"
|
||||
|
||||
@@ -628,7 +598,7 @@ prop-d:: [[nada]]"}])
|
||||
"OR query")
|
||||
|
||||
(comment
|
||||
;; FIXME: load-test-files doesn't save `b4` to the db when DB_GRAPH=1
|
||||
;; FIXME: load-test-files doesn't save `b4`
|
||||
(is (= ["b1" "b4"]
|
||||
(map testable-content
|
||||
(dsl-query "(or [[tag2]] [[page 4]])")))
|
||||
@@ -639,28 +609,20 @@ prop-d:: [[nada]]"}])
|
||||
(dsl-query "(or [[tag2]] [[page not exists]])")))
|
||||
"OR query with nonexistent page should return meaningful results")
|
||||
|
||||
(when js/process.env.DB_GRAPH
|
||||
(is (= #{"b1" "bar" "b3"}
|
||||
(->> (dsl-query "(not [[page 2]])")
|
||||
(is (= #{"b1" "bar" "b3"}
|
||||
(->> (dsl-query "(not [[page 2]])")
|
||||
;; Only filter to page1 to get meaningful results
|
||||
(filter #(= "page1" (get-in % [:block/page :block/name])))
|
||||
(map testable-content)
|
||||
(set)))
|
||||
"NOT query"))))
|
||||
(filter #(= "page1" (get-in % [:block/page :block/name])))
|
||||
(map testable-content)
|
||||
(set)))
|
||||
"NOT query")))
|
||||
|
||||
(deftest nested-page-ref-queries
|
||||
(load-test-files (if js/process.env.DB_GRAPH
|
||||
[{:page {:block/title "page1"}
|
||||
:blocks [{:block/title "p1 [[Parent page]]"
|
||||
:build/children [{:block/title "[[Child page]]"}]}
|
||||
{:block/title "p2 [[Parent page]]"
|
||||
:build/children [{:block/title "Non linked content"}]}]}]
|
||||
[{:file/path "pages/page1.md"
|
||||
:file/content "foo:: bar
|
||||
- p1 [[Parent page]]
|
||||
- [[Child page]]
|
||||
- p2 [[Parent page]]
|
||||
- Non linked content"}]))
|
||||
(load-test-files [{:page {:block/title "page1"}
|
||||
:blocks [{:block/title "p1 [[Parent page]]"
|
||||
:build/children [{:block/title "[[Child page]]"}]}
|
||||
{:block/title "p2 [[Parent page]]"
|
||||
:build/children [{:block/title "Non linked content"}]}]}])
|
||||
(is (= (set
|
||||
["Non linked content"
|
||||
"p2"
|
||||
@@ -670,19 +632,14 @@ prop-d:: [[nada]]"}])
|
||||
(dsl-query "(and [[Parent page]] (not [[Child page]]))"))))))
|
||||
|
||||
(deftest between-queries
|
||||
(load-test-files [{:file/path "journals/2020_12_26.md"
|
||||
:file/content "foo::bar
|
||||
- DONE 26-b1
|
||||
created-at:: 1608968448113
|
||||
- LATER 26-b2-modified-later
|
||||
created-at:: 1608968448114
|
||||
- DONE 26-b3
|
||||
created-at:: 1608968448115
|
||||
- 26-b4
|
||||
created-at:: 1608968448116
|
||||
"}])
|
||||
(load-test-files
|
||||
[{:page {:build/journal 20201226}
|
||||
:blocks [{:build.test/title "DONE 26-b1", :block/created-at 1608968448113}
|
||||
{:build.test/title "LATER 26-b2-modified-later", :block/created-at 1608968448114}
|
||||
{:build.test/title "DONE 26-b3", :block/created-at 1608968448115}
|
||||
{:block/title "26-b4", :block/created-at 1608968448116}]}])
|
||||
|
||||
(let [task-filter (if js/process.env.DB_GRAPH "(task todo done)" "(task later done)")]
|
||||
(let [task-filter "(task todo done)"]
|
||||
(are [x y] (= (count (dsl-query x)) y)
|
||||
(str "(and " task-filter " (between [[Dec 26th, 2020]] tomorrow))")
|
||||
3
|
||||
@@ -691,85 +648,25 @@ created-at:: 1608968448116
|
||||
(str "(and " task-filter " (between [[Dec 26th, 2020]] [[Dec 27th, 2020]]))")
|
||||
3)
|
||||
|
||||
(when js/process.env.DB_GRAPH
|
||||
(is (= 3 (count (dsl-query "(and (task todo done) (between created-at [[Dec 26th, 2020]]))"))))
|
||||
(is (= 3 (count (dsl-query "(and (task todo done) (between created-at [[Dec 26th, 2020]] +1d))")))))))
|
||||
(is (= 3 (count (dsl-query "(and (task todo done) (between created-at [[Dec 26th, 2020]]))"))))
|
||||
(is (= 3 (count (dsl-query "(and (task todo done) (between created-at [[Dec 26th, 2020]] +1d))"))))))
|
||||
|
||||
(deftest custom-query-test
|
||||
(load-test-files [{:file/path "pages/page1.md"
|
||||
:file/content "foo:: bar
|
||||
- NOW b1
|
||||
- TODO b2
|
||||
- LATER b3
|
||||
- b3"}])
|
||||
(load-test-files
|
||||
[{:page {:block/title "page1", :build/properties {:foo "bar"}}
|
||||
:blocks [{:build.test/title "NOW b1"}
|
||||
{:build.test/title "TODO b2"}
|
||||
{:build.test/title "LATER b3"}
|
||||
{:block/title "b3"}]}])
|
||||
|
||||
(let [task-query (if js/process.env.DB_GRAPH
|
||||
'(task doing)
|
||||
'(task now))]
|
||||
(is (= ["NOW b1"]
|
||||
(let [task-query '(task doing)]
|
||||
(is (= ["b1"]
|
||||
(map :block/title (custom-query {:query task-query}))))
|
||||
|
||||
(is (= ["NOW b1"]
|
||||
(is (= ["b1"]
|
||||
(map :block/title (custom-query {:query (list 'and task-query "b")})))
|
||||
"Query with rule that can't be derived from the form itself")))
|
||||
|
||||
(def get-property-value #(get-in %1 [:block/properties %2]))
|
||||
|
||||
(when-not js/process.env.DB_GRAPH
|
||||
(deftest sort-by-queries
|
||||
(load-test-files [{:file/path "journals/2020_02_25.md"
|
||||
:file/content "rating:: 10"}
|
||||
{:file/path "journals/2020_12_26.md"
|
||||
:file/content "rating:: 8
|
||||
- DONE 26-b1
|
||||
created-at:: 1608968448113
|
||||
fruit:: plum
|
||||
- LATER 26-b2-modified-later
|
||||
created-at:: 1608968448114
|
||||
fruit:: apple
|
||||
- DONE 26-b3 has no fruit to test sorting of absent property value
|
||||
created-at:: 1608968448115
|
||||
- 26-b4
|
||||
created-at:: 1608968448116
|
||||
"}])
|
||||
(let [task-filter "(task later done)"]
|
||||
(testing "sort-by user block property fruit"
|
||||
(let [result (->> (dsl-query (str "(and " task-filter " (sort-by fruit))"))
|
||||
(map #(get-property-value % :fruit)))]
|
||||
(is (= ["plum" "apple" nil]
|
||||
result)
|
||||
"sort-by correctly defaults to desc"))
|
||||
|
||||
(let [result (->> (dsl-query (str "(and " task-filter " (sort-by fruit desc))"))
|
||||
(map #(get-property-value % :fruit)))]
|
||||
(is (= ["plum" "apple" nil]
|
||||
result)
|
||||
"sort-by desc"))
|
||||
|
||||
(let [result (->> (dsl-query (str "(and " task-filter " (sort-by fruit asc))"))
|
||||
(map #(get-property-value % :fruit)))]
|
||||
(is (= [nil "apple" "plum"]
|
||||
result)
|
||||
"sort-by asc")))
|
||||
|
||||
(testing "sort-by hidden, built-in block property created-at"
|
||||
(let [result (->> (dsl-query (str "(and " task-filter " (sort-by created-at desc))"))
|
||||
(map #(get-property-value % :created-at)))]
|
||||
(is (= [1608968448115 1608968448114 1608968448113]
|
||||
result))
|
||||
"sorted-by desc")
|
||||
|
||||
(let [result (->> (dsl-query (str "(and " task-filter " (sort-by created-at asc))"))
|
||||
(map #(get-property-value % :created-at)))]
|
||||
(is (= [1608968448113 1608968448114 1608968448115]
|
||||
result)
|
||||
"sorted-by asc")))
|
||||
|
||||
(testing "user page property rating"
|
||||
(is (= [10 8]
|
||||
(->> (dsl-query "(and (page-property rating) (sort-by rating))")
|
||||
(map #(get-property-value % :rating)))))))))
|
||||
|
||||
(deftest simplify-query
|
||||
(are [x y] (= (query-dsl/simplify-query x) y)
|
||||
'(and [[foo]])
|
||||
@@ -814,20 +711,4 @@ created-at:: 1608968448116
|
||||
(or (and [?b :block/priority ?priority] [(contains? #{"A"} ?priority)])
|
||||
(not [?b :block/priority #{"A"}]
|
||||
[(contains? #{"A"} ?priority)]))]
|
||||
(frontend.db/get-db test-helper/test-db))))
|
||||
|
||||
(when-not js/process.env.DB_GRAPH
|
||||
(deftest namespace-queries
|
||||
(load-test-files [{:file/path "pages/ns1.page1.md"
|
||||
:file/content "foo"}
|
||||
{:file/path "pages/ns1.page2.md"
|
||||
:file/content "bar"}
|
||||
{:file/path "pages/ns2.page1.md"
|
||||
:file/content "baz"}])
|
||||
|
||||
(is (= #{"ns1/page1" "ns1/page2"}
|
||||
(set (map :block/name (dsl-query "(namespace ns1)")))))
|
||||
|
||||
(is (= #{}
|
||||
(set (map :block/name (dsl-query "(namespace blarg)"))))
|
||||
"Correctly returns no results")))
|
||||
(frontend.db/get-db test-helper/test-db))))
|
||||
Reference in New Issue
Block a user