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")