@@ -684,385 +684,4 @@ pub fn render_opts<'a, N, E, G, W>(g: &'a G,
684684}
685685
686686#[ cfg( test) ]
687- mod tests {
688- use NodeLabels :: * ;
689- use super :: { Id , Labeller , Nodes , Edges , GraphWalk , render, Style } ;
690- use super :: LabelText :: { self , LabelStr , EscStr , HtmlStr } ;
691- use std:: io;
692- use std:: io:: prelude:: * ;
693-
694- /// each node is an index in a vector in the graph.
695- type Node = usize ;
696- struct Edge {
697- from : usize ,
698- to : usize ,
699- label : & ' static str ,
700- style : Style ,
701- }
702-
703- fn edge ( from : usize , to : usize , label : & ' static str , style : Style ) -> Edge {
704- Edge {
705- from,
706- to,
707- label,
708- style,
709- }
710- }
711-
712- struct LabelledGraph {
713- /// The name for this graph. Used for labeling generated `digraph`.
714- name : & ' static str ,
715-
716- /// Each node is an index into `node_labels`; these labels are
717- /// used as the label text for each node. (The node *names*,
718- /// which are unique identifiers, are derived from their index
719- /// in this array.)
720- ///
721- /// If a node maps to None here, then just use its name as its
722- /// text.
723- node_labels : Vec < Option < & ' static str > > ,
724-
725- node_styles : Vec < Style > ,
726-
727- /// Each edge relates a from-index to a to-index along with a
728- /// label; `edges` collects them.
729- edges : Vec < Edge > ,
730- }
731-
732- // A simple wrapper around LabelledGraph that forces the labels to
733- // be emitted as EscStr.
734- struct LabelledGraphWithEscStrs {
735- graph : LabelledGraph ,
736- }
737-
738- enum NodeLabels < L > {
739- AllNodesLabelled ( Vec < L > ) ,
740- UnlabelledNodes ( usize ) ,
741- SomeNodesLabelled ( Vec < Option < L > > ) ,
742- }
743-
744- type Trivial = NodeLabels < & ' static str > ;
745-
746- impl NodeLabels < & ' static str > {
747- fn to_opt_strs ( self ) -> Vec < Option < & ' static str > > {
748- match self {
749- UnlabelledNodes ( len) => vec ! [ None ; len] ,
750- AllNodesLabelled ( lbls) => lbls. into_iter ( ) . map ( |l| Some ( l) ) . collect ( ) ,
751- SomeNodesLabelled ( lbls) => lbls. into_iter ( ) . collect ( ) ,
752- }
753- }
754-
755- fn len ( & self ) -> usize {
756- match self {
757- & UnlabelledNodes ( len) => len,
758- & AllNodesLabelled ( ref lbls) => lbls. len ( ) ,
759- & SomeNodesLabelled ( ref lbls) => lbls. len ( ) ,
760- }
761- }
762- }
763-
764- impl LabelledGraph {
765- fn new ( name : & ' static str ,
766- node_labels : Trivial ,
767- edges : Vec < Edge > ,
768- node_styles : Option < Vec < Style > > )
769- -> LabelledGraph {
770- let count = node_labels. len ( ) ;
771- LabelledGraph {
772- name,
773- node_labels : node_labels. to_opt_strs ( ) ,
774- edges,
775- node_styles : match node_styles {
776- Some ( nodes) => nodes,
777- None => vec ! [ Style :: None ; count] ,
778- } ,
779- }
780- }
781- }
782-
783- impl LabelledGraphWithEscStrs {
784- fn new ( name : & ' static str ,
785- node_labels : Trivial ,
786- edges : Vec < Edge > )
787- -> LabelledGraphWithEscStrs {
788- LabelledGraphWithEscStrs { graph : LabelledGraph :: new ( name, node_labels, edges, None ) }
789- }
790- }
791-
792- fn id_name < ' a > ( n : & Node ) -> Id < ' a > {
793- Id :: new ( format ! ( "N{}" , * n) ) . unwrap ( )
794- }
795-
796- impl < ' a > Labeller < ' a > for LabelledGraph {
797- type Node = Node ;
798- type Edge = & ' a Edge ;
799- fn graph_id ( & ' a self ) -> Id < ' a > {
800- Id :: new ( self . name ) . unwrap ( )
801- }
802- fn node_id ( & ' a self , n : & Node ) -> Id < ' a > {
803- id_name ( n)
804- }
805- fn node_label ( & ' a self , n : & Node ) -> LabelText < ' a > {
806- match self . node_labels [ * n] {
807- Some ( l) => LabelStr ( l. into ( ) ) ,
808- None => LabelStr ( id_name ( n) . name ( ) ) ,
809- }
810- }
811- fn edge_label ( & ' a self , e : & & ' a Edge ) -> LabelText < ' a > {
812- LabelStr ( e. label . into ( ) )
813- }
814- fn node_style ( & ' a self , n : & Node ) -> Style {
815- self . node_styles [ * n]
816- }
817- fn edge_style ( & ' a self , e : & & ' a Edge ) -> Style {
818- e. style
819- }
820- }
821-
822- impl < ' a > Labeller < ' a > for LabelledGraphWithEscStrs {
823- type Node = Node ;
824- type Edge = & ' a Edge ;
825- fn graph_id ( & ' a self ) -> Id < ' a > {
826- self . graph . graph_id ( )
827- }
828- fn node_id ( & ' a self , n : & Node ) -> Id < ' a > {
829- self . graph . node_id ( n)
830- }
831- fn node_label ( & ' a self , n : & Node ) -> LabelText < ' a > {
832- match self . graph . node_label ( n) {
833- LabelStr ( s) | EscStr ( s) | HtmlStr ( s) => EscStr ( s) ,
834- }
835- }
836- fn edge_label ( & ' a self , e : & & ' a Edge ) -> LabelText < ' a > {
837- match self . graph . edge_label ( e) {
838- LabelStr ( s) | EscStr ( s) | HtmlStr ( s) => EscStr ( s) ,
839- }
840- }
841- }
842-
843- impl < ' a > GraphWalk < ' a > for LabelledGraph {
844- type Node = Node ;
845- type Edge = & ' a Edge ;
846- fn nodes ( & ' a self ) -> Nodes < ' a , Node > {
847- ( 0 ..self . node_labels . len ( ) ) . collect ( )
848- }
849- fn edges ( & ' a self ) -> Edges < ' a , & ' a Edge > {
850- self . edges . iter ( ) . collect ( )
851- }
852- fn source ( & ' a self , edge : & & ' a Edge ) -> Node {
853- edge. from
854- }
855- fn target ( & ' a self , edge : & & ' a Edge ) -> Node {
856- edge. to
857- }
858- }
859-
860- impl < ' a > GraphWalk < ' a > for LabelledGraphWithEscStrs {
861- type Node = Node ;
862- type Edge = & ' a Edge ;
863- fn nodes ( & ' a self ) -> Nodes < ' a , Node > {
864- self . graph . nodes ( )
865- }
866- fn edges ( & ' a self ) -> Edges < ' a , & ' a Edge > {
867- self . graph . edges ( )
868- }
869- fn source ( & ' a self , edge : & & ' a Edge ) -> Node {
870- edge. from
871- }
872- fn target ( & ' a self , edge : & & ' a Edge ) -> Node {
873- edge. to
874- }
875- }
876-
877- fn test_input ( g : LabelledGraph ) -> io:: Result < String > {
878- let mut writer = Vec :: new ( ) ;
879- render ( & g, & mut writer) . unwrap ( ) ;
880- let mut s = String :: new ( ) ;
881- Read :: read_to_string ( & mut & * writer, & mut s) ?;
882- Ok ( s)
883- }
884-
885- // All of the tests use raw-strings as the format for the expected outputs,
886- // so that you can cut-and-paste the content into a .dot file yourself to
887- // see what the graphviz visualizer would produce.
888-
889- #[ test]
890- fn empty_graph ( ) {
891- let labels: Trivial = UnlabelledNodes ( 0 ) ;
892- let r = test_input ( LabelledGraph :: new ( "empty_graph" , labels, vec ! [ ] , None ) ) ;
893- assert_eq ! ( r. unwrap( ) ,
894- r#"digraph empty_graph {
895- }
896- "# ) ;
897- }
898-
899- #[ test]
900- fn single_node ( ) {
901- let labels: Trivial = UnlabelledNodes ( 1 ) ;
902- let r = test_input ( LabelledGraph :: new ( "single_node" , labels, vec ! [ ] , None ) ) ;
903- assert_eq ! ( r. unwrap( ) ,
904- r#"digraph single_node {
905- N0[label="N0"];
906- }
907- "# ) ;
908- }
909-
910- #[ test]
911- fn single_node_with_style ( ) {
912- let labels: Trivial = UnlabelledNodes ( 1 ) ;
913- let styles = Some ( vec ! [ Style :: Dashed ] ) ;
914- let r = test_input ( LabelledGraph :: new ( "single_node" , labels, vec ! [ ] , styles) ) ;
915- assert_eq ! ( r. unwrap( ) ,
916- r#"digraph single_node {
917- N0[label="N0"][style="dashed"];
918- }
919- "# ) ;
920- }
921-
922- #[ test]
923- fn single_edge ( ) {
924- let labels: Trivial = UnlabelledNodes ( 2 ) ;
925- let result = test_input ( LabelledGraph :: new ( "single_edge" ,
926- labels,
927- vec ! [ edge( 0 , 1 , "E" , Style :: None ) ] ,
928- None ) ) ;
929- assert_eq ! ( result. unwrap( ) ,
930- r#"digraph single_edge {
931- N0[label="N0"];
932- N1[label="N1"];
933- N0 -> N1[label="E"];
934- }
935- "# ) ;
936- }
937-
938- #[ test]
939- fn single_edge_with_style ( ) {
940- let labels: Trivial = UnlabelledNodes ( 2 ) ;
941- let result = test_input ( LabelledGraph :: new ( "single_edge" ,
942- labels,
943- vec ! [ edge( 0 , 1 , "E" , Style :: Bold ) ] ,
944- None ) ) ;
945- assert_eq ! ( result. unwrap( ) ,
946- r#"digraph single_edge {
947- N0[label="N0"];
948- N1[label="N1"];
949- N0 -> N1[label="E"][style="bold"];
950- }
951- "# ) ;
952- }
953-
954- #[ test]
955- fn test_some_labelled ( ) {
956- let labels: Trivial = SomeNodesLabelled ( vec ! [ Some ( "A" ) , None ] ) ;
957- let styles = Some ( vec ! [ Style :: None , Style :: Dotted ] ) ;
958- let result = test_input ( LabelledGraph :: new ( "test_some_labelled" ,
959- labels,
960- vec ! [ edge( 0 , 1 , "A-1" , Style :: None ) ] ,
961- styles) ) ;
962- assert_eq ! ( result. unwrap( ) ,
963- r#"digraph test_some_labelled {
964- N0[label="A"];
965- N1[label="N1"][style="dotted"];
966- N0 -> N1[label="A-1"];
967- }
968- "# ) ;
969- }
970-
971- #[ test]
972- fn single_cyclic_node ( ) {
973- let labels: Trivial = UnlabelledNodes ( 1 ) ;
974- let r = test_input ( LabelledGraph :: new ( "single_cyclic_node" ,
975- labels,
976- vec ! [ edge( 0 , 0 , "E" , Style :: None ) ] ,
977- None ) ) ;
978- assert_eq ! ( r. unwrap( ) ,
979- r#"digraph single_cyclic_node {
980- N0[label="N0"];
981- N0 -> N0[label="E"];
982- }
983- "# ) ;
984- }
985-
986- #[ test]
987- fn hasse_diagram ( ) {
988- let labels = AllNodesLabelled ( vec ! [ "{x,y}" , "{x}" , "{y}" , "{}" ] ) ;
989- let r = test_input ( LabelledGraph :: new ( "hasse_diagram" ,
990- labels,
991- vec ! [ edge( 0 , 1 , "" , Style :: None ) ,
992- edge( 0 , 2 , "" , Style :: None ) ,
993- edge( 1 , 3 , "" , Style :: None ) ,
994- edge( 2 , 3 , "" , Style :: None ) ] ,
995- None ) ) ;
996- assert_eq ! ( r. unwrap( ) ,
997- r#"digraph hasse_diagram {
998- N0[label="{x,y}"];
999- N1[label="{x}"];
1000- N2[label="{y}"];
1001- N3[label="{}"];
1002- N0 -> N1[label=""];
1003- N0 -> N2[label=""];
1004- N1 -> N3[label=""];
1005- N2 -> N3[label=""];
1006- }
1007- "# ) ;
1008- }
1009-
1010- #[ test]
1011- fn left_aligned_text ( ) {
1012- let labels = AllNodesLabelled ( vec ! [
1013- "if test {\
1014- \\ l branch1\
1015- \\ l} else {\
1016- \\ l branch2\
1017- \\ l}\
1018- \\ lafterward\
1019- \\ l",
1020- "branch1" ,
1021- "branch2" ,
1022- "afterward" ] ) ;
1023-
1024- let mut writer = Vec :: new ( ) ;
1025-
1026- let g = LabelledGraphWithEscStrs :: new ( "syntax_tree" ,
1027- labels,
1028- vec ! [ edge( 0 , 1 , "then" , Style :: None ) ,
1029- edge( 0 , 2 , "else" , Style :: None ) ,
1030- edge( 1 , 3 , ";" , Style :: None ) ,
1031- edge( 2 , 3 , ";" , Style :: None ) ] ) ;
1032-
1033- render ( & g, & mut writer) . unwrap ( ) ;
1034- let mut r = String :: new ( ) ;
1035- Read :: read_to_string ( & mut & * writer, & mut r) . unwrap ( ) ;
1036-
1037- assert_eq ! ( r,
1038- r#"digraph syntax_tree {
1039- N0[label="if test {\l branch1\l} else {\l branch2\l}\lafterward\l"];
1040- N1[label="branch1"];
1041- N2[label="branch2"];
1042- N3[label="afterward"];
1043- N0 -> N1[label="then"];
1044- N0 -> N2[label="else"];
1045- N1 -> N3[label=";"];
1046- N2 -> N3[label=";"];
1047- }
1048- "# ) ;
1049- }
1050-
1051- #[ test]
1052- fn simple_id_construction ( ) {
1053- let id1 = Id :: new ( "hello" ) ;
1054- match id1 {
1055- Ok ( _) => { }
1056- Err ( ..) => panic ! ( "'hello' is not a valid value for id anymore" ) ,
1057- }
1058- }
1059-
1060- #[ test]
1061- fn badly_formatted_id ( ) {
1062- let id2 = Id :: new ( "Weird { struct : ure } !!!" ) ;
1063- match id2 {
1064- Ok ( _) => panic ! ( "graphviz id suddenly allows spaces, brackets and stuff" ) ,
1065- Err ( ..) => { }
1066- }
1067- }
1068- }
687+ mod tests;
0 commit comments