Maps · Layers: tests hold what clusters promise

Tests hold that a pan keeps a focused cluster, that a cluster away from
the view takes no Tab, that a zoom out folding a focused pin hands its
focus to the map, and that a press shows members far apart whole. The
heat test pins the quartic kernel's value halfway out; a ring of fewer
than four positions fails with its own reason, and has a test.
This commit is contained in:
ZacharyZhang-NY committed 2026-09-27 22:57:05 -04:00
1 parent e3a96b04e0
commit 3e5c5f37ba
4 files changed
+112 -7

No files matched your search

+10 -2
View File
@@ -141,8 +141,14 @@ fn line(json: &Value) -> Result<Vec<LatLon>> {
fn ring(json: &Value) -> Result<Vec<LatLon>> {
let ring = list(json, position)?;
if ring.len() < 4 || ring.first() != ring.last() {
bail!("a ring of {} positions that does not close", ring.len());
if ring.len() < 4 {
bail!(
"a ring of {} positions; a ring holds four or more",
ring.len()
);
}
if ring.first() != ring.last() {
bail!("a ring that does not close");
}
Ok(ring)
}
@@ -211,6 +217,8 @@ mod tests {
assert!(reason(r#"{"type": "LineString", "coordinates": [[0, 0]]}"#).contains("line of 1"));
let open = r#"{"type": "Polygon", "coordinates": [[[0,0],[1,0],[1,1],[0,1]]]}"#;
assert!(reason(open).contains("does not close"));
let short = r#"{"type": "Polygon", "coordinates": [[[0,0],[1,1],[0,0]]]}"#;
assert!(reason(short).contains("four or more"));
let named = r#"{"type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Point"}}]}"#;
let named = reason(named);
assert!(
+5 -4
View File
@@ -13,7 +13,7 @@ impl Heat {
}
}
/// Each weighted view point spreads a quartic kernel `reach` pixels wide over cells `cell` pixels square across a view of `size`; the sum is scaled so its densest cell is 1. Fails on a negative or non-finite weight.
/// Each weighted view point spreads a quartic kernel reaching `reach` pixels from it over cells `cell` pixels square across a view of `size`; the sum is scaled so its densest cell is 1. Fails on a negative or non-finite weight.
pub(crate) fn density(
points: &[((f32, f32), f32)],
(w, h): (f32, f32),
@@ -74,9 +74,10 @@ mod tests {
1.0,
"the cell under the point is the densest"
);
assert!(
heat.at(3, 2) > 0.0 && heat.at(3, 2) < 1.0,
"it falls off beside"
assert_eq!(
heat.at(3, 2),
0.5625,
"halfway out a quartic kernel keeps (1 - 1/4) squared"
);
assert_eq!(heat.at(6, 2), 0.0, "past its reach nothing");
}
+96
View File
@@ -107,3 +107,99 @@ fn every_layer_paints_over_repeated_worlds(cx: &mut TestAppContext) {
fn a_route_of_one_place_fails() {
RouteLine::new([LatLon::new(0.0, 0.0)]);
}
/// A pan moves the view, not the world's squares: the focused cluster keeps its focus and Enter still presses it.
#[gpui::test]
fn a_pan_keeps_a_focused_cluster(cx: &mut TestAppContext) {
let (host, cx) = stage(crowd, cx);
focus_map(cx);
press("tab", cx);
press("left", cx);
press("enter", cx);
assert!(
last(&host, cx).zoom > europe().zoom,
"the cluster kept focus through the pan"
);
}
fn far_crowd(_: &Stage, owner: Entity<Stage>) -> AnyElement {
MapView::new("map", europe())
.markers([
MapMarker::new("tokyo", LatLon::new(35.7, 139.7)),
MapMarker::new("chiba", LatLon::new(35.9, 140.0)),
])
.cluster_markers()
.on_marker(|_, _, _| {})
.on_viewport(move |view, _, cx| hear(&owner, view, cx))
.into_any_element()
}
/// A cluster whose place lies outside the view takes no Tab, as a pin there takes none: Tab reaches the zoom button.
#[gpui::test]
fn a_cluster_away_from_the_view_takes_no_tab(cx: &mut TestAppContext) {
let (host, cx) = stage(far_crowd, cx);
focus_map(cx);
press("tab", cx);
press("enter", cx);
assert_eq!(last(&host, cx).zoom, 3.0, "Enter on the zoom button");
}
fn folding(_: &Stage, owner: Entity<Stage>) -> AnyElement {
let near = CROWD.map(|(key, lat, lon)| MapMarker::new(key, LatLon::new(lat, lon)));
MapView::new("map", MapViewport::new(LatLon::new(45.0, 0.0), 3.0))
.markers(
near.into_iter()
.chain([MapMarker::new("rome", LatLon::new(41.9, 12.5))]),
)
.cluster_markers()
.on_marker(|_, _, _| {})
.on_viewport(move |view, _, cx| hear(&owner, view, cx))
.into_any_element()
}
/// At zoom 3 Rome stands alone; a zoom out folds it into the capitals' cluster, and its focus goes to the map.
#[gpui::test]
fn a_zoom_out_folding_a_focused_pin_hands_focus_to_the_map(cx: &mut TestAppContext) {
let (host, cx) = stage(folding, cx);
focus_map(cx);
press("tab", cx);
press("tab", cx);
press("-", cx);
assert_eq!(last(&host, cx).zoom, 2.0);
let before = moves(&host, cx);
press("left", cx);
assert_eq!(moves(&host, cx), before + 1, "the map holds focus");
}
const APART: [(f64, f64); 2] = [(20.0, -2.5), (21.0, 16.5)];
fn apart(_: &Stage, owner: Entity<Stage>) -> AnyElement {
MapView::new("map", MapViewport::new(LatLon::new(20.0, 7.0), 2.0))
.markers(
APART.iter().enumerate().map(|(ix, (lat, lon))| {
MapMarker::new(format!("far-{ix}"), LatLon::new(*lat, *lon))
}),
)
.cluster_markers()
.on_marker(|_, _, _| {})
.on_viewport(move |view, _, cx| hear(&owner, view, cx))
.into_any_element()
}
/// Two pins 19 degrees apart in one square: the cluster's press shows both, which no fit of one alone would.
#[gpui::test]
fn a_clusters_press_shows_far_members_whole(cx: &mut TestAppContext) {
let (host, cx) = stage(apart, cx);
focus_map(cx);
press("tab", cx);
press("enter", cx);
let fit = last(&host, cx);
assert!(fit.zoom > 2.0, "nearer in: {}", fit.zoom);
for (lat, lon) in APART {
let (x, y) = fit.to_view(LatLon::new(lat, lon), SIZE, TILE);
assert!(
(0.0..=SIZE.0).contains(&x) && (0.0..=SIZE.1).contains(&y),
"{lat}, {lon} at {x}, {y}"
);
}
}
+1 -1
View File
@@ -12,10 +12,10 @@ use crate::{
theme::Theme,
};
/// The view inside the map's 1px border, in pixels.
mod layers;
mod popup;
/// The view inside the map's 1px border, in pixels.
const SIZE: (f32, f32) = (398.0, 298.0);
const TILE: f32 = 256.0;