use crate::assert_slice_eq;
use crate::common;
#[test]
#[serial]
fn windows() {
common::reset();
let mut window = spice::Cell::<f64>::new(64);
assert_eq!(spice::wncard(&mut window), 0);
spice::wninsd(10.0, 20.0, &mut window);
spice::wninsd(30.0, 40.0, &mut window);
common::assert_ok("wninsd");
assert_eq!(spice::wncard(&mut window), 2);
assert_eq!(spice::wnfetd(&mut window, 0), (10.0, 20.0));
assert_eq!(spice::wnfetd(&mut window, 1), (30.0, 40.0));
spice::wninsd(15.0, 35.0, &mut window);
assert_eq!(spice::wncard(&mut window), 1);
assert_eq!(spice::wnfetd(&mut window, 0), (10.0, 40.0));
assert_eq!(window.len(), 2);
assert_eq!(window.to_vec(), vec![10.0, 40.0]);
common::unload();
}
#[test]
#[serial]
fn gfoclt() {
common::load();
let mut confinement = spice::Cell::<f64>::new(64);
spice::wninsd(0.0, common::LAST, &mut confinement);
let found = spice::gfoclt(
"ANY",
"MOON",
"ELLIPSOID",
"IAU_MOON",
"SUN",
"ELLIPSOID",
"IAU_SUN",
"NONE",
"EARTH",
3600.0,
&mut confinement,
);
common::assert_ok("gfoclt");
let mut found = found;
let intervals = spice::wncard(&mut found);
assert!(
intervals >= 1,
"the satellite should cross the solar disc once"
);
let (start, stop) = spice::wnfetd(&mut found, 0);
assert!(start < stop);
assert!(
(13.0 * 86400.0..16.0 * 86400.0).contains(&start),
"expected the crossing around 14.75 days, got {}",
start / 86400.0
);
let inside = spice::occult(
"MOON",
"ELLIPSOID",
"IAU_MOON",
"SUN",
"ELLIPSOID",
"IAU_SUN",
"NONE",
"EARTH",
(start + stop) / 2.0,
);
assert_ne!(inside, 0, "the geometry finder and occult should agree");
let outside = spice::occult(
"MOON",
"ELLIPSOID",
"IAU_MOON",
"SUN",
"ELLIPSOID",
"IAU_SUN",
"NONE",
"EARTH",
0.0,
);
assert_eq!(outside, 0);
let mut empty = spice::Cell::<f64>::new(8);
let mut nothing = spice::gfoclt(
"ANY",
"MOON",
"ELLIPSOID",
"IAU_MOON",
"SUN",
"ELLIPSOID",
"IAU_SUN",
"NONE",
"EARTH",
3600.0,
&mut empty,
);
common::assert_ok("gfoclt over an empty confinement");
assert_eq!(spice::wncard(&mut nothing), 0);
common::unload();
}
#[test]
#[serial]
fn window_arithmetic() {
common::reset();
let mut a = spice::Cell::<f64>::new(64);
let mut b = spice::Cell::<f64>::new(64);
for (left, right) in [(1.0, 3.0), (7.0, 11.0), (23.0, 26.0)] {
spice::wninsd(left, right, &mut a);
}
for (left, right) in [(2.0, 4.0), (8.0, 10.0), (16.0, 18.0)] {
spice::wninsd(left, right, &mut b);
}
common::assert_ok("building the windows");
let mut result = spice::Cell::<f64>::new(64);
spice::wnunid(&mut a, &mut b, &mut result);
assert_eq!(
result.to_vec(),
vec![1.0, 4.0, 7.0, 11.0, 16.0, 18.0, 23.0, 26.0]
);
spice::wnintd(&mut a, &mut b, &mut result);
assert_eq!(result.to_vec(), vec![2.0, 3.0, 8.0, 10.0]);
spice::wndifd(&mut a, &mut b, &mut result);
assert_eq!(
result.to_vec(),
vec![1.0, 2.0, 7.0, 8.0, 10.0, 11.0, 23.0, 26.0]
);
spice::wncomd(0.0, 30.0, &mut a, &mut result);
assert_eq!(
result.to_vec(),
vec![0.0, 1.0, 3.0, 7.0, 11.0, 23.0, 26.0, 30.0]
);
common::assert_ok("window set operations");
assert!(spice::wnelmd(2.0, &mut a));
assert!(!spice::wnelmd(5.0, &mut a));
assert!(spice::wnincd(1.5, 2.5, &mut a));
assert!(!spice::wnincd(1.5, 5.0, &mut a));
let mut same = a.clone();
assert!(spice::wnreld(&mut a, "=", &mut same));
assert!(!spice::wnreld(&mut a, "<>", &mut same));
assert!(spice::wnreld(&mut a, "<>", &mut b));
let (measure, average, deviation, shortest, longest) = spice::wnsumd(&mut a);
assert_relative_eq!(measure, 9.0, epsilon = 1e-12);
assert_relative_eq!(average, 3.0, epsilon = 1e-12);
assert_relative_eq!(deviation, (2.0f64 / 3.0).sqrt(), epsilon = 1e-12);
assert_eq!(shortest, 0, "the interval of length 2 is the first");
assert_eq!(longest, 2, "the interval of length 4 is the second");
common::unload();
}
#[test]
#[serial]
fn window_reshaping() {
common::reset();
let mut window = spice::Cell::<f64>::new(64);
for (left, right) in [(1.0, 3.0), (7.0, 11.0), (23.0, 27.0)] {
spice::wninsd(left, right, &mut window);
}
let mut expanded = window.clone();
spice::wnexpd(1.0, 1.0, &mut expanded);
assert_eq!(expanded.to_vec(), vec![0.0, 4.0, 6.0, 12.0, 22.0, 28.0]);
spice::wncond(1.0, 1.0, &mut expanded);
assert_eq!(expanded.to_vec(), window.to_vec());
let mut filled = window.clone();
spice::wnfild(5.0, &mut filled);
assert_eq!(filled.to_vec(), vec![1.0, 11.0, 23.0, 27.0]);
let mut filtered = window.clone();
spice::wnfltd(3.0, &mut filtered);
assert_eq!(filtered.to_vec(), vec![7.0, 11.0, 23.0, 27.0]);
let mut left = window.clone();
spice::wnextd('L', &mut left);
assert_eq!(left.to_vec(), vec![1.0, 1.0, 7.0, 7.0, 23.0, 23.0]);
let mut right = window.clone();
spice::wnextd('R', &mut right);
assert_eq!(right.to_vec(), vec![3.0, 3.0, 11.0, 11.0, 27.0, 27.0]);
common::assert_ok("reshaping windows");
common::unload();
}
const BEGIN: f64 = common::FIRST + common::STEP;
const END: f64 = common::LAST - common::STEP;
fn confinement() -> spice::Cell<f64> {
span(BEGIN, END)
}
fn span(start: f64, stop: f64) -> spice::Cell<f64> {
let mut window = spice::Cell::<f64>::new(64);
spice::wninsd(start, stop, &mut window);
window
}
fn midpoints(window: &mut spice::Cell<f64>) -> Vec<f64> {
(0..spice::wncard(window))
.map(|index| {
let (start, stop) = spice::wnfetd(window, index);
(start + stop) / 2.0
})
.collect()
}
fn crossings(window: &mut spice::Cell<f64>) -> Vec<f64> {
let mut found = Vec::new();
for index in 0..spice::wncard(window) {
let (start, stop) = spice::wnfetd(window, index);
for et in [start, stop] {
if et > BEGIN + 60.0 && et < END - 60.0 {
found.push(et);
}
}
}
found
}
fn state(target: &str, et: f64, observer: &str) -> ([f64; 3], [f64; 3]) {
let (state, _) = spice::spkezr(target, et, "J2000", "NONE", observer);
(
[state[0], state[1], state[2]],
[state[3], state[4], state[5]],
)
}
#[test]
#[serial]
fn distance_and_range_rate() {
common::load();
let mut cnfine = confinement();
let mut closer = spice::gfdist(
"MOON",
"NONE",
"SUN",
"<",
common::ORBIT_RADIUS,
0.0,
common::STEP,
&mut cnfine,
);
common::assert_ok("gfdist");
assert!(spice::wncard(&mut closer) >= 1, "the search found nothing");
for et in midpoints(&mut closer) {
let (position, _) = state("MOON", et, "SUN");
assert!(
spice::vnorm(position) < common::ORBIT_RADIUS,
"inside an interval the distance should be below the reference value"
);
}
for et in crossings(&mut closer) {
let (position, _) = state("MOON", et, "SUN");
assert_relative_eq!(spice::vnorm(position), common::ORBIT_RADIUS, epsilon = 1.0);
}
let mut cnfine = confinement();
let mut approaching = spice::gfrr(
"MOON",
"NONE",
"SUN",
"<",
0.0,
0.0,
common::STEP,
&mut cnfine,
);
common::assert_ok("gfrr");
assert!(spice::wncard(&mut approaching) >= 1);
for et in midpoints(&mut approaching) {
let (position, velocity) = state("MOON", et, "SUN");
assert!(
spice::vdot(position, velocity) < 0.0,
"the satellite should be approaching at {et}"
);
}
for et in crossings(&mut approaching) {
let (position, velocity) = state("MOON", et, "SUN");
let rate = spice::vdot(position, velocity) / spice::vnorm(position);
assert_relative_eq!(rate, 0.0, epsilon = 1e-6);
}
let mut cnfine = span(0.0, END);
let mut nearest = spice::gfdist(
"MOON",
"NONE",
"SUN",
"ABSMIN",
0.0,
0.0,
common::STEP,
&mut cnfine,
);
common::assert_ok("gfdist for the absolute minimum");
assert_eq!(spice::wncard(&mut nearest), 1);
let (start, stop) = spice::wnfetd(&mut nearest, 0);
assert_relative_eq!(start, stop, epsilon = 1e-6);
let (position, _) = state("MOON", start, "SUN");
assert_relative_eq!(
spice::vnorm(position),
common::ORBIT_RADIUS - common::SATELLITE_RADIUS,
epsilon = 1.0
);
common::unload();
}
#[test]
#[serial]
fn position_coordinates() {
common::load();
let mut cnfine = confinement();
let mut ahead = spice::gfposc(
"MOON",
"J2000",
"NONE",
"EARTH",
"RECTANGULAR",
"X",
">",
0.0,
0.0,
common::STEP,
&mut cnfine,
);
common::assert_ok("gfposc");
assert_eq!(spice::wncard(&mut ahead), 1);
for et in midpoints(&mut ahead) {
let (position, _) = state("MOON", et, "EARTH");
assert!(position[0] > 0.0);
}
for et in crossings(&mut ahead) {
let (position, _) = state("MOON", et, "EARTH");
assert_relative_eq!(position[0], 0.0, epsilon = 1e-3);
}
common::unload();
}
#[test]
#[serial]
fn angles() {
common::load();
let mut cnfine = confinement();
let mut lit = spice::gfpa(
"MOON",
"SUN",
"NONE",
"EARTH",
">",
std::f64::consts::FRAC_PI_2,
0.0,
common::STEP,
&mut cnfine,
);
common::assert_ok("gfpa");
assert!(spice::wncard(&mut lit) >= 1);
for et in midpoints(&mut lit) {
assert!(spice::phaseq(et, "MOON", "SUN", "EARTH", "NONE") > std::f64::consts::FRAC_PI_2);
}
for et in crossings(&mut lit) {
assert_relative_eq!(
spice::phaseq(et, "MOON", "SUN", "EARTH", "NONE"),
std::f64::consts::FRAC_PI_2,
epsilon = 1e-6
);
}
let widest = (common::SATELLITE_RADIUS / common::ORBIT_RADIUS).atan();
let mut cnfine = confinement();
let mut apart = spice::gfsep(
"EARTH",
"POINT",
"J2000",
"MOON",
"POINT",
"J2000",
"NONE",
"SUN",
">",
0.75 * widest,
0.0,
common::STEP,
&mut cnfine,
);
common::assert_ok("gfsep");
assert!(spice::wncard(&mut apart) >= 1);
let separation = |et: f64| {
let (target, _) = state("EARTH", et, "SUN");
let (satellite, _) = state("MOON", et, "SUN");
spice::vsep(target, satellite)
};
for et in midpoints(&mut apart) {
assert!(separation(et) > 0.75 * widest);
}
for et in crossings(&mut apart) {
assert_relative_eq!(separation(et), 0.75 * widest, epsilon = 1e-9);
}
let spoint = [common::SHAPE_RADIUS, 0.0, 0.0];
let mut cnfine = confinement();
let mut noon = spice::gfilum(
"Ellipsoid",
"INCIDENCE",
"EARTH",
"SUN",
"IAU_EARTH",
"NONE",
"MOON",
spoint,
"<",
0.3,
0.0,
common::STEP,
&mut cnfine,
);
common::assert_ok("gfilum");
assert!(
(35..45).contains(&spice::wncard(&mut noon)),
"one window per rotation over about forty days, got {}",
spice::wncard(&mut noon)
);
let incidence = |et: f64| {
let (_, _, _, incidence, _) = spice::ilumin(
"Ellipsoid",
"EARTH",
et,
"IAU_EARTH",
"NONE",
"MOON",
spoint,
);
incidence
};
for et in midpoints(&mut noon) {
assert!(incidence(et) < 0.3);
}
for et in crossings(&mut noon) {
assert_relative_eq!(incidence(et), 0.3, epsilon = 1e-6);
}
common::unload();
}
#[test]
#[serial]
fn surface_points() {
common::load();
let mut cnfine = confinement();
let mut eastern = spice::gfsubc(
"EARTH",
"IAU_EARTH",
"Near point: ellipsoid",
"NONE",
"SUN",
"LATITUDINAL",
"LONGITUDE",
">",
0.0,
0.0,
common::STEP,
&mut cnfine,
);
common::assert_ok("gfsubc");
assert!(
(35..45).contains(&spice::wncard(&mut eastern)),
"one window per rotation, got {}",
spice::wncard(&mut eastern)
);
let sub_longitude = |et: f64| {
let (spoint, _, _) = spice::subpnt(
"Near point: ellipsoid",
"EARTH",
et,
"IAU_EARTH",
"NONE",
"SUN",
);
spice::reclat(spoint).1
};
for et in midpoints(&mut eastern) {
assert!(sub_longitude(et) > 0.0);
}
for et in crossings(&mut eastern) {
assert_relative_eq!(sub_longitude(et).sin(), 0.0, epsilon = 1e-6);
}
let dvec = [1.0, 0.0, 0.0];
let mut cnfine = confinement();
let mut eastern = spice::gfsntc(
"SUN",
"IAU_SUN",
"Ellipsoid",
"NONE",
"EARTH",
"TEST_SUNWARD",
dvec,
"LATITUDINAL",
"LONGITUDE",
">",
0.0,
0.0,
common::STEP,
&mut cnfine,
);
common::assert_ok("gfsntc");
assert!(spice::wncard(&mut eastern) >= 1);
let intercept_longitude = |et: f64| {
let (spoint, _, _, found) = spice::sincpt(
"Ellipsoid",
"SUN",
et,
"IAU_SUN",
"NONE",
"EARTH",
"TEST_SUNWARD",
dvec,
);
assert!(found, "the ray should always reach the centre");
spice::reclat(spoint).1
};
for et in midpoints(&mut eastern) {
assert!(intercept_longitude(et) > 0.0);
}
for et in crossings(&mut eastern) {
assert_relative_eq!(intercept_longitude(et).sin(), 0.0, epsilon = 1e-6);
}
common::unload();
}
#[test]
#[serial]
fn fields_of_view() {
common::load();
let mut cnfine = confinement();
let always = spice::gfrfov(
"TEST_INSTRUMENT",
[0.0, 0.0, 1.0],
"J2000",
"NONE",
"TEST_SPACECRAFT",
common::STEP,
&mut cnfine,
);
common::assert_ok("gfrfov");
assert_eq!(always.to_vec(), vec![BEGIN, END]);
let mut cnfine = confinement();
let mut never = spice::gfrfov(
"TEST_INSTRUMENT",
[0.0, 0.0, -1.0],
"J2000",
"NONE",
"TEST_SPACECRAFT",
common::STEP,
&mut cnfine,
);
common::assert_ok("gfrfov looking the other way");
assert_eq!(spice::wncard(&mut never), 0);
let mut cnfine = confinement();
let mut rises = spice::gftfov(
"TEST_TELESCOPE",
"MOON",
"POINT",
"",
"NONE",
"EARTH",
600.0,
&mut cnfine,
);
common::assert_ok("gftfov");
assert!(
(35..45).contains(&spice::wncard(&mut rises)),
"one pass per rotation over about forty days, got {}",
spice::wncard(&mut rises)
);
for et in midpoints(&mut rises) {
assert!(
spice::fovtrg("TEST_TELESCOPE", "MOON", "POINT", "", "NONE", "EARTH", et),
"the satellite should be in view at {et}"
);
}
for et in crossings(&mut rises) {
let before = spice::fovtrg(
"TEST_TELESCOPE",
"MOON",
"POINT",
"",
"NONE",
"EARTH",
et - 1.0,
);
let after = spice::fovtrg(
"TEST_TELESCOPE",
"MOON",
"POINT",
"",
"NONE",
"EARTH",
et + 1.0,
);
assert_ne!(before, after, "the field of view should change at {et}");
}
common::unload();
}
unsafe extern "C" fn coordinate(et: f64, value: *mut f64) {
let (position, _) = spice::spkpos("MOON", et, "J2000", "NONE", "EARTH");
unsafe { *value = position[0] };
}
unsafe extern "C" fn decreasing(
udfuns: Option<spice::UdFuns>,
et: f64,
isdecr: *mut spice::c::SpiceBoolean,
) {
let derivative = spice::uddc(
udfuns.expect("the search passes its own function"),
et,
60.0,
);
unsafe { *isdecr = derivative as spice::c::SpiceBoolean };
}
unsafe extern "C" fn ahead(
_udfuns: Option<spice::UdFuns>,
et: f64,
xbool: *mut spice::c::SpiceBoolean,
) {
let (position, _) = spice::spkpos("MOON", et, "J2000", "NONE", "EARTH");
unsafe { *xbool = (position[0] > 0.0) as spice::c::SpiceBoolean };
}
#[test]
#[serial]
fn user_defined_searches() {
common::load();
assert_eq!(spice::udf(1.0), 0.0);
let et = common::EPOCH;
let (_, velocity) = state("MOON", et, "EARTH");
assert!(velocity[0] < 0.0);
assert!(spice::uddc(coordinate, et, 60.0));
assert_relative_eq!(
spice::uddf(coordinate, et, 60.0),
velocity[0],
epsilon = 1e-6
);
let mut cnfine = confinement();
let built_in = spice::gfposc(
"MOON",
"J2000",
"NONE",
"EARTH",
"RECTANGULAR",
"X",
">",
0.0,
0.0,
common::STEP,
&mut cnfine,
)
.to_vec();
common::assert_ok("gfposc");
let mut cnfine = confinement();
let scalar = spice::gfuds(
coordinate,
decreasing,
">",
0.0,
0.0,
common::STEP,
&mut cnfine,
)
.to_vec();
common::assert_ok("gfuds");
let mut cnfine = confinement();
let boolean = spice::gfudb(coordinate, ahead, common::STEP, &mut cnfine).to_vec();
common::assert_ok("gfudb");
assert_eq!(built_in.len(), 2, "one interval, so two endpoints");
assert_slice_eq(&scalar, &built_in, 1e-6);
assert_slice_eq(&boolean, &built_in, 1e-6);
common::unload();
}
const SIGINT: i32 = 2;
const SIG_DFL: usize = 0;
extern "C" {
fn signal(sig: i32, handler: usize) -> usize;
}
#[test]
#[serial]
fn stepping_and_interrupts() {
common::load();
spice::gfsstp(120.0);
assert_eq!(spice::gfstep(0.0), 120.0);
assert_eq!(spice::gfstep(common::EPOCH), 120.0);
common::assert_ok("gfsstp and gfstep");
assert_eq!(spice::gfrefn(10.0, 20.0, true, false), 15.0);
assert_eq!(spice::gfrefn(20.0, 10.0, false, true), 15.0);
common::assert_ok("gfrefn");
let mut window = span(0.0, 100.0);
spice::gfrepi(&mut window, "Working ", " done");
spice::gfrepu(0.0, 100.0, 50.0);
spice::gfrepf();
common::assert_ok("the progress reporter");
assert!(!spice::gfbail());
spice::gfinth(SIGINT);
common::assert_ok("gfinth");
assert!(spice::gfbail());
spice::gfclrh();
assert!(!spice::gfbail());
unsafe { signal(SIGINT, SIG_DFL) };
let crossing = |tolerance: f64| {
spice::gfstol(tolerance);
let mut cnfine = confinement();
let mut window = spice::gfposc(
"MOON",
"J2000",
"NONE",
"EARTH",
"RECTANGULAR",
"X",
">",
0.0,
0.0,
common::STEP,
&mut cnfine,
);
common::assert_ok("gfposc under a set tolerance");
spice::wnfetd(&mut window, 0).0
};
let coarse = crossing(600.0);
let fine = crossing(1e-6);
assert_relative_eq!(coarse, fine, epsilon = 600.0);
assert_eq!(spice::intmax(), i32::MAX);
assert_eq!(spice::intmin(), i32::MIN);
common::unload();
}
#[test]
#[serial]
fn searches_driven_by_the_caller() {
common::load();
spice::gfsstp(common::STEP);
spice::gfstol(1e-6);
let mut cnfine = span(0.0, END);
let occultations = spice::gfoclt(
"ANY",
"MOON",
"ELLIPSOID",
"IAU_MOON",
"SUN",
"ELLIPSOID",
"IAU_SUN",
"NONE",
"EARTH",
common::STEP,
&mut cnfine,
)
.to_vec();
common::assert_ok("gfoclt");
assert!(!occultations.is_empty());
let mut cnfine = span(0.0, END);
let mut result = spice::Cell::<f64>::new(64);
spice::raw::gfocce(
"ANY",
"MOON",
"ELLIPSOID",
"IAU_MOON",
"SUN",
"ELLIPSOID",
"IAU_SUN",
"NONE",
"EARTH",
1e-6,
spice::c::gfstep_c,
spice::c::gfrefn_c,
false,
spice::c::gfrepi_c,
spice::c::gfrepu_c,
spice::c::gfrepf_c,
false,
spice::c::gfbail_c,
&mut cnfine,
&mut result,
);
common::assert_ok("gfocce");
assert_slice_eq(&result.to_vec(), &occultations, 1e-3);
spice::gfsstp(600.0);
let mut cnfine = confinement();
let passes = spice::gftfov(
"TEST_TELESCOPE",
"MOON",
"POINT",
"",
"NONE",
"EARTH",
600.0,
&mut cnfine,
)
.to_vec();
common::assert_ok("gftfov");
let mut cnfine = confinement();
let mut result = spice::Cell::<f64>::new(256);
spice::raw::gffove(
"TEST_TELESCOPE",
"POINT",
[0.0, 0.0, 1.0],
"MOON",
"",
"NONE",
"EARTH",
1e-6,
spice::c::gfstep_c,
spice::c::gfrefn_c,
false,
spice::c::gfrepi_c,
spice::c::gfrepu_c,
spice::c::gfrepf_c,
false,
spice::c::gfbail_c,
&mut cnfine,
&mut result,
);
common::assert_ok("gffove");
assert_slice_eq(&result.to_vec(), &passes, 1e-3);
spice::gfsstp(common::STEP);
let mut cnfine = confinement();
let distances = spice::gfdist(
"MOON",
"NONE",
"SUN",
"<",
common::ORBIT_RADIUS,
0.0,
common::STEP,
&mut cnfine,
)
.to_vec();
common::assert_ok("gfdist");
let mut cnfine = confinement();
let mut result = spice::Cell::<f64>::new(64);
spice::raw::gfevnt(
spice::c::gfstep_c,
spice::c::gfrefn_c,
"DISTANCE",
&["TARGET", "OBSERVER", "ABCORR"],
&["MOON", "SUN", "NONE"],
&[],
&[],
&[],
"<",
common::ORBIT_RADIUS,
1e-6,
0.0,
false,
spice::c::gfrepi_c,
spice::c::gfrepu_c,
spice::c::gfrepf_c,
32,
false,
spice::c::gfbail_c,
&mut cnfine,
&mut result,
);
common::assert_ok("gfevnt");
assert_slice_eq(&result.to_vec(), &distances, 1e-3);
common::unload();
}
#[test]
#[serial]
fn validating_a_window() {
common::reset();
let mut window = spice::Cell::<f64>::new(16);
for endpoint in [10.0, 12.0, 2.0, 7.0, 1.0, 5.0, 23.0, 29.0] {
spice::appndd(endpoint, &mut window);
}
common::assert_ok("appndd");
assert_eq!(window.len(), 8);
spice::wnvald(16, 8, &mut window);
common::assert_ok("wnvald");
assert_eq!(window.to_vec(), vec![1.0, 7.0, 10.0, 12.0, 23.0, 29.0]);
assert_eq!(spice::wncard(&mut window), 3);
}