Add GWTTestSuite to bin GWTTestCases to minimize the number of times the test cases must switch between GWT Modules.
Add TestSuites for groups of tests where none previously existed.
Perform an outofdate check on the benchmark viewer app to eliminate unnecessary rebuilds.
Switch the "ant test" build target to run with suite-level granularity.

Patch by: bobv, scott
Review by: scott


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1952 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/common.ant.xml b/common.ant.xml
index a37656d..036441e 100755
--- a/common.ant.xml
+++ b/common.ant.xml
@@ -92,7 +92,7 @@
 	<!-- JUnit support -->
 	<property name="gwt.dev.staging.jar" location="${gwt.build.staging}/gwt-${build.host.platform}-${gwt.version}/gwt-dev-${build.host.platform}.jar" />
 	<property name="gwt.junit.port" value="8888" />
-	<property name="gwt.junit.testcase.includes" value="**/*Test.class"/>
+	<property name="gwt.junit.testcase.includes" value="**/*Suite.class"/>
 	
 	<!--
 		Comma delimited list of host and path components on which to run remote browser testing.
@@ -144,9 +144,9 @@
 			<mkdir dir="@{test.reports}" />
 
 			<echo message="${javac.out} ${javac.junit.out}" />
-			<junit dir="@{test.out}" fork="yes" printsummary="yes" haltonfailure="true">
+			<junit dir="@{test.out}" fork="yes" printsummary="yes" failureproperty="junit.failure" >
 				<jvmarg line="${junit.platform.args}" />
-				<jvmarg line="-Xmx256m" />
+				<jvmarg line="-Xmx512m" />
 				<sysproperty key="gwt.args" value="@{test.args}" />
 				<sysproperty key="gwt.devjar" value="${gwt.dev.staging.jar}" />
 				<sysproperty key="java.awt.headless" value="true" />
@@ -168,6 +168,7 @@
 					<fileset refid="@{test.cases}" />
 				</batchtest>
 			</junit>
+			<fail message="One or more junit tests failed" if="junit.failure" />
 		</sequential>
 	</macrodef>
 
diff --git a/samples/build.xml b/samples/build.xml
index c5e87d1..bc5ad97 100644
--- a/samples/build.xml
+++ b/samples/build.xml
@@ -34,7 +34,15 @@
 		<gwt.ant dir="simplexml" />
 	</target>
 
-	<target name="-do" depends="dynatable, hello, i18n, json, kitchensink, mail, simplexml" description="Run all subprojects" />
+	<target name="-do" description="Run all subprojects" >
+		<antcall target="dynatable" />
+		<antcall target="hello" />
+		<antcall target="i18n" />
+		<antcall target="json" />
+		<antcall target="kitchensink" />
+		<antcall target="mail" />
+		<antcall target="simplexml" />
+	</target>
 
 	<target name="build" description="Builds GWT">
 		<antcall target="-do">
diff --git a/samples/common.ant.xml b/samples/common.ant.xml
index 401381a..ac4f9ed 100755
--- a/samples/common.ant.xml
+++ b/samples/common.ant.xml
@@ -40,7 +40,7 @@
 				<fileset file="${gwt.user.jar}" />
 				<fileset file="${gwt.dev.jar}" />
 			</sourcefiles>
-			<targetfiles path="${sample.build}/www/com.google.gwt.sample.${sample.package}.${sample.module}/com.google.gwt.sample.${sample.package}.${sample.module}.nocache.html" />
+			<targetfiles path="${sample.build}/www/com.google.gwt.sample.${sample.package}.${sample.module}/std/com.google.gwt.sample.${sample.package}.${sample.module}.nocache.js" />
 			<sequential>
 				<mkdir dir="${sample.build}/www" />
 				<java dir="${sample.build}" classname="com.google.gwt.dev.GWTCompiler" classpath="src:${sample.build}/bin:${gwt.user.jar}:${gwt.dev.jar}" fork="yes" failonerror="true">
diff --git a/tools/benchmark-viewer/build.xml b/tools/benchmark-viewer/build.xml
index bf460e9..b4409a5 100755
--- a/tools/benchmark-viewer/build.xml
+++ b/tools/benchmark-viewer/build.xml
@@ -64,7 +64,7 @@
 	<target name="build" depends="compile, gwtc" description="Build and package this project">
 		<mkdir dir="${gwt.build.lib}" />
                 <copy todir="${tools.build}/www-new/${tools.module.path}" flatten="true" >
-                  <fileset dir="${tools.build}/www/${tools.module}" />
+                  <fileset dir="${tools.build}/www/${tools.module}/std" />
                 </copy>
                     
 		<gwt.jar>
@@ -85,11 +85,23 @@
 
 	<target name="gwtc" description="Compile to JavaScript">
 	  	<mkdir dir="${tools.build}/www" />
-		<java dir="${tools.build}" classname="com.google.gwt.dev.GWTCompiler" classpath="src:${gwt.user.jar}:${gwt.dev.jar}" fork="yes" failonerror="true">
-			<arg value="-out" />
-			<arg file="${tools.build}/www" />
-			<arg value="${tools.module}" />
-		</java>
+		<outofdate>
+			<sourcefiles>
+				<fileset dir="src" />
+				<fileset file="${gwt.user.jar}" />
+				<fileset file="${gwt.dev.jar}" />
+			</sourcefiles>
+			<targetfiles>
+				<fileset dir="${tools.build}/www" />
+			</targetfiles>
+			<sequential>
+				<java dir="${tools.build}" classname="com.google.gwt.dev.GWTCompiler" classpath="src:${gwt.user.jar}:${gwt.dev.jar}" fork="yes" failonerror="true">
+					<arg value="-out" />
+					<arg file="${tools.build}/www" />
+					<arg value="${tools.module}" />
+				</java>
+			</sequential>
+		</outofdate>
 	</target>
 
 	<target name="remoteweb-test" description="Run a remoteweb test at the given host and path">
diff --git a/user/build.xml b/user/build.xml
index 2d50926..dda881b 100755
--- a/user/build.xml
+++ b/user/build.xml
@@ -1,106 +1,20 @@
 <project name="user" default="build" basedir=".">
 	<property name="gwt.root" location=".." />
 	<property name="project.tail" value="user" />
+	<property name="test.args" value="" />
 	<import file="${gwt.root}/common.ant.xml" />
 
 	<!--
 		Default hosted mode test cases
 	-->
 	<fileset id="default.hosted.tests" dir="${javac.junit.out}" 
-			 includes="${gwt.junit.testcase.includes}">
-		<!--
-			Requires manual testing, because it generates intentional failures.
-		-->
-		<exclude name="com/google/gwt/junit/client/ParallelRemoteTest.class" />
-
-		<!--
-			Causes a security dialog to popup and subsequently blocks testing
-		-->
-		<exclude name="com/google/gwt/user/client/ui/FormPanelTest.class" />
-
-		<!--
-			Need to confirm with JGW if this should still be disabled
-		-->
-		<exclude name="com/google/gwt/user/client/ui/HistoryTest.class" />
-
-		<!--
-			Safari regression:
-				Testcase: testPositioning took 7.514 sec
-				FAILED
-					expected=225 actual=207
-					junit.framework.AssertionFailedError:  expected=225 actual=207
-		-->
-		<exclude name="com/google/gwt/user/client/ui/AbsolutePanelTest.class" />
-	</fileset>
+			 includes="${gwt.junit.testcase.includes}" />
 
 	<!--
 		Default web mode test cases
 	-->
 	<fileset id="default.web.tests" dir="${javac.junit.out}"
- 		 	 includes="${gwt.junit.testcase.includes}">
-		<!--
-			Requires manual testing, because it generates intentional failures.
-		-->
-		<exclude name="com/google/gwt/junit/client/ParallelRemoteTest.class" />
-		
-		<!--
-			Causes a security dialog to popup and subsequently blocks testing
-		-->
-		<exclude name="com/google/gwt/user/client/ui/FormPanelTest.class" />
-
-		<!--
-			Need to confirm with JGW if this should still be disabled
-		-->
-		<exclude name="com/google/gwt/user/client/ui/HistoryTest.class" />
-
-		<!--
-			Safari Failures:
-				Testcase: testFunctionCaching took 0.112 sec
-			        Caused an ERROR
-					JavaScript RangeError exception: Maximum call stack size exceeded.
-					com.google.gwt.core.client.JavaScriptException: JavaScript RangeError exception: Maximum call stack size exceeded.
-			
-			Linux Web Mode Failures:
-				Testcase: testFunctionCaching took 1.004 sec
-			        Caused an ERROR
-					JavaScript InternalError exception: too much recursion
-					com.google.gwt.core.client.JavaScriptException: JavaScript InternalError exception: too much recursion
-		-->
-		<exclude name="com/google/gwt/dev/jjs/test/HostedTest.class" />
-
-		<!--
-			Safari Failures:
-				Testcase: testRecursion took 1.003 sec
-			        Caused an ERROR
-					JavaScript RangeError exception: Maximum call stack size exceeded.
-					com.google.gwt.core.client.JavaScriptException: JavaScript RangeError exception: Maximum call stack size exceeded.
-		-->
-		<exclude name="com/google/gwt/dev/jjs/test/MethodCallTest.class" />
-
-		<!--
-			Safari Failures:
-				Testcase: testJso took 1.005 sec
-				        Caused an ERROR
-				JavaScript RangeError exception: Maximum call stack size exceeded.
-				com.google.gwt.core.client.JavaScriptException: JavaScript RangeError exception: Maximum call stack size exceeded.
-		-->
-		<exclude name="com/google/gwt/dev/jjs/test/MiscellaneousTest.class" />
-
-		<!--
-			Safari regression:
-				Testcase: testPositioning took 7.514 sec
-					FAILED
-				expected=225 actual=207
-				junit.framework.AssertionFailedError:  expected=225 actual=207
-		-->
-		<exclude name="com/google/gwt/user/client/ui/AbsolutePanelTest.class" />
-
-		<!--
-			No compiler support yet; waiting on Class.getEnumConstants()
-		-->
-		<exclude name="com/google/gwt/emultest/java/util/EnumMapTest.class" />
-		<exclude name="com/google/gwt/emultest/java/util/EnumSetTest.class" />
-	</fileset>
+ 		 	 includes="${gwt.junit.testcase.includes}" />
 
 	<!-- Platform shouldn't matter here, just picking one -->
 	<property.ensure name="gwt.dev.jar" location="${gwt.build.lib}/gwt-dev-linux.jar" />
@@ -153,15 +67,15 @@
 
 	<target name="remoteweb-test" description="Run a remoteweb test at the given host and path">
 		<echo message="Performing remote browser testing at rmi://${gwt.remote.browser}" />
-		<gwt.junit test.args="-out www -web -remoteweb rmi://${gwt.remote.browser}" test.out="${junit.out}/${gwt.remote.browser}" test.cases="default.web.tests" />
+		<gwt.junit test.args="${test.args} -out www -web -remoteweb rmi://${gwt.remote.browser}" test.out="${junit.out}/${gwt.remote.browser}" test.cases="default.web.tests" />
 	</target>
 
 	<target name="test.hosted" depends="compile, compile.tests" description="Run only hosted-mode tests for this project.">
-		<gwt.junit test.out="${junit.out}/${build.host.platform}-hosted-mode" test.cases="default.hosted.tests" />
+		<gwt.junit test.args="${test.args}" test.out="${junit.out}/${build.host.platform}-hosted-mode" test.cases="default.hosted.tests" />
 	</target>
 
 	<target name="test.web" depends="compile, compile.tests" description="Run only web-mode tests for this project.">
-		<gwt.junit test.args="-out www -web" test.out="${junit.out}/${build.host.platform}-web-mode" test.cases="default.web.tests" />
+		<gwt.junit test.args="${test.args} -out www -web" test.out="${junit.out}/${build.host.platform}-web-mode" test.cases="default.web.tests" />
 	</target>
 
 	<target name="test" depends="compile, compile.tests" description="Run hosted-mode, web-mode and remoteweb tests for this project.">
@@ -171,7 +85,8 @@
 			Run hosted and web mode tests for the platform on which this build
 			is executing
 		-->
-		<parallel threadcount="1">
+		<limit failonerror="true" hours="1">
+		<parallel threadsPerProcessor="1">
 			<antcall target="test.hosted"/>
 
 			<antcall target="test.web"/>
@@ -181,6 +96,7 @@
 			-->
 			<foreach list="${gwt.remote.browsers}" delimiter="," parallel="true" maxThreads="1" target="remoteweb-test" param="gwt.remote.browser" />
 		</parallel>
+		</limit>
 	</target>
 
 	<target name="clean" description="Cleans this project's intermediate and output files">
diff --git a/user/src/com/google/gwt/junit/tools/GWTTestSuite.java b/user/src/com/google/gwt/junit/tools/GWTTestSuite.java
new file mode 100644
index 0000000..f4962cc
--- /dev/null
+++ b/user/src/com/google/gwt/junit/tools/GWTTestSuite.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2008 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.tools;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * A utility class to optimize the order in which GWTTestCases are run by
+ * minimizing the number of times the test framework switches modules.
+ */
+public class GWTTestSuite extends TestSuite {
+  private final Map<String, TestSuite> moduleSuites = new TreeMap<String, TestSuite>();
+
+  private TestSuite nonGWTTestSuite;
+
+  public GWTTestSuite() {
+  }
+
+  public GWTTestSuite(String name) {
+    super(name);
+  }
+
+  @Override
+  public void addTest(Test test) {
+    if (test instanceof TestSuite) {
+      doAddTest((TestSuite) test);
+    } else {
+      doAddTest(test);
+    }
+  }
+
+  private void doAddTest(Test test) {
+    TestSuite moduleSuite = getModuleSuiteFor(test);
+    moduleSuite.addTest(test);
+  }
+
+  private void doAddTest(TestSuite suite) {
+    Test[] homogenized = homogenize(suite);
+    for (Test test : homogenized) {
+      doAddTest(test);
+    }
+  }
+
+  /**
+   * Returns the "module" suite this test should be placed in; only accurate for
+   * suites that are homogeneous.
+   */
+  private TestSuite getModuleSuiteFor(Test test) {
+    if (test instanceof TestSuite) {
+      TestSuite suite = (TestSuite) test;
+      if (suite.countTestCases() == 0) {
+        return nonGWTTestSuite;
+      } else {
+        return getModuleSuiteFor(suite.testAt(0));
+      }
+    } else if (test instanceof GWTTestCase) {
+      GWTTestCase gwtTest = (GWTTestCase) test;
+      TestSuite suite = moduleSuites.get(gwtTest.getModuleName());
+      if (suite == null) {
+        suite = new TestSuite(gwtTest.getModuleName() + ".gwt.xml");
+        moduleSuites.put(gwtTest.getModuleName(), suite);
+        super.addTest(suite);
+      }
+      return suite;
+    } else {
+      if (nonGWTTestSuite == null) {
+        nonGWTTestSuite = new TestSuite("Non-GWT");
+        super.addTest(nonGWTTestSuite);
+      }
+      return nonGWTTestSuite;
+    }
+  }
+
+  /**
+   * Breaks non-homogeneous suites into two or more homogeneous suites. A
+   * homogeneous suite is one in which all tests run within a single module.
+   */
+  @SuppressWarnings("unchecked")
+  private TestSuite[] homogenize(TestSuite suite) {
+    String suiteName = suite.getName();
+
+    // Each sub-test is placed into a "bucket" corresponding to its module.
+    List<TestSuite> buckets = new ArrayList<TestSuite>();
+    Map<TestSuite, TestSuite> moduleToBucket = new HashMap<TestSuite, TestSuite>();
+
+    // Sort the sub-tests into buckets by module.
+    for (Enumeration<Test> enumeration = suite.tests(); enumeration.hasMoreElements();) {
+      Test test = enumeration.nextElement();
+      if (test instanceof TestSuite) {
+        // Recursively homogenize any sub-suites.
+        TestSuite[] subSuites = homogenize((TestSuite) test);
+        for (TestSuite subSuite : subSuites) {
+          sortIntoBucket(subSuite, buckets, moduleToBucket, suiteName);
+        }
+      } else {
+        sortIntoBucket(test, buckets, moduleToBucket, suiteName);
+      }
+    }
+
+    // Return myself if there's only one bucket; otherwise return the buckets.
+    int numBuckets = buckets.size();
+    if (numBuckets == 1) {
+      return new TestSuite[] {suite};
+    } else {
+      return buckets.toArray(new TestSuite[numBuckets]);
+    }
+  }
+
+  private void sortIntoBucket(Test test, List<TestSuite> buckets,
+      Map<TestSuite, TestSuite> moduleToBucket, String newBucketName) {
+    TestSuite module = getModuleSuiteFor(test);
+    TestSuite bucket = moduleToBucket.get(module);
+    if (bucket == null) {
+      bucket = new TestSuite(newBucketName);
+      buckets.add(bucket);
+      moduleToBucket.put(module, bucket);
+    }
+    bucket.addTest(test);
+  }
+}
diff --git a/user/test/com/google/gwt/dev/cfg/TagSuite.java b/user/test/com/google/gwt/dev/cfg/TagSuite.java
index db56ebf..7a9d44b 100644
--- a/user/test/com/google/gwt/dev/cfg/TagSuite.java
+++ b/user/test/com/google/gwt/dev/cfg/TagSuite.java
@@ -15,8 +15,9 @@
  */
 package com.google.gwt.dev.cfg;
 
+import com.google.gwt.junit.tools.GWTTestSuite;
+
 import junit.framework.Test;
-import junit.framework.TestSuite;
 
 /**
  * Tests all classes in GWT JRE emulation library.
@@ -24,7 +25,7 @@
 public class TagSuite {
 
   public static Test suite() {
-    TestSuite suite = new TestSuite(
+    GWTTestSuite suite = new GWTTestSuite(
         "Tests for public, source, and super-source tags");
 
     // $JUnit-BEGIN$
diff --git a/user/test/com/google/gwt/dev/jjs/CompilerSuite.java b/user/test/com/google/gwt/dev/jjs/CompilerSuite.java
index b2a71ad..37775c7 100644
--- a/user/test/com/google/gwt/dev/jjs/CompilerSuite.java
+++ b/user/test/com/google/gwt/dev/jjs/CompilerSuite.java
@@ -36,9 +36,9 @@
 import com.google.gwt.dev.jjs.test.MiscellaneousTest;
 import com.google.gwt.dev.jjs.test.NativeLongTest;
 import com.google.gwt.dev.jjs.test.VarargsTest;
+import com.google.gwt.junit.tools.GWTTestSuite;
 
 import junit.framework.Test;
-import junit.framework.TestSuite;
 
 /**
  * The complete compiler suite.
@@ -46,7 +46,7 @@
 public class CompilerSuite {
 
   public static Test suite() {
-    TestSuite suite = new TestSuite("Test for com.google.gwt.dev.jjs");
+    GWTTestSuite suite = new GWTTestSuite("Test for com.google.gwt.dev.jjs");
 
     // $JUnit-BEGIN$
     suite.addTestSuite(AnnotationsTest.class);
diff --git a/user/test/com/google/gwt/emultest/EmulSuite.java b/user/test/com/google/gwt/emultest/EmulSuite.java
index 37e510d..6f11f17 100644
--- a/user/test/com/google/gwt/emultest/EmulSuite.java
+++ b/user/test/com/google/gwt/emultest/EmulSuite.java
@@ -37,9 +37,9 @@
 import com.google.gwt.emultest.java.util.HashMapTest;
 import com.google.gwt.emultest.java.util.HashSetTest;
 import com.google.gwt.emultest.java.util.StackTest;
+import com.google.gwt.junit.tools.GWTTestSuite;
 
 import junit.framework.Test;
-import junit.framework.TestSuite;
 
 /**
  * TODO: document me.
@@ -48,7 +48,7 @@
 
   /** Note: due to compiler error, only can use one Test Case at a time. */
   public static Test suite() {
-    TestSuite suite = new TestSuite("Tests for com.google.gwt.emul.java");
+    GWTTestSuite suite = new GWTTestSuite("Tests for com.google.gwt.emul.java");
 
     // $JUnit-BEGIN$
     suite.addTestSuite(BooleanTest.class);
diff --git a/user/test/com/google/gwt/http/HTTPSuite.java b/user/test/com/google/gwt/http/HTTPSuite.java
index 8ea7a61..379a093 100644
--- a/user/test/com/google/gwt/http/HTTPSuite.java
+++ b/user/test/com/google/gwt/http/HTTPSuite.java
@@ -19,16 +19,16 @@
 import com.google.gwt.http.client.RequestTest;
 import com.google.gwt.http.client.ResponseTest;
 import com.google.gwt.http.client.URLTest;
+import com.google.gwt.junit.tools.GWTTestSuite;
 
 import junit.framework.Test;
-import junit.framework.TestSuite;
 
 /**
  * TODO: document me.
  */
 public class HTTPSuite {
   public static Test suite() {
-    TestSuite suite = new TestSuite(
+    GWTTestSuite suite = new GWTTestSuite(
         "Test for suite for the com.google.gwt.http module");
 
     suite.addTestSuite(URLTest.class);
diff --git a/user/test/com/google/gwt/i18n/I18NSuite.java b/user/test/com/google/gwt/i18n/I18NSuite.java
new file mode 100644
index 0000000..f5ea159
--- /dev/null
+++ b/user/test/com/google/gwt/i18n/I18NSuite.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 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.i18n;
+
+import com.google.gwt.i18n.client.DateTimeFormat_de_Test;
+import com.google.gwt.i18n.client.DateTimeParse_en_Test;
+import com.google.gwt.i18n.client.DateTimeParse_zh_CN_Test;
+import com.google.gwt.i18n.client.I18N2Test;
+import com.google.gwt.i18n.client.I18NTest;
+import com.google.gwt.i18n.client.LocaleInfoTest;
+import com.google.gwt.i18n.client.LocaleInfo_ar_Test;
+import com.google.gwt.i18n.client.LocaleInfo_none_Test;
+import com.google.gwt.i18n.client.NumberFormat_en_Test;
+import com.google.gwt.i18n.client.NumberFormat_fr_Test;
+import com.google.gwt.i18n.client.NumberParse_en_Test;
+import com.google.gwt.i18n.client.NumberParse_fr_Test;
+import com.google.gwt.i18n.rebind.util.AbstractResourceTest;
+import com.google.gwt.junit.tools.GWTTestSuite;
+
+import junit.framework.Test;
+
+/**
+ * All I18N tests.
+ */
+public class I18NSuite {
+  public static Test suite() {
+    GWTTestSuite suite = new GWTTestSuite("All I18N tests");
+
+    // $JUnit-BEGIN$
+    suite.addTestSuite(AbstractResourceTest.class);
+    suite.addTestSuite(ConstantMapTest.class);
+    suite.addTestSuite(DateTimeFormat_de_Test.class);
+    suite.addTestSuite(DateTimeParse_en_Test.class);
+    suite.addTestSuite(DateTimeParse_zh_CN_Test.class);
+    suite.addTestSuite(I18NTest.class);
+    suite.addTestSuite(I18N2Test.class);
+    suite.addTestSuite(LocaleInfo_ar_Test.class);
+    suite.addTestSuite(LocaleInfo_none_Test.class);
+    suite.addTestSuite(LocaleInfoTest.class);
+    suite.addTestSuite(NumberFormat_en_Test.class);
+    suite.addTestSuite(NumberFormat_fr_Test.class);
+    suite.addTestSuite(NumberParse_en_Test.class);
+    suite.addTestSuite(NumberParse_fr_Test.class);
+    // $JUnit-END$
+
+    return suite;
+  }
+}
diff --git a/user/test/com/google/gwt/json/JSONSuite.java b/user/test/com/google/gwt/json/JSONSuite.java
new file mode 100644
index 0000000..0d44b49
--- /dev/null
+++ b/user/test/com/google/gwt/json/JSONSuite.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2008 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.json;
+
+import com.google.gwt.json.client.JSONTest;
+import com.google.gwt.junit.tools.GWTTestSuite;
+
+import junit.framework.Test;
+
+/**
+ * All JSON tests.
+ */
+public class JSONSuite {
+  public static Test suite() {
+    GWTTestSuite suite = new GWTTestSuite();
+
+    suite.addTestSuite(JSONTest.class);
+
+    return suite;
+  }
+}
diff --git a/user/test/com/google/gwt/module/ModuleSuite.java b/user/test/com/google/gwt/module/ModuleSuite.java
new file mode 100644
index 0000000..422fa3c
--- /dev/null
+++ b/user/test/com/google/gwt/module/ModuleSuite.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008 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.module;
+
+import com.google.gwt.junit.tools.GWTTestSuite;
+import com.google.gwt.module.client.DoubleScriptInjectionTest;
+import com.google.gwt.module.client.SingleScriptInjectionTest;
+
+import junit.framework.Test;
+
+/**
+ * Tests script and resource injection.
+ */
+public class ModuleSuite {
+  public static Test suite() {
+    GWTTestSuite suite = new GWTTestSuite();
+    
+    suite.addTestSuite(SingleScriptInjectionTest.class);
+    suite.addTestSuite(DoubleScriptInjectionTest.class);
+    
+    return suite;
+  }
+}
diff --git a/user/test/com/google/gwt/user/RPCSuite.java b/user/test/com/google/gwt/user/RPCSuite.java
index 7b1729f..384d3cf 100644
--- a/user/test/com/google/gwt/user/RPCSuite.java
+++ b/user/test/com/google/gwt/user/RPCSuite.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user;
 
+import com.google.gwt.junit.tools.GWTTestSuite;
 import com.google.gwt.user.client.rpc.CollectionsTest;
 import com.google.gwt.user.client.rpc.CustomFieldSerializerTest;
 import com.google.gwt.user.client.rpc.EnumsTest;
@@ -29,14 +30,14 @@
 import com.google.gwt.user.server.rpc.impl.StandardSerializationPolicyTest;
 
 import junit.framework.Test;
-import junit.framework.TestSuite;
 
 /**
  * A collection of TestCases for the RPC system.
  */
 public class RPCSuite {
   public static Test suite() {
-    TestSuite suite = new TestSuite("Test for com.google.gwt.user.client.rpc");
+    GWTTestSuite suite = new GWTTestSuite(
+        "Test for com.google.gwt.user.client.rpc");
 
     suite.addTestSuite(SerializableTypeOracleBuilderTest.class);
     suite.addTestSuite(RPCTest.class);
diff --git a/user/test/com/google/gwt/user/UISuite.java b/user/test/com/google/gwt/user/UISuite.java
index 16b09ab..6185e41 100644
--- a/user/test/com/google/gwt/user/UISuite.java
+++ b/user/test/com/google/gwt/user/UISuite.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2008 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
@@ -15,6 +15,10 @@
  */
 package com.google.gwt.user;
 
+import com.google.gwt.junit.tools.GWTTestSuite;
+import com.google.gwt.user.client.CommandExecutorTest;
+import com.google.gwt.user.client.CookieTest;
+import com.google.gwt.user.client.WindowTest;
 import com.google.gwt.user.client.ui.AbsolutePanelTest;
 import com.google.gwt.user.client.ui.CheckBoxTest;
 import com.google.gwt.user.client.ui.CustomButtonTest;
@@ -42,6 +46,7 @@
 import com.google.gwt.user.client.ui.PopupTest;
 import com.google.gwt.user.client.ui.PrefixTreeTest;
 import com.google.gwt.user.client.ui.RadioButtonTest;
+import com.google.gwt.user.client.ui.RichTextAreaTest;
 import com.google.gwt.user.client.ui.ScrollPanelTest;
 import com.google.gwt.user.client.ui.SplitPanelTest;
 import com.google.gwt.user.client.ui.StackPanelTest;
@@ -54,20 +59,25 @@
 import com.google.gwt.user.client.ui.VerticalPanelTest;
 import com.google.gwt.user.client.ui.WidgetCollectionTest;
 import com.google.gwt.user.client.ui.WidgetIteratorsTest;
+import com.google.gwt.user.client.ui.WidgetOnLoadTest;
+import com.google.gwt.user.client.ui.impl.ClippedImagePrototypeTest;
+import com.google.gwt.xml.client.XMLTest;
 
 import junit.framework.Test;
-import junit.framework.TestSuite;
 
 /**
  * TODO: document me.
  */
 public class UISuite {
   public static Test suite() {
-    TestSuite suite = new TestSuite(
+    GWTTestSuite suite = new GWTTestSuite(
         "Test for suite for the com.google.gwt.ui module");
 
     suite.addTestSuite(AbsolutePanelTest.class);
     suite.addTestSuite(CheckBoxTest.class);
+    suite.addTestSuite(ClippedImagePrototypeTest.class);
+    suite.addTestSuite(CommandExecutorTest.class);
+    suite.addTestSuite(CookieTest.class);
     suite.addTestSuite(CustomButtonTest.class);
     suite.addTestSuite(DecoratorPanelTest.class);
     suite.addTestSuite(DelegatingKeyboardListenerCollectionTest.class);
@@ -95,6 +105,7 @@
     suite.addTestSuite(PopupTest.class);
     suite.addTestSuite(PrefixTreeTest.class);
     suite.addTestSuite(RadioButtonTest.class);
+    suite.addTestSuite(RichTextAreaTest.class);
     suite.addTestSuite(ScrollPanelTest.class);
     suite.addTestSuite(SplitPanelTest.class);
     suite.addTestSuite(StackPanelTest.class);
@@ -107,6 +118,9 @@
     suite.addTestSuite(VerticalPanelTest.class);
     suite.addTestSuite(WidgetCollectionTest.class);
     suite.addTestSuite(WidgetIteratorsTest.class);
+    suite.addTestSuite(WidgetOnLoadTest.class);
+    suite.addTestSuite(WindowTest.class);
+    suite.addTestSuite(XMLTest.class);
 
     return suite;
   }
diff --git a/user/test/test/ServletMappingSuite.java b/user/test/test/ServletMappingSuite.java
new file mode 100644
index 0000000..e4178d5
--- /dev/null
+++ b/user/test/test/ServletMappingSuite.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2008 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 test;
+
+import com.google.gwt.junit.tools.GWTTestSuite;
+
+import junit.framework.Test;
+
+/**
+ * Tests servlet mappings.
+ */
+public class ServletMappingSuite {
+  public static Test suite() {
+    GWTTestSuite suite = new GWTTestSuite();
+    
+    suite.addTestSuite(ServletMappingTest.class);
+    
+    return suite;
+  }
+}