use wolf_graph::prelude::*;
use wolf_graph_dot::prelude::*;
use indoc::indoc;
#[test]
fn test1() {
let mut compound = make_test_compound();
compound.add_node(nid!(1), None::<NodeID>, eid!("r1")).unwrap();
compound.add_node(nid!(2), None::<NodeID>, eid!("r2")).unwrap();
compound.add_node(nid!(3), Some(nid!(1)), eid!("13")).unwrap();
for node in ["J", "A"] {
compound.move_node(nid!(node), Some(nid!(1))).unwrap();
}
for node in ["G", "3"] {
compound.move_node(nid!(node), Some(nid!(2))).unwrap();
}
for node in ["I", "C", "K"] {
compound.move_node(nid!(node), Some(nid!(3))).unwrap();
}
let dot = indoc! {r#"
digraph G {
subgraph cluster_1 {
label="1" color="red"
A [label="A"]
J [label="J"]
}
subgraph cluster_2 {
label="2" color="green"
subgraph cluster_3 {
label="3" color="blue"
C [label="C"]
I [label="I"]
K [label="K"]
}
G [label="G"]
}
B [label="B"]
D [label="D"]
E [label="E"]
F [label="F"]
H [label="H"]
A -> C [label="AC"]
A -> D [label="AD"]
A -> E [label="AE"]
B -> A [label="BA"]
B -> C [label="BC"]
B -> G [label="BG"]
C -> D [label="CD"]
E -> D [label="ED"]
F -> D [label="FD"]
F -> E [label="FE"]
G -> I [label="GI"]
H -> J [label="HJ"]
I -> B [label="IB"]
I -> C [label="IC"]
I -> K [label="IK"]
J -> A [label="JA"]
J -> E [label="JE"]
J -> F [label="JF"]
}
"#};
assert_eq!(compound.dot_format(), dot.trim());
}
#[derive(Debug, Clone, PartialEq, Default)]
struct Empty;
type EmptyGraph = Graph<Empty, Empty, Empty>;
type TestCompound = Compound<EmptyGraph>;
impl DotEncodable<Empty, Empty, Empty> for TestCompound {
fn dot_edge_attributes(&self, edge: &EdgeID) -> Option<EdgeAttributes> {
Some(EdgeAttributes::new(Some(edge.to_string()), None, None, None, None, None, None))
}
fn dot_node_attributes(&self, node: &NodeID) -> Option<NodeAttributes> {
Some(NodeAttributes::new(Some(node.to_string()), None, None, None))
}
fn dot_is_compound(&self) -> bool {
true
}
fn dot_children(&self, node: Option<&NodeID>) -> Nodes {
self.children(node).unwrap()
}
fn dot_group_attributes(&self, group: &NodeID) -> Option<GroupAttributes> {
let color = match group.as_str() {
"1" => Some(Color::RED),
"2" => Some(Color::GREEN),
"3" => Some(Color::BLUE),
_ => None,
};
Some(GroupAttributes::new(Some(group.to_string()), color))
}
}
fn make_test_compound() -> TestCompound {
let graph = make_test_compound_graph(graph_edges());
let mut forest = BlankForest::new();
for node in graph.all_nodes().iter() {
forest.add_node(node, None::<NodeID>, eid!(format!("r{}", node))).unwrap();
}
TestCompound::new_with_graph_and_forest(graph, forest).unwrap()
}
fn make_test_compound_graph(edges: Vec<(EdgeID, NodeID, NodeID)>) -> EmptyGraph {
let mut graph = EmptyGraph::default();
for (label, source, target) in edges.iter() {
if !graph.has_node(source) {
graph.add_node(source).unwrap();
}
if !graph.has_node(target) {
graph.add_node(target).unwrap();
}
graph.add_edge(label, source, target).unwrap();
}
graph
}
fn graph_edges() -> Vec<(EdgeID, NodeID, NodeID)> {
let v = vec![
("AC", "A", "C"),
("AD", "A", "D"),
("AE", "A", "E"),
("BA", "B", "A"),
("BC", "B", "C"),
("BG", "B", "G"),
("CD", "C", "D"),
("ED", "E", "D"),
("FD", "F", "D"),
("FE", "F", "E"),
("HJ", "H", "J"),
("IC", "I", "C"),
("IK", "I", "K"),
("JA", "J", "A"),
("JE", "J", "E"),
("JF", "J", "F"),
("GI", "G", "I"), ("IB", "I", "B"), ];
v.into_iter().map(|(a, b, c)| (eid!(a), nid!(b), nid!(c))).collect()
}