use s2rst::s2::CellId;
const CSV: &str = include_str!("data/cpp_cellid_vectors.csv");
fn section_lines(name: &str) -> Vec<&'static str> {
let header = format!("# {name}");
let mut in_section = false;
let mut lines = Vec::new();
for line in CSV.lines() {
if line == header {
in_section = true;
continue;
}
if in_section {
if line.starts_with('#') || line.is_empty() {
break;
}
lines.push(line);
}
}
lines
}
fn u64f(s: &str) -> u64 {
s.trim().parse().unwrap()
}
#[test]
fn edge_neighbors_match_cpp() {
let lines = section_lines("CELLID_EDGE_NEIGHBORS");
assert!(!lines.is_empty(), "no CELLID_EDGE_NEIGHBORS vectors");
let mut checked = 0usize;
for line in lines {
let f: Vec<u64> = line.split(',').map(u64f).collect();
assert_eq!(f.len(), 5, "bad CELLID_EDGE_NEIGHBORS row: {line}");
let got = CellId(f[0]).edge_neighbors();
let expected = [CellId(f[1]), CellId(f[2]), CellId(f[3]), CellId(f[4])];
assert_eq!(
got, expected,
"edge_neighbors disagrees with C++ on: {line}"
);
checked += 1;
}
assert!(
checked > 4000,
"expected the full vector set, only checked {checked}"
);
}
#[test]
fn range_matches_cpp() {
let lines = section_lines("CELLID_RANGE");
assert!(!lines.is_empty(), "no CELLID_RANGE vectors");
for line in lines {
let f: Vec<u64> = line.split(',').map(u64f).collect();
assert_eq!(f.len(), 3, "bad CELLID_RANGE row: {line}");
let c = CellId(f[0]);
assert_eq!(
c.range_min(),
CellId(f[1]),
"range_min disagrees on: {line}"
);
assert_eq!(
c.range_max(),
CellId(f[2]),
"range_max disagrees on: {line}"
);
}
}
#[test]
fn contains_intersects_match_cpp() {
let lines = section_lines("CELLID_CONTAINS");
assert!(!lines.is_empty(), "no CELLID_CONTAINS vectors");
for line in lines {
let p: Vec<&str> = line.split(',').collect();
assert_eq!(p.len(), 4, "bad CELLID_CONTAINS row: {line}");
let a = CellId(u64f(p[0]));
let b = CellId(u64f(p[1]));
assert_eq!(
a.contains(b),
p[2].trim() == "1",
"contains disagrees on: {line}"
);
assert_eq!(
a.intersects(b),
p[3].trim() == "1",
"intersects disagrees on: {line}"
);
}
}
#[test]
fn children_match_cpp() {
let lines = section_lines("CELLID_CHILDREN");
assert!(!lines.is_empty(), "no CELLID_CHILDREN vectors");
for line in lines {
let f: Vec<u64> = line.split(',').map(u64f).collect();
assert_eq!(f.len(), 5, "bad CELLID_CHILDREN row: {line}");
let got = CellId(f[0]).children();
let expected = [CellId(f[1]), CellId(f[2]), CellId(f[3]), CellId(f[4])];
assert_eq!(got, expected, "children disagrees with C++ on: {line}");
}
}
#[test]
fn face_ij_match_cpp() {
let lines = section_lines("CELLID_FACE_IJ");
assert!(!lines.is_empty(), "no CELLID_FACE_IJ vectors");
for line in lines {
let p: Vec<&str> = line.split(',').collect();
assert_eq!(p.len(), 5, "bad CELLID_FACE_IJ row: {line}");
let (face, i, j, orientation) = CellId(u64f(p[0])).to_face_ij_orientation();
let want = |idx: usize| p[idx].trim().parse::<i64>().unwrap();
assert_eq!(i64::from(u8::from(face)), want(1), "face on: {line}");
assert_eq!(i64::from(i), want(2), "i on: {line}");
assert_eq!(i64::from(j), want(3), "j on: {line}");
assert_eq!(i64::from(orientation), want(4), "orientation on: {line}");
}
}