use libreda_db::netlist::prelude::*;
use itertools::Itertools;
#[test]
fn test_circuit_eq() {
let mut netlist = RcNetlist::new();
let a = netlist.create_circuit("a", vec![]);
let b = netlist.create_circuit("b", vec![]);
assert_eq!(a.clone(), a.clone());
assert_eq!(&a, &a);
assert_ne!(a.clone(), b.clone());
assert_ne!(&a, &b);
}
#[test]
#[should_panic(expected = "Cannot create recursive instances.")]
fn test_circuit_no_recursion_1() {
let mut netlist = RcNetlist::new();
let top = netlist.create_circuit("top", vec![]);
let _top_inst = top.create_circuit_instance(&top, Some("top_inst"));
}
#[test]
#[should_panic(expected = "Cannot create recursive instances.")]
fn test_circuit_no_recursion_2() {
let mut netlist = RcNetlist::new();
let top = netlist.create_circuit("top", vec![]);
let sub = netlist.create_circuit("sub", vec![]);
let _sub_inst = top.create_circuit_instance(&sub, Some("sub_inst"));
let _top_inst = sub.create_circuit_instance(&top, Some("recursive_inst"));
}
#[test]
fn test_create_and_remove_instance() {
let mut netlist = RcNetlist::new();
let top = netlist.create_circuit("top", vec![]);
let sub = netlist.create_circuit("sub", vec![]);
assert_ne!(top.id(), sub.id());
let sub_inst = top.create_circuit_instance(&sub, Some("sub_inst"));
assert_eq!(sub_inst.name(), Some(&"sub_inst".to_string()));
assert_eq!(top.each_instance().collect_vec(), vec![sub_inst.clone()]);
assert_eq!(top.num_instances(), 1);
assert_eq!(top.num_references(), 0);
assert_eq!(sub.num_references(), 1);
assert_eq!(sub_inst.parent_circuit().upgrade(), Some(top.clone()));
top.remove_circuit_instance(&sub_inst);
assert_eq!(top.each_instance().collect_vec(), vec![]);
assert_eq!(top.num_instances(), 0);
assert_eq!(top.num_references(), 0);
assert_eq!(sub.num_references(), 0);
}
#[test]
fn test_dependent_circuits() {
let mut netlist = RcNetlist::new();
let top = netlist.create_circuit("top", vec![]);
let sub = netlist.create_circuit("sub", vec![]);
let sub_inst = top.create_circuit_instance(&sub, Some("sub_inst"));
assert_eq!(sub.each_dependent_circuit().collect_vec(), vec![top.clone()]);
assert_eq!(top.each_dependent_circuit().collect_vec(), vec![]);
assert_eq!(top.each_circuit_dependency().collect_vec(), vec![sub.clone()]);
assert_eq!(sub.each_circuit_dependency().collect_vec(), vec![]);
top.remove_circuit_instance(&sub_inst);
assert_eq!(sub.each_dependent_circuit().collect_vec(), vec![]);
assert_eq!(top.each_circuit_dependency().collect_vec(), vec![]);
}
#[test]
fn test_simple_net() {
let mut netlist = RcNetlist::new();
let top = netlist.create_circuit("top", vec![Pin::new_input("A")]);
let a = netlist.create_circuit("a", vec![Pin::new_input("A")]);
let b = netlist.create_circuit("b", vec![Pin::new_input("A")]);
let a_inst = top.create_circuit_instance(&a, Some("a_inst"));
let b_inst = top.create_circuit_instance(&b, Some("b_inst"));
let net1 = top.create_net(Some("Net1"));
assert_eq!(net1.parent_circuit().upgrade(), Some(top.clone()));
assert_eq!(Some(net1.clone()), top.net_by_name("Net1"));
top.connect_pin_by_id(0, Some(net1.clone()));
a_inst.connect_pin_by_id(0, Some(net1.clone()));
b_inst.connect_pin_by_id(0, Some(net1.clone()));
assert_eq!(net1.num_terminals(), 3);
assert_eq!(net1.each_terminal().count(), 3);
assert_eq!(net1.each_terminal()
.filter_map(|t| match t {
TerminalRef::Pin(p) => Some(p),
_ => None
})
.count(), 1, "Number of connections to `Pin`s is wrong.");
assert_eq!(net1.each_terminal()
.filter_map(|t| match t {
TerminalRef::PinInstance(p) => Some(p),
_ => None
})
.count(), 2, "Number of connections to `PinInstance`s is wrong.");
assert_eq!(net1.each_instance().unique().count(), 2);
}
#[test]
fn test_rename_net() {
let mut netlist = RcNetlist::new();
let top = netlist.create_circuit("top", vec![Pin::new_input("A")]);
let net1 = top.create_net(Some("Net1"));
assert_eq!(Some(net1.clone()), top.net_by_name("Net1"));
net1.rename(Some("NewName"));
assert_eq!(Some(net1.clone()), top.net_by_name("NewName"));
net1.rename(Some("Net1"));
assert_eq!(Some(net1.clone()), top.net_by_name("Net1"));
net1.rename::<String>(None);
assert_eq!(None, top.net_by_name("Net1"));
}
#[test]
fn test_flatten_circuit_instance() {
let mut netlist = RcNetlist::new();
let top = netlist.create_circuit("top", vec![Pin::new_input("A")]);
let a = netlist.create_circuit("a", vec![Pin::new_input("A")]);
let b = netlist.create_circuit("b", vec![Pin::new_input("A")]);
let a_inst = top.create_circuit_instance(&a, Some("a_inst"));
let b_inst = a.create_circuit_instance(&b, Some("b_inst"));
let net1 = top.create_net(Some("Net1"));
top.connect_pin_by_id(0, Some(net1.clone()));
a_inst.connect_pin_by_id(0, Some(net1.clone()));
let net2 = a.create_net(Some("Net2"));
a.connect_pin_by_id(0, Some(net2.clone()));
b_inst.connect_pin_by_id(0, Some(net2));
top.flatten_circuit_instance(&a_inst);
assert_eq!(top.num_instances(), 1);
assert!(top.circuit_instance_by_name("a_inst").is_none());
assert!(top.circuit_instance_by_name("a_inst:b_inst").is_some());
assert_eq!(net1.num_terminals(), 2);
}