Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 23s
Cycle-safe DFS in explain.sx, complements shortest-path relations-path. 135/135. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
131 lines
4.3 KiB
Plaintext
131 lines
4.3 KiB
Plaintext
;; lib/relations/tests/routes.sx — extension: all simple paths (route enumeration).
|
|
|
|
(define relations-ro-pass 0)
|
|
(define relations-ro-fail 0)
|
|
(define relations-ro-failures (list))
|
|
|
|
(define
|
|
relations-ro-check!
|
|
(fn
|
|
(name got expected)
|
|
(if
|
|
(= got expected)
|
|
(set! relations-ro-pass (+ relations-ro-pass 1))
|
|
(do
|
|
(set! relations-ro-fail (+ relations-ro-fail 1))
|
|
(append!
|
|
relations-ro-failures
|
|
(str name "\n expected: " expected "\n got: " got))))))
|
|
|
|
(define
|
|
relations-ro-subset?
|
|
(fn
|
|
(xs ys)
|
|
(cond
|
|
((= (len xs) 0) true)
|
|
((relations-member? (first xs) ys)
|
|
(relations-ro-subset? (rest xs) ys))
|
|
(else false))))
|
|
|
|
;; Order-insensitive set equality; elements compared structurally (works for
|
|
;; lists-of-paths since `=` is structural).
|
|
(define
|
|
relations-ro-set=?
|
|
(fn
|
|
(xs ys)
|
|
(and
|
|
(= (len xs) (len ys))
|
|
(relations-ro-subset? xs ys)
|
|
(relations-ro-subset? ys xs))))
|
|
|
|
;; Diamond + branch + a cycle with an exit.
|
|
;; parent: a->b, a->c, b->d, c->d, b->e
|
|
;; member: a->z (a different kind, to test isolation)
|
|
;; parent cycle: g->h, h->g, h->out
|
|
(define
|
|
relations-ro-fixture
|
|
(fn
|
|
()
|
|
(relations-build-db
|
|
(list
|
|
(relations-rel (quote a) (quote b) (quote parent))
|
|
(relations-rel (quote a) (quote c) (quote parent))
|
|
(relations-rel (quote b) (quote d) (quote parent))
|
|
(relations-rel (quote c) (quote d) (quote parent))
|
|
(relations-rel (quote b) (quote e) (quote parent))
|
|
(relations-rel (quote a) (quote z) (quote member))
|
|
(relations-rel (quote g) (quote h) (quote parent))
|
|
(relations-rel (quote h) (quote g) (quote parent))
|
|
(relations-rel (quote h) (quote out) (quote parent))))))
|
|
|
|
(define
|
|
relations-ro-run-all!
|
|
(fn
|
|
()
|
|
(let
|
|
((db (relations-ro-fixture)))
|
|
(do
|
|
(relations-ro-check!
|
|
"two routes a->d"
|
|
(relations-ro-set=?
|
|
(relations-all-paths db (quote a) (quote d) (quote parent))
|
|
(list
|
|
(list (quote a) (quote b) (quote d))
|
|
(list (quote a) (quote c) (quote d))))
|
|
true)
|
|
(relations-ro-check!
|
|
"single route a->e"
|
|
(relations-all-paths db (quote a) (quote e) (quote parent))
|
|
(list (list (quote a) (quote b) (quote e))))
|
|
(relations-ro-check!
|
|
"no route -> empty"
|
|
(relations-all-paths db (quote a) (quote zzz) (quote parent))
|
|
(list))
|
|
(relations-ro-check!
|
|
"self route is the singleton path"
|
|
(relations-all-paths db (quote a) (quote a) (quote parent))
|
|
(list (list (quote a))))
|
|
(relations-ro-check!
|
|
"route through a cycle terminates"
|
|
(relations-all-paths db (quote g) (quote out) (quote parent))
|
|
(list (list (quote g) (quote h) (quote out))))
|
|
(relations-ro-check!
|
|
"route count a->d is 2"
|
|
(len (relations-all-paths db (quote a) (quote d) (quote parent)))
|
|
2)
|
|
(relations-ro-check!
|
|
"kind isolation: no parent route to member target"
|
|
(relations-all-paths db (quote a) (quote z) (quote parent))
|
|
(list))
|
|
(relations-ro-check!
|
|
"member route a->z"
|
|
(relations-all-paths db (quote a) (quote z) (quote member))
|
|
(list (list (quote a) (quote z))))
|
|
(do
|
|
(relations/load!
|
|
(list
|
|
(relations-rel (quote p) (quote q) (quote parent))
|
|
(relations-rel (quote p) (quote r) (quote parent))
|
|
(relations-rel (quote q) (quote s) (quote parent))
|
|
(relations-rel (quote r) (quote s) (quote parent))))
|
|
(relations-ro-check!
|
|
"api all-paths two routes p->s"
|
|
(relations-ro-set=?
|
|
(relations/all-paths (quote p) (quote s) (quote parent))
|
|
(list
|
|
(list (quote p) (quote q) (quote s))
|
|
(list (quote p) (quote r) (quote s))))
|
|
true)
|
|
(relations/load! (list)))))))
|
|
|
|
(define
|
|
relations-routes-tests-run!
|
|
(fn
|
|
()
|
|
(do
|
|
(set! relations-ro-pass 0)
|
|
(set! relations-ro-fail 0)
|
|
(set! relations-ro-failures (list))
|
|
(relations-ro-run-all!)
|
|
{:failures relations-ro-failures :total (+ relations-ro-pass relations-ro-fail) :passed relations-ro-pass :failed relations-ro-fail})))
|