;; 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]")))))