- Add `currentTrainMetadata.ts` to manage carrying forward official position metadata between train snapshots. - Introduce `lineDisplayName.ts` for mapping line IDs to display names. - Create `officialPositionCache.ts` for parsing and serializing official position data with cache validation. - Enhance `officialPositionService.ts` to support persistent caching of official positions and improve resolver functionality. - Update `requestCoordinator.ts` to allow cancellation of polling requests without disposing of the coordinator. - Modify `trainTimeFiltering.ts` to incorporate line ID context when checking for duplicate train data. - Refactor `useCurrentTrain.tsx` to support polling for current train data with official position enrichment. - Add tests for new features, including persistent cache behavior and handling of ambiguous train data.
114 lines
2.8 KiB
TypeScript
114 lines
2.8 KiB
TypeScript
import { strict as assert } from "node:assert";
|
|
import { test } from "node:test";
|
|
import {
|
|
checkDuplicateTrainData,
|
|
lineIdFromStationNumber,
|
|
} from "../lib/checkDuplicateTrainData";
|
|
import type { StationProps } from "../lib/CommonTypes";
|
|
import type { trainDataType } from "../lib/trainPositionTextArray";
|
|
|
|
const stationList: StationProps[][] = Array.from({ length: 9 }, (_, index) => {
|
|
if (index === 0) {
|
|
return [
|
|
{
|
|
StationName: "高松",
|
|
Station_JP: "高松",
|
|
StationNumber: "Y00",
|
|
} as StationProps,
|
|
];
|
|
}
|
|
if (index === 5) {
|
|
return [
|
|
{
|
|
StationName: "高松",
|
|
Station_JP: "高松",
|
|
StationNumber: "T28",
|
|
} as StationProps,
|
|
];
|
|
}
|
|
return [];
|
|
});
|
|
|
|
const duplicateRows: trainDataType[] = [
|
|
{ num: "363D", Pos: "高松", PosNum: 279, Line: "yosan", delay: "入線" },
|
|
{ num: "363D", Pos: "高松", PosNum: 279, Line: "koutoku", delay: "入線" },
|
|
];
|
|
|
|
test("station number keeps Takamatsu line context when selecting a duplicate", () => {
|
|
assert.equal(lineIdFromStationNumber("Y00"), "yosan");
|
|
assert.equal(lineIdFromStationNumber("T28"), "koutoku");
|
|
assert.equal(lineIdFromStationNumber("高松"), undefined);
|
|
|
|
const koutoku = checkDuplicateTrainData(duplicateRows, stationList, ["koutoku"]);
|
|
assert.equal(koutoku?.Line, "koutoku");
|
|
|
|
const yosan = checkDuplicateTrainData(duplicateRows, stationList, ["yosan"]);
|
|
assert.equal(yosan?.Line, "yosan");
|
|
|
|
const priority = checkDuplicateTrainData(duplicateRows, stationList, [
|
|
"koutoku",
|
|
"yosan",
|
|
]);
|
|
assert.equal(priority?.Line, "koutoku");
|
|
});
|
|
|
|
test("prefers a non-preview position when duplicate rows share a line", () => {
|
|
const rows: trainDataType[] = [
|
|
{
|
|
num: "1007M",
|
|
Pos: "高松予告窓",
|
|
PosNum: 279,
|
|
Line: "yosan",
|
|
delay: 0,
|
|
},
|
|
{
|
|
num: "1007M",
|
|
Pos: "高松",
|
|
PosNum: 279,
|
|
Line: "yosan",
|
|
delay: 0,
|
|
},
|
|
];
|
|
|
|
const selected = checkDuplicateTrainData(rows, stationList, ["yosan"]);
|
|
assert.equal(selected?.Pos, "高松");
|
|
});
|
|
|
|
test("prefers a non-preview line before route matching", () => {
|
|
const rows: trainDataType[] = [
|
|
{
|
|
num: "1007M",
|
|
Pos: "高松予告窓",
|
|
PosNum: 279,
|
|
Line: "yosan",
|
|
delay: 0,
|
|
},
|
|
{
|
|
num: "1007M",
|
|
Pos: "高松",
|
|
PosNum: 279,
|
|
Line: "koutoku",
|
|
delay: 0,
|
|
},
|
|
];
|
|
|
|
const selected = checkDuplicateTrainData(rows, stationList, [
|
|
"yosan",
|
|
"koutoku",
|
|
]);
|
|
assert.equal(selected?.Line, "koutoku");
|
|
});
|
|
|
|
test("keeps a preview position when it is the only available observation", () => {
|
|
const row: trainDataType = {
|
|
num: "1007M",
|
|
Pos: "高松予告窓",
|
|
PosNum: 279,
|
|
Line: "yosan",
|
|
delay: 0,
|
|
};
|
|
|
|
const selected = checkDuplicateTrainData([row], stationList, ["yosan"]);
|
|
assert.equal(selected?.Pos, "高松予告窓");
|
|
});
|