USING: accessors arrays assocs combinators.short-circuit continuations formatting graphviz graphviz.attributes graphviz.dot graphviz.notation graphviz.render graphviz.render.private images.loader.private io.directories io.directories.hierarchy io.files io.files.unique io.launcher io.pathnames kernel locals make math math.combinatorics math.parser memoize namespaces sequences sequences.extras sets splitting system tools.test ; FROM: namespaces => set ; IN: graphviz.tests ! XXX hack : force-error-message ( flag -- elts ) [ [ default-graphviz-program , , "?" , ] { } make try-output-process ! To balance the stack height, have to return a default ! 'elts' value, though it shouldn't ever get pushed: f ] [ nip output>> "Use one of: " split1 nip "\n" ?tail drop " " split ] recover ; ! http://www.graphviz.org/Download_macos.php#comment-474 : remove-sfdp-in-case-homebrew-is-dumb ( seq -- seq' ) os macosx? [ "sfdp" swap remove ] when ; SYMBOLS: supported-layouts supported-formats ; : init-supported-layouts/formats ( -- ) "-K" force-error-message standard-layouts intersect remove-sfdp-in-case-homebrew-is-dumb supported-layouts set-global "-T" force-error-message standard-formats intersect supported-formats set-global ; ! Can't use cleanup-unique-working-directory without fixing ! issue #890, so skip the cleanup on Windows. :: cleanup-unique-working-directory* ( quot -- ) unique-directory :> path path [ path quot with-temporary-directory ] with-directory os windows? [ path delete-tree ] unless ; inline ! Can't predict file extension since we use Graphviz's actual ! -O flag, so just look to see that there seems to be some sort ! of output. : graphviz-output-appears-to-exist? ( base -- ? ) current-directory get directory-files [ swap head? ] with count 1 = ; : next! ( seq -- elt ) [ first ] [ 1 rotate! ] bi ; :: smoke-test ( graph -- pass? ) supported-formats get-global next! :> -T supported-layouts get-global next! :> -K [ graph "smoke-test" -T -K graphviz "smoke-test" graphviz-output-appears-to-exist? ] cleanup-unique-working-directory* ; : preview-smoke-test ( graph -- pass? ) f "pass?" [ [ exists? "pass?" set ] with-preview "pass?" get ] with-variable ; : K_n ( n -- graph ) node[ "point" =shape ]; graph[ "t" =labelloc "circo" =layout ]; over number>string "K " prepend =label swap iota 2 [ first2 add-edge ] each-combination ; :: partite-set ( n color -- cluster ) color color =color node[ color =color ]; n iota [ number>string color prepend add-node ] each ; :: K_n,m ( n m -- graph ) node[ "point" =shape ]; graph[ "t" =labelloc "dot" =layout "LR" =rankdir ]; n "#FF0000" partite-set m "#0000FF" partite-set add-edge n m "K %d,%d" sprintf =label ; : add-cycle ( graph n -- graph' ) [ iota add-path ] [ 1 - 0 add-edge ] bi ; : C_n ( n -- graph ) graph[ "t" =labelloc "circo" =layout ]; node[ "point" =shape ]; over number>string "C " prepend =label swap add-cycle ; : W_n ( n -- graph ) graph[ "t" =labelloc "twopi" =layout ]; node[ "point" =shape ]; over number>string "W " prepend =label over add-node over 1 - add-cycle swap [ ] [ 1 - iota >array ] bi add-edge ; : cluster-example ( -- graph ) "dot" =layout 0 "filled" =style "lightgrey" =color node[ "filled" =style "white" =color ]; { "a0" "a1" "a2" "a3" } ~-> "process #1" =label add 1 node[ "filled" =style ]; { "b0" "b1" "b2" "b3" } ~-> "process #2" =label "blue" =color add "start" "a0" -> "start" "b0" -> "a1" "b3" -> "b2" "a3" -> "a3" "a0" -> "a3" "end" -> "b3" "end" -> "start" add-node[ "Mdiamond" =shape ]; "end" add-node[ "Msquare" =shape ]; ; : colored-circle ( i -- node ) [ ] keep [ 16.0 / 0.5 + =width ] [ 16.0 / 0.5 + =height ] [ 16 * "#%2x0000" sprintf =fillcolor ] tri ; : colored-circles-example ( -- graph ) graph[ "3,3" =size "circo" =layout ]; node[ "filled" =style "circle" =shape "true" =fixedsize "" =label ]; edge[ "invis" =style ]; 0 add-node[ "invis" =style "none" =shape ]; 16 iota [ [ 0 -- ] [ colored-circle add ] bi ] each ; : dfa-example ( -- graph ) "LR" =rankdir "8,5" =size node[ "doublecircle" =shape ]; { "LR_0" "LR_3" "LR_4" "LR_8" } add-nodes node[ "circle" =shape ]; "LR_0" "LR_2" ->[ "SS(B)" =label ]; "LR_0" "LR_1" ->[ "SS(S)" =label ]; "LR_1" "LR_3" ->[ "S($end)" =label ]; "LR_2" "LR_6" ->[ "SS(b)" =label ]; "LR_2" "LR_5" ->[ "SS(a)" =label ]; "LR_2" "LR_4" ->[ "S(A)" =label ]; "LR_5" "LR_7" ->[ "S(b)" =label ]; "LR_5" "LR_5" ->[ "S(a)" =label ]; "LR_6" "LR_6" ->[ "S(b)" =label ]; "LR_6" "LR_5" ->[ "S(a)" =label ]; "LR_7" "LR_8" ->[ "S(b)" =label ]; "LR_7" "LR_5" ->[ "S(a)" =label ]; "LR_8" "LR_6" ->[ "S(b)" =label ]; "LR_8" "LR_5" ->[ "S(a)" =label ]; ; : record-example ( -- graph ) graph[ "LR" =rankdir "8,8" =size ]; node[ 8 =fontsize "record" =shape ]; "node0" add-node[ " 0x10ba8| " =label ]; "node1" add-node[ " 0xf7fc4380| | |-1" =label ]; "node2" add-node[ " 0xf7fc44b8| | |2" =label ]; "node3" add-node[ " 3.43322790286038071e-06|44.79998779296875|0" =label ]; "node4" add-node[ " 0xf7fc4380| | |2" =label ]; "node5" add-node[ " (nil)| | |-1" =label ]; "node6" add-node[ " 0xf7fc4380| | |1" =label ]; "node7" add-node[ " 0xf7fc4380| | |2" =label ]; "node8" add-node[ " (nil)| | |-1" =label ]; "node9" add-node[ " (nil)| | |-1" =label ]; "node10" add-node[ " (nil)| | |-1" =label ]; "node11" add-node[ " (nil)| | |-1" =label ]; "node12" add-node[ " 0xf7fc43e0| | |1" =label ]; "node0" "node1" ->[ "f0" =tailport "f0" =headport ]; "node0" "node2" ->[ "f1" =tailport "f0" =headport ]; "node1" "node3" ->[ "f0" =tailport "f0" =headport ]; "node1" "node4" ->[ "f1" =tailport "f0" =headport ]; "node1" "node5" ->[ "f2" =tailport "f0" =headport ]; "node4" "node3" ->[ "f0" =tailport "f0" =headport ]; "node4" "node6" ->[ "f1" =tailport "f0" =headport ]; "node4" "node10" ->[ "f2" =tailport "f0" =headport ]; "node6" "node3" ->[ "f0" =tailport "f0" =headport ]; "node6" "node7" ->[ "f1" =tailport "f0" =headport ]; "node6" "node9" ->[ "f2" =tailport "f0" =headport ]; "node7" "node3" ->[ "f0" =tailport "f0" =headport ]; "node7" "node1" ->[ "f1" =tailport "f0" =headport ]; "node7" "node8" ->[ "f2" =tailport "f0" =headport ]; "node10" "node11" ->[ "f1" =tailport "f0" =headport ]; "node10" "node12" ->[ "f2" =tailport "f0" =headport ]; "node11" "node1" ->[ "f2" =tailport "f0" =headport ]; ; :: with-global-value ( value variable quot -- ) variable get-global "orig" [ [ value variable set-global quot call ] [ "orig" get variable set-global ] [ ] cleanup ] with-variable ; inline : preview-format-test ( format -- pass? ) preview-format [ preview-smoke-test ] with-global-value ; : valid-preview-formats ( -- formats ) types get keys "jpe" suffix supported-formats get-global intersect ; : encoding-test ( encoding -- pass? ) graph-encoding [ smoke-test ] with-global-value ; default-graphviz-program [ init-supported-layouts/formats { t } [ 5 K_n smoke-test ] unit-test { t } [ 6 K_n smoke-test ] unit-test { t } [ 7 K_n smoke-test ] unit-test { t } [ 8 K_n preview-smoke-test ] unit-test { t } [ 8 6 K_n,m smoke-test ] unit-test { t } [ 7 5 K_n,m smoke-test ] unit-test { t } [ 3 9 K_n,m smoke-test ] unit-test { t } [ 3 4 K_n,m preview-smoke-test ] unit-test { t } [ 5 C_n smoke-test ] unit-test { t } [ 6 C_n smoke-test ] unit-test { t } [ 7 C_n smoke-test ] unit-test { t } [ 8 C_n preview-smoke-test ] unit-test { t } [ 5 W_n smoke-test ] unit-test { t } [ 6 W_n smoke-test ] unit-test { t } [ 7 W_n smoke-test ] unit-test { t } [ 8 W_n preview-smoke-test ] unit-test { t } [ cluster-example smoke-test ] unit-test { t } [ cluster-example preview-smoke-test ] unit-test { t } [ colored-circles-example smoke-test ] unit-test { t } [ colored-circles-example preview-smoke-test ] unit-test { t } [ dfa-example smoke-test ] unit-test { t } [ dfa-example preview-smoke-test ] unit-test { t } [ record-example smoke-test ] unit-test { t } [ record-example preview-smoke-test ] unit-test { t } [ valid-preview-formats [ preview-format-test ] all? ] unit-test [ supported-formats get-global valid-preview-formats diff [ preview-format-test ] attempt-all ] [ unsupported-preview-format? ] must-fail-with { t } [ USE: io.encodings.8-bit.latin1 latin1 encoding-test ] unit-test { t } [ USE: io.encodings.utf8 utf8 encoding-test ] unit-test [ USE: io.encodings.ascii ascii encoding-test ] [ unsupported-encoding? ] must-fail-with ] when