One station, several views, several displays
A railway station has the dashboard’s problem: which trains to show and how to show them change for different reasons. Views (the next trains, then each platform) decide which trains appear; displays (an LED board, the announcer, then a phone alert) decide how a train is shown. Each level starts from the previous level’s finished code, so you can begin at any of them.
The station is adding a screen at the end of each platform, showing every train still to leave from that platform, and the station app is adding phone alerts. The platform screens use the same LED boards and the announcer reads them at each platform; riders can follow either view on their phone.
Today the per-platform view and the phone alert return nothing. If either is written for one display or one view at a time, the station is back to a function per pairing: six now, more with the next display.
Reproduce Show platform 2 on the LED board with Airport leaving platform 2 in 6 minutes, Harbour leaving platform 1 now, Docks that has already left platform 2, and Stadium leaving platform 2 now. It should list Stadium, then Airport. Today it shows nothing.
Acceptance criteria PlatformTrains shows every train still to leave from its platform, soonest first, equal times keeping their order, with no cap, titled “Platform 2”. The phone alert writes a train as “Airport (P2) now” or “Docks (P3) 12 min”, and a screen as “Next trains: row, row”, or “Platform 3: none” with no rows. Every view works on every display, the checker’s own included, and the four pairings that worked before are unchanged. Neither view knows which display it holds; no display knows which view called it. Notes Cases print what a view or a display returns, on one line. The checker shows both views on a display of its own (destination@platform+minutes) and calls each display’s operations directly. Keep the Display contract and every class, method and field name; PlatformTrains takes its display, then its platform.