mcai-graph 0.3.0

Graph definition for Media Cloud AI Workflows representation
Documentation
use mcai_graph::{Dimensions, Graph, GraphConfiguration, Link, LinkType, NodeConfiguration};
use mcai_types::Coordinates;

#[test]
pub fn test_graph() {
  // Setup graph configuration & nodes

  let node_config = NodeConfiguration::new(20, 5, 10, 10);
  assert_eq!(20, node_config.width());
  assert_eq!(5, node_config.height());
  assert_eq!(10, node_config.x_gap());
  assert_eq!(10, node_config.y_gap());
  assert_eq!(Dimensions::new(20, 5), node_config.get_dimensions());

  let graph_config = GraphConfiguration::new(node_config.clone());
  assert_eq!(&node_config, graph_config.node_configuration());

  let mut graph = Graph::new(graph_config);

  let node_1_coordinates = node_config.get_coordinates(0, 1);
  let node_2_coordinates = node_config.get_coordinates(1, 1);
  let node_3_coordinates = Coordinates::new(456, 345);

  graph.add_node(0, node_1_coordinates);
  graph.add_node(1, node_2_coordinates);
  graph.add_node(2, node_3_coordinates.clone());

  assert_eq!(3, graph.nodes().len());
  let shared_node_1 = graph.get_node(0).unwrap();
  let shared_node_2 = graph.get_node(1).unwrap();
  let shared_node_3 = graph.get_node(2).unwrap();

  // Check nodes coordinates

  assert_eq!(
    Coordinates::new(30, 0),
    shared_node_1.borrow().coordinates()
  );
  assert_eq!(
    Coordinates::new(30, 15),
    shared_node_2.borrow().coordinates()
  );
  assert_eq!(node_3_coordinates, shared_node_3.borrow().coordinates());

  assert_eq!(
    Coordinates::new(40, 0),
    shared_node_1.borrow().get_input_coordinates()
  );
  assert_eq!(
    Coordinates::new(40, 5),
    shared_node_1.borrow().get_output_coordinates()
  );

  // Move node
  let node_3_coordinates = Coordinates::new(543, 123);

  graph.move_node(2, node_3_coordinates.clone());

  assert_eq!(node_3_coordinates, shared_node_3.borrow().coordinates());

  // Connect nodes & check links

  graph.connect(0, 1, &LinkType::Parentage);
  graph.connect(1, 2, &LinkType::Parentage);

  assert!(shared_node_2.borrow().parents().contains(&shared_node_1));
  assert!(shared_node_3.borrow().parents().contains(&shared_node_2));

  graph.connect(0, 2, &LinkType::Requirement);

  assert!(shared_node_3.borrow().required().contains(&shared_node_1));

  assert!(shared_node_1
    .borrow()
    .get_links(&LinkType::Parentage)
    .is_empty());

  let node_2_to_1_link = Link::new(
    1,
    0,
    Coordinates { x: 40, y: 15 },
    Coordinates { x: 40, y: 5 },
    LinkType::Parentage,
  );

  assert_eq!(1, node_2_to_1_link.start_node_id());
  assert_eq!(0, node_2_to_1_link.end_node_id());
  assert_eq!(Coordinates { x: 40, y: 15 }, node_2_to_1_link.start());
  assert_eq!(Coordinates { x: 40, y: 5 }, node_2_to_1_link.end());
  assert_eq!(LinkType::Parentage, node_2_to_1_link.kind());

  assert_eq!(
    node_2_to_1_link,
    *shared_node_2
      .borrow()
      .get_links(&LinkType::Parentage)
      .get(0)
      .unwrap()
  );

  let node_3_to_2_link = Link::new(
    2,
    1,
    Coordinates { x: 553, y: 123 },
    Coordinates { x: 40, y: 20 },
    LinkType::Parentage,
  );

  assert_eq!(
    node_3_to_2_link,
    *shared_node_3
      .borrow()
      .get_links(&LinkType::Parentage)
      .get(0)
      .unwrap()
  );

  let node_3_to_1_link = Link::new(
    2,
    0,
    Coordinates { x: 553, y: 123 },
    Coordinates { x: 40, y: 5 },
    LinkType::Requirement,
  );

  assert_eq!(
    node_3_to_1_link,
    *shared_node_3
      .borrow()
      .get_links(&LinkType::Requirement)
      .get(0)
      .unwrap()
  );

  let graph_links = graph.get_links(LinkType::Parentage);
  assert_eq!(2, graph_links.len());
  assert!(graph_links.contains(&node_2_to_1_link));
  assert!(graph_links.contains(&node_3_to_2_link));

  let graph_links = graph.get_links(LinkType::Requirement);
  assert_eq!(1, graph_links.len());
  assert!(graph_links.contains(&node_3_to_1_link));

  // Disconnect

  graph.disconnect(1, 2, &LinkType::Parentage);

  let graph_links = graph.get_links(LinkType::Parentage);
  assert_eq!(1, graph_links.len());
  assert!(graph_links.contains(&node_2_to_1_link));

  graph.disconnect(0, 2, &LinkType::Requirement);

  let graph_links = graph.get_links(LinkType::Requirement);
  assert!(graph_links.is_empty());
}