mirror of https://codeberg.org/topola/topola.git
tests: perform some undo-redo sanity testing before each test
This commit is contained in:
parent
91480453b3
commit
cd1e78db6f
|
|
@ -1,43 +1,61 @@
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
use petgraph::{stable_graph::NodeIndex, unionfind::UnionFind, visit::NodeIndexable};
|
use petgraph::{stable_graph::NodeIndex, unionfind::UnionFind, visit::NodeIndexable};
|
||||||
use topola::{
|
use topola::{
|
||||||
autorouter::{board::Board, Autorouter},
|
autorouter::{
|
||||||
|
board::Board,
|
||||||
|
history::HistoryError,
|
||||||
|
invoker::{Invoker, InvokerError},
|
||||||
|
Autorouter,
|
||||||
|
},
|
||||||
drawing::{
|
drawing::{
|
||||||
graph::{GetLayer, GetMaybeNet},
|
graph::{GetLayer, GetMaybeNet},
|
||||||
rules::RulesTrait,
|
rules::RulesTrait,
|
||||||
},
|
},
|
||||||
|
dsn::{design::DsnDesign, rules::DsnRules},
|
||||||
graph::GetNodeIndex,
|
graph::GetNodeIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn unionfind(autorouter: &mut Autorouter<impl RulesTrait>) -> UnionFind<NodeIndex<usize>> {
|
pub fn load_design_and_assert(filename: &str) -> Invoker<DsnRules> {
|
||||||
for ratline in autorouter.ratsnest().graph().edge_indices() {
|
let design = DsnDesign::load_from_file(filename).unwrap();
|
||||||
// Accessing endpoints may create new dots because apex construction is lazy, so we access
|
let mut invoker = Invoker::new(Autorouter::new(design.make_board()).unwrap());
|
||||||
// tem all before starting unionfind, as it requires a constant index bound.
|
|
||||||
let _ = autorouter.ratline_endpoints(ratline);
|
assert!(matches!(
|
||||||
|
invoker.undo(),
|
||||||
|
Err(InvokerError::History(HistoryError::NoPreviousCommand))
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
invoker.redo(),
|
||||||
|
Err(InvokerError::History(HistoryError::NoNextCommand))
|
||||||
|
));
|
||||||
|
|
||||||
|
invoker
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn replay_and_assert(invoker: &mut Invoker<DsnRules>, filename: &str) {
|
||||||
|
let file = File::open(filename).unwrap();
|
||||||
|
invoker.replay(serde_json::from_reader(file).unwrap());
|
||||||
|
|
||||||
|
let prev_node_count = invoker.autorouter().board().layout().drawing().node_count();
|
||||||
|
|
||||||
|
// Sanity test: check if node count remained the same after some attempts at undo-redo.
|
||||||
|
|
||||||
|
if invoker.redo().is_ok() {
|
||||||
|
let _ = invoker.undo();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut unionfind = UnionFind::new(
|
if invoker.undo().is_ok() {
|
||||||
autorouter
|
if invoker.undo().is_ok() {
|
||||||
.board()
|
let _ = invoker.redo();
|
||||||
.layout()
|
|
||||||
.drawing()
|
|
||||||
.geometry()
|
|
||||||
.graph()
|
|
||||||
.node_bound(),
|
|
||||||
);
|
|
||||||
|
|
||||||
for primitive in autorouter.board().layout().drawing().primitive_nodes() {
|
|
||||||
for joined in autorouter
|
|
||||||
.board()
|
|
||||||
.layout()
|
|
||||||
.drawing()
|
|
||||||
.geometry()
|
|
||||||
.joineds(primitive)
|
|
||||||
{
|
|
||||||
unionfind.union(primitive.node_index(), joined.node_index());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _ = invoker.redo();
|
||||||
}
|
}
|
||||||
|
|
||||||
unionfind
|
assert_eq!(
|
||||||
|
invoker.autorouter().board().layout().drawing().node_count(),
|
||||||
|
prev_node_count,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assert_single_layer_groundless_autoroute(
|
pub fn assert_single_layer_groundless_autoroute(
|
||||||
|
|
@ -130,3 +148,35 @@ pub fn assert_band_length(
|
||||||
dbg!(band_length);
|
dbg!(band_length);
|
||||||
assert!((band_length - length).abs() < epsilon);
|
assert!((band_length - length).abs() < epsilon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unionfind(autorouter: &mut Autorouter<impl RulesTrait>) -> UnionFind<NodeIndex<usize>> {
|
||||||
|
for ratline in autorouter.ratsnest().graph().edge_indices() {
|
||||||
|
// Accessing endpoints may create new dots because apex construction is lazy, so we access
|
||||||
|
// tem all before starting unionfind, as it requires a constant index bound.
|
||||||
|
let _ = autorouter.ratline_endpoints(ratline);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut unionfind = UnionFind::new(
|
||||||
|
autorouter
|
||||||
|
.board()
|
||||||
|
.layout()
|
||||||
|
.drawing()
|
||||||
|
.geometry()
|
||||||
|
.graph()
|
||||||
|
.node_bound(),
|
||||||
|
);
|
||||||
|
|
||||||
|
for primitive in autorouter.board().layout().drawing().primitive_nodes() {
|
||||||
|
for joined in autorouter
|
||||||
|
.board()
|
||||||
|
.layout()
|
||||||
|
.drawing()
|
||||||
|
.geometry()
|
||||||
|
.joineds(primitive)
|
||||||
|
{
|
||||||
|
unionfind.union(primitive.node_index(), joined.node_index());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unionfind
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,12 @@ mod common;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_0603_breakout() {
|
fn test_0603_breakout() {
|
||||||
let design =
|
let mut invoker =
|
||||||
DsnDesign::load_from_file("tests/single_layer/data/0603_breakout/0603_breakout.dsn")
|
common::load_design_and_assert("tests/single_layer/data/0603_breakout/0603_breakout.dsn");
|
||||||
.unwrap();
|
common::replay_and_assert(
|
||||||
let mut invoker = Invoker::new(Autorouter::new(design.make_board()).unwrap());
|
&mut invoker,
|
||||||
let file = File::open("tests/single_layer/data/0603_breakout/autoroute_all.cmd").unwrap();
|
"tests/single_layer/data/0603_breakout/autoroute_all.cmd",
|
||||||
invoker.replay(serde_json::from_reader(file).unwrap());
|
);
|
||||||
|
|
||||||
let (mut autorouter, ..) = invoker.destruct();
|
let (mut autorouter, ..) = invoker.destruct();
|
||||||
|
|
||||||
|
|
@ -35,15 +35,13 @@ fn test_0603_breakout() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_tht_diode_bridge_rectifier() {
|
fn test_tht_diode_bridge_rectifier() {
|
||||||
let design = DsnDesign::load_from_file(
|
let mut invoker = common::load_design_and_assert(
|
||||||
"tests/single_layer/data/tht_diode_bridge_rectifier/tht_diode_bridge_rectifier.dsn",
|
"tests/single_layer/data/tht_diode_bridge_rectifier/tht_diode_bridge_rectifier.dsn",
|
||||||
);
|
);
|
||||||
let board = design.unwrap().make_board();
|
common::replay_and_assert(
|
||||||
|
&mut invoker,
|
||||||
let mut invoker = Invoker::new(Autorouter::new(board).unwrap());
|
"tests/single_layer/data/tht_diode_bridge_rectifier/autoroute_all.cmd",
|
||||||
let file =
|
);
|
||||||
File::open("tests/single_layer/data/tht_diode_bridge_rectifier/autoroute_all.cmd").unwrap();
|
|
||||||
invoker.replay(serde_json::from_reader(file).unwrap());
|
|
||||||
|
|
||||||
let (mut autorouter, ..) = invoker.destruct();
|
let (mut autorouter, ..) = invoker.destruct();
|
||||||
|
|
||||||
|
|
@ -54,16 +52,13 @@ fn test_tht_diode_bridge_rectifier() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_four_3rd_order_smd_lc_filters() {
|
fn test_four_3rd_order_smd_lc_filters() {
|
||||||
let design = DsnDesign::load_from_file(
|
let mut invoker = common::load_design_and_assert(
|
||||||
"tests/single_layer/data/four_3rd_order_smd_lc_filters/four_3rd_order_smd_lc_filters.dsn",
|
"tests/single_layer/data/four_3rd_order_smd_lc_filters/four_3rd_order_smd_lc_filters.dsn",
|
||||||
);
|
);
|
||||||
let board = design.unwrap().make_board();
|
common::replay_and_assert(
|
||||||
|
&mut invoker,
|
||||||
let mut invoker = Invoker::new(Autorouter::new(board).unwrap());
|
"tests/single_layer/data/four_3rd_order_smd_lc_filters/autoroute_signals.cmd",
|
||||||
let file =
|
);
|
||||||
File::open("tests/single_layer/data/four_3rd_order_smd_lc_filters/autoroute_signals.cmd")
|
|
||||||
.unwrap();
|
|
||||||
invoker.replay(serde_json::from_reader(file).unwrap());
|
|
||||||
|
|
||||||
let (mut autorouter, ..) = invoker.destruct();
|
let (mut autorouter, ..) = invoker.destruct();
|
||||||
|
|
||||||
|
|
@ -71,18 +66,16 @@ fn test_four_3rd_order_smd_lc_filters() {
|
||||||
//common::assert_number_of_conncomps(&mut autorouter, 16);
|
//common::assert_number_of_conncomps(&mut autorouter, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: This test fails indeterministically.
|
||||||
#[test]
|
#[test]
|
||||||
fn test_3pin_xlr_tht_female_to_tht_female() {
|
fn test_3pin_xlr_tht_female_to_tht_female() {
|
||||||
let design = DsnDesign::load_from_file(
|
let mut invoker = common::load_design_and_assert(
|
||||||
"tests/single_layer/data/3pin_xlr_tht_female_to_tht_female/3pin_xlr_tht_female_to_tht_female.dsn"
|
"tests/single_layer/data/3pin_xlr_tht_female_to_tht_female/3pin_xlr_tht_female_to_tht_female.dsn",
|
||||||
|
);
|
||||||
|
common::replay_and_assert(
|
||||||
|
&mut invoker,
|
||||||
|
"tests/single_layer/data/3pin_xlr_tht_female_to_tht_female/autoroute_all.cmd",
|
||||||
);
|
);
|
||||||
let board = design.unwrap().make_board();
|
|
||||||
|
|
||||||
let mut invoker = Invoker::new(Autorouter::new(board).unwrap());
|
|
||||||
let file =
|
|
||||||
File::open("tests/single_layer/data/3pin_xlr_tht_female_to_tht_female/autoroute_all.cmd")
|
|
||||||
.unwrap();
|
|
||||||
invoker.replay(serde_json::from_reader(file).unwrap());
|
|
||||||
|
|
||||||
let (mut autorouter, ..) = invoker.destruct();
|
let (mut autorouter, ..) = invoker.destruct();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue