### Question:
TripCountingRootCatchup implements RootCatchup { @Override public Root catchupFrom( long fromId ) { updateTripCount( fromId ); assertTripCount(); return rootSupplier.get(); } TripCountingRootCatchup( Supplier<Root> rootSupplier ); @Override Root catchupFrom( long fromId );  }### Answer:
@Test public void mustThrowOnConsecutiveCatchupsFromSamePage() { TripCountingRootCatchup tripCountingRootCatchup = getTripCounter(); try { for ( int i = 0; i < TripCountingRootCatchup.MAX_TRIP_COUNT; i++ ) { tripCountingRootCatchup.catchupFrom( 10 ); } fail( "Expected to throw" ); } catch ( TreeInconsistencyException e ) { } }
@Test public void mustNotThrowOnInterleavedCatchups() { TripCountingRootCatchup tripCountingRootCatchup = getTripCounter(); for ( int i = 0; i < TripCountingRootCatchup.MAX_TRIP_COUNT * 4; i++ ) { tripCountingRootCatchup.catchupFrom( i % 2 ); } }
@Test public void mustReturnRootUsingProvidedSupplier() { Root expectedRoot = new Root( 1, 2 ); Supplier<Root> rootSupplier = () -> expectedRoot; TripCountingRootCatchup tripCountingRootCatchup = new TripCountingRootCatchup( rootSupplier ); Root actualRoot = tripCountingRootCatchup.catchupFrom( 10 ); assertSame( expectedRoot, actualRoot ); }