@@ -0,0 +1,2766 @@
+package org.realityforge.arez.api2.test;%0A%0Aimport org.realityforge.arez.api2.AbstractArezTest;%0Aimport org.realityforge.arez.api2.ArezContext;%0Aimport org.realityforge.guiceyloops.shared.ValueUtil;%0Aimport org.testng.annotations.Test;%0Aimport static org.testng.Assert.*;%0A%0Apublic class TransactionApiTest%0A  extends AbstractArezTest%0A%7B%0A  @Test%0A  public void transactionsCanProduceValues()%0A    throws Exception%0A  %7B%0A    final ArezContext context = new ArezContext();%0A%0A    assertFalse( context.isTransactionActive() );%0A%0A    final String expectedValue = ValueUtil.randomString();%0A%0A    final String v0 =%0A      context.transaction( ValueUtil.randomString(), null, () -%3E %7B%0A        assertTrue( context.isTransactionActive() );%0A        return expectedValue;%0A      %7D );%0A%0A    assertFalse( context.isTransactionActive() );%0A%0A    assertEquals( v0, expectedValue );%0A  %7D%0A%0A  @Test%0A  public void transactionsCanBeNested()%0A    throws Exception%0A  %7B%0A    final ArezContext context = new ArezContext();%0A%0A    assertFalse( context.isTransactionActive() );%0A%0A    context.transaction( ValueUtil.randomString(), null, () -%3E %7B%0A      assertTrue( context.isTransactionActive() );%0A%0A      //First nested exception%0A      context.transaction( ValueUtil.randomString(), null, () -%3E %7B%0A        assertTrue( context.isTransactionActive() );%0A%0A        //Second nested exception%0A        context.transaction( ValueUtil.randomString(), null, () -%3E %7B%0A          assertTrue( context.isTransactionActive() );%0A        %7D );%0A%0A        assertTrue( context.isTransactionActive() );%0A      %7D );%0A%0A      assertTrue( context.isTransactionActive() );%0A    %7D );%0A%0A    assertFalse( context.isTransactionActive() );%0A  %7D%0A%0A  @Test%0A  public void valueProducingTransactionsCanBeNested()%0A    throws Exception%0A  %7B%0A    final ArezContext context = new ArezContext();%0A%0A    assertFalse( context.isTransactionActive() );%0A%0A    final String expectedValue = ValueUtil.randomString();%0A%0A    final String v0 =%0A      context.transaction( ValueUtil.randomString(), null, () -%3E %7B%0A        assertTrue( context.isTransactionActive() );%0A%0A        //First nested exception%0A        final String v1 =%0A          context.transaction( ValueUtil.randomString(), null, () -%3E %7B%0A            assertTrue( context.isTransactionActive() );%0A%0A            //Second nested exception%0A            final String v2 =%0A              context.transaction( ValueUtil.randomString(), null, () -%3E %7B%0A                assertTrue( context.isTransactionActive() );%0A                return expectedValue;%0A              %7D );%0A%0A            assertTrue( context.isTransactionActive() );%0A%0A            return v2;%0A          %7D );%0A%0A        assertTrue( context.isTransactionActive() );%0A        return v1;%0A      %7D );%0A%0A    assertFalse( context.isTransactionActive() );%0A%0A    assertEquals( v0, expectedValue );%0A  %7D%0A%7D%0A

Add some minimal tests that exercise the API layer