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) })