feat(map): add persisted ghost pin sandbox
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { after, before, test } from "node:test";
|
||||
|
||||
import { createServer } from "vite";
|
||||
|
||||
let server;
|
||||
let ghostPins;
|
||||
|
||||
before(async () => {
|
||||
server = await createServer({
|
||||
appType: "custom",
|
||||
logLevel: "silent",
|
||||
server: { middlewareMode: true },
|
||||
});
|
||||
ghostPins = await server.ssrLoadModule("/src/core/map/ghostPins.ts");
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await server?.close();
|
||||
});
|
||||
|
||||
test("ghost pins are generated inside the requested current-view radius", () => {
|
||||
const samples = [0, 0.25, 0.5, 0.75, 0.1, 0.9];
|
||||
let index = 0;
|
||||
const pins = ghostPins.generateGhostPins({
|
||||
anchor: { longitude: 37.618423, latitude: 55.751244 },
|
||||
count: 3,
|
||||
radiusMeters: 1_000,
|
||||
random: () => samples[index++ % samples.length],
|
||||
timestamp: 42,
|
||||
});
|
||||
|
||||
assert.equal(pins.length, 3);
|
||||
assert.equal(new Set(pins.map((pin) => pin.label)).size, 3);
|
||||
assert.ok(pins.every((pin) => /^\d{6}$/.test(pin.label)));
|
||||
assert.ok(pins.every((pin) => pin.id.startsWith("ghost-16-")));
|
||||
assert.ok(pins.every((pin) => pin.speedMetersPerSecond >= 3));
|
||||
});
|
||||
|
||||
test("numeric pin names remain unique with a degenerate random source", () => {
|
||||
const pins = ghostPins.generateGhostPins({
|
||||
anchor: { longitude: 37.618423, latitude: 55.751244 },
|
||||
count: 4,
|
||||
radiusMeters: 1_000,
|
||||
random: () => 0,
|
||||
timestamp: 42,
|
||||
});
|
||||
|
||||
assert.equal(new Set(pins.map((pin) => pin.label)).size, 4);
|
||||
});
|
||||
@@ -22,7 +22,7 @@ after(async () => {
|
||||
|
||||
function serverDocument(overrides = {}) {
|
||||
return {
|
||||
schema_version: "missioncore.map-view/v2",
|
||||
schema_version: "missioncore.map-view/v3",
|
||||
revision: 0,
|
||||
view: {
|
||||
camera: {
|
||||
@@ -89,6 +89,36 @@ function serverDocument(overrides = {}) {
|
||||
grid: true,
|
||||
targets: true,
|
||||
},
|
||||
ghost_pins: {
|
||||
count: 12,
|
||||
radius_meters: 5000,
|
||||
simulation_enabled: false,
|
||||
anchor: null,
|
||||
positions: [],
|
||||
presentation: {
|
||||
color: "#6fb5fb",
|
||||
opacity: 0.9,
|
||||
stem_height_meters: 1500,
|
||||
head_size_px: 6,
|
||||
stem_width_px: 3,
|
||||
outline_color: "#0c0d12",
|
||||
outline_opacity: 0.6,
|
||||
outline_width_px: 1,
|
||||
label_mode: "attributes",
|
||||
label_font_weight: 600,
|
||||
label_size_px: 13,
|
||||
label_color: "#f5f5f5",
|
||||
label_background_color: "#0c0d12",
|
||||
label_background_opacity: 0.86,
|
||||
label_padding_x: 8,
|
||||
label_padding_y: 5,
|
||||
label_offset_x: 15,
|
||||
label_offset_y: 10,
|
||||
label_max_length: 48,
|
||||
label_hide_camera_height_meters: 70000,
|
||||
target_hide_camera_height_meters: 100000,
|
||||
},
|
||||
},
|
||||
},
|
||||
...overrides,
|
||||
};
|
||||
@@ -103,6 +133,8 @@ test("map view starts from the canonical Foundry camera without a fabricated sub
|
||||
assert.equal(document.view.selectedSubjectId, null);
|
||||
assert.equal(document.view.cacheIntent.enabled, true);
|
||||
assert.equal(document.view.cacheIntent.noOverwrite, true);
|
||||
assert.equal(document.view.ghostPins.count, 12);
|
||||
assert.equal(document.view.ghostPins.positions.length, 0);
|
||||
});
|
||||
|
||||
test("map view decodes and re-encodes the complete versioned contract", () => {
|
||||
@@ -128,6 +160,7 @@ test("map view decodes and re-encodes the complete versioned contract", () => {
|
||||
assert.equal(decoded.view.inspectorOpenSections[0], "camera");
|
||||
assert.equal(encoded.view.camera.latitude, 55.7558);
|
||||
assert.equal(encoded.view.cache_intent.no_overwrite, true);
|
||||
assert.equal(encoded.view.ghost_pins.presentation.stem_height_meters, 1500);
|
||||
assert.equal("schema_version" in encoded, false);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user