use eunoia::geometry::shapes::{Circle, Ellipse};
use eunoia::spec::DiagramSpec;
use eunoia::{DiagramSpecBuilder, Fitter, InputType};
use std::time::{Duration, Instant};
fn issue89_spec() -> DiagramSpec {
DiagramSpecBuilder::new()
.set("A", 55.0)
.set("B", 810.0)
.set("C", 102.0)
.set("D", 364.0)
.set("E", 101.0)
.set("F", 24.0)
.set("G", 34.0)
.set("H", 61.0)
.set("I", 194.0)
.set("J", 107.0)
.set("K", 53.0)
.set("L", 75.0)
.set("M", 11.0)
.set("N", 65.0)
.set("O", 16.0)
.set("P", 82.0)
.set("Q", 13.0)
.intersection(&["F", "O"], 5.0)
.intersection(&["G", "O"], 5.0)
.intersection(&["F", "G"], 5.0)
.intersection(&["D", "I"], 47.0)
.intersection(&["D", "E"], 33.0)
.intersection(&["K", "L"], 9.0)
.intersection(&["A", "K"], 7.0)
.intersection(&["K", "N"], 7.0)
.intersection(&["A", "N"], 7.0)
.intersection(&["A", "L"], 7.0)
.intersection(&["K", "P"], 7.0)
.intersection(&["A", "P"], 7.0)
.intersection(&["L", "N"], 7.0)
.intersection(&["N", "P"], 7.0)
.intersection(&["C", "K"], 7.0)
.intersection(&["A", "C"], 7.0)
.intersection(&["L", "P"], 7.0)
.intersection(&["E", "G"], 6.0)
.intersection(&["J", "K"], 7.0)
.intersection(&["A", "J"], 7.0)
.intersection(&["C", "O"], 5.0)
.intersection(&["G", "H"], 4.0)
.intersection(&["C", "N"], 7.0)
.intersection(&["J", "N"], 7.0)
.intersection(&["E", "F"], 5.0)
.intersection(&["C", "F"], 5.0)
.intersection(&["C", "L"], 7.0)
.intersection(&["J", "L"], 7.0)
.intersection(&["C", "P"], 7.0)
.intersection(&["J", "P"], 7.0)
.intersection(&["C", "G"], 5.0)
.intersection(&["D", "K"], 15.0)
.intersection(&["C", "J"], 7.0)
.intersection(&["A", "D"], 12.0)
.intersection(&["D", "L"], 12.0)
.intersection(&["E", "O"], 3.0)
.intersection(&["E", "H"], 4.0)
.intersection(&["C", "I"], 6.0)
.intersection(&["C", "D"], 8.0)
.intersection(&["D", "H"], 7.0)
.intersection(&["D", "N"], 7.0)
.intersection(&["D", "P"], 7.0)
.intersection(&["D", "J"], 7.0)
.intersection(&["C", "E"], 3.0)
.intersection(&["H", "O"], 1.0)
.intersection(&["B", "D"], 15.0)
.intersection(&["B", "C"], 11.0)
.intersection(&["F", "H"], 1.0)
.intersection(&["E", "M"], 1.0)
.intersection(&["B", "E"], 8.0)
.intersection(&["B", "K"], 7.0)
.intersection(&["I", "K"], 2.0)
.intersection(&["A", "B"], 7.0)
.intersection(&["B", "N"], 7.0)
.intersection(&["B", "L"], 7.0)
.intersection(&["B", "P"], 7.0)
.intersection(&["D", "F"], 3.0)
.intersection(&["B", "J"], 7.0)
.intersection(&["I", "L"], 2.0)
.intersection(&["C", "H"], 1.0)
.intersection(&["D", "O"], 1.0)
.intersection(&["D", "G"], 1.0)
.input_type(InputType::Exclusive)
.build()
.unwrap()
}
const TIME_BUDGET: Duration = Duration::from_secs(180);
#[test]
#[ignore = "slow: full 17-set fit"]
fn issue89_circles_terminate() {
let spec = issue89_spec();
let t0 = Instant::now();
let layout = Fitter::<Circle>::new(&spec).seed(1).fit().unwrap();
let elapsed = t0.elapsed();
assert!(
elapsed < TIME_BUDGET,
"circle fit took {elapsed:?}, exceeds budget {TIME_BUDGET:?}"
);
assert!(
layout.diag_error().is_finite(),
"diag_error must be finite, got {}",
layout.diag_error()
);
}
#[test]
#[ignore = "slow: full 17-set fit"]
fn issue89_ellipses_terminate() {
let spec = issue89_spec();
let t0 = Instant::now();
let layout = Fitter::<Ellipse>::new(&spec).seed(1).fit().unwrap();
let elapsed = t0.elapsed();
assert!(
elapsed < TIME_BUDGET,
"ellipse fit took {elapsed:?}, exceeds budget {TIME_BUDGET:?}"
);
assert!(
layout.diag_error().is_finite(),
"diag_error must be finite, got {}",
layout.diag_error()
);
}