Files
fuelboard/FuelBoardTests/Tests/FuelBoardSharedTests/StationAddressLineTests.swift
T
FuelBoard Contributor bb053de8b1 Listing rows: verdict text hugs its icon, and the address stops repeating the name
Two things the listing row was saying twice, or too loosely.

- The verdict capsule used a Label, and a Label lays its icon and title out
  across the width it is given: in a listing row that left 22pt of empty space
  between the symbol and "Save £1.07 after travel". It is now an HStack with
  an explicit 3pt spacing (5pt in the detail sheet), so the text sits beside its
  icon and the capsule background hugs the pair. Measured on the same row: the
  capsule text moved x 412 -> 341 and the pill 270-831 -> 270-691.

- The address line printed the station name a second time. The official Fuel
  Finder address field usually opens with the station's own name ("CHIDSWELL
  SERVICE STATION, LEEDS ROAD, DEWSBURY, WF12 7QW" for "Jet Chidswell"): 14% of
  the dump's addresses start with the exact name, and 13% also end with the
  postcode the row appended again. StationAddressLine (new, in Shared/, so the
  row and the detail sheet share one rule) drops a leading repeat of the name
  and writes the postcode exactly once.

The rules are deliberately conservative: a leading segment carrying a house
number is a real street address and is left alone ("41 ANNACLOY RD ANNACLOY"),
and a partial-word match ("Jet" against "JETSON FILLING STATION") never cuts
into a word. 14 new tests (169 total, 0 failures) pin the shapes found in the
real dump as well as the examples above.

Verified on the simulator: the first listing row's second line went from
"CHIDSWELL SERVICE STA..." to "LEEDS ROAD, DEWSBURY...", and the detail sheet
reads "Sainsbury's Halifax / WADE STREET, HX1 1SB".
2026-10-11 19:33:26 +01:00

161 lines
6.7 KiB
Swift

import XCTest
@testable import FuelBoardShared
/// The row and the detail sheet show the station name themselves, so the address
/// line must not repeat it — and must not eat a genuine street address either.
/// Every address below is a real string from the Fuel Finder dump.
final class StationAddressLineTests: XCTestCase {
// MARK: - The name is dropped when the address repeats it
func testAddressStartingWithTheExactName() {
XCTAssertEqual(
StationAddressLine.display(
address: "RING ROAD SERVICE STATION OSMASTON PARK ROAD, DERBY, DE23 8WL",
postcode: "DE23 8WL",
name: "Ring Road Service Station"),
"OSMASTON PARK ROAD, DERBY, DE23 8WL")
}
func testNameHeldInTheFirstSegment() {
// The real "Jet Chidswell" row, which read as its own name twice.
XCTAssertEqual(
StationAddressLine.display(
address: "CHIDSWELL SERVICE STATION, LEEDS ROAD, DEWSBURY, WF12 7QW",
postcode: "WF12 7QW",
name: "Jet Chidswell"),
"LEEDS ROAD, DEWSBURY, WF12 7QW")
}
func testNameMatchIgnoresSpacingAndPunctuation() {
XCTAssertEqual(
StationAddressLine.display(
address: "TESCO EXTRA, LEEDS ROAD, LS1 1AA",
postcode: "LS1 1AA",
name: "Tesco Extra"),
"LEEDS ROAD, LS1 1AA")
}
// MARK: - A real street address is left alone
func testStreetAddressWithoutTheNameIsUntouched() {
XCTAssertEqual(
StationAddressLine.display(
address: "66B Drumconvis Rd Coagh",
postcode: "",
name: "Corner filling station"),
"66B Drumconvis Rd Coagh")
}
func testHouseNumberInTheFirstSegmentBlocksTheStrip() {
// "41 ANNACLOY RD ANNACLOY" is a street address, not a restatement of
// the name — stripping it would delete where the station actually is.
XCTAssertEqual(
StationAddressLine.display(
address: "41 ANNACLOY RD ANNACLOY",
postcode: "",
name: "ANNACLOY FILLING STATION"),
"41 ANNACLOY RD ANNACLOY")
}
func testUnrelatedNameIsKept() {
XCTAssertEqual(
StationAddressLine.display(
address: "BALDWINS GATE FILLING STATION BALDWINS GATE, NEWCASTLE, ST5 5DA",
postcode: "ST5 5DA",
name: "Galaxy Overseas Limited"),
"BALDWINS GATE FILLING STATION BALDWINS GATE, NEWCASTLE, ST5 5DA")
}
func testDigitFreeSegmentThatIsNotTheNameIsKept() {
XCTAssertEqual(
StationAddressLine.display(
address: "HIGH STREET, LEEDS, LS1 1AA",
postcode: "LS1 1AA",
name: "Texaco Garage"),
"HIGH STREET, LEEDS, LS1 1AA")
}
func testPartialWordPrefixNeverCutsIntoAWord() {
// "Jet" matches the first letters of "JETSON"; the address is not the name.
XCTAssertEqual(
StationAddressLine.display(
address: "JETSON FILLING STATION, LEEDS ROAD",
postcode: "",
name: "Jet"),
"JETSON FILLING STATION, LEEDS ROAD")
}
// MARK: - The postcode is written exactly once
func testPostcodeAtTheEndOfTheAddressIsNotRepeated() {
let line = StationAddressLine.display(
address: "5-15 High Street, LEEDS, LS1 1AA",
postcode: "LS1 1AA",
name: "Boundary Service station Gulf")
XCTAssertEqual(line, "5-15 High Street, LEEDS, LS1 1AA")
XCTAssertEqual(line.components(separatedBy: "LS1 1AA").count - 1, 1)
}
func testPostcodeIsAppendedWhenTheAddressLacksIt() {
XCTAssertEqual(
StationAddressLine.display(
address: "7 STEAM MILLS, CINDERFORD",
postcode: "GL14 3JD",
name: "Steam Mills Garage"),
"7 STEAM MILLS, CINDERFORD, GL14 3JD")
}
func testEmptyAddressFallsBackToThePostcode() {
XCTAssertEqual(
StationAddressLine.display(address: " ", postcode: "LS1 1AA", name: "Anything"),
"LS1 1AA")
}
func testBlankPostcodeLeavesJustTheAddress() {
XCTAssertEqual(
StationAddressLine.display(address: "76-78 BURN ROAD", postcode: "", name: "SOLO 24 HR"),
"76-78 BURN ROAD")
}
func testWhitespaceIsCollapsed() {
XCTAssertEqual(
StationAddressLine.display(
address: "41 ANNACLOY RD ANNACLOY",
postcode: "",
name: "Somewhere Else"),
"41 ANNACLOY RD ANNACLOY")
}
// MARK: - Every station in the real dump produces a sane line
func testRealDumpNeverProducesAnEmptyOrNameLedLine() throws {
// Guards the rule against the shapes in the live data rather than the
// handful of examples above.
let stations: [(name: String, address: String, postcode: String)] = [
("Ravenspoint Trading Ltd", "RAVENSPOINT CENTRE KERSHADER, ISLE OF LEWIS, HS2 9QA", "HS2 9QA"),
("Galaxy Overseas Limited", "BALDWINS GATE FILLING STATION BALDWINS GATE, NEWCASTLE, ST5 5DA", "ST5 5DA"),
("Jet Chidswell", "CHIDSWELL SERVICE STATION, LEEDS ROAD, DEWSBURY, WF12 7QW", "WF12 7QW"),
("Corner filling station", "66B Drumconvis Rd Coagh", ""),
("Belcoo Service Station", "3, LATTONE ROAD, BELCOO EAST, BELCOO, ENNISKILLEN, BT93 5AQ", "BT93 5AQ"),
("ANNACLOY FILLING STATION", "41 ANNACLOY RD ANNACLOY", ""),
("Boundary Service station Gulf", "5-15 High Street", ""),
("SOLO 24 HR", "76-78 BURN ROAD", ""),
("Steam Mills Garage", "7 STEAM MILLS, CINDERFORD, GL14 3JD", "GL14 3JD"),
("Carnagh House Valero", "191 A Castleblayney Road Keady", ""),
]
for station in stations {
let line = StationAddressLine.display(
address: station.address, postcode: station.postcode, name: station.name)
XCTAssertFalse(line.isEmpty, "empty line for \(station.name)")
XCTAssertFalse(line.hasPrefix(" "), "leading space for \(station.name)")
XCTAssertFalse(line.hasSuffix(","), "trailing comma for \(station.name)")
XCTAssertFalse(line.contains(" "), "double space for \(station.name)")
// Never the name alone as the first words — the header has it.
let key = station.name.lowercased().filter { $0.isLetter || $0.isNumber }
let lineKey = line.lowercased().filter { $0.isLetter || $0.isNumber }
XCTAssertFalse(lineKey.hasPrefix(key), "\(station.name) still leads its own address: \(line)")
}
}
}