diff options
author | seancarroll <seanc28@gmail.com> | 2021-01-20 21:51:57 -0600 |
---|---|---|
committer | seancarroll <seanc28@gmail.com> | 2021-01-20 21:51:57 -0600 |
commit | 7d5d439ed2f465120825c918f920bd9fbfd3169f (patch) | |
tree | 4545ef6d834d8bd5f6b0d3c860511d3ddc042984 /tests | |
parent | ec3468a275314f16769439736b7514b40e3b49c0 (diff) | |
download | dotavious-7d5d439ed2f465120825c918f920bd9fbfd3169f.zip |
Attribute Constraints
This adds some attribute constraints. We validate certain constraints
based on information from http://www.graphviz.org/doc/info/attrs.html.
Validation errors are collected as part of builders, we still add the
attribute regardless or not if it fails validation, and build methods
return ValidationResult<T> where errors is a Vec<ValidationError>. We
still add attributes even if the validation fails so that users can
ignore validation errors and build appropriate struct.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/dot.rs | 236 |
1 files changed, 198 insertions, 38 deletions
diff --git a/tests/dot.rs b/tests/dot.rs index 8244a52..fbfd935 100644 --- a/tests/dot.rs +++ b/tests/dot.rs @@ -23,7 +23,7 @@ fn test_input(g: Graph) -> io::Result<String> { #[test] fn empty_digraph_without_id() { - let g = GraphBuilder::new_directed(None).build(); + let g = GraphBuilder::new_directed(None).build().unwrap(); let r = test_input(g); assert_eq!( r.unwrap(), @@ -35,7 +35,7 @@ fn empty_digraph_without_id() { #[test] fn support_display() { - let g = GraphBuilder::new_directed(None).build(); + let g = GraphBuilder::new_directed(None).build().unwrap(); let dot = Dot { graph: g }; assert_eq!( @@ -50,7 +50,8 @@ fn support_display() { fn graph_comment() { let g = GraphBuilder::new_directed(None) .comment("Comment goes here") - .build(); + .build() + .unwrap(); let r = test_input(g); assert_eq!( r.unwrap(), @@ -63,7 +64,9 @@ digraph { #[test] fn empty_digraph() { - let g = GraphBuilder::new_directed(Some("empty_graph".to_string())).build(); + let g = GraphBuilder::new_directed(Some("empty_graph".to_string())) + .build() + .unwrap(); let r = test_input(g); assert_eq!( r.unwrap(), @@ -75,7 +78,9 @@ fn empty_digraph() { #[test] fn empty_undirected_graph() { - let g = GraphBuilder::new_undirected(Some("empty_graph".to_string())).build(); + let g = GraphBuilder::new_undirected(Some("empty_graph".to_string())) + .build() + .unwrap(); let r = test_input(g); assert_eq!( r.unwrap(), @@ -89,7 +94,8 @@ fn empty_undirected_graph() { fn single_node() { let g = GraphBuilder::new_directed(Some("single_node".to_string())) .add_node(Node::new("N0".to_string())) - .build(); + .build() + .unwrap(); let r = test_input(g); assert_eq!( r.unwrap(), @@ -104,11 +110,13 @@ fn single_node() { fn single_node_with_style() { let node = NodeBuilder::new("N0".to_string()) .style(NodeStyle::Dashed) - .build(); + .build() + .unwrap(); let g = GraphBuilder::new_directed(Some("single_node".to_string())) .add_node(node) - .build(); + .build() + .unwrap(); let r = test_input(g); assert_eq!( @@ -132,10 +140,10 @@ fn support_non_inline_builder() { node_builder.add_attribute("foo", AttributeText::quoted("baz")); } - let node = node_builder.build(); + let node = node_builder.build().unwrap(); g.add_node(node); - let r = test_input(g.build()); + let r = test_input(g.build().unwrap()); assert_eq!( r.unwrap(), r#"digraph single_node { @@ -149,11 +157,13 @@ fn support_non_inline_builder() { fn builder_support_shape() { let node = NodeBuilder::new("N0".to_string()) .shape(Shape::Note) - .build(); + .build() + .unwrap(); let g = GraphBuilder::new_directed(Some("node_shape".to_string())) .add_node(node) - .build(); + .build() + .unwrap(); let r = test_input(g); assert_eq!( @@ -171,7 +181,8 @@ fn single_edge() { .add_node(Node::new("N0".to_string())) .add_node(Node::new("N1".to_string())) .add_edge(Edge::new("N0".to_string(), "N1".to_string())) - .build(); + .build() + .unwrap(); let r = test_input(g); @@ -190,13 +201,15 @@ fn single_edge() { fn single_edge_with_style() { let edge = EdgeBuilder::new("N0".to_string(), "N1".to_string()) .style(EdgeStyle::Bold) - .build(); + .build() + .unwrap(); let g = GraphBuilder::new_directed(Some("single_edge".to_string())) .add_node(Node::new("N0".to_string())) .add_node(Node::new("N1".to_string())) .add_edge(edge) - .build(); + .build() + .unwrap(); let r = test_input(g); @@ -216,12 +229,14 @@ fn edge_statement_port_position() { let node_0 = NodeBuilder::new("N0".to_string()) .shape(Shape::Record) .label("a|<port0>b") - .build(); + .build() + .unwrap(); let node_1 = NodeBuilder::new("N1".to_string()) .shape(Shape::Record) .label("e|<port1>f") - .build(); + .build() + .unwrap(); let edge = EdgeBuilder::new("N0".to_string(), "N1".to_string()) .source_port_position(PortPosition::Port { @@ -232,13 +247,15 @@ fn edge_statement_port_position() { port_name: "port1".to_string(), compass_point: Some(CompassPoint::NE), }) - .build(); + .build() + .unwrap(); let g = GraphBuilder::new_directed(Some("edge_statement_port_position".to_string())) .add_node(node_0) .add_node(node_1) .add_edge(edge) - .build(); + .build() + .unwrap(); let r = test_input(g); @@ -258,12 +275,14 @@ fn port_position_attribute() { let node_0 = NodeBuilder::new("N0".to_string()) .shape(Shape::Record) .label("a|<port0>b") - .build(); + .build() + .unwrap(); let node_1 = NodeBuilder::new("N1".to_string()) .shape(Shape::Record) .label("e|<port1>f") - .build(); + .build() + .unwrap(); let edge = EdgeBuilder::new("N0".to_string(), "N1".to_string()) .tail_port(PortPosition::Port { @@ -274,13 +293,15 @@ fn port_position_attribute() { port_name: "port1".to_string(), compass_point: Some(CompassPoint::NE), }) - .build(); + .build() + .unwrap(); let g = GraphBuilder::new_directed(Some("port_position_attribute".to_string())) .add_node(node_0) .add_node(node_1) .add_edge(edge) - .build(); + .build() + .unwrap(); let r = test_input(g); @@ -313,7 +334,8 @@ fn graph_attributes() { "color".to_string(), AttributeText::from(Color::Named("red")), ) - .build(); + .build() + .unwrap(); let r = test_input(g); @@ -358,7 +380,8 @@ fn graph_attributes_extend() { .cloned() .collect(), ) - .build(); + .build() + .unwrap(); let r = test_input(g); @@ -377,19 +400,23 @@ fn graph_attributes_extend() { fn graph_attributes_statement_builders() { let graph_attributes = GraphAttributeStatementBuilder::new() .rank_dir(RankDir::LeftRight) - .build(); + .build() + .unwrap(); let node_attributes = NodeAttributeStatementBuilder::new() .style(NodeStyle::Filled) - .build(); + .build() + .unwrap(); let edge_attributes = EdgeAttributeStatementBuilder::new() .color(Color::Named("red")) - .build(); + .build() + .unwrap(); let g = GraphBuilder::new_directed(Some("graph_attributes".to_string())) .add_graph_attributes(graph_attributes) .add_node_attributes(node_attributes) .add_edge_attributes(edge_attributes) - .build(); + .build() + .unwrap(); let r = test_input(g); @@ -412,18 +439,21 @@ fn clusters() { .label("process #1".to_string()) .style(GraphStyle::Filled) .color(Color::Named("lightgrey")) - .build(), + .build() + .unwrap(), ) .add_node_attributes( NodeAttributeStatementBuilder::new() .style(NodeStyle::Filled) .color(Color::Named("white")) - .build(), + .build() + .unwrap(), ) .add_edge(Edge::new("a0".to_string(), "a1".to_string())) .add_edge(Edge::new("a1".to_string(), "a2".to_string())) .add_edge(Edge::new("a2".to_string(), "a3".to_string())) - .build(); + .build() + .unwrap(); let cluster_1 = SubGraphBuilder::new(Some("cluster_1".to_string())) .add_graph_attributes( @@ -431,28 +461,33 @@ fn clusters() { .label("process #2".to_string()) .style(GraphStyle::Filled) .color(Color::Named("blue")) - .build(), + .build() + .unwrap(), ) .add_node_attributes( NodeAttributeStatementBuilder::new() .style(NodeStyle::Filled) - .build(), + .build() + .unwrap(), ) .add_edge(Edge::new("b0".to_string(), "b1".to_string())) .add_edge(Edge::new("b1".to_string(), "b2".to_string())) .add_edge(Edge::new("b2".to_string(), "b3".to_string())) - .build(); + .build() + .unwrap(); let g = GraphBuilder::new_directed(Some("G".to_string())) .add_node( NodeBuilder::new("start".to_string()) .shape(Shape::Mdiamond) - .build(), + .build() + .unwrap(), ) .add_node( NodeBuilder::new("end".to_string()) .shape(Shape::Msquare) - .build(), + .build() + .unwrap(), ) .add_sub_graph(cluster_0) .add_sub_graph(cluster_1) @@ -463,7 +498,8 @@ fn clusters() { .add_edge(Edge::new("a3".to_string(), "a0".to_string())) .add_edge(Edge::new("a3".to_string(), "end".to_string())) .add_edge(Edge::new("b3".to_string(), "end".to_string())) - .build(); + .build() + .unwrap(); let r = test_input(g); @@ -499,3 +535,127 @@ fn clusters() { "# ); } + +#[test] +fn edge_validation_error() { + let edge_builder = EdgeBuilder::new("N0".to_string(), "N1".to_string()) + .arrow_size(-1.0) + .build(); + + assert!(edge_builder.is_err()); + + let validation_errors = edge_builder.unwrap_err(); + assert_eq!(1, validation_errors.len()); + assert_eq!("arrowsize", validation_errors.get(0).unwrap().field); + assert_eq!( + "Must be greater than or equal to 0", + validation_errors.get(0).unwrap().message + ); +} + +#[test] +fn edge_build_ignore_validation_error() { + let edge = EdgeBuilder::new("N0".to_string(), "N1".to_string()) + .arrow_size(-1.0) + .build_ignore_validation(); + + assert!(edge.attributes.contains_key("arrowsize")) +} + +#[test] +fn edge_attributes_validation_error() { + let edge_builder = EdgeAttributeStatementBuilder::new() + .arrow_size(-1.0) + .build(); + + assert!(edge_builder.is_err()); + + let validation_errors = edge_builder.unwrap_err(); + assert_eq!(1, validation_errors.len()); + assert_eq!("arrowsize", validation_errors.get(0).unwrap().field); + assert_eq!( + "Must be greater than or equal to 0", + validation_errors.get(0).unwrap().message + ); +} + +#[test] +fn edge_attribute_build_ignore_validation_error() { + let edge = EdgeAttributeStatementBuilder::new() + .arrow_size(-1.0) + .build_ignore_validation(); + + assert!(edge.contains_key("arrowsize")) +} + +#[test] +fn node_validation_error() { + let node_builder = NodeBuilder::new("N0".to_string()).height(0.0).build(); + + assert!(node_builder.is_err()); + + let validation_errors = node_builder.unwrap_err(); + assert_eq!(1, validation_errors.len()); + assert_eq!("height", validation_errors.get(0).unwrap().field); + assert_eq!( + "Must be greater than or equal to 0.02", + validation_errors.get(0).unwrap().message + ); +} + +#[test] +fn node_build_ignore_validation_error() { + let node = NodeBuilder::new("N0".to_string()) + .height(0.0) + .build_ignore_validation(); + + assert!(node.attributes.contains_key("height")) +} + +#[test] +fn node_attribute_validation_error() { + let node_builder = NodeAttributeStatementBuilder::new().height(0.0).build(); + + assert!(node_builder.is_err()); + + let validation_errors = node_builder.unwrap_err(); + assert_eq!(1, validation_errors.len()); + assert_eq!("height", validation_errors.get(0).unwrap().field); + assert_eq!( + "Must be greater than or equal to 0.02", + validation_errors.get(0).unwrap().message + ); +} + +#[test] +fn node_attribute_build_ignore_validation_error() { + let node = NodeAttributeStatementBuilder::new() + .height(0.0) + .build_ignore_validation(); + + assert!(node.contains_key("height")) +} + +#[test] +fn graph_attributes_validation_error() { + let graph_builder = GraphAttributeStatementBuilder::new().font_size(0.0).build(); + + assert!(graph_builder.is_err()); + + let validation_errors = graph_builder.unwrap_err(); + assert_eq!(1, validation_errors.len()); + assert_eq!("fontsize", validation_errors.get(0).unwrap().field); + assert_eq!( + "Must be greater than or equal to 1.0", + validation_errors.get(0).unwrap().message + ); +} + +#[test] +fn graph_attributes_build_ignore_validation_error() { + let graph = GraphAttributeStatementBuilder::new() + .font_size(0.0) + .build_ignore_validation(); + + assert!(graph.contains_key("fontsize")) +} |