0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-08 07:50:43 -05:00
penpot/frontend/test/frontend_tests/util_range_tree_test.cljs
2024-01-08 09:32:50 +01:00

204 lines
7 KiB
Clojure

;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns frontend-tests.util-range-tree-test
(:require
[app.common.geom.point :as gpt]
[app.util.range-tree :as rt]
[cljs.pprint :refer [pprint]]
[cljs.test :as t :include-macros true]))
(defn check-max-height [tree num-nodes])
(defn check-sorted [tree])
(defn create-random-tree [num-nodes])
(t/deftest test-insert-and-retrieve-data
(t/testing "Retrieve on empty tree"
(let [tree (rt/make-tree)]
(t/is (= (rt/get tree 100) nil))))
(t/testing "First insert/retrieval"
(let [tree (-> (rt/make-tree)
(rt/insert 100 :a))]
(t/is (= (rt/get tree 100) [:a]))
(t/is (= (rt/get tree 200) nil))))
(t/testing "Insert best case scenario"
(let [tree (-> (rt/make-tree)
(rt/insert 100 :a)
(rt/insert 50 :b)
(rt/insert 200 :c))]
(t/is (= (rt/get tree 100) [:a]))
(t/is (= (rt/get tree 50) [:b]))
(t/is (= (rt/get tree 200) [:c]))))
(t/testing "Insert duplicate entry"
(let [tree (-> (rt/make-tree)
(rt/insert 100 :a)
(rt/insert 50 :b)
(rt/insert 200 :c)
(rt/insert 50 :d)
(rt/insert 200 :e))]
(t/is (= (rt/get tree 100) [:a]))
(t/is (= (rt/get tree 50) [:b :d]))
(t/is (= (rt/get tree 200) [:c :e])))))
(t/deftest test-remove-elements
(t/testing "Insert and delete data but not the node"
(let [tree (-> (rt/make-tree)
(rt/insert 100 :a)
(rt/insert 100 :b)
(rt/insert 100 :c)
(rt/remove 100 :b))]
(t/is (= (rt/get tree 100) [:a :c]))))
(t/testing "Try to delete data not in the node is noop"
(let [tree (-> (rt/make-tree)
(rt/insert 100 :a)
(rt/insert 100 :b)
(rt/insert 100 :c)
(rt/remove 100 :xx))]
(t/is (= (rt/get tree 100) [:a :b :c]))))
(t/testing "Delete data and node"
(let [tree (-> (rt/make-tree)
(rt/insert 100 :a)
(rt/insert 200 :b)
(rt/insert 300 :c)
(rt/remove 200 :b))]
(t/is (= (rt/get tree 200) nil))))
(t/testing "Delete root node the new tree should be correct"
(let [tree (-> (rt/make-tree)
(rt/insert 100 :a)
(rt/insert 50 :b)
(rt/insert 150 :c)
(rt/insert 25 :d)
(rt/insert 75 :e)
(rt/insert 125 :f)
(rt/insert 175 :g)
(rt/remove 100 :a))]
(t/is (= (rt/get tree 100) nil))
(t/is (= (rt/get tree 50) [:b]))
(t/is (= (rt/get tree 150) [:c]))
(t/is (= (rt/get tree 25) [:d]))
(t/is (= (rt/get tree 75) [:e]))
(t/is (= (rt/get tree 125) [:f]))
(t/is (= (rt/get tree 175) [:g]))))
(t/testing "Adds a bunch of nodes and then delete. The tree should be empty"
;; Try an increase range
(let [size 10000
tree (rt/make-tree)
tree (reduce #(rt/insert %1 %2 :x) tree (range 0 (dec size)))
tree (reduce #(rt/remove %1 %2 :x) tree (range 0 (dec size)))]
(t/is (rt/empty? tree)))
;; Try a decreleasing range
(let [size 10000
tree (rt/make-tree)
tree (reduce #(rt/insert %1 %2 :x) tree (range (dec size) -1 -1))
tree (reduce #(rt/remove %1 %2 :x) tree (range (dec size) -1 -1))]
(t/is (rt/empty? tree)))))
(t/deftest test-update-elements
(t/testing "Updates an element"
(let [tree (-> (rt/make-tree)
(rt/insert 100 :a)
(rt/insert 50 :b)
(rt/insert 150 :c)
(rt/insert 50 :d)
(rt/insert 50 :e)
(rt/update 50 :d :xx))]
(t/is (= (rt/get tree 50) [:b :xx :e]))))
(t/testing "Try to update non-existing element"
(let [tree (-> (rt/make-tree)
(rt/insert 100 :a)
(rt/insert 50 :b)
(rt/insert 150 :c)
(rt/insert 50 :d)
(rt/insert 50 :e)
(rt/update 50 :zz :xx))]
(t/is (= (rt/get tree 50) [:b :d :e])))))
(t/deftest test-range-query
(t/testing "Creates a tree and test different range queries"
(let [tree (-> (rt/make-tree)
(rt/insert 0 :a)
(rt/insert 25 :b)
(rt/insert 50 :c)
(rt/insert 75 :d)
(rt/insert 100 :e)
(rt/insert 100 :f)
(rt/insert 125 :g)
(rt/insert 150 :h)
(rt/insert 175 :i)
(rt/insert 200 :j)
(rt/insert 200 :k))]
(t/is (= (rt/range-query tree 0 200)
[[0 [:a]]
[25 [:b]]
[50 [:c]]
[75 [:d]]
[100 [:e :f]]
[125 [:g]]
[150 [:h]]
[175 [:i]]
[200 [:j :k]]]))
(t/is (= (rt/range-query tree 0 100)
[[0 [:a]]
[25 [:b]]
[50 [:c]]
[75 [:d]]
[100 [:e :f]]]))
(t/is (= (rt/range-query tree 100 200)
[[100 [:e :f]]
[125 [:g]]
[150 [:h]]
[175 [:i]]
[200 [:j :k]]]))
(t/is (= (rt/range-query tree 10 60)
[[25 [:b]]
[50 [:c]]]))
(t/is (= (rt/range-query tree 199.5 200.5)
[[200 [:j :k]]]))))
(t/testing "Empty range query"
(let [tree (-> (rt/make-tree)
(rt/insert 100 :a)
(rt/insert 50 :b)
(rt/insert 150 :c)
(rt/insert 25 :d)
(rt/insert 75 :e)
(rt/insert 125 :f)
(rt/insert 175 :g))]
(t/is (= (rt/range-query tree -100 0) []))
(t/is (= (rt/range-query tree 200 300) []))
(t/is (= (rt/range-query tree 200 0) []))))
(t/testing "Range query over null should return empty"
(t/is (= (rt/range-query nil 0 100) []))))
(t/deftest test-balanced-tree
(t/testing "Creates a worst-case BST and probes for a balanced height"
(let [size 1024
tree (reduce #(rt/insert %1 %2 :x) (rt/make-tree) (range 0 (dec size)))
height (rt/height tree)]
(t/is (= height (inc (js/Math.log2 size)))))))
(t/deftest test-to-string
(t/testing "Creates a tree and prints it"
(let [tree (-> (rt/make-tree)
(rt/insert 50 :a)
(rt/insert 25 :b)
(rt/insert 25 :c)
(rt/insert 100 :d)
(rt/insert 75 :e))
result (str tree)]
(t/is (= result "25: [:b, :c], 50: [:a], 75: [:e], 100: [:d]")))))