Spaces:
Sleeping
Sleeping
File size: 4,033 Bytes
f6213fc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | import test from 'node:test';
import assert from 'node:assert/strict';
import {
buildDeliveryTimelineModel,
buildVehicleTimelineModel,
refreshPlan,
refreshServerPlan,
} from '../static/app/models.mjs';
import {
colorForVehicle,
routeStyleForVehicle,
} from '../static/app/ui/overview.mjs';
function basePlan() {
return {
name: 'Test City',
routingMode: 'straight_line',
deliveries: [
{
id: 0,
label: 'A',
kind: 'business',
lat: 43.7696,
lng: 11.2558,
demand: 3,
minStartTime: 8 * 3600,
maxEndTime: 12 * 3600,
serviceDuration: 10 * 60,
},
{
id: 1,
label: 'B',
kind: 'residential',
lat: 43.7710,
lng: 11.2620,
demand: 2,
minStartTime: 9 * 3600,
maxEndTime: 18 * 3600,
serviceDuration: 5 * 60,
},
],
vehicles: [
{
id: 0,
name: 'Alpha',
capacity: 10,
homeLat: 43.7696,
homeLng: 11.2558,
departureTime: 6 * 3600,
deliveryOrder: [0, 1],
},
],
viewState: {},
};
}
test('refreshPlan builds preview assignments and scores', () => {
const plan = refreshPlan(basePlan());
assert.equal(plan.viewState.preview.vehicles.length, 1);
assert.equal(plan.viewState.preview.deliveries[0].assignedVehicleName, 'Alpha');
assert.equal(plan.viewState.preview.unassignedDeliveryIds.length, 0);
});
test('refreshServerPlan preserves authoritative backend preview', () => {
const plan = basePlan();
plan.viewState.preview = {
hardScore: -99,
softScore: -12345,
unassignedDeliveryIds: [1],
vehicles: [],
deliveries: [],
};
const refreshed = refreshServerPlan(plan);
assert.equal(refreshed.viewState.preview.hardScore, -99);
assert.equal(refreshed.viewState.preview.softScore, -12345);
assert.deepEqual(refreshed.viewState.preview.unassignedDeliveryIds, [1]);
});
test('refreshPlan recomputes draft preview from straight-line estimates', () => {
const plan = basePlan();
plan.viewState.preview = {
hardScore: -99,
softScore: -12345,
unassignedDeliveryIds: [1],
vehicles: [],
deliveries: [],
};
const refreshed = refreshPlan(plan);
assert.equal(Math.abs(refreshed.viewState.preview.hardScore), 0);
assert.notEqual(refreshed.viewState.preview.softScore, -12345);
assert.equal(refreshed.viewState.preview.vehicles.length, 1);
assert.ok(refreshed.viewState.preview.vehicles[0].totalTravelSeconds > 0);
});
test('refreshPlan uses dominant unassigned-delivery hard penalty', () => {
const plan = basePlan();
plan.vehicles[0].deliveryOrder = [0];
const refreshed = refreshPlan(plan);
assert.equal(refreshed.viewState.preview.unassignedDeliveryIds.length, 1);
assert.ok(
refreshed.viewState.preview.hardScore <= -1_000_000,
`expected unassigned hard penalty to dominate, got ${refreshed.viewState.preview.hardScore}`,
);
});
test('timeline model builders emit lane collections', () => {
const preview = refreshPlan(basePlan()).viewState.preview;
const vehicleModel = buildVehicleTimelineModel(preview);
const deliveryModel = buildDeliveryTimelineModel(preview);
assert.equal(vehicleModel.lanes.length, 1);
assert.equal(vehicleModel.lanes[0].items.length, 2);
assert.equal(deliveryModel.lanes.length, 2);
assert.ok(deliveryModel.lanes[0].items.length >= 1);
});
test('vehicle map colors are unique across the ten-vehicle tutorial dataset', () => {
const colors = Array.from({ length: 10 }, (_, vehicleId) => colorForVehicle(vehicleId));
assert.equal(new Set(colors).size, 10);
assert.notEqual(colorForVehicle(1), colorForVehicle(9));
});
test('route highlight style is keyed by vehicle id, not color reuse', () => {
assert.deepEqual(routeStyleForVehicle(1, 1), {
color: colorForVehicle(1),
opacity: 1,
weight: 5,
});
assert.deepEqual(routeStyleForVehicle(9, 1), {
color: colorForVehicle(9),
opacity: 0.2,
weight: 2,
});
});
|