61 lines
1.5 KiB
Python
61 lines
1.5 KiB
Python
import sys
|
|
sys.path.insert(0, "/root/.hermes/wizard-outputs/beam")
|
|
from topo_sort import topo_sort
|
|
|
|
def check(order, edges):
|
|
pos = {n:i for i,n in enumerate(order)}
|
|
for u,v in edges:
|
|
assert pos[u] < pos[v], (u,v,order)
|
|
|
|
# DAG basic
|
|
order, cyc = topo_sort([1,2,3], [(1,2),(2,3)])
|
|
assert cyc is None and order == [1,2,3], (order,cyc)
|
|
check(order, [(1,2),(2,3)])
|
|
|
|
# disconnected
|
|
order, cyc = topo_sort([1,2,3,4], [(1,2)])
|
|
assert cyc is None and set(order)=={1,2,3,4}
|
|
check(order, [(1,2)])
|
|
|
|
# deterministic tie-break
|
|
order, cyc = topo_sort(["b","a","c"], [])
|
|
assert order == ["a","b","c"], order
|
|
|
|
# duplicate edges deduped
|
|
order, cyc = topo_sort([1,2], [(1,2),(1,2)])
|
|
assert cyc is None and order==[1,2]
|
|
|
|
# cycle
|
|
order, cyc = topo_sort([1,2,3], [(1,2),(2,3),(3,1)])
|
|
assert cyc is not None
|
|
# verify it's a cycle
|
|
s = set(cyc)
|
|
assert len(cyc) == len(s)+1 or len(cyc)==len(s), cyc # cycle list may include repeat? ours no repeat of first? we built v..u no repeat
|
|
# check edges close
|
|
edgeset = {(1,2),(2,3),(3,1)}
|
|
# cycle consecutive
|
|
for i in range(len(cyc)):
|
|
a=cyc[i]; b=cyc[(i+1)%len(cyc)]
|
|
assert (a,b) in edgeset, (a,b)
|
|
print("cycle:", cyc)
|
|
|
|
# self loop
|
|
order, cyc = topo_sort([1], [(1,1)])
|
|
assert cyc == [1], cyc
|
|
|
|
# unknown node raises
|
|
try:
|
|
topo_sort([1], [(1,2)])
|
|
raise SystemExit("expected ValueError")
|
|
except ValueError:
|
|
pass
|
|
|
|
# duplicate node raises
|
|
try:
|
|
topo_sort([1,1], [])
|
|
raise SystemExit("expected ValueError")
|
|
except ValueError:
|
|
pass
|
|
|
|
print("ALL TESTS PASSED")
|