Revision: 6280
Author: [email protected]
Date: Thu Oct  1 10:42:54 2009
Log: Merging tr...@6278:6279 trunk.
- NoBatchingStrategy now runs tests as they are executed by JUnit.

svn merge -r6278:6279 --ignore-ancestry  
https://google-web-toolkit.googlecode.com/svn/trunk/ .


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

Added:
   
/branches/snapshot-2009.09.23-r6200/user/test/com/google/gwt/junit/CompileStrategyTest.java
Modified:
  /branches/snapshot-2009.09.23-r6200/branch-info.txt
   
/branches/snapshot-2009.09.23-r6200/user/src/com/google/gwt/junit/BatchingStrategy.java
   
/branches/snapshot-2009.09.23-r6200/user/src/com/google/gwt/junit/CompileStrategy.java
   
/branches/snapshot-2009.09.23-r6200/user/src/com/google/gwt/junit/JUnitShell.java
   
/branches/snapshot-2009.09.23-r6200/user/test/com/google/gwt/junit/BatchingStrategyTest.java
   
/branches/snapshot-2009.09.23-r6200/user/test/com/google/gwt/junit/JUnitSuite.java

=======================================
--- /dev/null
+++  
/branches/snapshot-2009.09.23-r6200/user/test/com/google/gwt/junit/CompileStrategyTest.java
      
Thu Oct  1 10:42:54 2009
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2009 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.gwt.junit;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.cfg.ModuleDef;
+import com.google.gwt.junit.JUnitShell.Strategy;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests of {...@link BatchingStrategy}. This test must run after a
+ * {...@link GWTTestCase} to ensure that JUnitShell is already initialized.
+ */
+public class CompileStrategyTest extends TestCase {
+
+  /**
+   * A mock {...@link RunStyle} used for testing.
+   */
+  private static class MockRunStyle extends RunStyle {
+
+    public MockRunStyle() {
+      super(null);
+    }
+
+    @Override
+    public boolean isLocal() {
+      return true;
+    }
+
+    @Override
+    public void launchModule(String moduleName) {
+    }
+
+    @Override
+    public void maybeCompileModule(String moduleName) {
+    }
+  }
+
+  /**
+   * A mock {...@link JUnitMessageQueue} used for testing.
+   */
+  private static class MockJUnitMessageQueue extends JUnitMessageQueue {
+
+    /**
+     * The test blocks added to the queue.
+     */
+    private List<TestInfo[]> testBlocks;
+
+    /**
+     * Indicates that this is the last test block.
+     */
+    private boolean isLastBlock;
+
+    public MockJUnitMessageQueue() {
+      super(1);
+    }
+
+    @Override
+    void addTestBlocks(List<TestInfo[]> newTestBlocks, boolean  
isLastBlock) {
+      assertNull(testBlocks);
+      this.testBlocks = newTestBlocks;
+      this.isLastBlock = isLastBlock;
+    }
+
+    void assertIsLastBlock(boolean expected) {
+      assertEquals(expected, isLastBlock);
+    }
+
+    void assertTestBlocks(List<TestInfo[]> expected) {
+      if (expected == null || testBlocks == null) {
+        assertEquals(expected, testBlocks);
+        return;
+      }
+
+      assertEquals(expected.size(), testBlocks.size());
+      for (int i = 0; i < testBlocks.size(); i++) {
+        TestInfo[] actualBlock = testBlocks.get(i);
+        TestInfo[] expectedBlock = expected.get(i);
+        assertEquals(expectedBlock.length, actualBlock.length);
+        for (int j = 0; j < expectedBlock.length; j++) {
+          assertEquals(expectedBlock[j], actualBlock[j]);
+        }
+      }
+    }
+  }
+
+  /**
+   * A mock {...@link CompileStrategy} used for testing.
+   */
+  private static class MockCompileStrategy extends CompileStrategy {
+
+    /**
+     * The number of modules to mock.
+     */
+    private int mockModuleCount;
+
+    private MockJUnitMessageQueue messageQueue = new  
MockJUnitMessageQueue();
+
+    /**
+     * Construct a new {...@link MockCompileStrategy}.
+     *
+     * @param mockModuleCount the number of modules
+     */
+    public MockCompileStrategy(int mockModuleCount) {
+      this.mockModuleCount = mockModuleCount;
+    }
+
+    @Override
+    public ModuleDef maybeCompileModule(String moduleName,
+        String syntheticModuleName, Strategy strategy, RunStyle runStyle,
+        BatchingStrategy batchingStrategy, TreeLogger treeLogger) {
+      fail("This method should not be called.");
+      return null;
+    }
+
+    @Override
+    MockJUnitMessageQueue getMessageQueue() {
+      return messageQueue;
+    }
+
+    @Override
+    int getModuleCount() {
+      return mockModuleCount;
+    }
+
+    @Override
+    ModuleDef maybeCompileModuleImpl2(String moduleName,
+        String syntheticModuleName, Strategy strategy, RunStyle runStyle,
+        TreeLogger treeLogger) {
+      return null;
+    }
+  }
+
+  /**
+   * A mock test case used for testing.
+   */
+  private static class MockGWTTestCase extends GWTTestCase {
+    @Override
+    public String getModuleName() {
+      return "com.google.gwt.junit.JUnit";
+    }
+
+    @Override
+    public String getName() {
+      return "testMethod1";
+    }
+
+    public void testMethod0() {
+    }
+
+    public void testMethod1() {
+    }
+
+    public void testMethod2() {
+    }
+  }
+
+  public void testMaybeAddTestBlockForCurrentTestWithoutBatching() {
+    BatchingStrategy batchingStrategy = new NoBatchingStrategy();
+    assertTrue(batchingStrategy.isSingleTestOnly());
+
+    // Maybe add the current test.
+    GWTTestCase testCase = new MockGWTTestCase();
+    MockCompileStrategy strategy = new MockCompileStrategy(-1);
+    strategy.maybeAddTestBlockForCurrentTest(testCase, batchingStrategy);
+
+    // Generate the expected blocks.
+    TestInfo testInfo = new TestInfo(testCase.getSyntheticModuleName(),
+        testCase.getClass().getName(), testCase.getName());
+    List<TestInfo[]> testBlocks = new ArrayList<TestInfo[]>();
+    testBlocks.add(new TestInfo[] {testInfo});
+
+    // Verify the test is added to the queue.
+    strategy.getMessageQueue().assertIsLastBlock(false);
+    strategy.getMessageQueue().assertTestBlocks(testBlocks);
+  }
+
+  public void testMaybeAddTestBlockForCurrentTestWithBatching() {
+    BatchingStrategy batchingStrategy = new ModuleBatchingStrategy();
+    assertFalse(batchingStrategy.isSingleTestOnly());
+
+    // Maybe add the current test.
+    GWTTestCase testCase = new MockGWTTestCase();
+    MockCompileStrategy strategy = new MockCompileStrategy(-1);
+    strategy.maybeAddTestBlockForCurrentTest(testCase, batchingStrategy);
+
+    // Verify the test is not added to the queue.
+    strategy.getMessageQueue().assertTestBlocks(null);
+  }
+
+  public void testMaybeCompileModuleImplWithoutBatching() {
+    BatchingStrategy batchingStrategy = new NoBatchingStrategy();
+    assertTrue(batchingStrategy.isSingleTestOnly());
+
+    // Maybe add the current test.
+    RunStyle runStyle = new MockRunStyle();
+    GWTTestCase testCase = new MockGWTTestCase();
+    MockCompileStrategy strategy = new MockCompileStrategy(-1);
+    try {
+      strategy.maybeCompileModuleImpl(testCase.getModuleName(),
+          testCase.getSyntheticModuleName(), testCase.getStrategy(),  
runStyle,
+          batchingStrategy, TreeLogger.NULL);
+    } catch (UnableToCompleteException e) {
+      fail("Unexpected UnableToCompleteException: " + e.getMessage());
+    }
+
+    // Verify the test block is not added to the queue.
+    strategy.getMessageQueue().assertTestBlocks(null);
+  }
+
+  public void testMaybeCompileModuleImplWithBatchingLastModule() {
+    BatchingStrategy batchingStrategy = new ModuleBatchingStrategy();
+    assertFalse(batchingStrategy.isSingleTestOnly());
+
+    // Maybe add the current test.
+    RunStyle runStyle = new MockRunStyle();
+    GWTTestCase testCase = new MockGWTTestCase();
+    MockCompileStrategy strategy = new MockCompileStrategy(-1);
+    try {
+      strategy.maybeCompileModuleImpl(testCase.getModuleName(),
+          testCase.getSyntheticModuleName(), testCase.getStrategy(),  
runStyle,
+          batchingStrategy, TreeLogger.NULL);
+    } catch (UnableToCompleteException e) {
+      fail("Unexpected UnableToCompleteException: " + e.getMessage());
+    }
+
+    // Verify the test block is added to the queue.
+    strategy.getMessageQueue().assertIsLastBlock(true);
+    strategy.getMessageQueue().assertTestBlocks(
+        batchingStrategy.getTestBlocks(testCase.getSyntheticModuleName()));
+  }
+
+  public void testMaybeCompileModuleImplWithBatchingNotLastModule() {
+    BatchingStrategy batchingStrategy = new ClassBatchingStrategy();
+    assertFalse(batchingStrategy.isSingleTestOnly());
+
+    // Maybe add the current test.
+    RunStyle runStyle = new MockRunStyle();
+    GWTTestCase testCase = new MockGWTTestCase();
+    MockCompileStrategy strategy = new MockCompileStrategy(1000);
+    try {
+      strategy.maybeCompileModuleImpl(testCase.getModuleName(),
+          testCase.getSyntheticModuleName(), testCase.getStrategy(),  
runStyle,
+          batchingStrategy, TreeLogger.NULL);
+    } catch (UnableToCompleteException e) {
+      fail("Unexpected UnableToCompleteException: " + e.getMessage());
+    }
+
+    // Verify the test block is added to the queue.
+    strategy.getMessageQueue().assertIsLastBlock(false);
+    strategy.getMessageQueue().assertTestBlocks(
+        batchingStrategy.getTestBlocks(testCase.getSyntheticModuleName()));
+  }
+}
=======================================
--- /branches/snapshot-2009.09.23-r6200/branch-info.txt Wed Sep 30 12:56:26  
2009
+++ /branches/snapshot-2009.09.23-r6200/branch-info.txt Thu Oct  1 10:42:54  
2009
@@ -7,4 +7,5 @@

  Merges:
  /trunk/@6234:6235 was merged (r6236) into this branch
-/trunk/@6264:6265 was merged (r????) into this branch
+/trunk/@6264:6265 was merged (r6266) into this branch
+/trunk/@6278:6279 was merged (r????) into this branch
=======================================
---  
/branches/snapshot-2009.09.23-r6200/user/src/com/google/gwt/junit/BatchingStrategy.java
  
Wed Sep 30 12:56:26 2009
+++  
/branches/snapshot-2009.09.23-r6200/user/src/com/google/gwt/junit/BatchingStrategy.java
  
Thu Oct  1 10:42:54 2009
@@ -39,6 +39,21 @@
     */
    public abstract List<TestInfo[]> getTestBlocks(String  
syntheticModuleName);

+  /**
+   * Check if this batching strategy only supports execution of a single  
test at
+   * a time.
+   *
+   * If this method returns true, test methods will be executed on the  
client as
+   * they are run by JUnit. If it returns false, test methods will be  
batched
+   * and sent to the clients in groups. If you are using a test runner that
+   * shards test methods across multiple clients, you should use a  
strategy that
+   * returns false (such as {...@link NoBatchingStrategy}) or all tests will  
be
+   * executed on all clients.
+   *
+   * @return true if batches never contain more than one test
+   */
+  public abstract boolean isSingleTestOnly();
+
    /**
     * Get the set of tests for this module, minus tests that should not be
     * executed.
@@ -72,6 +87,11 @@
      }
      return testBlocks;
    }
+
+  @Override
+  public boolean isSingleTestOnly() {
+    return true;
+  }
  }

  /**
@@ -105,6 +125,11 @@
      }
      return testBlocks;
    }
+
+  @Override
+  public boolean isSingleTestOnly() {
+    return false;
+  }
  }

  /**
@@ -121,4 +146,9 @@
      }
      return testBlocks;
    }
-}
+
+  @Override
+  public boolean isSingleTestOnly() {
+    return false;
+  }
+}
=======================================
---  
/branches/snapshot-2009.09.23-r6200/user/src/com/google/gwt/junit/CompileStrategy.java
   
Thu Sep 17 13:59:15 2009
+++  
/branches/snapshot-2009.09.23-r6200/user/src/com/google/gwt/junit/CompileStrategy.java
   
Thu Oct  1 10:42:54 2009
@@ -43,6 +43,23 @@
     * adding test batches that have already been added.
     */
    private Set<String> compiledModuleNames = new HashSet<String>();
+
+  /**
+   * Maybe add a test block for the currently executed test case.
+   *
+   * @param testCase the test case being run
+   * @param batchingStrategy the batching strategy
+   */
+  public void maybeAddTestBlockForCurrentTest(GWTTestCase testCase,
+      BatchingStrategy batchingStrategy) {
+    if (batchingStrategy.isSingleTestOnly()) {
+      TestInfo testInfo = new TestInfo(testCase.getSyntheticModuleName(),
+          testCase.getClass().getName(), testCase.getName());
+      List<TestInfo[]> testBlocks = new ArrayList<TestInfo[]>(1);
+      testBlocks.add(new TestInfo[] {testInfo});
+      getMessageQueue().addTestBlocks(testBlocks, false);
+    }
+  }

    /**
     * Let the compile strategy compile another module. This is called while
@@ -85,6 +102,57 @@
        BatchingStrategy batchingStrategy, TreeLogger treeLogger)
        throws UnableToCompleteException {

+    // Let the runstyle compile the module.
+    ModuleDef moduleDef = maybeCompileModuleImpl2(moduleName,
+        syntheticModuleName, strategy, runStyle, treeLogger);
+
+    // Add all test blocks for the module if we haven't seen this module  
before.
+    if (!compiledModuleNames.contains(syntheticModuleName)) {
+      compiledModuleNames.add(syntheticModuleName);
+      if (!batchingStrategy.isSingleTestOnly()) {
+        // Use >= so we can mock getModuleCount and force isFinalModule to  
true
+        boolean isFinalModule = compiledModuleNames.size() >=  
getModuleCount();
+        List<TestInfo[]> testBlocks =  
batchingStrategy.getTestBlocks(syntheticModuleName);
+        getMessageQueue().addTestBlocks(testBlocks, isFinalModule);
+      }
+    }
+
+    return moduleDef;
+  }
+
+  /**
+   * Visible for testing and mocking.
+   *
+   * @return the {...@link JUnitMessageQueue}
+   */
+  JUnitMessageQueue getMessageQueue() {
+    return JUnitShell.getMessageQueue();
+  }
+
+  /**
+   * Visible for testing and mocking.
+   *
+   * @return the number of modules to test
+   */
+  int getModuleCount() {
+    return GWTTestCase.getModuleCount();
+  }
+
+  /**
+   * Let the {...@link RunStyle} compile the module if needed
+   *
+   * Visible for testing and mocking.
+   *
+   * @param moduleName the module name
+   * @param syntheticModuleName the synthetic module name
+   * @param strategy the strategy
+   * @param runStyle the run style
+   * @param treeLogger the logger
+   * @return the {...@link ModuleDef} describing the synthetic module
+   */
+  ModuleDef maybeCompileModuleImpl2(String moduleName,
+      String syntheticModuleName, Strategy strategy, RunStyle runStyle,
+      TreeLogger treeLogger) throws UnableToCompleteException {
      /*
       * Synthesize a synthetic module that derives from the user-specified  
module
       * but also includes JUnit support.
@@ -103,14 +171,6 @@
      moduleNameProp.setValue(syntheticModuleName);

      runStyle.maybeCompileModule(syntheticModuleName);
-
-    // Add all test blocks for the module if we haven't seen this module  
before.
-    if (!compiledModuleNames.contains(syntheticModuleName)) {
-      compiledModuleNames.add(syntheticModuleName);
-      boolean isFinalModule = compiledModuleNames.size() ==  
GWTTestCase.getModuleCount();
-      List<TestInfo[]> testBlocks =  
batchingStrategy.getTestBlocks(syntheticModuleName);
-      JUnitShell.getMessageQueue().addTestBlocks(testBlocks,  
isFinalModule);
-    }

      return moduleDef;
    }
=======================================
---  
/branches/snapshot-2009.09.23-r6200/user/src/com/google/gwt/junit/JUnitShell.java
        
Wed Sep 30 12:56:26 2009
+++  
/branches/snapshot-2009.09.23-r6200/user/src/com/google/gwt/junit/JUnitShell.java
        
Thu Oct  1 10:42:54 2009
@@ -1005,6 +1005,7 @@
        processTestResult(testCase, testResult, strategy);
        return;
      }
+    compileStrategy.maybeAddTestBlockForCurrentTest(testCase,  
batchingStrategy);

      try {
        if (firstLaunch) {
=======================================
---  
/branches/snapshot-2009.09.23-r6200/user/test/com/google/gwt/junit/BatchingStrategyTest.java
     
Wed Sep 30 12:56:26 2009
+++  
/branches/snapshot-2009.09.23-r6200/user/test/com/google/gwt/junit/BatchingStrategyTest.java
     
Thu Oct  1 10:42:54 2009
@@ -79,22 +79,28 @@
        FAKE_MODULE_SYNTHETIC_NAME,  
TestClass2.class.getName(), "testMethod5");

    public void testClassBatchingStrategy() {
+    BatchingStrategy strategy = new ClassBatchingStrategy();
+    assertFalse(strategy.isSingleTestOnly());
      List<TestInfo[]> testBlocks = new ArrayList<TestInfo[]>();
      testBlocks.add(new TestInfo[] {TEST_INFO_0_0, TEST_INFO_0_1});
      testBlocks.add(new TestInfo[] {TEST_INFO_1_2, TEST_INFO_1_3,  
TEST_INFO_1_4});
      testBlocks.add(new TestInfo[] {TEST_INFO_2_5});
-    testBatchingStrategy(new ClassBatchingStrategy(), testBlocks);
+    testBatchingStrategy(strategy, testBlocks);
    }

    public void testModuleBatchingStrategy() {
+    BatchingStrategy strategy = new ModuleBatchingStrategy();
+    assertFalse(strategy.isSingleTestOnly());
      List<TestInfo[]> testBlocks = new ArrayList<TestInfo[]>();
      testBlocks.add(new TestInfo[] {
          TEST_INFO_0_0, TEST_INFO_0_1, TEST_INFO_1_2, TEST_INFO_1_3,
          TEST_INFO_1_4, TEST_INFO_2_5});
-    testBatchingStrategy(new ModuleBatchingStrategy(), testBlocks);
+    testBatchingStrategy(strategy, testBlocks);
    }

    public void testNoBatchingStrategy() {
+    BatchingStrategy strategy = new NoBatchingStrategy();
+    assertTrue(strategy.isSingleTestOnly());
      List<TestInfo[]> testBlocks = new ArrayList<TestInfo[]>();
      testBlocks.add(new TestInfo[] {TEST_INFO_0_0});
      testBlocks.add(new TestInfo[] {TEST_INFO_0_1});
@@ -102,7 +108,7 @@
      testBlocks.add(new TestInfo[] {TEST_INFO_1_3});
      testBlocks.add(new TestInfo[] {TEST_INFO_1_4});
      testBlocks.add(new TestInfo[] {TEST_INFO_2_5});
-    testBatchingStrategy(new NoBatchingStrategy(), testBlocks);
+    testBatchingStrategy(strategy, testBlocks);
    }

    /**
=======================================
---  
/branches/snapshot-2009.09.23-r6200/user/test/com/google/gwt/junit/JUnitSuite.java
       
Wed Sep 30 12:56:26 2009
+++  
/branches/snapshot-2009.09.23-r6200/user/test/com/google/gwt/junit/JUnitSuite.java
       
Thu Oct  1 10:42:54 2009
@@ -25,7 +25,8 @@
   */
  public class JUnitSuite {
    public static Test suite() {
-    GWTTestSuite suite = new GWTTestSuite("Test for suite for  
com.google.gwt.junit");
+    GWTTestSuite suite = new GWTTestSuite(
+        "Test for suite for com.google.gwt.junit");

      // client
      // Suppressed due to flakiness on Linux
@@ -34,6 +35,7 @@

      // Must run after a GWTTestCase so JUnitShell is initialized.
      suite.addTestSuite(BatchingStrategyTest.class);
+    suite.addTestSuite(CompileStrategyTest.class);

      suite.addTestSuite(FakeMessagesMakerTest.class);
      suite.addTestSuite(JUnitMessageQueueTest.class);

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

Reply via email to