mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-22 06:56:35 +00:00
fix(tours): a city walk saved offline shows its stays and total at once, and the planner plans the total its overview shows (CW-02)
A city walk created or changed while offline now carries its stops, the minutes its stays are entered with and how many have none yet, worked out from its points the way the server will answer them. The day row, the tour detail and the summary show the walking time with the stays as soon as the walk is saved, with "at least" where a stay is missing, and a stay changed while the write waits shows its new total rather than the one of the last answer. The server and the client count the stops in one shared place. The planner plans a walk whose walking time is not known yet with at least the stays entered, as its overview says, so the planned field and the check against the longest plan read the same total. In the tour detail a longer time such as an "at least" total wraps on a phone instead of being cut, and the boxes of a row keep one height. A total entered by hand falls back to its short name where its column is too narrow.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { isClosedLoop, walkStationsOf } from './tour-walk';
|
||||
import { isClosedLoop, walkStationFacts, walkStationsOf } from './tour-walk';
|
||||
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
@@ -33,3 +33,38 @@ describe('walkStationsOf (CW-02, CW-03)', () => {
|
||||
expect(walkStationsOf([])).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('walkStationFacts (CW-02, CW-03)', () => {
|
||||
it('counts the stops of a walk, sums the stays entered and counts the ones nobody entered apart', () => {
|
||||
const museum = { ...market, stay_minutes: 90 };
|
||||
const cafe = { ...park, stay_minutes: 30 };
|
||||
expect(walkStationFacts('walk', [cathedral, steer, museum, cafe])).toEqual({
|
||||
station_count: 3,
|
||||
station_stay_minutes: 120,
|
||||
station_stays_unknown: 1,
|
||||
});
|
||||
});
|
||||
|
||||
it('counts the start of a loop once, with its stay, and a stay of 0 as entered', () => {
|
||||
const start = { ...cathedral, stay_minutes: 20 };
|
||||
const passed = { ...market, stay_minutes: 0 };
|
||||
expect(walkStationFacts('walk', [start, passed, { ...start }])).toEqual({
|
||||
station_count: 2,
|
||||
station_stay_minutes: 20,
|
||||
station_stays_unknown: 0,
|
||||
});
|
||||
expect(walkStationFacts('walk', [])).toEqual({
|
||||
station_count: 0,
|
||||
station_stay_minutes: 0,
|
||||
station_stays_unknown: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('says nothing of the stations of any other type', () => {
|
||||
expect(walkStationFacts('hike', [cathedral, { ...market, stay_minutes: 30 }])).toEqual({
|
||||
station_count: null,
|
||||
station_stay_minutes: null,
|
||||
station_stays_unknown: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,3 +31,30 @@ export function walkStationsOf<T extends Spot & { shaping?: boolean | null }>(po
|
||||
const route = isClosedLoop(points) ? points.slice(0, -1) : points;
|
||||
return route.filter((point) => !point.shaping);
|
||||
}
|
||||
|
||||
/** What a list says of a city walk's stations: how many, their stays as far as entered, and how many have none. */
|
||||
interface WalkStationFacts {
|
||||
station_count: number | null;
|
||||
station_stay_minutes: number | null;
|
||||
station_stays_unknown: number | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* CW-02, CW-03: a city walk's stations as a list counts them, from its points:
|
||||
* a shaping point and the way back of a loop are no station, a stay nobody
|
||||
* entered is counted apart and never as nothing. Any other type has none. The
|
||||
* server answers a list with it, and the client works out the same for a walk
|
||||
* saved offline until the write replays.
|
||||
*/
|
||||
export function walkStationFacts(
|
||||
tourType: string,
|
||||
points: readonly (Spot & { shaping?: boolean | null; stay_minutes?: number | null })[],
|
||||
): WalkStationFacts {
|
||||
if (tourType !== 'walk') return { station_count: null, station_stay_minutes: null, station_stays_unknown: null };
|
||||
const stations = walkStationsOf(points);
|
||||
return {
|
||||
station_count: stations.length,
|
||||
station_stay_minutes: stations.reduce((sum, station) => sum + (station.stay_minutes ?? 0), 0),
|
||||
station_stays_unknown: stations.filter((station) => station.stay_minutes == null).length,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user