Revision: 10499
Author:   [email protected]
Date:     Fri Aug  5 09:53:30 2011
Log: Support chained requests where the returned proxy type is not reachable from the canonical RequestContext.
Issue 6641.
Patch by: bobv
Review by: rjrjr

Review at http://gwt-code-reviews.appspot.com/1499810

http://code.google.com/p/google-web-toolkit/source/detail?r=10499

Added:
/trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryChainedContextTest.java /trunk/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryChainedContextJreTest.java
Modified:
/trunk/user/src/com/google/web/bindery/requestfactory/shared/impl/AbstractRequestContext.java /trunk/user/src/com/google/web/bindery/requestfactory/vm/InProcessRequestContext.java /trunk/user/test/com/google/web/bindery/requestfactory/gwt/RequestFactorySuite.java /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryTest.java /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryTestBase.java /trunk/user/test/com/google/web/bindery/requestfactory/vm/RequestFactoryJreSuite.java

=======================================
--- /dev/null
+++ /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryChainedContextTest.java Fri Aug 5 09:53:30 2011
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.web.bindery.requestfactory.gwt.client;
+
+import com.google.gwt.core.client.GWT;
+import com.google.web.bindery.event.shared.SimpleEventBus;
+import com.google.web.bindery.requestfactory.shared.ProxyFor;
+import com.google.web.bindery.requestfactory.shared.Receiver;
+import com.google.web.bindery.requestfactory.shared.Request;
+import com.google.web.bindery.requestfactory.shared.RequestContext;
+import com.google.web.bindery.requestfactory.shared.RequestFactory;
+import com.google.web.bindery.requestfactory.shared.Service;
+import com.google.web.bindery.requestfactory.shared.SimpleBarProxy;
+import com.google.web.bindery.requestfactory.shared.SimpleBarRequest;
+import com.google.web.bindery.requestfactory.shared.SimpleFooProxy;
+import com.google.web.bindery.requestfactory.shared.SimpleFooRequest;
+import com.google.web.bindery.requestfactory.shared.ValueProxy;
+
+/**
+ * Tests various aspects of how {@code RequestContext.append()} behaves.
+ */
+public class RequestFactoryChainedContextTest extends RequestFactoryTestBase {
+  /**
+ * A RequestFactory where the contained RequestContext types have disjoint
+   * reachable proxy types.
+   */
+  protected interface Factory extends RequestFactory {
+    ACtx a();
+
+    BCtx b();
+  }
+
+  /**
+   * Mandatory javadoc comment.
+   */
+  public static class A {
+    public static A a() {
+      return new A();
+    }
+  }
+
+  @Service(A.class)
+  interface ACtx extends RequestContext {
+    Request<AProxy> a();
+  }
+
+  @ProxyFor(A.class)
+  interface AProxy extends ValueProxy {
+  }
+
+  /**
+   * Mandatory javadoc comment.
+   */
+  public static class B {
+    public static B b() {
+      return new B();
+    }
+  }
+
+  @Service(B.class)
+  interface BCtx extends RequestContext {
+    Request<BProxy> b();
+  }
+
+  @ProxyFor(B.class)
+  interface BProxy extends ValueProxy {
+  }
+
+  private static final int DELAY_TEST_FINISH = 5000;
+
+  @Override
+  public String getModuleName() {
+    return "com.google.web.bindery.requestfactory.gwt.RequestFactorySuite";
+  }
+
+  /**
+   * Basic functional test of the append method.
+   */
+  public void testAppend() {
+    delayTestFinish(DELAY_TEST_FINISH);
+    SimpleFooRequest fooCtx1 = req.simpleFooRequest();
+    SimpleFooProxy foo1 = fooCtx1.create(SimpleFooProxy.class);
+    SimpleBarRequest barCtx = fooCtx1.append(req.simpleBarRequest());
+    SimpleFooRequest fooCtx2 = barCtx.append(req.simpleFooRequest());
+
+    assertNotSame(fooCtx1, fooCtx2);
+    assertSame(foo1, barCtx.edit(foo1));
+    assertSame(foo1, fooCtx2.edit(foo1));
+
+    SimpleBarProxy foo2 = barCtx.create(SimpleBarProxy.class);
+    assertSame(foo2, fooCtx1.edit(foo2));
+    assertSame(foo2, fooCtx2.edit(foo2));
+
+    SimpleFooProxy foo3 = fooCtx2.create(SimpleFooProxy.class);
+    assertSame(foo3, fooCtx1.edit(foo3));
+    assertSame(foo3, barCtx.edit(foo3));
+
+    try {
+      // Throws exception because c3 has already accumulated some state
+      req.simpleValueContext().append(fooCtx2);
+      fail("Should have thrown IllegalStateException");
+    } catch (IllegalStateException expected) {
+    }
+
+    try {
+ // Throws exception because a different RequestFactory instance is used
+      fooCtx2.append(createFactory().simpleFooRequest());
+      fail("Should have thrown IllegalStateException");
+    } catch (IllegalStateException expected) {
+    }
+
+    // Queue up two invocations, and test that both Receivers are called
+    final boolean[] seen = {false, false};
+    fooCtx1.add(1, 2).to(new Receiver<Integer>() {
+      @Override
+      public void onSuccess(Integer response) {
+        seen[0] = true;
+        assertEquals(3, response.intValue());
+      }
+    });
+    barCtx.countSimpleBar().to(new Receiver<Long>() {
+      @Override
+      public void onSuccess(Long response) {
+        seen[1] = true;
+        assertEquals(2, response.longValue());
+      }
+    });
+
+    // It doesn't matter which context instance is fired
+    barCtx.fire(new Receiver<Void>() {
+      @Override
+      public void onSuccess(Void response) {
+        assertTrue(seen[0]);
+        assertTrue(seen[1]);
+        finishTestAndReset();
+      }
+    });
+
+    /*
+     * Since the common State has been locked, calling any other
+     * context-mutation methods should fail.
+     */
+    try {
+      fooCtx1.fire();
+      fail("Should have thrown exception");
+    } catch (IllegalStateException expected) {
+    }
+    try {
+      fooCtx2.fire();
+      fail("Should have thrown exception");
+    } catch (IllegalStateException expected) {
+    }
+    try {
+      fooCtx2.create(SimpleFooProxy.class);
+      fail("Should have thrown exception");
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+  /**
+   * Ensure that a method invoked on an appended context can result in the
+   * creation of a proxy not reachable from canonical context.
+   */
+  public void testChainedProxyInstantiation() {
+    delayTestFinish(DELAY_TEST_FINISH);
+    Factory f = createChainedFactory();
+
+    ACtx aCtx = f.a();
+    checkReachableTypes(aCtx, AProxy.class, BProxy.class);
+
+    RequestContext ctx = aCtx.a().to(new Receiver<AProxy>() {
+      @Override
+      public void onSuccess(AProxy response) {
+        assertNotNull(response);
+      }
+    });
+
+    BCtx bCtx = ctx.append(f.b());
+    checkReachableTypes(aCtx, AProxy.class, BProxy.class);
+    checkReachableTypes(bCtx, BProxy.class, AProxy.class);
+
+    bCtx.b().to(new Receiver<BProxy>() {
+      @Override
+      public void onSuccess(BProxy response) {
+        assertNotNull(response);
+      }
+    });
+    ctx.fire(new Receiver<Void>() {
+      @Override
+      public void onSuccess(Void response) {
+        finishTest();
+      }
+    });
+  }
+
+  protected Factory createChainedFactory() {
+    Factory f = GWT.create(Factory.class);
+    f.initialize(new SimpleEventBus());
+    return f;
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/test/com/google/web/bindery/requestfactory/server/RequestFactoryChainedContextJreTest.java Fri Aug 5 09:53:30 2011
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.web.bindery.requestfactory.server;
+
+import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryChainedContextTest;
+import com.google.web.bindery.requestfactory.shared.SimpleRequestFactory;
+
+/**
+ * Runs the RequestFactoryChainedContext tests in-process.
+ */
+public class RequestFactoryChainedContextJreTest extends RequestFactoryChainedContextTest {
+
+  @Override
+  public String getModuleName() {
+    return null;
+  }
+
+  @Override
+  protected Factory createChainedFactory() {
+    return RequestFactoryJreTest.createInProcess(Factory.class);
+  }
+
+  @Override
+  protected SimpleRequestFactory createFactory() {
+ return RequestFactoryJreTest.createInProcess(SimpleRequestFactory.class);
+  }
+}
=======================================
--- /trunk/user/src/com/google/web/bindery/requestfactory/shared/impl/AbstractRequestContext.java Fri Jun 10 10:21:52 2011 +++ /trunk/user/src/com/google/web/bindery/requestfactory/shared/impl/AbstractRequestContext.java Fri Aug 5 09:53:30 2011
@@ -61,6 +61,7 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -98,6 +99,12 @@
    * Encapsulates all state contained by the AbstractRequestContext.
    */
   protected static class State {
+    /**
+ * Supports the case where chained contexts are used and a response comes + * back from the server with a proxy type not reachable from the canonical
+     * context.
+     */
+    public Set<AbstractRequestContext> appendedContexts;
     public final AbstractRequestContext canonical;
     public final DialectImpl dialect;
     public FanoutReceiver<Void> fanout;
@@ -137,8 +144,19 @@
public State(AbstractRequestFactory requestFactory, DialectImpl dialect,
         AbstractRequestContext canonical) {
       this.requestFactory = requestFactory;
-      this.dialect = dialect;
       this.canonical = canonical;
+      this.dialect = dialect;
+    }
+
+    public void addContext(AbstractRequestContext ctx) {
+      if (appendedContexts == null) {
+        appendedContexts = Collections.singleton(ctx);
+      } else {
+        if (appendedContexts.size() == 1) {
+ appendedContexts = new LinkedHashSet<AbstractRequestContext>(appendedContexts);
+        }
+        appendedContexts.add(ctx);
+      }
     }

     public AbstractRequestContext getCanonicalContext() {
@@ -231,7 +249,7 @@
(Class<BaseProxy>) state.invocations.get(0).getRequestData().getReturnType();

       SimpleProxyId<BaseProxy> id = getRequestFactory().allocateId(target);
-      AutoBean<BaseProxy> bean = createProxy(target, id);
+      AutoBean<BaseProxy> bean = createProxy(target, id, true);
       // XXX expose this as a proper API
       ((AbstractAutoBean<?>) bean).setData(result);
       // AutoBeanCodex.decodeInto(result, bean);
@@ -453,7 +471,7 @@
   private State state;

protected AbstractRequestContext(AbstractRequestFactory factory, Dialect dialect) {
-    this.state = new State(factory, dialect.create(this), this);
+    setState(new State(factory, dialect.create(this), this));
   }

   public <T extends RequestContext> T append(T other) {
@@ -465,7 +483,7 @@
     if (!child.state.isClean()) {
throw new IllegalStateException("The provided RequestContext has been changed");
     }
-    child.state = state;
+    child.setState(state);
     return other;
   }

@@ -476,21 +494,9 @@
     checkLocked();

     SimpleProxyId<T> id = state.requestFactory.allocateId(clazz);
-    AutoBean<T> created = createProxy(clazz, id);
+    AutoBean<T> created = createProxy(clazz, id, false);
     return takeOwnership(created);
   }
-
-  /**
-   * Creates a new proxy with an assigned ID.
-   */
- public <T extends BaseProxy> AutoBean<T> createProxy(Class<T> clazz, SimpleProxyId<T> id) {
-    AutoBean<T> created = getAutoBeanFactory().create(clazz);
-    if (created == null) {
- throw new IllegalArgumentException("Unknown proxy type " + clazz.getName());
-    }
-    created.setTag(STABLE_ID, id);
-    return created;
-  }

   public <T extends BaseProxy> T edit(T object) {
     return editProxy(object);
@@ -532,8 +538,8 @@
       @Override
       protected RequestData makeRequestData() {
         // This method is normally generated, hence the ugly constructor
-        return new RequestData(Constants.FIND_METHOD_OPERATION,
- new Object[] {proxyId}, propertyRefs, proxyId.getProxyClass(), null); + return new RequestData(Constants.FIND_METHOD_OPERATION, new Object[] {proxyId},
+            propertyRefs, proxyId.getProxyClass(), null);
       }
     };
   }
@@ -642,7 +648,7 @@
    */
   public boolean isValueType(Class<?> clazz) {
     return state.requestFactory.isValueType(clazz);
-  };
+  }

   public void setFireDisabled(boolean disabled) {
     state.fireDisabled = disabled;
@@ -653,6 +659,39 @@
    */
   protected void addInvocation(AbstractRequest<?> request) {
     state.dialect.addInvocation(request);
+  };
+
+  /**
+   * Creates a new proxy with an assigned ID.
+   *
+   * @param clazz The proxy type
+   * @param id The id to be assigned to the new proxy
+ * @param useAppendedContexts if {@code true} use the AutoBeanFactory types
+   *          associated with any contexts that have been passed into
+ * {@link #append(RequestContext)}. If {@code false}, this method
+   *          will only create proxy types reachable from the implemented
+   *          RequestContext interface.
+   * @throws IllegalArgumentException if the requested proxy type cannot be
+   *           created
+   */
+ protected <T extends BaseProxy> AutoBean<T> createProxy(Class<T> clazz, SimpleProxyId<T> id,
+      boolean useAppendedContexts) {
+    AutoBean<T> created = null;
+    if (useAppendedContexts) {
+      for (AbstractRequestContext ctx : state.appendedContexts) {
+        created = ctx.getAutoBeanFactory().create(clazz);
+        if (created != null) {
+          break;
+        }
+      }
+    } else {
+      created = getAutoBeanFactory().create(clazz);
+    }
+    if (created != null) {
+      created.setTag(STABLE_ID, id);
+      return created;
+    }
+ throw new IllegalArgumentException("Unknown proxy type " + clazz.getName());
   }

   /**
@@ -747,7 +786,7 @@
     AutoBean<Q> bean = (AutoBean<Q>) state.returnedProxies.get(id);
     if (bean == null) {
       Class<Q> proxyClass = id.getProxyClass();
-      bean = createProxy(proxyClass, id);
+      bean = createProxy(proxyClass, id, true);
       state.returnedProxies.put(id, bean);
     }

@@ -770,7 +809,7 @@
     AutoBean<?> parent;
     if (stableId.isEphemeral()) {
       // Newly-created object, use a blank object to compare against
-      parent = createProxy(stableId.getProxyClass(), stableId);
+      parent = createProxy(stableId.getProxyClass(), stableId, true);

       // Newly-created objects go into the persist operation bucket
       operation.setOperation(WriteOperation.PERSIST);
@@ -779,7 +818,7 @@
       operation.setStrength(Strength.EPHEMERAL);
     } else if (stableId.isSynthetic()) {
       // Newly-created object, use a blank object to compare against
-      parent = createProxy(stableId.getProxyClass(), stableId);
+      parent = createProxy(stableId.getProxyClass(), stableId, true);

       // Newly-created objects go into the persist operation bucket
       operation.setOperation(WriteOperation.PERSIST);
@@ -1199,6 +1238,11 @@
     freezeEntities(false);
     state.locked = false;
   }
+
+  private void setState(State state) {
+    this.state = state;
+    state.addContext(this);
+  }

   /**
    * Make the EnityProxy bean edited and owned by this RequestContext.
=======================================
--- /trunk/user/src/com/google/web/bindery/requestfactory/vm/InProcessRequestContext.java Fri Jun 10 11:06:22 2011 +++ /trunk/user/src/com/google/web/bindery/requestfactory/vm/InProcessRequestContext.java Fri Aug 5 09:53:30 2011
@@ -203,9 +203,10 @@
   }

   @Override
- public <T extends BaseProxy> AutoBean<T> createProxy(Class<T> clazz, SimpleProxyId<T> id) { + protected <T extends BaseProxy> AutoBean<T> createProxy(Class<T> clazz, SimpleProxyId<T> id,
+      boolean useAppendedContexts) {
     if (tokenResolver.isReferencedType(clazz.getName())) {
-      return super.createProxy(clazz, id);
+      return super.createProxy(clazz, id, useAppendedContexts);
     }
throw new IllegalArgumentException("Unknown proxy type " + clazz.getName());
   }
=======================================
--- /trunk/user/test/com/google/web/bindery/requestfactory/gwt/RequestFactorySuite.java Fri May 27 04:59:21 2011 +++ /trunk/user/test/com/google/web/bindery/requestfactory/gwt/RequestFactorySuite.java Fri Aug 5 09:53:30 2011
@@ -18,6 +18,7 @@
 import com.google.gwt.junit.tools.GWTTestSuite;
 import com.google.web.bindery.requestfactory.gwt.client.RequestBatcherTest;
 import com.google.web.bindery.requestfactory.gwt.client.FindServiceTest;
+import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryChainedContextTest; import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryExceptionHandlerTest; import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryExceptionPropagationTest; import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryPolymorphicTest;
@@ -47,6 +48,7 @@
     suite.addTestSuite(FindServiceTest.class);
     suite.addTestSuite(LocatorTest.class);
     suite.addTestSuite(RequestFactoryTest.class);
+    suite.addTestSuite(RequestFactoryChainedContextTest.class);
     suite.addTestSuite(RequestFactoryExceptionHandlerTest.class);
     suite.addTestSuite(RequestFactoryExceptionPropagationTest.class);
     suite.addTestSuite(RequestFactoryPolymorphicTest.class);
=======================================
--- /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryTest.java Sat Jul 30 02:03:17 2011 +++ /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryTest.java Fri Aug 5 09:53:30 2011
@@ -241,87 +241,6 @@
           }
         });
   }
-
-  public void testAppend() {
-    delayTestFinish(DELAY_TEST_FINISH);
-    SimpleFooRequest c1 = req.simpleFooRequest();
-    SimpleFooProxy foo1 = c1.create(SimpleFooProxy.class);
-    SimpleBarRequest c2 = c1.append(req.simpleBarRequest());
-    SimpleFooRequest c3 = c2.append(req.simpleFooRequest());
-
-    assertNotSame(c1, c3);
-    assertSame(foo1, c2.edit(foo1));
-    assertSame(foo1, c3.edit(foo1));
-
-    SimpleBarProxy foo2 = c2.create(SimpleBarProxy.class);
-    assertSame(foo2, c1.edit(foo2));
-    assertSame(foo2, c3.edit(foo2));
-
-    SimpleFooProxy foo3 = c3.create(SimpleFooProxy.class);
-    assertSame(foo3, c1.edit(foo3));
-    assertSame(foo3, c2.edit(foo3));
-
-    try {
-      // Throws exception because c3 has already accumulated some state
-      req.simpleValueContext().append(c3);
-      fail("Should have thrown IllegalStateException");
-    } catch (IllegalStateException expected) {
-    }
-
-    try {
- // Throws exception because a different RequestFactory instance is used
-      c3.append(createFactory().simpleFooRequest());
-      fail("Should have thrown IllegalStateException");
-    } catch (IllegalStateException expected) {
-    }
-
-    // Queue up two invocations, and test that both Receivers are called
-    final boolean[] seen = {false, false};
-    c1.add(1, 2).to(new Receiver<Integer>() {
-      @Override
-      public void onSuccess(Integer response) {
-        seen[0] = true;
-        assertEquals(3, response.intValue());
-      }
-    });
-    c2.countSimpleBar().to(new Receiver<Long>() {
-      @Override
-      public void onSuccess(Long response) {
-        seen[1] = true;
-        assertEquals(2, response.longValue());
-      }
-    });
-
-    // It doesn't matter which context instance is fired
-    c2.fire(new Receiver<Void>() {
-      @Override
-      public void onSuccess(Void response) {
-        assertTrue(seen[0]);
-        assertTrue(seen[1]);
-        finishTestAndReset();
-      }
-    });
-
-    /*
-     * Since the common State has been locked, calling any other
-     * context-mutation methods should fail.
-     */
-    try {
-      c1.fire();
-      fail("Should have thrown exception");
-    } catch (IllegalStateException expected) {
-    }
-    try {
-      c3.fire();
-      fail("Should have thrown exception");
-    } catch (IllegalStateException expected) {
-    }
-    try {
-      c3.create(SimpleFooProxy.class);
-      fail("Should have thrown exception");
-    } catch (IllegalStateException expected) {
-    }
-  }

   /**
    * Test that we can commit child objects.
=======================================
--- /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryTestBase.java Thu Apr 21 12:15:42 2011 +++ /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryTestBase.java Fri Aug 5 09:53:30 2011
@@ -27,6 +27,7 @@
 import com.google.web.bindery.requestfactory.shared.EntityProxyChange;
 import com.google.web.bindery.requestfactory.shared.ProxySerializer;
 import com.google.web.bindery.requestfactory.shared.Receiver;
+import com.google.web.bindery.requestfactory.shared.RequestContext;
 import com.google.web.bindery.requestfactory.shared.SimpleFooRequest;
 import com.google.web.bindery.requestfactory.shared.SimpleRequestFactory;
 import com.google.web.bindery.requestfactory.shared.impl.BaseProxyCategory;
@@ -85,6 +86,29 @@
     assertEquals(a, b);
     assertEquals(b, a);
   }
+
+  /**
+ * Check that some proxy type can be created by the given context and that
+   * some other proxy type can't.
+   */
+ protected void checkReachableTypes(RequestContext ctx, Class<? extends BaseProxy> shouldWork,
+      Class<? extends BaseProxy> shouldFail) {
+    assertNotNull(ctx.create(shouldWork));
+    try {
+      // Metadata computation has only RequestFactory resolution
+      // http://code.google.com/p/google-web-toolkit/issues/detail?id=6658
+      if (GWT.isClient()) {
+        ctx.create(shouldFail);
+        fail();
+      } else {
+        assertNotNull(ctx.create(shouldFail));
+      }
+    } catch (IllegalArgumentException expected) {
+      if (!GWT.isClient()) {
+ fail("Expect the create call to always work in RFSource implementation");
+      }
+    }
+  }

   /**
    * Run the given proxy through a ProxySerializer and verify that the
=======================================
--- /trunk/user/test/com/google/web/bindery/requestfactory/vm/RequestFactoryJreSuite.java Thu Jun 16 03:10:29 2011 +++ /trunk/user/test/com/google/web/bindery/requestfactory/vm/RequestFactoryJreSuite.java Fri Aug 5 09:53:30 2011
@@ -20,6 +20,7 @@
 import com.google.web.bindery.requestfactory.server.FanoutReceiverJreTest;
 import com.google.web.bindery.requestfactory.server.FindServiceJreTest;
 import com.google.web.bindery.requestfactory.server.LocatorJreTest;
+import com.google.web.bindery.requestfactory.server.RequestFactoryChainedContextJreTest; import com.google.web.bindery.requestfactory.server.RequestFactoryExceptionPropagationJreTest; import com.google.web.bindery.requestfactory.server.RequestFactoryInterfaceValidatorTest;
 import com.google.web.bindery.requestfactory.server.RequestFactoryJreTest;
@@ -46,6 +47,7 @@
     suite.addTestSuite(FanoutReceiverJreTest.class);
     suite.addTestSuite(FindServiceJreTest.class);
     suite.addTestSuite(LocatorJreTest.class);
+    suite.addTestSuite(RequestFactoryChainedContextJreTest.class);
     suite.addTestSuite(RequestFactoryExceptionPropagationJreTest.class);
     suite.addTestSuite(RequestFactoryInterfaceValidatorTest.class);
     suite.addTestSuite(RequestFactoryJreTest.class);

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to