@@ -684,385 +684,4 @@ pub fn render_opts<'a, N, E, G, W>(g: &'a G,
684
684
}
685
685
686
686
#[ 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