package org.realityforge.arez.api2;

import org.realityforge.guiceyloops.shared.ValueUtil;
import org.testng.annotations.Test;
import static org.testng.Assert.*;

public class ObserverTest
  extends AbstractArezTest
{
  @Test
  public void initialState()
    throws Exception
  {
    final ArezContext context = new ArezContext();
    final String name = ValueUtil.randomString();
    final int nextNodeId = context.currentNextNodeId();
    final Observer observer = new Observer( context, name );

    // Verify all "Node" behaviour
    assertEquals( observer.getContext(), context );
    assertEquals( observer.getName(), name );
    assertEquals( observer.getId(), nextNodeId );
    assertEquals( observer.toString(), name );

    // Starts out inactive and inactive means no dependencies
    assertEquals( observer.getState(), ObserverState.INACTIVE );
    assertEquals( observer.isActive(), false );
    assertEquals( observer.isInactive(), true );
    assertEquals( observer.getDependencies().size(), 0 );

    // All the hooks start out null
    assertEquals( observer.getOnActivate(), null );
    assertEquals( observer.getOnDeactivate(), null );
    assertEquals( observer.getOnStale(), null );

    final Action onActivate = () -> {
    };
    final Action onDeactivate = () -> {
    };
    final Action onStale = () -> {
    };

    // Ensure hooks can be modified
    observer.setOnActivate( onActivate );
    observer.setOnDeactivate( onDeactivate );
    observer.setOnStale( onStale );

    assertEquals( observer.getOnActivate(), onActivate );
    assertEquals( observer.getOnDeactivate(), onDeactivate );
    assertEquals( observer.getOnStale(), onStale );

    observer.invariantState();
  }

  @Test
  public void invariantState_failsIfDependenciesPresentForInactive()
    throws Exception
  {
    final ArezContext context = new ArezContext();
    final Observer observer = new Observer( context, ValueUtil.randomString() );

    observer.invariantState();

    final TestObservable observable = new TestObservable( context, ValueUtil.randomString() );
    observer.getDependencies().add( observable );

    final IllegalStateException exception =
      expectThrows( IllegalStateException.class, observer::invariantState );

    assertEquals( exception.getMessage(),
                  "Observer named '" + observer.getName() + "' is inactive " +
                  "but still has dependencies: [" + observable.getName() + "]." );
  }
}

@@ -1738,50 +1738,1857 @@
 iant
-State_failsIfDependenciesPresentForInactiv
+DependenciesBackLink()%0A    throws Exception%0A  %7B%0A    final ArezContext context = new ArezContext();%0A    final Observer observer = new Observer( context, ValueUtil.randomString() );%0A%0A    final TestObservable observable = new TestObservable( context, ValueUtil.randomString() );%0A    observer.getDependencies().add( observable );%0A%0A    final IllegalStateException exception =%0A      expectThrows( IllegalStateException.class, () -%3E observer.invariantDependenciesBackLink( %22TEST1%22 ) );%0A%0A    assertEquals( exception.getMessage(),%0A                  %22TEST1: Observer named '%22 + observer.getName() + %22' has dependency observable named '%22 +%0A                  observable.getName() + %22' which does not contain the observer in the list of observers.%22 );%0A%0A    //Setup correct back link%0A    observable.addObserver( observer );%0A%0A    // Back link created so should be good%0A    observer.invariantDependenciesBackLink( %22TEST2%22 );%0A  %7D%0A%0A  @Test%0A  public void invariantDependenciesUnique()%0A    throws Exception%0A  %7B%0A    final ArezContext context = new ArezContext();%0A    final Observer observer = new Observer( context, ValueUtil.randomString() );%0A%0A    final TestObservable observable = new TestObservable( context, ValueUtil.randomString() );%0A%0A    observer.getDependencies().add( observable );%0A%0A    observer.invariantDependenciesUnique( %22TEST1%22 );%0A%0A    // Add a duplicate%0A    observer.getDependencies().add( observable );%0A%0A    final IllegalStateException exception =%0A      expectThrows( IllegalStateException.class, () -%3E observer.invariantDependenciesUnique( %22TEST2%22 ) );%0A%0A    assertEquals( exception.getMessage(),%0A                  %22TEST2: The set of dependencies in observer named '%22 + observer.getName() + %22' is %22 +%0A                  %22not unique. Current list: '%5B%22 + observable.getName() + %22, %22 + observable.getName() + %22%5D'.%22 );%0A  %7D%0A%0A  @Test%0A  public void invariantStat
 e()%0A

Add tests around other invariants