207 lines
8.6 KiB
Clojure
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))))))
|