;; lib/relations/tests/comp.sx — extension: weakly-connected components. (define relations-cp-pass 0) (define relations-cp-fail 0) (define relations-cp-failures (list)) (define relations-cp-check! (fn (name got expected) (if (= got expected) (set! relations-cp-pass (+ relations-cp-pass 1)) (do (set! relations-cp-fail (+ relations-cp-fail 1)) (append! relations-cp-failures (str name "\n expected: " expected "\n got: " got)))))) (define relations-cp-subset? (fn (xs ys) (cond ((= (len xs) 0) true) ((relations-member? (first xs) ys) (relations-cp-subset? (rest xs) ys)) (else false)))) (define relations-cp-set=? (fn (xs ys) (and (= (len xs) (len ys)) (relations-cp-subset? xs ys) (relations-cp-subset? ys xs)))) ;; Does `comps` (a list of node-lists) contain a component set-equal to `want`? (define relations-cp-has-comp? (fn (comps want) (cond ((= (len comps) 0) false) ((relations-cp-set=? (first comps) want) true) (else (relations-cp-has-comp? (rest comps) want))))) ;; Three parent components + a separate member graph. ;; parent: a->b, b->c ; x->y ; z->z (self-loop, its own component) ;; member: m->n (define relations-cp-fixture (fn () (relations-build-db (list (relations-rel (quote a) (quote b) (quote parent)) (relations-rel (quote b) (quote c) (quote parent)) (relations-rel (quote x) (quote y) (quote parent)) (relations-rel (quote z) (quote z) (quote parent)) (relations-rel (quote m) (quote n) (quote member)))))) (define relations-cp-run-all! (fn () (let ((db (relations-cp-fixture))) (do (relations-cp-check! "component of a" (relations-cp-set=? (relations-component db (quote a) (quote parent)) (list (quote a) (quote b) (quote c))) true) (relations-cp-check! "component of c (same as a, undirected)" (relations-cp-set=? (relations-component db (quote c) (quote parent)) (list (quote a) (quote b) (quote c))) true) (relations-cp-check! "self-loop node is its own component" (relations-cp-set=? (relations-component db (quote z) (quote parent)) (list (quote z))) true) (relations-cp-check! "three parent components" (relations-component-count db (quote parent)) 3) (relations-cp-check! "one member component" (relations-component-count db (quote member)) 1) (let ((comps (relations-components db (quote parent)))) (do (relations-cp-check! "partition includes a-b-c" (relations-cp-has-comp? comps (list (quote a) (quote b) (quote c))) true) (relations-cp-check! "partition includes x-y" (relations-cp-has-comp? comps (list (quote x) (quote y))) true) (relations-cp-check! "partition includes z" (relations-cp-has-comp? comps (list (quote z))) true))) (relations-cp-check! "kind isolation: member component count is 1" (relations-component-count db (quote member)) 1) (do (relations/load! (list (relations-rel (quote p) (quote q) (quote parent)) (relations-rel (quote r) (quote s) (quote parent)))) (relations-cp-check! "api component" (relations-cp-set=? (relations/component (quote p) (quote parent)) (list (quote p) (quote q))) true) (relations-cp-check! "api component-count" (relations/component-count (quote parent)) 2) (relations/load! (list))))))) (define relations-comp-tests-run! (fn () (do (set! relations-cp-pass 0) (set! relations-cp-fail 0) (set! relations-cp-failures (list)) (relations-cp-run-all!) {:failures relations-cp-failures :total (+ relations-cp-pass relations-cp-fail) :passed relations-cp-pass :failed relations-cp-fail})))