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)") } } }