who_need_help/assets/js/map_cluster_features.test.mjs

124 lines
4.0 KiB
JavaScript

import assert from "node:assert/strict"
import test from "node:test"
import {Supercluster} from "@maplibre/geojson-vt"
import {
clusterCountLabel,
clusterExpansionTarget,
clusterSizeClass,
pointFeatureCollection
} from "./map_cluster_features.mjs"
const buildIndex = points => {
const index = new Supercluster({
radius: 64,
maxZoom: 21,
minPoints: 2,
map: properties => ({
total_count: properties.weight,
urgent_count: properties.urgent_weight
}),
reduce: (accumulated, properties) => {
accumulated.total_count += properties.total_count
accumulated.urgent_count += properties.urgent_count
}
})
index.load(pointFeatureCollection(points).features)
return index
}
test("weighted server nodes preserve the represented record total", () => {
const index = buildIndex([
{id: "request:4:1:1", type: "cluster", longitude: 30.50, latitude: 50.45, count: 700},
{
id: "request:4:1:2",
type: "cluster",
longitude: 30.51,
latitude: 50.46,
count: 300,
urgent_count: 10
},
{id: "one", type: "request", longitude: -74.0, latitude: 40.7}
])
const world = index.getClusters([-180, -85, 180, 85], 0)
const represented = world.reduce(
(sum, feature) => sum + (feature.properties.total_count || feature.properties.weight),
0
)
const urgent = world.reduce(
(sum, feature) => sum + (feature.properties.urgent_count || feature.properties.urgent_weight),
0
)
assert.equal(represented, 1_001)
assert.equal(urgent, 10)
})
test("server hierarchy metadata survives GeoJSON conversion without becoming a native cluster", () => {
const feature = pointFeatureCollection([
{
id: "request:11:1197:1378",
type: "cluster",
cluster_id: "request:11:1197:1378",
parent_cluster_id: "request:10:598:689",
hierarchy_level: 11,
expansion_zoom: 13,
longitude: 30.52,
latitude: 50.45,
count: 27
}
]).features[0]
assert.equal(feature.properties.server_cluster_id, "request:11:1197:1378")
assert.equal(feature.properties.parent_cluster_id, "request:10:598:689")
assert.equal(feature.properties.hierarchy_level, 11)
assert.equal(feature.properties.expansion_zoom, 13)
assert.equal(feature.properties.weight, 27)
assert.equal("point_count" in feature.properties, false)
})
test("native clusters expose an expansion zoom and eventually split unique coordinates", () => {
const index = buildIndex([
{id: "a", longitude: 30.52340, latitude: 50.45010},
{id: "b", longitude: 30.52341, latitude: 50.45011},
{id: "c", longitude: 30.60, latitude: 50.50}
])
const world = index.getClusters([-180, -85, 180, 85], 0)
const cluster = world.find(feature => feature.properties.cluster)
assert.ok(cluster)
assert.ok(index.getClusterExpansionZoom(cluster.properties.cluster_id) > 0)
assert.equal(
index.getClusters([30.5, 50.4, 30.7, 50.6], 22)
.filter(feature => !feature.properties.cluster)
.length,
3
)
})
test("cluster size classes remain stable for accessible count buttons", () => {
assert.equal(clusterSizeClass(999), "is-md")
assert.equal(clusterSizeClass(1_000), "is-lg")
assert.equal(clusterSizeClass(10_000), "is-xl")
assert.equal(clusterSizeClass(100_000), "is-xxl")
})
test("large visual counts are compact while exact values remain available to accessibility text", () => {
assert.equal(clusterCountLabel(999, "en"), "999")
assert.equal(clusterCountLabel(1_250, "en"), "1.3K")
assert.equal(clusterCountLabel(48_533, "en"), "49K")
assert.equal(clusterCountLabel(1_000_000, "en"), "1M")
})
test("cluster expansion always advances at least one integer zoom level", () => {
assert.equal(clusterExpansionTarget(9, 9), 10)
assert.equal(clusterExpansionTarget(8.999_999_096_835_52, 9), 10)
assert.equal(clusterExpansionTarget(10.999_994_193_019_71, 11), 12)
assert.equal(clusterExpansionTarget(9.6, 10), 10)
assert.equal(clusterExpansionTarget(9.6, 13), 13)
assert.equal(clusterExpansionTarget(21.9, 24), 22)
})