use approx::abs_diff_eq;
use boostvoronoi::prelude::*;

type I = i32;

pub fn almost_equal(x1: f64, x2: f64, y1: f64, y2: f64) -> bool {
    let epsilon = 0.001;
    abs_diff_eq!(x1, x2, epsilon = epsilon) && abs_diff_eq!(y1, y2, epsilon = epsilon)
}

#[test]
fn single_segment_point_1() -> Result<(), BvError> {
    let output = {
        let _p = [Point { x: 9, y: 10 }];
        let _s = [Line::new(Point { x: 10, y: 11 }, Point { x: 12, y: 13 })];
        Builder::<I>::default()
            .with_vertices(_p.iter())?
            .with_segments(_s.iter())?
            .build()?
    };
    assert_eq!(output.cells().len(), 4);
    let cell = output.cells()[0];
    assert_eq!(cell.id(), 0);
    assert_eq!(cell.source_index(), 0);
    let cell = output.cells()[1];
    assert_eq!(cell.id(), 1);
    assert_eq!(cell.source_index(), 1);
    let cell = output.cells()[2];
    assert_eq!(cell.id(), 2);
    assert_eq!(cell.source_index(), 1);
    let cell = output.cells()[3];
    assert_eq!(cell.id(), 3);
    assert_eq!(cell.source_index(), 1);
    assert_eq!(output.vertices().len(), 0);
    assert_eq!(output.edges().len(), 6);
    assert_eq!(output.edges().first().unwrap().cell()?, 0);
    assert!(output.edges().first().unwrap().vertex0().is_none());
    assert_eq!(output.edges().first().unwrap().twin()?, 1);
    assert_eq!(output.edges().first().unwrap().next()?, 0);
    assert_eq!(output.edges().first().unwrap().prev()?, 0);
    assert_eq!(output.edges().get(1).unwrap().cell()?, 1);
    assert!(output.edges().get(1).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(1).unwrap().twin()?, 0);
    assert_eq!(output.edges().get(1).unwrap().next()?, 2);
    assert_eq!(output.edges().get(1).unwrap().prev()?, 2);
    assert_eq!(output.edges().get(2).unwrap().cell()?, 1);
    assert!(output.edges().get(2).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(2).unwrap().twin()?, 3);
    assert_eq!(output.edges().get(2).unwrap().next()?, 1);
    assert_eq!(output.edges().get(2).unwrap().prev()?, 1);
    assert_eq!(output.edges().get(3).unwrap().cell()?, 2);
    assert!(output.edges().get(3).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(3).unwrap().twin()?, 2);
    assert_eq!(output.edges().get(3).unwrap().next()?, 4);
    assert_eq!(output.edges().get(3).unwrap().prev()?, 4);
    assert_eq!(output.edges().get(4).unwrap().cell()?, 2);
    assert!(output.edges().get(4).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(4).unwrap().twin()?, 5);
    assert_eq!(output.edges().get(4).unwrap().next()?, 3);
    assert_eq!(output.edges().get(4).unwrap().prev()?, 3);
    assert_eq!(output.edges().get(5).unwrap().cell()?, 3);
    assert!(output.edges().get(5).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(5).unwrap().twin()?, 4);
    assert_eq!(output.edges().get(5).unwrap().next()?, 5);
    assert_eq!(output.edges().get(5).unwrap().prev()?, 5);
    Ok(())
}

#[allow(clippy::excessive_precision)]
#[test]
fn single_segment_point_2() -> Result<(), BvError> {
    let point_new = |x, y| Point::<I> { x, y };

    let output = {
        let _p = [point_new(12, 14)];
        let _s = [Line::new(point_new(10, 11), point_new(12, 13))];
        Builder::<I>::default()
            .with_vertices(_p.iter())?
            .with_segments(_s.iter())?
            .build()?
    };
    assert_eq!(output.cells().len(), 4);
    let cell = output.cells()[0];
    assert_eq!(cell.id(), 0);
    assert_eq!(cell.source_index(), 1);
    assert!(!cell.is_degenerate());
    assert!(cell.contains_point());
    assert!(!cell.contains_segment());
    let cell = output.cells()[1];
    assert_eq!(cell.id(), 1);
    assert_eq!(cell.source_index(), 1);
    assert!(!cell.is_degenerate());
    assert!(!cell.contains_point());
    assert!(cell.contains_segment());
    let cell = output.cells()[2];
    assert_eq!(cell.id(), 2);
    assert_eq!(cell.source_index(), 1);
    assert!(!cell.is_degenerate());
    assert!(cell.contains_point());
    assert!(!cell.contains_segment());
    let cell = output.cells()[3];
    assert_eq!(cell.id(), 3);
    assert_eq!(cell.source_index(), 0);
    assert!(!cell.is_degenerate());
    assert!(cell.contains_point());
    assert!(!cell.contains_segment());
    assert_eq!(output.vertices().len(), 2);
    assert_eq!(output.edges().len(), 10);
    let v = output.vertices()[0];
    assert!(almost_equal(v.x(), 11.5000000, v.y(), 13.5000000));
    assert_eq!(v.get_incident_edge()?, 7);
    let v = output.vertices()[1];
    assert!(almost_equal(v.x(), 3.5000000, v.y(), 17.5000000));
    assert_eq!(v.get_incident_edge()?, 9);
    assert_eq!(output.edges().first().unwrap().cell()?, 0);
    assert!(output.edges().first().unwrap().vertex0().is_none());
    assert_eq!(output.edges().first().unwrap().twin()?, 1);
    assert_eq!(output.edges().first().unwrap().next()?, 9);
    assert_eq!(output.edges().first().unwrap().prev()?, 9);
    let e = output.edges()[0];
    assert_eq!(output.edge_get_vertex1(e.id())?.unwrap(), 1);
    assert_eq!(output.edge_rot_next(e.id()).unwrap(), 8);
    assert_eq!(output.edge_rot_prev(e.id()).unwrap(), 2);
    assert!(!output.edge_is_finite(e.id())?);
    assert!(output.edge_is_infinite(e.id())?);
    assert!(e.is_linear());
    assert!(!e.is_curved());
    assert!(!e.is_primary());
    assert!(e.is_secondary());
    assert_eq!(output.edges().get(1).unwrap().cell()?, 1);
    assert_eq!(output.edges().get(1).unwrap().vertex0().unwrap(), 1);
    assert_eq!(output.edges().get(1).unwrap().twin()?, 0);
    assert_eq!(output.edges().get(1).unwrap().next()?, 2);
    assert_eq!(output.edges().get(1).unwrap().prev()?, 4);
    let e = output.edges()[1];
    assert!(output.edge_get_vertex1(e.id())?.is_none());
    assert_eq!(output.edge_rot_next(e.id()).unwrap(), 5);
    assert_eq!(output.edge_rot_prev(e.id()).unwrap(), 9);
    assert!(!output.edge_is_finite(e.id())?);
    assert!(output.edge_is_infinite(e.id())?);
    assert!(e.is_linear());
    assert!(!e.is_curved());
    assert!(!e.is_primary());
    assert!(e.is_secondary());
    assert_eq!(output.edges().get(2).unwrap().cell()?, 1);
    assert!(output.edges().get(2).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(2).unwrap().twin()?, 3);
    assert_eq!(output.edges().get(2).unwrap().next()?, 4);
    assert_eq!(output.edges().get(2).unwrap().prev()?, 1);
    let e = output.edges()[2];
    assert_eq!(output.edge_get_vertex1(e.id())?.unwrap(), 0);
    assert_eq!(output.edge_rot_next(e.id()).unwrap(), 0);
    assert_eq!(output.edge_rot_prev(e.id()).unwrap(), 6);
    assert!(!output.edge_is_finite(e.id())?);
    assert!(output.edge_is_infinite(e.id())?);
    assert!(e.is_linear());
    assert!(!e.is_curved());
    assert!(!e.is_primary());
    assert!(e.is_secondary());
    assert_eq!(output.edges().get(3).unwrap().cell()?, 2);
    assert_eq!(output.edges().get(3).unwrap().vertex0().unwrap(), 0);
    assert_eq!(output.edges().get(3).unwrap().twin()?, 2);
    assert_eq!(output.edges().get(3).unwrap().next()?, 6);
    assert_eq!(output.edges().get(3).unwrap().prev()?, 6);
    let e = output.edges()[3];
    assert!(output.edge_get_vertex1(e.id())?.is_none());
    assert_eq!(output.edge_rot_next(e.id()).unwrap(), 7);
    assert_eq!(output.edge_rot_prev(e.id()).unwrap(), 4);
    assert!(!output.edge_is_finite(e.id())?);
    assert!(output.edge_is_infinite(e.id())?);
    assert!(e.is_linear());
    assert!(!e.is_curved());
    assert!(!e.is_primary());
    assert!(e.is_secondary());
    assert_eq!(output.edges().get(4).unwrap().cell()?, 1);
    assert_eq!(output.edges().get(4).unwrap().vertex0().unwrap(), 0);
    assert_eq!(output.edges().get(4).unwrap().twin()?, 5);
    assert_eq!(output.edges().get(4).unwrap().next()?, 1);
    assert_eq!(output.edges().get(4).unwrap().prev()?, 2);
    let e = output.edges()[4];
    assert_eq!(output.edge_get_vertex1(e.id())?.unwrap(), 1);
    assert_eq!(output.edge_rot_next(e.id()).unwrap(), 3);
    assert_eq!(output.edge_rot_prev(e.id()).unwrap(), 7);
    assert!(output.edge_is_finite(e.id())?);
    assert!(!output.edge_is_infinite(e.id())?);
    assert!(!e.is_linear());
    assert!(e.is_curved());
    assert!(e.is_primary());
    assert!(!e.is_secondary());
    assert_eq!(output.edges().get(5).unwrap().cell()?, 3);
    assert_eq!(output.edges().get(5).unwrap().vertex0().unwrap(), 1);
    assert_eq!(output.edges().get(5).unwrap().twin()?, 4);
    assert_eq!(output.edges().get(5).unwrap().next()?, 7);
    assert_eq!(output.edges().get(5).unwrap().prev()?, 8);
    let e = output.edges()[5];
    assert_eq!(output.edge_get_vertex1(e.id())?.unwrap(), 0);
    assert_eq!(output.edge_rot_next(e.id()).unwrap(), 9);
    assert_eq!(output.edge_rot_prev(e.id()).unwrap(), 1);
    assert!(output.edge_is_finite(e.id())?);
    assert!(!output.edge_is_infinite(e.id())?);
    assert!(!e.is_linear());
    assert!(e.is_curved());
    assert!(e.is_primary());
    assert!(!e.is_secondary());
    assert_eq!(output.edges().get(6).unwrap().cell()?, 2);
    assert!(output.edges().get(6).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(6).unwrap().twin()?, 7);
    assert_eq!(output.edges().get(6).unwrap().next()?, 3);
    assert_eq!(output.edges().get(6).unwrap().prev()?, 3);
    let e = output.edges()[6];
    assert_eq!(output.edge_get_vertex1(e.id())?.unwrap(), 0);
    assert_eq!(output.edge_rot_next(e.id()).unwrap(), 2);
    assert_eq!(output.edge_rot_prev(e.id()).unwrap(), 8);
    assert!(!output.edge_is_finite(e.id())?);
    assert!(output.edge_is_infinite(e.id())?);
    assert!(e.is_linear());
    assert!(!e.is_curved());
    assert!(e.is_primary());
    assert!(!e.is_secondary());
    assert_eq!(output.edges().get(7).unwrap().cell()?, 3);
    assert_eq!(output.edges().get(7).unwrap().vertex0().unwrap(), 0);
    assert_eq!(output.edges().get(7).unwrap().twin()?, 6);
    assert_eq!(output.edges().get(7).unwrap().next()?, 8);
    assert_eq!(output.edges().get(7).unwrap().prev()?, 5);
    let e = output.edges()[7];
    assert!(output.edge_get_vertex1(e.id())?.is_none());
    assert_eq!(output.edge_rot_next(e.id()).unwrap(), 4);
    assert_eq!(output.edge_rot_prev(e.id()).unwrap(), 3);
    assert!(!output.edge_is_finite(e.id())?);
    assert!(output.edge_is_infinite(e.id())?);
    assert!(e.is_linear());
    assert!(!e.is_curved());
    assert!(e.is_primary());
    assert!(!e.is_secondary());
    assert_eq!(output.edges().get(8).unwrap().cell()?, 3);
    assert!(output.edges().get(8).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(8).unwrap().twin()?, 9);
    assert_eq!(output.edges().get(8).unwrap().next()?, 5);
    assert_eq!(output.edges().get(8).unwrap().prev()?, 7);
    let e = output.edges()[8];
    assert_eq!(output.edge_get_vertex1(e.id())?.unwrap(), 1);
    assert_eq!(output.edge_rot_next(e.id()).unwrap(), 6);
    assert_eq!(output.edge_rot_prev(e.id()).unwrap(), 0);
    assert!(!output.edge_is_finite(e.id())?);
    assert!(output.edge_is_infinite(e.id())?);
    assert!(e.is_linear());
    assert!(!e.is_curved());
    assert!(e.is_primary());
    assert!(!e.is_secondary());
    assert_eq!(output.edges().get(9).unwrap().cell()?, 0);
    assert_eq!(output.edges().get(9).unwrap().vertex0().unwrap(), 1);
    assert_eq!(output.edges().get(9).unwrap().twin()?, 8);
    assert_eq!(output.edges().get(9).unwrap().next()?, 0);
    assert_eq!(output.edges().get(9).unwrap().prev()?, 0);
    let e = output.edges()[9];
    assert!(output.edge_get_vertex1(e.id())?.is_none());
    assert_eq!(output.edge_rot_next(e.id()).unwrap(), 1);
    assert_eq!(output.edge_rot_prev(e.id()).unwrap(), 5);
    assert!(!output.edge_is_finite(e.id())?);
    assert!(output.edge_is_infinite(e.id())?);
    assert!(e.is_linear());
    assert!(!e.is_curved());
    assert!(e.is_primary());
    assert!(!e.is_secondary());
    Ok(())
}

#[test]
fn single_segment_point_3() -> Result<(), BvError> {
    let point_new = |x, y| Point::<I> { x, y };
    let output = {
        let _p = [point_new(12, 14), point_new(4, 5)];
        let _s = [Line::new(point_new(10, 11), point_new(12, 13))];
        Builder::<I>::default()
            .with_vertices(_p.iter())?
            .with_segments(_s.iter())?
            .build()?
    };
    assert_eq!(output.cells().len(), 5);
    let cell = output.cells()[0];
    assert_eq!(cell.id(), 0);
    assert_eq!(cell.source_index(), 1);
    let cell = output.cells()[1];
    assert_eq!(cell.id(), 1);
    assert_eq!(cell.source_index(), 2);
    let cell = output.cells()[2];
    assert_eq!(cell.id(), 2);
    assert_eq!(cell.source_index(), 2);
    let cell = output.cells()[3];
    assert_eq!(cell.id(), 3);
    assert_eq!(cell.source_index(), 2);
    let cell = output.cells()[4];
    assert_eq!(cell.id(), 4);
    assert_eq!(cell.source_index(), 0);
    assert_eq!(output.vertices().len(), 3);
    assert_eq!(output.edges().len(), 14);
    let v = output.vertices()[0];
    assert!(almost_equal(v.x(), 11.5, v.y(), 13.5));
    let v = output.vertices()[1];
    assert!(almost_equal(v.x(), 3.5, v.y(), 17.5));
    let v = output.vertices()[2];
    assert!(almost_equal(v.x(), -14.5, v.y(), 29.5));
    assert_eq!(output.edges().first().unwrap().cell()?, 0);
    assert!(output.edges().first().unwrap().vertex0().is_none());
    assert_eq!(output.edges().first().unwrap().twin()?, 1);
    assert_eq!(output.edges().first().unwrap().next()?, 13);
    assert_eq!(output.edges().first().unwrap().prev()?, 13);
    assert_eq!(output.edges().get(1).unwrap().cell()?, 1);
    assert_eq!(output.edges().get(1).unwrap().vertex0().unwrap(), 2);
    assert_eq!(output.edges().get(1).unwrap().twin()?, 0);
    assert_eq!(output.edges().get(1).unwrap().next()?, 2);
    assert_eq!(output.edges().get(1).unwrap().prev()?, 11);
    assert_eq!(output.edges().get(2).unwrap().cell()?, 1);
    assert!(output.edges().get(2).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(2).unwrap().twin()?, 3);
    assert_eq!(output.edges().get(2).unwrap().next()?, 11);
    assert_eq!(output.edges().get(2).unwrap().prev()?, 1);
    assert_eq!(output.edges().get(3).unwrap().cell()?, 2);
    assert_eq!(output.edges().get(3).unwrap().vertex0().unwrap(), 1);
    assert_eq!(output.edges().get(3).unwrap().twin()?, 2);
    assert_eq!(output.edges().get(3).unwrap().next()?, 4);
    assert_eq!(output.edges().get(3).unwrap().prev()?, 6);
    assert_eq!(output.edges().get(4).unwrap().cell()?, 2);
    assert!(output.edges().get(4).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(4).unwrap().twin()?, 5);
    assert_eq!(output.edges().get(4).unwrap().next()?, 6);
    assert_eq!(output.edges().get(4).unwrap().prev()?, 3);
    assert_eq!(output.edges().get(5).unwrap().cell()?, 3);
    assert_eq!(output.edges().get(5).unwrap().vertex0().unwrap(), 0);
    assert_eq!(output.edges().get(5).unwrap().twin()?, 4);
    assert_eq!(output.edges().get(5).unwrap().next()?, 8);
    assert_eq!(output.edges().get(5).unwrap().prev()?, 8);
    assert_eq!(output.edges().get(6).unwrap().cell()?, 2);
    assert_eq!(output.edges().get(6).unwrap().vertex0().unwrap(), 0);
    assert_eq!(output.edges().get(6).unwrap().twin()?, 7);
    assert_eq!(output.edges().get(6).unwrap().next()?, 3);
    assert_eq!(output.edges().get(6).unwrap().prev()?, 4);
    assert_eq!(output.edges().get(7).unwrap().cell()?, 4);
    assert_eq!(output.edges().get(7).unwrap().vertex0().unwrap(), 1);
    assert_eq!(output.edges().get(7).unwrap().twin()?, 6);
    assert_eq!(output.edges().get(7).unwrap().next()?, 9);
    assert_eq!(output.edges().get(7).unwrap().prev()?, 10);
    assert_eq!(output.edges().get(8).unwrap().cell()?, 3);
    assert!(output.edges().get(8).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(8).unwrap().twin()?, 9);
    assert_eq!(output.edges().get(8).unwrap().next()?, 5);
    assert_eq!(output.edges().get(8).unwrap().prev()?, 5);
    assert_eq!(output.edges().get(9).unwrap().cell()?, 4);
    assert_eq!(output.edges().get(9).unwrap().vertex0().unwrap(), 0);
    assert_eq!(output.edges().get(9).unwrap().twin()?, 8);
    assert_eq!(output.edges().get(9).unwrap().next()?, 12);
    assert_eq!(output.edges().get(9).unwrap().prev()?, 7);
    assert_eq!(output.edges().get(10).unwrap().cell()?, 4);
    assert_eq!(output.edges().get(10).unwrap().vertex0().unwrap(), 2);
    assert_eq!(output.edges().get(10).unwrap().twin()?, 11);
    assert_eq!(output.edges().get(10).unwrap().next()?, 7);
    assert_eq!(output.edges().get(10).unwrap().prev()?, 12);
    assert_eq!(output.edges().get(11).unwrap().cell()?, 1);
    assert_eq!(output.edges().get(11).unwrap().vertex0().unwrap(), 1);
    assert_eq!(output.edges().get(11).unwrap().twin()?, 10);
    assert_eq!(output.edges().get(11).unwrap().next()?, 1);
    assert_eq!(output.edges().get(11).unwrap().prev()?, 2);
    assert_eq!(output.edges().get(12).unwrap().cell()?, 4);
    assert!(output.edges().get(12).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(12).unwrap().twin()?, 13);
    assert_eq!(output.edges().get(12).unwrap().next()?, 10);
    assert_eq!(output.edges().get(12).unwrap().prev()?, 9);
    assert_eq!(output.edges().get(13).unwrap().cell()?, 0);
    assert_eq!(output.edges().get(13).unwrap().vertex0().unwrap(), 2);
    assert_eq!(output.edges().get(13).unwrap().twin()?, 12);
    assert_eq!(output.edges().get(13).unwrap().next()?, 0);
    assert_eq!(output.edges().get(13).unwrap().prev()?, 0);
    Ok(())
}

#[test]
fn single_segment_point_4() -> Result<(), BvError> {
    let point_new = |x, y| Point::<I> { x, y };
    let output = {
        let _p = [point_new(10, 14), point_new(8, 7), point_new(11, 11)];
        let _s = [Line::new(point_new(10, 11), point_new(12, 13))];
        Builder::<I>::default()
            .with_vertices(_p.iter())
            .expect("single_segment_point_3")
            .with_segments(_s.iter())
            .expect("single_segment_point_3")
            .build()
            .expect("single_segment_point_3")
    };
    assert_eq!(output.cells().len(), 6);
    let cell = output.cells()[0];
    assert_eq!(cell.id(), 0);
    assert_eq!(cell.source_index(), 1);
    let cell = output.cells()[1];
    assert_eq!(cell.id(), 1);
    assert_eq!(cell.source_index(), 3);
    let cell = output.cells()[2];
    assert_eq!(cell.id(), 2);
    assert_eq!(cell.source_index(), 0);
    let cell = output.cells()[3];
    assert_eq!(cell.id(), 3);
    assert_eq!(cell.source_index(), 3);
    let cell = output.cells()[4];
    assert_eq!(cell.id(), 4);
    assert_eq!(cell.source_index(), 2);
    let cell = output.cells()[5];
    assert_eq!(cell.id(), 5);
    assert_eq!(cell.source_index(), 3);
    assert_eq!(output.vertices().len(), 6);
    assert_eq!(output.edges().len(), 22);
    let v = output.vertices()[0];
    assert!(almost_equal(v.x(), 2.0, v.y(), 12.5));
    let v = output.vertices()[1];
    assert!(almost_equal(v.x(), 8.5, v.y(), 12.5));
    let v = output.vertices()[2];
    assert!(almost_equal(v.x(), 10.5, v.y(), 10.5));
    let v = output.vertices()[3];
    assert!(almost_equal(v.x(), 11.1667, v.y(), 13.8333));
    let v = output.vertices()[4];
    assert!(almost_equal(v.x(), 10.5, v.y(), 8.25));
    let v = output.vertices()[5];
    assert!(almost_equal(v.x(), 14.5, v.y(), 10.5));
    assert_eq!(output.edges().first().unwrap().cell()?, 0);
    assert_eq!(output.edges().first().unwrap().vertex0().unwrap(), 4);
    assert_eq!(output.edges().first().unwrap().twin()?, 1);
    assert_eq!(output.edges().first().unwrap().next()?, 2);
    assert_eq!(output.edges().first().unwrap().prev()?, 18);
    assert_eq!(output.edges().get(1).unwrap().cell()?, 1);
    assert_eq!(output.edges().get(1).unwrap().vertex0().unwrap(), 0);
    assert_eq!(output.edges().get(1).unwrap().twin()?, 0);
    assert_eq!(output.edges().get(1).unwrap().next()?, 12);
    assert_eq!(output.edges().get(1).unwrap().prev()?, 6);
    assert_eq!(output.edges().get(2).unwrap().cell()?, 0);
    assert_eq!(output.edges().get(2).unwrap().vertex0().unwrap(), 0);
    assert_eq!(output.edges().get(2).unwrap().twin()?, 3);
    assert_eq!(output.edges().get(2).unwrap().next()?, 18);
    assert_eq!(output.edges().get(2).unwrap().prev()?, 0);
    assert_eq!(output.edges().get(3).unwrap().cell()?, 2);
    assert!(output.edges().get(3).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(3).unwrap().twin()?, 2);
    assert_eq!(output.edges().get(3).unwrap().next()?, 7);
    assert_eq!(output.edges().get(3).unwrap().prev()?, 17);
    assert_eq!(output.edges().get(4).unwrap().cell()?, 1);
    assert_eq!(output.edges().get(4).unwrap().vertex0().unwrap(), 2);
    assert_eq!(output.edges().get(4).unwrap().twin()?, 5);
    assert_eq!(output.edges().get(4).unwrap().next()?, 6);
    assert_eq!(output.edges().get(4).unwrap().prev()?, 12);
    assert_eq!(output.edges().get(5).unwrap().cell()?, 3);
    assert_eq!(output.edges().get(5).unwrap().vertex0().unwrap(), 1);
    assert_eq!(output.edges().get(5).unwrap().twin()?, 4);
    assert_eq!(output.edges().get(5).unwrap().next()?, 10);
    assert_eq!(output.edges().get(5).unwrap().prev()?, 8);
    assert_eq!(output.edges().get(6).unwrap().cell()?, 1);
    assert_eq!(output.edges().get(6).unwrap().vertex0().unwrap(), 1);
    assert_eq!(output.edges().get(6).unwrap().twin()?, 7);
    assert_eq!(output.edges().get(6).unwrap().next()?, 1);
    assert_eq!(output.edges().get(6).unwrap().prev()?, 4);
    assert_eq!(output.edges().get(7).unwrap().cell()?, 2);
    assert_eq!(output.edges().get(7).unwrap().vertex0().unwrap(), 0);
    assert_eq!(output.edges().get(7).unwrap().twin()?, 6);
    assert_eq!(output.edges().get(7).unwrap().next()?, 9);
    assert_eq!(output.edges().get(7).unwrap().prev()?, 3);
    assert_eq!(output.edges().get(8).unwrap().cell()?, 3);
    assert_eq!(output.edges().get(8).unwrap().vertex0().unwrap(), 3);
    assert_eq!(output.edges().get(8).unwrap().twin()?, 9);
    assert_eq!(output.edges().get(8).unwrap().next()?, 5);
    assert_eq!(output.edges().get(8).unwrap().prev()?, 14);
    assert_eq!(output.edges().get(9).unwrap().cell()?, 2);
    assert_eq!(output.edges().get(9).unwrap().vertex0().unwrap(), 1);
    assert_eq!(output.edges().get(9).unwrap().twin()?, 8);
    assert_eq!(output.edges().get(9).unwrap().next()?, 17);
    assert_eq!(output.edges().get(9).unwrap().prev()?, 7);
    assert_eq!(output.edges().get(10).unwrap().cell()?, 3);
    assert_eq!(output.edges().get(10).unwrap().vertex0().unwrap(), 2);
    assert_eq!(output.edges().get(10).unwrap().twin()?, 11);
    assert_eq!(output.edges().get(10).unwrap().next()?, 14);
    assert_eq!(output.edges().get(10).unwrap().prev()?, 5);
    assert_eq!(output.edges().get(11).unwrap().cell()?, 4);
    assert_eq!(output.edges().get(11).unwrap().vertex0().unwrap(), 5);
    assert_eq!(output.edges().get(11).unwrap().twin()?, 10);
    assert_eq!(output.edges().get(11).unwrap().next()?, 13);
    assert_eq!(output.edges().get(11).unwrap().prev()?, 20);
    assert_eq!(output.edges().get(12).unwrap().cell()?, 1);
    assert_eq!(output.edges().get(12).unwrap().vertex0().unwrap(), 4);
    assert_eq!(output.edges().get(12).unwrap().twin()?, 13);
    assert_eq!(output.edges().get(12).unwrap().next()?, 4);
    assert_eq!(output.edges().get(12).unwrap().prev()?, 1);
    assert_eq!(output.edges().get(13).unwrap().cell()?, 4);
    assert_eq!(output.edges().get(13).unwrap().vertex0().unwrap(), 2);
    assert_eq!(output.edges().get(13).unwrap().twin()?, 12);
    assert_eq!(output.edges().get(13).unwrap().next()?, 19);
    assert_eq!(output.edges().get(13).unwrap().prev()?, 11);
    assert_eq!(output.edges().get(14).unwrap().cell()?, 3);
    assert_eq!(output.edges().get(14).unwrap().vertex0().unwrap(), 5);
    assert_eq!(output.edges().get(14).unwrap().twin()?, 15);
    assert_eq!(output.edges().get(14).unwrap().next()?, 8);
    assert_eq!(output.edges().get(14).unwrap().prev()?, 10);
    assert_eq!(output.edges().get(15).unwrap().cell()?, 5);
    assert_eq!(output.edges().get(15).unwrap().vertex0().unwrap(), 3);
    assert_eq!(output.edges().get(15).unwrap().twin()?, 14);
    assert_eq!(output.edges().get(15).unwrap().next()?, 21);
    assert_eq!(output.edges().get(15).unwrap().prev()?, 16);
    assert_eq!(output.edges().get(16).unwrap().cell()?, 5);
    assert!(output.edges().get(16).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(16).unwrap().twin()?, 17);
    assert_eq!(output.edges().get(16).unwrap().next()?, 15);
    assert_eq!(output.edges().get(16).unwrap().prev()?, 21);
    assert_eq!(output.edges().get(17).unwrap().cell()?, 2);
    assert_eq!(output.edges().get(17).unwrap().vertex0().unwrap(), 3);
    assert_eq!(output.edges().get(17).unwrap().twin()?, 16);
    assert_eq!(output.edges().get(17).unwrap().next()?, 3);
    assert_eq!(output.edges().get(17).unwrap().prev()?, 9);
    assert_eq!(output.edges().get(18).unwrap().cell()?, 0);
    assert!(output.edges().get(18).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(18).unwrap().twin()?, 19);
    assert_eq!(output.edges().get(18).unwrap().next()?, 0);
    assert_eq!(output.edges().get(18).unwrap().prev()?, 2);
    assert_eq!(output.edges().get(19).unwrap().cell()?, 4);
    assert_eq!(output.edges().get(19).unwrap().vertex0().unwrap(), 4);
    assert_eq!(output.edges().get(19).unwrap().twin()?, 18);
    assert_eq!(output.edges().get(19).unwrap().next()?, 20);
    assert_eq!(output.edges().get(19).unwrap().prev()?, 13);
    assert_eq!(output.edges().get(20).unwrap().cell()?, 4);
    assert!(output.edges().get(20).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(20).unwrap().twin()?, 21);
    assert_eq!(output.edges().get(20).unwrap().next()?, 11);
    assert_eq!(output.edges().get(20).unwrap().prev()?, 19);
    assert_eq!(output.edges().get(21).unwrap().cell()?, 5);
    assert_eq!(output.edges().get(21).unwrap().vertex0().unwrap(), 5);
    assert_eq!(output.edges().get(21).unwrap().twin()?, 20);
    assert_eq!(output.edges().get(21).unwrap().next()?, 16);
    assert_eq!(output.edges().get(21).unwrap().prev()?, 15);
    Ok(())
}

#[test]
fn single_segment_point_5() -> Result<(), BvError> {
    let point_new = |x, y| Point::<I> { x, y };
    let output = {
        let _p = [point_new(10, 14), point_new(8, 7), point_new(11, 11)];
        let _s = [Line::new(point_new(12, 13), point_new(10, 11))];
        Builder::<I>::default()
            .with_vertices(_p.iter())?
            .with_segments(_s.iter())?
            .build()?
    };
    assert_eq!(output.cells().len(), 6);
    let cell = output.cells()[0];
    assert_eq!(cell.id(), 0);
    assert_eq!(cell.source_index(), 1);
    let cell = output.cells()[1];
    assert_eq!(cell.id(), 1);
    assert_eq!(cell.source_index(), 3);
    let cell = output.cells()[2];
    assert_eq!(cell.id(), 2);
    assert_eq!(cell.source_index(), 0);
    let cell = output.cells()[3];
    assert_eq!(cell.id(), 3);
    assert_eq!(cell.source_index(), 3);
    let cell = output.cells()[4];
    assert_eq!(cell.id(), 4);
    assert_eq!(cell.source_index(), 2);
    let cell = output.cells()[5];
    assert_eq!(cell.id(), 5);
    assert_eq!(cell.source_index(), 3);
    assert_eq!(output.vertices().len(), 6);
    assert_eq!(output.edges().len(), 22);
    let v = output.vertices()[0];
    assert!(almost_equal(v.x(), 2.0, v.y(), 12.5));
    let v = output.vertices()[1];
    assert!(almost_equal(v.x(), 8.5, v.y(), 12.5));
    let v = output.vertices()[2];
    assert!(almost_equal(v.x(), 10.5, v.y(), 10.5));
    let v = output.vertices()[3];
    assert!(almost_equal(v.x(), 11.1667, v.y(), 13.8333));
    let v = output.vertices()[4];
    assert!(almost_equal(v.x(), 10.5, v.y(), 8.25));
    let v = output.vertices()[5];
    assert!(almost_equal(v.x(), 14.5, v.y(), 10.5));
    assert_eq!(output.edges().first().unwrap().cell()?, 0);
    assert_eq!(output.edges().first().unwrap().vertex0().unwrap(), 4);
    assert_eq!(output.edges().first().unwrap().twin()?, 1);
    assert_eq!(output.edges().first().unwrap().next()?, 2);
    assert_eq!(output.edges().first().unwrap().prev()?, 18);
    assert_eq!(output.edges().get(1).unwrap().cell()?, 1);
    assert_eq!(output.edges().get(1).unwrap().vertex0().unwrap(), 0);
    assert_eq!(output.edges().get(1).unwrap().twin()?, 0);
    assert_eq!(output.edges().get(1).unwrap().next()?, 12);
    assert_eq!(output.edges().get(1).unwrap().prev()?, 6);
    assert_eq!(output.edges().get(2).unwrap().cell()?, 0);
    assert_eq!(output.edges().get(2).unwrap().vertex0().unwrap(), 0);
    assert_eq!(output.edges().get(2).unwrap().twin()?, 3);
    assert_eq!(output.edges().get(2).unwrap().next()?, 18);
    assert_eq!(output.edges().get(2).unwrap().prev()?, 0);
    assert_eq!(output.edges().get(3).unwrap().cell()?, 2);
    assert!(output.edges().get(3).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(3).unwrap().twin()?, 2);
    assert_eq!(output.edges().get(3).unwrap().next()?, 7);
    assert_eq!(output.edges().get(3).unwrap().prev()?, 17);
    assert_eq!(output.edges().get(4).unwrap().cell()?, 1);
    assert_eq!(output.edges().get(4).unwrap().vertex0().unwrap(), 2);
    assert_eq!(output.edges().get(4).unwrap().twin()?, 5);
    assert_eq!(output.edges().get(4).unwrap().next()?, 6);
    assert_eq!(output.edges().get(4).unwrap().prev()?, 12);
    assert_eq!(output.edges().get(5).unwrap().cell()?, 3);
    assert_eq!(output.edges().get(5).unwrap().vertex0().unwrap(), 1);
    assert_eq!(output.edges().get(5).unwrap().twin()?, 4);
    assert_eq!(output.edges().get(5).unwrap().next()?, 10);
    assert_eq!(output.edges().get(5).unwrap().prev()?, 8);
    assert_eq!(output.edges().get(6).unwrap().cell()?, 1);
    assert_eq!(output.edges().get(6).unwrap().vertex0().unwrap(), 1);
    assert_eq!(output.edges().get(6).unwrap().twin()?, 7);
    assert_eq!(output.edges().get(6).unwrap().next()?, 1);
    assert_eq!(output.edges().get(6).unwrap().prev()?, 4);
    assert_eq!(output.edges().get(7).unwrap().cell()?, 2);
    assert_eq!(output.edges().get(7).unwrap().vertex0().unwrap(), 0);
    assert_eq!(output.edges().get(7).unwrap().twin()?, 6);
    assert_eq!(output.edges().get(7).unwrap().next()?, 9);
    assert_eq!(output.edges().get(7).unwrap().prev()?, 3);
    assert_eq!(output.edges().get(8).unwrap().cell()?, 3);
    assert_eq!(output.edges().get(8).unwrap().vertex0().unwrap(), 3);
    assert_eq!(output.edges().get(8).unwrap().twin()?, 9);
    assert_eq!(output.edges().get(8).unwrap().next()?, 5);
    assert_eq!(output.edges().get(8).unwrap().prev()?, 14);
    assert_eq!(output.edges().get(9).unwrap().cell()?, 2);
    assert_eq!(output.edges().get(9).unwrap().vertex0().unwrap(), 1);
    assert_eq!(output.edges().get(9).unwrap().twin()?, 8);
    assert_eq!(output.edges().get(9).unwrap().next()?, 17);
    assert_eq!(output.edges().get(9).unwrap().prev()?, 7);
    assert_eq!(output.edges().get(10).unwrap().cell()?, 3);
    assert_eq!(output.edges().get(10).unwrap().vertex0().unwrap(), 2);
    assert_eq!(output.edges().get(10).unwrap().twin()?, 11);
    assert_eq!(output.edges().get(10).unwrap().next()?, 14);
    assert_eq!(output.edges().get(10).unwrap().prev()?, 5);
    assert_eq!(output.edges().get(11).unwrap().cell()?, 4);
    assert_eq!(output.edges().get(11).unwrap().vertex0().unwrap(), 5);
    assert_eq!(output.edges().get(11).unwrap().twin()?, 10);
    assert_eq!(output.edges().get(11).unwrap().next()?, 13);
    assert_eq!(output.edges().get(11).unwrap().prev()?, 20);
    assert_eq!(output.edges().get(12).unwrap().cell()?, 1);
    assert_eq!(output.edges().get(12).unwrap().vertex0().unwrap(), 4);
    assert_eq!(output.edges().get(12).unwrap().twin()?, 13);
    assert_eq!(output.edges().get(12).unwrap().next()?, 4);
    assert_eq!(output.edges().get(12).unwrap().prev()?, 1);
    assert_eq!(output.edges().get(13).unwrap().cell()?, 4);
    assert_eq!(output.edges().get(13).unwrap().vertex0().unwrap(), 2);
    assert_eq!(output.edges().get(13).unwrap().twin()?, 12);
    assert_eq!(output.edges().get(13).unwrap().next()?, 19);
    assert_eq!(output.edges().get(13).unwrap().prev()?, 11);
    assert_eq!(output.edges().get(14).unwrap().cell()?, 3);
    assert_eq!(output.edges().get(14).unwrap().vertex0().unwrap(), 5);
    assert_eq!(output.edges().get(14).unwrap().twin()?, 15);
    assert_eq!(output.edges().get(14).unwrap().next()?, 8);
    assert_eq!(output.edges().get(14).unwrap().prev()?, 10);
    assert_eq!(output.edges().get(15).unwrap().cell()?, 5);
    assert_eq!(output.edges().get(15).unwrap().vertex0().unwrap(), 3);
    assert_eq!(output.edges().get(15).unwrap().twin()?, 14);
    assert_eq!(output.edges().get(15).unwrap().next()?, 21);
    assert_eq!(output.edges().get(15).unwrap().prev()?, 16);
    assert_eq!(output.edges().get(16).unwrap().cell()?, 5);
    assert!(output.edges().get(16).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(16).unwrap().twin()?, 17);
    assert_eq!(output.edges().get(16).unwrap().next()?, 15);
    assert_eq!(output.edges().get(16).unwrap().prev()?, 21);
    assert_eq!(output.edges().get(17).unwrap().cell()?, 2);
    assert_eq!(output.edges().get(17).unwrap().vertex0().unwrap(), 3);
    assert_eq!(output.edges().get(17).unwrap().twin()?, 16);
    assert_eq!(output.edges().get(17).unwrap().next()?, 3);
    assert_eq!(output.edges().get(17).unwrap().prev()?, 9);
    assert_eq!(output.edges().get(18).unwrap().cell()?, 0);
    assert!(output.edges().get(18).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(18).unwrap().twin()?, 19);
    assert_eq!(output.edges().get(18).unwrap().next()?, 0);
    assert_eq!(output.edges().get(18).unwrap().prev()?, 2);
    assert_eq!(output.edges().get(19).unwrap().cell()?, 4);
    assert_eq!(output.edges().get(19).unwrap().vertex0().unwrap(), 4);
    assert_eq!(output.edges().get(19).unwrap().twin()?, 18);
    assert_eq!(output.edges().get(19).unwrap().next()?, 20);
    assert_eq!(output.edges().get(19).unwrap().prev()?, 13);
    assert_eq!(output.edges().get(20).unwrap().cell()?, 4);
    assert!(output.edges().get(20).unwrap().vertex0().is_none());
    assert_eq!(output.edges().get(20).unwrap().twin()?, 21);
    assert_eq!(output.edges().get(20).unwrap().next()?, 11);
    assert_eq!(output.edges().get(20).unwrap().prev()?, 19);
    assert_eq!(output.edges().get(21).unwrap().cell()?, 5);
    assert_eq!(output.edges().get(21).unwrap().vertex0().unwrap(), 5);
    assert_eq!(output.edges().get(21).unwrap().twin()?, 20);
    assert_eq!(output.edges().get(21).unwrap().next()?, 16);
    assert_eq!(output.edges().get(21).unwrap().prev()?, 15);
    Ok(())
}
