99import static org .junit .jupiter .api .Assertions .assertNull ;
1010import static org .junit .jupiter .api .Assertions .assertThrows ;
1111import static org .junit .jupiter .api .Assertions .assertTrue ;
12+ import static org .mockito .Mockito .mock ;
1213
1314import com .google .transit .realtime .GtfsRealtime .TripDescriptor ;
1415import com .google .transit .realtime .GtfsRealtime .TripDescriptor .ScheduleRelationship ;
2425import java .util .concurrent .atomic .AtomicBoolean ;
2526import org .junit .jupiter .api .BeforeAll ;
2627import org .junit .jupiter .api .Test ;
28+ import org .mockito .Mock ;
2729import org .opentripplanner .ConstantsForTests ;
2830import org .opentripplanner .TestOtpModel ;
2931import org .opentripplanner ._support .time .ZoneIds ;
3032import org .opentripplanner .routing .algorithm .raptoradapter .transit .mappers .TransitLayerUpdater ;
33+ import org .opentripplanner .transit .model .basic .TransitMode ;
3134import org .opentripplanner .transit .model .framework .Deduplicator ;
3235import org .opentripplanner .transit .model .framework .FeedScopedId ;
3336import org .opentripplanner .transit .model .framework .Result ;
37+ import org .opentripplanner .transit .model .network .Route ;
38+ import org .opentripplanner .transit .model .network .StopPattern ;
3439import org .opentripplanner .transit .model .network .TripPattern ;
40+ import org .opentripplanner .transit .model .organization .Agency ;
41+ import org .opentripplanner .transit .model .site .RegularStop ;
42+ import org .opentripplanner .transit .model .site .StopLocation ;
3543import org .opentripplanner .transit .model .timetable .Trip ;
3644import org .opentripplanner .transit .model .timetable .TripIdAndServiceDate ;
3745import org .opentripplanner .transit .model .timetable .TripOnServiceDate ;
@@ -46,7 +54,8 @@ public class TimetableSnapshotTest {
4654 private static final ZoneId timeZone = ZoneIds .GMT ;
4755 public static final LocalDate SERVICE_DATE = LocalDate .of (2024 , 1 , 1 );
4856 private static Map <FeedScopedId , TripPattern > patternIndex ;
49- static String feedId ;
57+ private static String feedId ;
58+ private static Route route ;
5059
5160 @ BeforeAll
5261 public static void setUp () throws Exception {
@@ -412,6 +421,75 @@ void testClear() {
412421 assertNotNull (snapshot .getRealtimeAddedRoute (pattern .getRoute ().getId ()));
413422 }
414423
424+ /**
425+ * This test checks that an empty timetable is given to TransitLayerUpdater for previously
426+ * added patterns after the buffer is cleared.
427+ * <p>
428+ * Refer to bug #6197 for details.
429+ */
430+ @ Test
431+ void testTransitLayerUpdateAfterAddPatternAndClear () {
432+ var resolver = new TimetableSnapshot ();
433+ var today = LocalDate .now (timeZone );
434+
435+ var departureStopTime = new StopTime ();
436+ var arrivalStopTime = new StopTime ();
437+
438+ departureStopTime .setDepartureTime (0 );
439+ departureStopTime .setArrivalTime (0 );
440+ departureStopTime .setStop (RegularStop .of (new FeedScopedId (feedId , "XX" ), () -> 0 ).build ());
441+ arrivalStopTime .setDepartureTime (300 );
442+ arrivalStopTime .setArrivalTime (300 );
443+ arrivalStopTime .setStop (RegularStop .of (new FeedScopedId (feedId , "YY" ), () -> 1 ).build ());
444+
445+ var stopTimes = List .of (departureStopTime , arrivalStopTime );
446+
447+ var stopPattern = new StopPattern (stopTimes );
448+
449+ var route = patternIndex .values ().stream ().findFirst ().orElseThrow ().getRoute ();
450+ var pattern = TripPattern
451+ .of (new FeedScopedId (feedId , "1.1" ))
452+ .withRoute (route )
453+ .withStopPattern (stopPattern )
454+ .withCreatedByRealtimeUpdater (true )
455+ .build ();
456+
457+ var tripTimes = TripTimesFactory .tripTimes (
458+ Trip .of (new FeedScopedId (feedId , "addedTrip" )).withRoute (route ).build (),
459+ stopTimes ,
460+ new Deduplicator ()
461+ );
462+ var realTimeTripUpdate = new RealTimeTripUpdate (pattern , tripTimes , today , null , true , false );
463+ var transitLayerUpdater = new TransitLayerUpdater (null ) {
464+ int count = 0 ;
465+
466+ @ Override
467+ public void update (
468+ Collection <Timetable > updatedTimetables ,
469+ Map <TripPattern , SortedSet <Timetable >> timetables
470+ ) {
471+ var timetable = updatedTimetables .stream ().findFirst ().orElseThrow ();
472+ assertEquals (today , timetable .getServiceDate ());
473+ assertEquals (pattern , timetable .getPattern ());
474+
475+ if (count == 1 ) {
476+ // commited after clear
477+ assertThat (timetable .getTripTimes ()).isEmpty ();
478+ } else {
479+ // commited with an update
480+ assertThat (timetable .getTripTimes ()).hasSize (1 );
481+ }
482+ ++count ;
483+ }
484+ };
485+
486+ resolver .update (realTimeTripUpdate );
487+ resolver .commit (transitLayerUpdater , true );
488+
489+ resolver .clear (feedId );
490+ resolver .commit (transitLayerUpdater , true );
491+ }
492+
415493 private static TimetableSnapshot createCommittedSnapshot () {
416494 TimetableSnapshot timetableSnapshot = new TimetableSnapshot ();
417495 return timetableSnapshot .commit (null , true );
0 commit comments