mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
fix(roadtrip): keep a typed range when the parts round away to nothing
A consumption typed as 500 rather than 5.0 makes the tank arithmetic round to a range of zero. Zero is a number, so the `??` in effectiveRangeKm took it as the answer and discarded the range the traveller had typed by hand next to it, and useVehicleRange then folded that zero to null. What reached the rail was "no range at all": every fuel and charge warning went quiet, with nothing on screen naming the field that did it. A range that rounds below one kilometre is a typo rather than a car, so it is reported as no answer and the typed figure gets its turn.
This commit is contained in:
@@ -105,6 +105,22 @@ describe('unit round trip', () => {
|
||||
expect(showSpec('batteryKwh', 58, true)).toBe(58)
|
||||
})
|
||||
|
||||
it('FE-ROADTRIP-VEHRANGE-016: a consumption typed a hundred times too high does not silence the typed range', () => {
|
||||
// A consumption of 500 rather than 5.0 makes the parts round to nothing. Zero used
|
||||
// to count as an answer, so the `??` in effectiveRangeKm never reached the 500 km
|
||||
// the traveller had typed by hand, and every range warning went quiet with nothing
|
||||
// on screen to say which field did it.
|
||||
expect(rangeFromSpec('combustion', { tankLitres: 1, litresPer100: 500 })).toBeNull()
|
||||
expect(effectiveRangeKm('combustion', { tankLitres: 1, litresPer100: 500 }, 500)).toBe(500)
|
||||
|
||||
// Same shape on the other kind of car, where a decimal point is just as easy to lose.
|
||||
expect(rangeFromSpec('electric', { batteryKwh: 0.5, kwhPer100: 200 })).toBeNull()
|
||||
expect(effectiveRangeKm('electric', { batteryKwh: 0.5, kwhPer100: 200 }, 420)).toBe(420)
|
||||
|
||||
// One kilometre is still a figure, so the cut is below it and not at some round guess.
|
||||
expect(rangeFromSpec('combustion', { tankLitres: 1, litresPer100: 100 })).toBe(1)
|
||||
})
|
||||
|
||||
it('FE-ROADTRIP-VEHRANGE-015: an empty field stays empty rather than becoming a zero', () => {
|
||||
expect(showSpec('tankLitres', undefined, false)).toBeUndefined()
|
||||
expect(showSpec('tankLitres', 0, true)).toBeUndefined()
|
||||
|
||||
@@ -46,12 +46,25 @@ function positive(value: number | null | undefined): number | null {
|
||||
* Null rather than a guess whenever a piece is missing: half a specification is not a
|
||||
* range, and a made-up figure here becomes a fuel warning that fires at the wrong place.
|
||||
*/
|
||||
/**
|
||||
* A rounded range that came out at nothing is a typo, not a car.
|
||||
*
|
||||
* A consumption typed as 500 rather than 5.0 rounds to a range of zero, and zero is a
|
||||
* number: `effectiveRangeKm` would take it as the answer and throw away the range the
|
||||
* traveller had typed by hand right next to it. What reached the rail was "no range at
|
||||
* all", so every warning went quiet, with nothing on screen to say which field did it.
|
||||
* Reported as nothing instead, so the typed figure gets its turn.
|
||||
*/
|
||||
function atLeastAKilometre(km: number): number | null {
|
||||
return km >= 1 ? km : null
|
||||
}
|
||||
|
||||
export function rangeFromSpec(vehicle: VehicleKind | null | undefined, spec: VehicleSpec): number | null {
|
||||
if (vehicle === 'combustion') {
|
||||
const tank = positive(spec.tankLitres)
|
||||
const per100 = positive(spec.litresPer100)
|
||||
if (!tank || !per100) return null
|
||||
return Math.round((tank / per100) * 100)
|
||||
return atLeastAKilometre(Math.round((tank / per100) * 100))
|
||||
}
|
||||
|
||||
if (vehicle === 'electric') {
|
||||
@@ -63,7 +76,7 @@ export function rangeFromSpec(vehicle: VehicleKind | null | undefined, spec: Veh
|
||||
// the first metre of the trip.
|
||||
const lost = Math.min(90, Math.max(0, positive(spec.degradationPercent) ?? 0))
|
||||
const usable = battery * (1 - lost / 100)
|
||||
return Math.round((usable / per100) * 100)
|
||||
return atLeastAKilometre(Math.round((usable / per100) * 100))
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
Reference in New Issue
Block a user