Clarify Best Value route confidence

This commit is contained in:
FuelBoard Contributor
2026-10-13 10:30:41 +01:00
parent d8a85b7aa0
commit 9aa8a2ede1
10 changed files with 338 additions and 46 deletions
@@ -159,6 +159,60 @@ final class FuelSavingsEstimateTests: XCTestCase {
XCTAssertEqual(result?.distanceBasis, .straightLine)
}
func testBaselineStationUsesTheSameJourneyValuesAsSavings() {
let geographicallyNearest = station("geographically-nearest", price: 145.9)
let roadNearest = station("road-nearest", price: 146.9)
let noPrice = station("no-price", price: nil)
let baseline = FuelSavingsEstimator.baselineStation(
[geographicallyNearest, roadNearest, noPrice],
fuel: .e10,
journeyMiles: { station in
switch station.id {
case "geographically-nearest": return FuelSavingsJourney(miles: 8.0, basis: .roadRoute)
case "road-nearest": return FuelSavingsJourney(miles: 4.0, basis: .roadRoute)
case "no-price": return FuelSavingsJourney(miles: 1.0, basis: .roadRoute)
default: return nil
}
}
)
XCTAssertEqual(baseline?.id, "road-nearest",
"the Best Value baseline must be the shortest usable journey, not a separate straight-line/display-distance choice")
}
func testBaselineStationFallsBackThenChangesWhenRoadRoutesArrive() {
let stationA = station("a", price: 145.9)
let stationB = station("b", price: 146.9)
let noRoadRoutes = FuelSavingsEstimator.baselineStation(
[stationA, stationB],
fuel: .e10,
journeyMiles: { station in
switch station.id {
case "a": return FuelSavingsJourney(miles: 2.0, basis: .straightLine)
case "b": return FuelSavingsJourney(miles: 3.0, basis: .straightLine)
default: return nil
}
}
)
XCTAssertEqual(noRoadRoutes?.id, "a")
let partialRoadRoutes = FuelSavingsEstimator.baselineStation(
[stationA, stationB],
fuel: .e10,
journeyMiles: { station in
switch station.id {
case "a": return FuelSavingsJourney(miles: 5.0, basis: .roadRoute)
case "b": return FuelSavingsJourney(miles: 3.0, basis: .straightLine)
default: return nil
}
}
)
XCTAssertEqual(partialRoadRoutes?.id, "b",
"baseline must be recalculated from the latest journey values when routes arrive")
}
func testStationWithoutAPriceIsUnavailable() {
let baseline = station("baseline", price: 145.9)
let noPrice = station("no-price", price: nil)
@@ -237,7 +291,8 @@ final class FuelSavingsEstimateTests: XCTestCase {
XCTAssertEqual(result.extraDrivingCostGBP, 1.730, accuracy: 0.005)
XCTAssertEqual(result.netSavingGBP, -0.334, accuracy: 0.005)
XCTAssertEqual(result.status, .notWorthTheDrive)
XCTAssertEqual(result.headline(compact: true), "£0.33 worse off after travel (est.)")
XCTAssertEqual(result.journeyConfidence, .estimated)
XCTAssertEqual(result.headline(compact: true), "~£0.33 worse off after travel")
}
func testMeasuredRoadRoutesDropTheEstimateMarker() {
@@ -255,6 +310,7 @@ final class FuelSavingsEstimateTests: XCTestCase {
)
XCTAssertEqual(availability?.result?.distanceBasis, .roadRoute)
XCTAssertEqual(availability?.result?.journeyConfidence, .confirmed)
XCTAssertEqual(availability?.result?.headline(compact: true), "£0.33 worse off after travel")
XCTAssertEqual(availability?.result?.headline(), "£0.33 worse off after travel")
}
@@ -301,7 +357,7 @@ final class FuelSavingsEstimateTests: XCTestCase {
// £60 buys 37.5 L at 160p; 10p/litre cheaper saves £3.75; 0.4 extra
// return miles cost ~£0.09. Net ≈ £3.66.
XCTAssertEqual(result.netSavingGBP, 3.659, accuracy: 0.005)
XCTAssertEqual(result.headline(compact: true), "Save £3.66 after travel (est.)")
XCTAssertEqual(result.headline(compact: true), "~Save £3.66 after travel")
}
func testNeutralResultHeadlineIsBreakEven() {
@@ -420,7 +476,7 @@ final class FuelSavingsEstimateTests: XCTestCase {
status: .worthTheDrive,
distanceBasis: .straightLine
)
XCTAssertEqual(saving.capsuleHeadline(), "Save £1.00 after travel (est.)")
XCTAssertEqual(saving.capsuleHeadline(), "~Save £1.00 after travel")
let worse = FuelSavingsResult(
fillLitres: 30,