148 lines
4.6 KiB
TypeScript
148 lines
4.6 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import {
|
|
buildVehicleGrid,
|
|
buildVehicleRanking,
|
|
daysInclusive,
|
|
filterVehicleRecordsByRadius,
|
|
haversineKm,
|
|
parseNearbyQuery,
|
|
parseVehicleHeatmapQuery,
|
|
summarizeVehicleRecords,
|
|
vehicleGridPrecision,
|
|
type VehicleHeatmapRecord,
|
|
} from './vehicle-heatmap-model.js';
|
|
|
|
function record(overrides: Partial<VehicleHeatmapRecord> = {}): VehicleHeatmapRecord {
|
|
return {
|
|
date: '2026-07-01',
|
|
vin: 'VIN-A',
|
|
plate: '粤A00001',
|
|
time: '2026-07-01 08:00:00',
|
|
longitude: 120,
|
|
latitude: 30,
|
|
source: 'test',
|
|
sourceRecordId: '1',
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
test('车辆热力图查询继续使用固定默认日期和原有字符串处理规则', () => {
|
|
assert.deepEqual(parseVehicleHeatmapQuery({}), {
|
|
startDate: '2026-01-01',
|
|
endDate: '2026-07-13',
|
|
query: '',
|
|
batchModel: '',
|
|
metric: 'locations',
|
|
});
|
|
assert.deepEqual(parseVehicleHeatmapQuery({
|
|
startDate: '2026-06-01',
|
|
endDate: 'invalid',
|
|
query: ' 粤A ',
|
|
batchModel: ' 190台冷链 ',
|
|
metric: 'vehicles',
|
|
}), {
|
|
startDate: '2026-06-01',
|
|
endDate: '2026-07-13',
|
|
query: ' 粤A ',
|
|
batchModel: '190台冷链',
|
|
metric: 'vehicles',
|
|
});
|
|
});
|
|
|
|
test('附近查询继续沿用经纬度 Number 语义和 5 至 200 公里半径限制', () => {
|
|
assert.deepEqual(parseNearbyQuery({ lng: '', lat: '0', radiusKm: '0' }), {
|
|
center: { lng: 0, lat: 0 },
|
|
radiusKm: 50,
|
|
});
|
|
assert.deepEqual(parseNearbyQuery({ lng: '120', lat: '30', radiusKm: '-1' }), {
|
|
center: { lng: 120, lat: 30 },
|
|
radiusKm: 5,
|
|
});
|
|
assert.equal(parseNearbyQuery({ lng: '120', lat: '30', radiusKm: '500' }).radiusKm, 200);
|
|
assert.equal(parseNearbyQuery({ lng: 'bad', lat: '30' }).center, null);
|
|
});
|
|
|
|
test('网格精度继续按含首尾天数和筛选条件决定', () => {
|
|
assert.equal(daysInclusive('2026-07-01', '2026-07-14'), 14);
|
|
assert.equal(daysInclusive('2026-07-14', '2026-07-01'), 0);
|
|
assert.equal(vehicleGridPrecision('2026-07-01', '2026-07-14', '', ''), 3);
|
|
assert.equal(vehicleGridPrecision('2026-07-01', '2026-07-15', '', ''), 2);
|
|
assert.equal(vehicleGridPrecision('2026-07-01', '2026-07-15', ' ', ''), 3);
|
|
});
|
|
|
|
test('车辆网格继续区分位置次数和去重车辆数并保留插入顺序', () => {
|
|
const records = [
|
|
record({ vin: 'VIN-A', longitude: 120.1231, latitude: 30.9878 }),
|
|
record({ vin: 'VIN-A', longitude: 120.1232, latitude: 30.9879 }),
|
|
record({ vin: 'VIN-B', longitude: 120.1233, latitude: 30.9877 }),
|
|
record({ vin: 'VIN-C', longitude: 121, latitude: 31 }),
|
|
];
|
|
|
|
assert.deepEqual(buildVehicleGrid(records, 'locations', 3), {
|
|
points: [
|
|
{ lng: 120.123, lat: 30.988, count: 3 },
|
|
{ lng: 121, lat: 31, count: 1 },
|
|
],
|
|
max: 3,
|
|
});
|
|
assert.deepEqual(buildVehicleGrid(records, 'vehicles', 3), {
|
|
points: [
|
|
{ lng: 120.123, lat: 30.988, count: 2 },
|
|
{ lng: 121, lat: 31, count: 1 },
|
|
],
|
|
max: 2,
|
|
});
|
|
assert.deepEqual(buildVehicleGrid([], 'locations', 2), { points: [], max: 1 });
|
|
});
|
|
|
|
test('车辆排名继续按记录数、车牌排序并保留首末出现时间', () => {
|
|
const records = [
|
|
record({ vin: 'VIN-B', plate: '', time: '2026-07-02 10:00:00' }),
|
|
record({ vin: 'VIN-A', plate: '粤A00001', time: '2026-07-02 09:00:00' }),
|
|
record({ vin: 'VIN-B', plate: '粤B00001', time: '2026-07-01 08:00:00' }),
|
|
record({ vin: 'VIN-A', plate: '粤A00001', time: '2026-07-03 11:00:00' }),
|
|
];
|
|
|
|
assert.deepEqual(buildVehicleRanking(records), [
|
|
{
|
|
vin: 'VIN-A',
|
|
plateNumber: '粤A00001',
|
|
locationCount: 2,
|
|
firstSeen: '2026-07-02 09:00:00',
|
|
lastSeen: '2026-07-03 11:00:00',
|
|
},
|
|
{
|
|
vin: 'VIN-B',
|
|
plateNumber: '粤B00001',
|
|
locationCount: 2,
|
|
firstSeen: '2026-07-01 08:00:00',
|
|
lastSeen: '2026-07-02 10:00:00',
|
|
},
|
|
]);
|
|
assert.equal(buildVehicleRanking(records, 1).length, 1);
|
|
});
|
|
|
|
test('车辆统计和附近筛选继续使用 VIN、自然日去重及 Haversine 距离', () => {
|
|
const records = [
|
|
record({ vin: 'VIN-A', date: '2026-07-01' }),
|
|
record({ vin: 'VIN-A', date: '2026-07-02', longitude: 120.01 }),
|
|
record({ vin: 'VIN-B', date: '2026-07-02', longitude: 121 }),
|
|
];
|
|
|
|
assert.deepEqual(summarizeVehicleRecords(records), {
|
|
locationCount: 3,
|
|
vehicleCount: 2,
|
|
dayCount: 2,
|
|
});
|
|
assert.equal(haversineKm(120, 30, 120, 30), 0);
|
|
assert.ok(Math.abs(haversineKm(0, 0, 0, 1) - 111.195) < 0.01);
|
|
assert.deepEqual(
|
|
filterVehicleRecordsByRadius(records, { lng: 120, lat: 30 }, 5).map(({ vin, date }) => ({ vin, date })),
|
|
[
|
|
{ vin: 'VIN-A', date: '2026-07-01' },
|
|
{ vin: 'VIN-A', date: '2026-07-02' },
|
|
],
|
|
);
|
|
});
|