Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Use insta for mermaid/dot render tests #137

Merged
merged 2 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ criterion = { version = "0.5.1", features = ["html_reports"] }
rmp-serde = "1.1.1"
rstest = "0.21.0"
itertools = "0.13.0"
insta = "1.39.0"

[[bench]]
name = "bench_main"
Expand Down
165 changes: 165 additions & 0 deletions src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,168 @@ impl EdgeStyle {
}
}
}

#[cfg(test)]
mod test {
use std::fmt::Display;

use rstest::{fixture, rstest};

use crate::{Hierarchy, LinkMut, PortGraph, PortMut, PortView, Weights};

use super::{DotFormat, MermaidFormat};

/// A simple flat graph with some nodes and edges.
#[fixture]
fn flat_graph() -> (
&'static str,
PortGraph,
Option<Hierarchy>,
Option<Weights<String, String>>,
) {
let mut graph = PortGraph::new();
let n1 = graph.add_node(3, 2);
let n2 = graph.add_node(1, 0);
let n3 = graph.add_node(1, 0);
graph.link_nodes(n1, 0, n2, 0).unwrap();
graph.link_nodes(n1, 1, n3, 0).unwrap();
("flat", graph, None, None)
}

#[fixture]
fn hierarchy_graph() -> (
&'static str,
PortGraph,
Option<Hierarchy>,
Option<Weights<String, String>>,
) {
let mut graph = PortGraph::new();
let n1 = graph.add_node(3, 2);
let n2 = graph.add_node(0, 1);
let n3 = graph.add_node(1, 0);
graph.link_nodes(n2, 0, n3, 0).unwrap();

let mut hier = Hierarchy::new();
hier.push_child(n2, n1).unwrap();
hier.push_child(n3, n1).unwrap();

("hierarchy", graph, Some(hier), None)
}

/// A hierarchical graph with edges between different regions.
#[fixture]
fn hierarchy_interregional_graph() -> (
&'static str,
PortGraph,
Option<Hierarchy>,
Option<Weights<String, String>>,
) {
let mut graph = PortGraph::new();
let n1 = graph.add_node(3, 2);
let n2 = graph.add_node(0, 1);
let n3 = graph.add_node(1, 0);
let n4 = graph.add_node(1, 1);
let n5 = graph.add_node(1, 1);
graph.link_nodes(n2, 0, n3, 0).unwrap();
graph.link_nodes(n4, 0, n5, 0).unwrap();

let mut hier = Hierarchy::new();
hier.push_child(n2, n1).unwrap();
hier.push_child(n3, n1).unwrap();
hier.push_child(n4, n2).unwrap();
hier.push_child(n5, n3).unwrap();

("hierarchy_interregional", graph, Some(hier), None)
}

#[fixture]
fn weighted_graph() -> (
&'static str,
PortGraph,
Option<Hierarchy>,
Option<Weights<String, String>>,
) {
let mut graph = PortGraph::new();
let n1 = graph.add_node(0, 2);
let n2 = graph.add_node(1, 0);
let n3 = graph.add_node(1, 0);
let p10 = graph.output(n1, 0).unwrap();
let p11 = graph.output(n1, 1).unwrap();
let p20 = graph.input(n2, 0).unwrap();
let p30 = graph.input(n3, 0).unwrap();

graph.link_ports(p10, p20).unwrap();
graph.link_ports(p11, p30).unwrap();

let mut weights = Weights::new();
weights[n1] = "node1".to_string();
weights[n2] = "node2".to_string();
weights[n3] = "node3".to_string();
weights[p10] = "out 0".to_string();
weights[p11] = "out 1".to_string();
weights[p20] = "in 0".to_string();
weights[p30] = "in 0".to_string();

("weighted", graph, None, Some(weights))
}

#[rstest]
#[case::flat(flat_graph())]
#[case::hierarchy(hierarchy_graph())]
#[case::interregional(hierarchy_interregional_graph())]
#[case::weighted(weighted_graph())]
#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri
fn mermaid_output<WN: Display + Clone, WP>(
#[case] graph_elems: (
&str,
impl MermaidFormat,
Option<Hierarchy>,
Option<Weights<WN, WP>>,
),
) {
let (name, graph, hierarchy, weights) = graph_elems;
let mermaid = match (hierarchy, weights) {
(Some(h), Some(w)) => graph
.mermaid_format()
.with_hierarchy(&h)
.with_weights(&w)
.finish(),
(Some(h), None) => graph.mermaid_format().with_hierarchy(&h).finish(),
(None, Some(w)) => graph.mermaid_format().with_weights(&w).finish(),
(None, None) => graph.mermaid_string(),
};

let name = format!("{}__mermaid", name);
insta::assert_snapshot!(name, mermaid);
}

#[rstest]
#[case::flat(flat_graph())]
#[case::hierarchy(hierarchy_graph())]
#[case::interregional(hierarchy_interregional_graph())]
#[case::weighted(weighted_graph())]
#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri
fn dot_output<WN: Display + Clone, WP: Display + Clone>(
#[case] graph_elems: (
&str,
impl DotFormat,
Option<Hierarchy>,
Option<Weights<WN, WP>>,
),
) {
let (name, graph, hierarchy, weights) = graph_elems;
let dot = match (hierarchy, weights) {
(Some(h), Some(w)) => graph
.dot_format()
.with_hierarchy(&h)
.with_weights(&w)
.finish(),
(Some(h), None) => graph.dot_format().with_hierarchy(&h).finish(),
(None, Some(w)) => graph.dot_format().with_weights(&w).finish(),
(None, None) => graph.dot_string(),
};

let name = format!("{}__dot", name);
insta::assert_snapshot!(name, dot);
}
}
94 changes: 0 additions & 94 deletions src/render/dot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,97 +286,3 @@ struct PortCellStrings {
/// The label to show for the port.
pub label: String,
}

#[cfg(test)]
mod tests {
use crate::{LinkMut, PortGraph, PortMut, PortView};

use super::*;

#[test]
fn test_dot_string() {
let mut graph = PortGraph::new();
let n1 = graph.add_node(3, 2);
let n2 = graph.add_node(1, 0);
let n3 = graph.add_node(1, 0);
graph.link_nodes(n1, 0, n2, 0).unwrap();
graph.link_nodes(n1, 1, n3, 0).unwrap();

let dot = &graph.dot_string();
let expected = r#"digraph {
0 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="2" cellpadding="1" >0</td><td port="in1" align="text" colspan="2" cellpadding="1" >1</td><td port="in2" align="text" colspan="2" cellpadding="1" >2</td></tr><tr><td align="text" border="0" colspan="6">0</td></tr><tr><td port="out0" align="text" colspan="3" cellpadding="1" >0</td><td port="out1" align="text" colspan="3" cellpadding="1" >1</td></tr></table>>]
0:out0 -> 1:in0 [style=""]
0:out1 -> 2:in0 [style=""]
1 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="1" cellpadding="1" >0</td></tr><tr><td align="text" border="0" colspan="1">1</td></tr></table>>]
2 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="1" cellpadding="1" >0</td></tr><tr><td align="text" border="0" colspan="1">2</td></tr></table>>]
}
"#;
assert_eq!(dot, expected, "\n{}\n{}\n", dot, expected);
}

#[test]
fn test_hier_dot_string() {
let mut graph = PortGraph::new();
let n1 = graph.add_node(3, 2);
let n2 = graph.add_node(1, 0);
let n3 = graph.add_node(1, 0);
graph.link_nodes(n1, 0, n2, 0).unwrap();
graph.link_nodes(n1, 1, n3, 0).unwrap();

let mut hier = Hierarchy::new();

hier.push_child(n2, n1).unwrap();
hier.push_child(n3, n1).unwrap();
let dot = graph.dot_format().with_hierarchy(&hier).finish();
let expected = r#"digraph {
0 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="2" cellpadding="1" >0</td><td port="in1" align="text" colspan="2" cellpadding="1" >1</td><td port="in2" align="text" colspan="2" cellpadding="1" >2</td></tr><tr><td align="text" border="0" colspan="6">0</td></tr><tr><td port="out0" align="text" colspan="3" cellpadding="1" >0</td><td port="out1" align="text" colspan="3" cellpadding="1" >1</td></tr></table>>]
0:out0 -> 1:in0 [style=""]
0:out1 -> 2:in0 [style=""]
1 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="1" cellpadding="1" >0</td></tr><tr><td align="text" border="0" colspan="1">1</td></tr></table>>]
2 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="1" cellpadding="1" >0</td></tr><tr><td align="text" border="0" colspan="1">2</td></tr></table>>]
hier0 [shape=plain label="0"]
hier0 -> hier1 [style = "dashed"]
hier0 -> hier2 [style = "dashed"]
hier1 [shape=plain label="1"]
hier2 [shape=plain label="2"]
}
"#;
assert_eq!(dot, expected, "\n{}\n{}\n", dot, expected);
}

#[test]
fn test_dot_string_weighted() {
let mut graph = PortGraph::new();
let n1 = graph.add_node(0, 2);
let n2 = graph.add_node(1, 0);
let n3 = graph.add_node(1, 0);
let p10 = graph.output(n1, 0).unwrap();
let p11 = graph.output(n1, 1).unwrap();
let p20 = graph.input(n2, 0).unwrap();
let p30 = graph.input(n3, 0).unwrap();

graph.link_ports(p10, p20).unwrap();
graph.link_ports(p11, p30).unwrap();

let mut weights = Weights::new();
weights[n1] = "node1".to_string();
weights[n2] = "node2".to_string();
weights[n3] = "node3".to_string();
weights[p10] = "out 0".to_string();
weights[p11] = "out 1".to_string();
weights[p20] = "in 0".to_string();
weights[p30] = "in 0".to_string();

let dot = graph.dot_format().with_weights(&weights).finish();
println!("\n{}\n", dot);
let expected = r#"digraph {
0 [shape=plain label=<<table border="1"><tr><td align="text" border="0" colspan="2">node1</td></tr><tr><td port="out0" align="text" colspan="1" cellpadding="1" >0: out 0</td><td port="out1" align="text" colspan="1" cellpadding="1" >1: out 1</td></tr></table>>]
0:out0 -> 1:in0 [style=""]
0:out1 -> 2:in0 [style=""]
1 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="1" cellpadding="1" >0: in 0</td></tr><tr><td align="text" border="0" colspan="1">node2</td></tr></table>>]
2 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="1" cellpadding="1" >0: in 0</td></tr><tr><td align="text" border="0" colspan="1">node3</td></tr></table>>]
}
"#;
assert_eq!(dot, expected, "\n{}\n{}\n", dot, expected);
}
}
81 changes: 0 additions & 81 deletions src/render/mermaid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,84 +332,3 @@ pub fn encode_label(id: &str, label: &str) -> String {
}
format!("\"{}\"", label.replace('"', "#quot;").replace('\n', "<br>"))
}

#[cfg(test)]
mod tests {
use crate::{LinkMut, PortGraph, PortMut, PortView};

use super::*;

#[test]
fn test_mermaid_string() {
let mut graph = PortGraph::new();
let n1 = graph.add_node(3, 2);
let n2 = graph.add_node(1, 0);
let n3 = graph.add_node(1, 0);
graph.link_nodes(n1, 0, n2, 0).unwrap();
graph.link_nodes(n1, 1, n3, 0).unwrap();

let mermaid = &graph.mermaid_string();
let expected = r#"graph LR
0[0]
0-->1
0-->2
1[1]
2[2]
"#;
assert_eq!(mermaid, expected, "\n{}\n{}\n", mermaid, expected);
}

#[test]
fn test_hier_mermaid_string() {
let mut graph = PortGraph::new();
let n1 = graph.add_node(3, 2);
let n2 = graph.add_node(0, 1);
let n3 = graph.add_node(1, 0);
graph.link_nodes(n2, 0, n3, 0).unwrap();

let mut hier = Hierarchy::new();

hier.push_child(n2, n1).unwrap();
hier.push_child(n3, n1).unwrap();
let mermaid = graph.mermaid_format().with_hierarchy(&hier).finish();
let expected = r#"graph LR
subgraph 0 [0]
direction LR
1[1]
1-->2
2[2]
end
"#;
assert_eq!(mermaid, expected, "\n{}\n{}\n", mermaid, expected);
}

#[test]
fn test_mermaid_string_weighted() {
let mut graph = PortGraph::new();
let n1 = graph.add_node(0, 2);
let n2 = graph.add_node(1, 0);
let n3 = graph.add_node(1, 0);
let p10 = graph.output(n1, 0).unwrap();
let p11 = graph.output(n1, 1).unwrap();
let p20 = graph.input(n2, 0).unwrap();
let p30 = graph.input(n3, 0).unwrap();

graph.link_ports(p10, p20).unwrap();
graph.link_ports(p11, p30).unwrap();

let mut weights: Weights<String, ()> = Weights::new();
weights[n1] = "node1".to_string();
weights[n2] = "node2".to_string();
weights[n3] = "node3".to_string();

let mermaid = graph.mermaid_format().with_weights(&weights).finish();
let expected = r#"graph LR
0["node1"]
0-->1
0-->2
1["node2"]
2["node3"]
"#;
assert_eq!(mermaid, expected, "\n{}\n{}\n", mermaid, expected);
}
}
11 changes: 11 additions & 0 deletions src/snapshots/portgraph__render__test__flat__dot.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: src/render.rs
expression: dot
---
digraph {
0 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="2" cellpadding="1" >0</td><td port="in1" align="text" colspan="2" cellpadding="1" >1</td><td port="in2" align="text" colspan="2" cellpadding="1" >2</td></tr><tr><td align="text" border="0" colspan="6">0</td></tr><tr><td port="out0" align="text" colspan="3" cellpadding="1" >0</td><td port="out1" align="text" colspan="3" cellpadding="1" >1</td></tr></table>>]
0:out0 -> 1:in0 [style=""]
0:out1 -> 2:in0 [style=""]
1 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="1" cellpadding="1" >0</td></tr><tr><td align="text" border="0" colspan="1">1</td></tr></table>>]
2 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="1" cellpadding="1" >0</td></tr><tr><td align="text" border="0" colspan="1">2</td></tr></table>>]
}
10 changes: 10 additions & 0 deletions src/snapshots/portgraph__render__test__flat__mermaid.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
source: src/render.rs
expression: mermaid
---
graph LR
0[0]
0-->1
0-->2
1[1]
2[2]
15 changes: 15 additions & 0 deletions src/snapshots/portgraph__render__test__hierarchy__dot.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
source: src/render.rs
expression: dot
---
digraph {
0 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="2" cellpadding="1" >0</td><td port="in1" align="text" colspan="2" cellpadding="1" >1</td><td port="in2" align="text" colspan="2" cellpadding="1" >2</td></tr><tr><td align="text" border="0" colspan="6">0</td></tr><tr><td port="out0" align="text" colspan="3" cellpadding="1" >0</td><td port="out1" align="text" colspan="3" cellpadding="1" >1</td></tr></table>>]
1 [shape=plain label=<<table border="1"><tr><td align="text" border="0" colspan="1">1</td></tr><tr><td port="out0" align="text" colspan="1" cellpadding="1" >0</td></tr></table>>]
1:out0 -> 2:in0 [style=""]
2 [shape=plain label=<<table border="1"><tr><td port="in0" align="text" colspan="1" cellpadding="1" >0</td></tr><tr><td align="text" border="0" colspan="1">2</td></tr></table>>]
hier0 [shape=plain label="0"]
hier0 -> hier1 [style = "dashed"]
hier0 -> hier2 [style = "dashed"]
hier1 [shape=plain label="1"]
hier2 [shape=plain label="2"]
}
Loading
Loading