babashka/test-resources/lib_tests/loom/test/graph.cljc

207 lines
8.6 KiB
Clojure

(ns loom.test.graph
(:require [loom.graph :refer (graph digraph weighted-graph weighted-digraph
nodes edges has-node? has-edge? transpose fly-graph
weight graph? Graph directed? Digraph weighted?
WeightedGraph subgraph add-path add-cycle)]
[loom.attr :as attr]
#?@(:clj [[clojure.test :refer (deftest testing are is)]])
[loom.test.compliance-tester :refer [graph-test digraph-test
weighted-graph-test weighted-digraph-test]])
#?@(:cljs [(:require-macros [cljs.test :refer (deftest testing are is)])]))
(deftest test-default-implementations
(graph-test (graph))
(digraph-test (digraph))
(weighted-graph-test (weighted-graph))
(weighted-digraph-test (weighted-digraph)))
(deftest build-graph-test
(let [g1 (graph [1 2] [1 3] [2 3] 4)
g2 (graph {1 [2 3] 2 [3] 4 []})
g3 (graph g1)
g4 (graph g3 (digraph [5 6]) [7 8] 9)
g5 (graph)]
(testing "Construction, nodes, edges"
(are [expected got] (= expected got)
#{1 2 3 4} (set (nodes g1))
#{[1 2] [2 1] [1 3] [3 1] [2 3] [3 2]} (set (edges g1))
(set (nodes g2)) (set (nodes g1))
(set (edges g2)) (set (edges g1))
(set (nodes g3)) (set (nodes g1))
(set (nodes g3)) (set (nodes g1))
#{1 2 3 4 5 6 7 8 9} (set (nodes g4))
#{[1 2] [2 1] [1 3] [3 1] [2 3]
[3 2] [5 6] [6 5] [7 8] [8 7]} (set (edges g4))
#{} (set (nodes g5))
#{} (set (edges g5))
true (has-node? g1 4)
true (has-edge? g1 1 2)
false (has-node? g1 5)
false (has-edge? g1 4 1)))))
(deftest simple-graph-test
(let [g1 (graph [1 2] [1 3] [2 3] 4)
g2 (graph {1 [2 3] 2 [3] 4 []})
g3 (graph g1)
g4 (graph g3 (digraph [5 6]) [7 8] 9)
g5 (graph)]
(testing "Construction, nodes, edges"
(are [expected got] (= expected got)
#{1 2 3 4} (set (nodes g1))
#{[1 2] [2 1] [1 3] [3 1] [2 3] [3 2]} (set (edges g1))
(set (nodes g2)) (set (nodes g1))
(set (edges g2)) (set (edges g1))
(set (nodes g3)) (set (nodes g1))
(set (nodes g3)) (set (nodes g1))
#{1 2 3 4 5 6 7 8 9} (set (nodes g4))
#{[1 2] [2 1] [1 3] [3 1] [2 3]
[3 2] [5 6] [6 5] [7 8] [8 7]} (set (edges g4))
#{} (set (nodes g5))
#{} (set (edges g5))
true (has-node? g1 4)
true (has-edge? g1 1 2)
false (has-node? g1 5)
false (has-edge? g1 4 1)))))
(deftest simple-digraph-test
(let [g1 (digraph [1 2] [1 3] [2 3] 4)
g2 (digraph {1 [2 3] 2 [3] 4 []})
g3 (digraph g1)
g4 (digraph g3 (graph [5 6]) [7 8] 9)
g5 (digraph)
g6 (transpose g1)]
(testing "Construction, nodes, edges"
(are [expected got] (= expected got)
#{1 2 3 4} (set (nodes g1))
#{1 2 3 4} (set (nodes g6))
#{[1 2] [1 3] [2 3]} (set (edges g1))
#{[2 1] [3 1] [3 2]} (set (edges g6))
(set (nodes g2)) (set (nodes g1))
(set (edges g2)) (set (edges g1))
(set (nodes g3)) (set (nodes g1))
(set (nodes g3)) (set (nodes g1))
#{1 2 3 4 5 6 7 8 9} (set (nodes g4))
#{[1 2] [1 3] [2 3] [5 6] [6 5] [7 8]} (set (edges g4))
#{} (set (nodes g5))
#{} (set (edges g5))
true (has-node? g1 4)
true (has-edge? g1 1 2)
false (has-node? g1 5)
false (has-edge? g1 2 1)))))
(deftest simple-weighted-graph-test
(let [g1 (weighted-graph [1 2 77] [1 3 88] [2 3 99] 4)
g2 (weighted-graph {1 {2 77 3 88} 2 {3 99} 4 []})
g3 (weighted-graph g1)
g4 (weighted-graph g3 (weighted-digraph [5 6 88]) [7 8] 9)
g5 (weighted-graph)]
(testing "Construction, nodes, edges"
(are [expected got] (= expected got)
#{1 2 3 4} (set (nodes g1))
#{[1 2] [2 1] [1 3] [3 1] [2 3] [3 2]} (set (edges g1))
(set (nodes g2)) (set (nodes g1))
(set (edges g2)) (set (edges g1))
(set (nodes g3)) (set (nodes g1))
(set (nodes g3)) (set (nodes g1))
#{1 2 3 4 5 6 7 8 9} (set (nodes g4))
#{[1 2] [2 1] [1 3] [3 1] [2 3]
[3 2] [5 6] [6 5] [7 8] [8 7]} (set (edges g4))
#{} (set (nodes g5))
#{} (set (edges g5))
true (has-node? g1 4)
true (has-edge? g1 1 2)
false (has-node? g1 5)
false (has-edge? g1 4 1)))))
(deftest simple-weighted-digraph-test
(let [g1 (weighted-digraph [1 2 77] [1 3 88] [2 3 99] 4)
g2 (weighted-digraph {1 {2 77 3 88} 2 {3 99} 4 []})
g3 (weighted-digraph g1)
g4 (weighted-digraph g3 (weighted-graph [5 6 88]) [7 8] 9)
g5 (weighted-digraph)
g6 (transpose g1)]
(testing "Construction, nodes, edges"
(are [expected got] (= expected got)
#{1 2 3 4} (set (nodes g1))
#{1 2 3 4} (set (nodes g6))
#{[1 2] [1 3] [2 3]} (set (edges g1))
#{[2 1] [3 1] [3 2]} (set (edges g6))
(set (nodes g2)) (set (nodes g1))
(set (edges g2)) (set (edges g1))
(set (nodes g3)) (set (nodes g1))
(set (nodes g3)) (set (nodes g1))
#{1 2 3 4 5 6 7 8 9} (set (nodes g4))
#{[1 2] [1 3] [2 3] [5 6] [6 5] [7 8]} (set (edges g4))
#{} (set (nodes g5))
#{} (set (edges g5))
true (has-node? g1 4)
true (has-edge? g1 1 2)
false (has-node? g1 5)
false (has-edge? g1 2 1)))))
(deftest fly-graph-test
(let [fg1 (fly-graph :nodes [1 2 3]
:successors #(if (= 3 %) [1] [(inc %)])
:weight (constantly 88))
fg2 (fly-graph :successors #(if (= 3 %) [1] [(inc %)])
:start 1)]
(testing "Construction, nodes, edges"
(are [expected got] (= expected got)
#{1 2 3} (set (nodes fg1))
#{1 2 3} (set (nodes fg2))
#{[1 2] [2 3] [3 1]} (set (edges fg1))
#{[1 2] [2 3] [3 1]} (set (edges fg2))
88 (weight fg1 1 2)))
(testing "Predicates"
(are [expected got] (= expected got)
1 (has-node? fg1 1)
nil (has-node? fg1 11)
2 (has-node? fg2 2)
nil (has-node? fg2 11)))
;; TODO: finish
))
(deftest merge-graph-test
(testing "two graphs with attributes"
(let [g1 (attr/add-attr (digraph [1 2] 3 [1 4]) 1 :label "One")
g2 (attr/add-attr (digraph [1 3] [3 5]) 5 :label "Five")
merged (digraph g1 g2)]
(is (= "One" (attr/attr merged 1 :label)))
(is (= "Five" (attr/attr merged 5 :label)))))
(testing "with two weighted graphs"
(let [g1 (attr/add-attr (weighted-graph [1 2] 3 [1 4]) 1 :label "One")
g2 (attr/add-attr (weighted-graph [1 3] [3 5]) 5 :label "Five")
merged (weighted-graph g1 g2)]
(is (= "One" (attr/attr merged 1 :label)))
(is (= "Five" (attr/attr merged 5 :label))))))
(deftest utilities-test
(testing "Predicates"
(are [expected got] (= expected got)
true (every? true? (map graph? [(graph [1 2])
(digraph [1 2])
(weighted-graph [1 2])
(weighted-digraph [1 2])
(fly-graph :successors [1 2])
(reify Graph)]))
true (every? true? (map directed? [(digraph [1 2])
(weighted-digraph [1 2])
(fly-graph :predecessors [1 2])
(reify Digraph)]))
true (every? true? (map weighted? [(weighted-graph [1 2])
(weighted-digraph [1 2])
(fly-graph :weight (constantly 1))
(reify WeightedGraph)]))))
(testing "Adders"
(let [g (weighted-digraph [1 2] [2 3] [3 1])
sg (subgraph g [1 2])
pg (add-path (digraph) 1 2 3 4 5)
cg (add-cycle (digraph) 1 2 3)]
(are [expected got] (= expected got)
#{1 2} (set (nodes sg))
#{[1 2]} (set (edges sg))
true (graph? sg)
true (directed? sg)
true (weighted? sg)
#{[1 2] [2 3] [3 4] [4 5]} (set (edges pg))
#{[1 2] [2 3] [3 1]} (set (edges cg))))))