destination([ ['busProId' => 74, 'city' => 'Stuttgart', 'street' => 'Flughafen (Busterminal)', 'time' => '03:15'], ['busProId' => 673, 'city' => 'Stuttgart', 'street' => 'Schelmenwasenstr. 15', 'time' => '03:15'], ])); $this->assertSame([74, 673], array_column($options, 'busProId')); $this->assertSame(['Stuttgart', 'Stuttgart'], array_column($options, 'label')); $this->assertSame( ['Flughafen (Busterminal)', 'Schelmenwasenstr. 15'], array_column($options, 'street'), ); } public function testTwoBoardingPointsInOneTownBothSurviveByTown(): void { $options = PickupOptions::byTown($this->destination([ ['busProId' => 74, 'city' => 'Stuttgart', 'street' => 'Flughafen (Busterminal)', 'time' => '03:15'], ['busProId' => 673, 'city' => 'Stuttgart', 'street' => 'Schelmenwasenstr. 15', 'time' => '03:15'], ])); $this->assertSame([74, 673], array_column($options, 'busProId')); // the town alone would offer the teamer the same word twice $this->assertSame( ['Stuttgart, Flughafen (Busterminal)', 'Stuttgart, Schelmenwasenstr. 15'], array_column($options, 'label'), ); } public function testARepeatedTownWithoutAStreetFallsBackToTheDepartureTime(): void { $options = PickupOptions::byTown($this->destination([ ['busProId' => 1, 'city' => 'München', 'street' => null, 'time' => '03:00'], ['busProId' => 2, 'city' => 'München', 'street' => null, 'time' => '03:30'], ])); $this->assertSame(['München, 03:00 Uhr', 'München, 03:30 Uhr'], array_column($options, 'label')); } public function testARepeatedTownWithNeitherFallsBackToTheId(): void { $options = PickupOptions::byTown($this->destination([ ['busProId' => 1, 'city' => 'München', 'street' => null, 'time' => null], ['busProId' => 2, 'city' => 'München', 'street' => null, 'time' => null], ])); $this->assertSame(['München (Zustieg 1)', 'München (Zustieg 2)'], array_column($options, 'label')); } public function testAUniqueTownIsNotDisambiguated(): void { $options = PickupOptions::byTown($this->destination([ ['busProId' => 4, 'city' => 'Karlsruhe', 'street' => 'A5 - Autohof Bruchsal', 'time' => '23:59'], ])); $this->assertSame('Karlsruhe', $options[0]['label']); } public function testByTownIsAlphabeticalWhileDepartureOrderIsChronological(): void { $pickups = [ ['busProId' => 1, 'city' => 'Hannover', 'street' => 'ZOB', 'time' => '08.03.2024 20:45:00'], ['busProId' => 2, 'city' => 'Aachen', 'street' => 'Bushof', 'time' => '02:30'], ]; $this->assertSame(['Aachen', 'Hannover'], array_column(PickupOptions::byTown($this->destination($pickups)), 'label')); $this->assertSame(['Hannover', 'Aachen'], array_column(PickupOptions::inDepartureOrder($this->destination($pickups)), 'label')); } public function testTheDepartureIsANormalisedClockWhateverTheSourceHeld(): void { $options = PickupOptions::inDepartureOrder($this->destination([ ['busProId' => 1, 'city' => 'Hannover', 'street' => 'ZOB', 'time' => '08.03.2024 20:45:00'], ['busProId' => 2, 'city' => 'Kassel', 'street' => 'Auestadion', 'time' => '00:30'], ])); $this->assertSame(['20:45', '00:30'], array_column($options, 'departure')); } public function testABoardingPointWithoutATownFallsBackToItsId(): void { // none exist today; they arrive with MyE&P's export, which reports the boarding // points whose master data it could not resolve rather than dropping them $options = PickupOptions::inDepartureOrder($this->destination([ ['busProId' => 4711, 'city' => null, 'street' => null, 'time' => '05:00'], ])); $this->assertSame('Zustieg 4711', $options[0]['label']); $this->assertNull($options[0]['street']); } public function testABoardingPointWithoutAnIdIsDropped(): void { $options = PickupOptions::inDepartureOrder($this->destination([ ['busProId' => 0, 'city' => 'Nirgendwo', 'street' => null, 'time' => '05:00'], ['busProId' => 27, 'city' => 'Stuttgart', 'street' => null, 'time' => '06:00'], ])); $this->assertSame([27], array_column($options, 'busProId')); } public function testADestinationWithoutBoardingPointsYieldsNothing(): void { $this->assertSame([], PickupOptions::inDepartureOrder($this->destination([]))); $this->assertSame([], PickupOptions::byTown($this->destination([]))); } /** * @param list> $pickups */ private function destination(array $pickups): Destination { return (new Destination())->setPickups($pickups); } }