package org.realityforge.arez.api2;

import org.testng.annotations.Test;
import static org.testng.Assert.*;

public class ReactionSchedulerTest
  extends AbstractArezTest
{
  @Test
  public void construction()
    throws Exception
  {
    final ArezContext context = new ArezContext();
    final ReactionScheduler scheduler = new ReactionScheduler( context );

    assertEquals( scheduler.getContext(), context );

    assertEquals( scheduler.getPendingObservers().size(), 0 );

    assertEquals( scheduler.isRunningReactions(), false );
    assertEquals( scheduler.getCurrentReactionRound(), 0 );
    assertEquals( scheduler.getRemainingReactionsInCurrentRound(), 0 );
    assertEquals( scheduler.getMaxReactionRounds(), ReactionScheduler.DEFAULT_MAX_REACTION_ROUNDS );
  }

  @Test
  public void setMaxReactionRounds()
    throws Exception
  {
    final ArezContext context = new ArezContext();
    final ReactionScheduler scheduler = new ReactionScheduler( context );

    assertEquals( scheduler.getMaxReactionRounds(), ReactionScheduler.DEFAULT_MAX_REACTION_ROUNDS );

    scheduler.setMaxReactionRounds( 0 );
    assertEquals( scheduler.getMaxReactionRounds(), 0 );

    scheduler.setMaxReactionRounds( 1234 );
    assertEquals( scheduler.getMaxReactionRounds(), 1234 );
  }

  @Test
  public void setMaxReactionRounds_negativeValue()
    throws Exception
  {
    final ArezContext context = new ArezContext();
    final ReactionScheduler scheduler = new ReactionScheduler( context );

    assertEquals( scheduler.getMaxReactionRounds(), ReactionScheduler.DEFAULT_MAX_REACTION_ROUNDS );

    final IllegalStateException exception =
      expectThrows( IllegalStateException.class, () -> scheduler.setMaxReactionRounds( -1 ) );

    assertEquals( exception.getMessage(), "Attempting to set maxReactionRounds to negative value -1." );
  }
}

@@ -30,16 +30,120 @@
 .api2;%0A%0A
+import java.util.concurrent.atomic.AtomicInteger;%0Aimport org.realityforge.guiceyloops.shared.ValueUtil;%0A
 import o
@@ -1939,11 +1939,2164 @@
 %22 );%0A  %7D
+%0A%0A  @Test%0A  public void invokeObserver()%0A    throws Exception%0A  %7B%0A    final ArezContext context = new ArezContext();%0A    final ReactionScheduler scheduler = new ReactionScheduler( context );%0A%0A    final String name = ValueUtil.randomString();%0A    final TransactionMode mode = TransactionMode.READ_ONLY;%0A%0A    final AtomicInteger callCount = new AtomicInteger();%0A    final AtomicInteger errorCount = new AtomicInteger();%0A%0A    context.addObserverErrorHandler( ( observer, error, throwable ) -%3E errorCount.incrementAndGet() );%0A%0A    final Reaction reaction = observer -%3E %7B%0A      callCount.incrementAndGet();%0A      assertEquals( observer.getContext(), context );%0A      assertEquals( context.isTransactionActive(), true );%0A      assertEquals( context.getTransaction().getName(), name );%0A      assertEquals( context.getTransaction().getMode(), mode );%0A      assertEquals( observer.getName(), name );%0A    %7D;%0A%0A    final Observer observer = new Observer( context, name, mode, reaction );%0A%0A    scheduler.invokeObserver( observer );%0A%0A    assertEquals( callCount.get(), 1 );%0A    assertEquals( errorCount.get(), 0 );%0A  %7D%0A%0A%0A  @Test%0A  public void invokeObserver_reactionGeneratesError()%0A    throws Exception%0A  %7B%0A    final ArezContext context = new ArezContext();%0A    final ReactionScheduler scheduler = new ReactionScheduler( context );%0A%0A    final String name = ValueUtil.randomString();%0A    final TransactionMode mode = TransactionMode.READ_ONLY;%0A%0A    final AtomicInteger callCount = new AtomicInteger();%0A    final AtomicInteger errorCount = new AtomicInteger();%0A%0A    final RuntimeException exception = new RuntimeException( %22X%22 );%0A%0A    context.addObserverErrorHandler( ( observer, error, throwable ) -%3E %7B%0A      errorCount.incrementAndGet();%0A      assertEquals( error, ObserverError.REACTION_ERROR );%0A      assertEquals( throwable, exception );%0A    %7D );%0A%0A    final Reaction reaction = observer -%3E %7B%0A      callCount.incrementAndGet();%0A      throw exception;%0A    %7D;%0A%0A    final Observer observer = new Observer( context, name, mode, reaction );%0A%0A    scheduler.invokeObserver( observer );%0A%0A    assertEquals( callCount.get(), 1 );%0A    assertEquals( errorCount.get(), 1 );%0A  %7D
 %0A%7D%0A

Add tests around invokeObserver