ROLLED BACK AT r4334 DUE TO BUILD BREAK.

Added tests for arg processing of the main GWT entry points.
- Some testability tweaks on the classes being tested.


git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/1.6@4327 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/ArgProcessorBase.java b/dev/core/src/com/google/gwt/dev/ArgProcessorBase.java
new file mode 100644
index 0000000..3f38920
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/ArgProcessorBase.java
@@ -0,0 +1,37 @@
+/*
+ * 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.dev;
+
+import com.google.gwt.util.tools.ToolBase;
+
+/**
+ * Base class for new-style argument processors.
+ */
+abstract class ArgProcessorBase extends ToolBase {
+  /*
+   * Overridden to make public.
+   */
+  @Override
+  public final boolean processArgs(String[] args) {
+    return super.processArgs(args);
+  }
+
+  /*
+   * Made abstract to force override.
+   */
+  @Override
+  protected abstract String getName();
+}
diff --git a/dev/core/src/com/google/gwt/dev/CompileArgProcessor.java b/dev/core/src/com/google/gwt/dev/CompileArgProcessor.java
index fdc5e99..56eb33c 100644
--- a/dev/core/src/com/google/gwt/dev/CompileArgProcessor.java
+++ b/dev/core/src/com/google/gwt/dev/CompileArgProcessor.java
@@ -19,24 +19,12 @@
 import com.google.gwt.dev.util.arg.ArgHandlerModuleName;
 import com.google.gwt.dev.util.arg.ArgHandlerTreeLoggerFlag;
 import com.google.gwt.dev.util.arg.ArgHandlerWorkDirRequired;
-import com.google.gwt.util.tools.ToolBase;
 
-abstract class CompileArgProcessor extends ToolBase {
+abstract class CompileArgProcessor extends ArgProcessorBase {
   public CompileArgProcessor(CompileTaskOptions options) {
     registerHandler(new ArgHandlerLogLevel(options));
     registerHandler(new ArgHandlerTreeLoggerFlag(options));
     registerHandler(new ArgHandlerWorkDirRequired(options));
     registerHandler(new ArgHandlerModuleName(options));
   }
-
-  /*
-   * Overridden to make public.
-   */
-  @Override
-  public final boolean processArgs(String[] args) {
-    return super.processArgs(args);
-  }
-
-  @Override
-  protected abstract String getName();
 }
diff --git a/dev/core/src/com/google/gwt/dev/CompilePermsServer.java b/dev/core/src/com/google/gwt/dev/CompilePermsServer.java
index ace3385..ac4cc42 100644
--- a/dev/core/src/com/google/gwt/dev/CompilePermsServer.java
+++ b/dev/core/src/com/google/gwt/dev/CompilePermsServer.java
@@ -22,7 +22,6 @@
 import com.google.gwt.dev.util.arg.OptionLogLevel;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
 import com.google.gwt.util.tools.ArgHandlerString;
-import com.google.gwt.util.tools.ToolBase;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -162,7 +161,7 @@
     }
   }
 
-  static class ArgProcessor extends ToolBase {
+  static class ArgProcessor extends ArgProcessorBase {
     public ArgProcessor(CompileServerOptions options) {
       registerHandler(new ArgHandlerLogLevel(options));
       registerHandler(new ArgHandlerCompileHost(options));
@@ -170,14 +169,6 @@
       registerHandler(new ArgHandlerCookie(options));
     }
 
-    /*
-     * Overridden to make public.
-     */
-    @Override
-    public final boolean processArgs(String[] args) {
-      return super.processArgs(args);
-    }
-
     @Override
     protected String getName() {
       return CompilePermsServer.class.getName();
diff --git a/dev/core/src/com/google/gwt/dev/HostedMode.java b/dev/core/src/com/google/gwt/dev/HostedMode.java
index 93ebb2c..5fb7fb7 100644
--- a/dev/core/src/com/google/gwt/dev/HostedMode.java
+++ b/dev/core/src/com/google/gwt/dev/HostedMode.java
@@ -27,6 +27,7 @@
 import com.google.gwt.dev.shell.jetty.JettyLauncher;
 import com.google.gwt.dev.util.Util;
 import com.google.gwt.dev.util.arg.ArgHandlerExtraDir;
+import com.google.gwt.dev.util.arg.ArgHandlerLocalWorkers;
 import com.google.gwt.dev.util.arg.ArgHandlerModuleName;
 import com.google.gwt.dev.util.arg.ArgHandlerWarDir;
 import com.google.gwt.dev.util.arg.ArgHandlerWorkDirOptional;
@@ -68,10 +69,28 @@
     }
 
     @Override
-    public boolean setString(String arg) {
+    public boolean setString(String sclClassName) {
       // Supercedes -noserver.
       setRunTomcat(true);
-      return setServer(console, arg);
+      Throwable t;
+      try {
+        Class<?> clazz = Class.forName(sclClassName, true,
+            Thread.currentThread().getContextClassLoader());
+        Class<? extends ServletContainerLauncher> sclClass = clazz.asSubclass(ServletContainerLauncher.class);
+        setServerContainerLauncher(sclClass.newInstance());
+        return true;
+      } catch (ClassCastException e) {
+        t = e;
+      } catch (ClassNotFoundException e) {
+        t = e;
+      } catch (InstantiationException e) {
+        t = e;
+      } catch (IllegalAccessException e) {
+        t = e;
+      }
+      System.err.println("Unable to load server class '" + sclClassName + "'");
+      t.printStackTrace();
+      return false;
     }
   }
 
@@ -110,6 +129,7 @@
       registerHandler(new ArgHandlerWarDir(options));
       registerHandler(new ArgHandlerExtraDir(options));
       registerHandler(new ArgHandlerWorkDirOptional(options));
+      registerHandler(new ArgHandlerLocalWorkers(options));
       registerHandler(new ArgHandlerModuleName(options));
     }
 
@@ -187,9 +207,9 @@
   }
 
   /**
-   * The public API of this class is yet to be determined.
+   * Default constructor for testing; no public API yet.
    */
-  private HostedMode() {
+  HostedMode() {
   }
 
   @Override
@@ -292,6 +312,10 @@
     return -1;
   }
 
+  protected ServletContainerLauncher getServerContainerLauncher() {
+    return launcher;
+  }
+
   @Override
   protected boolean initModule(String moduleName) {
     ModuleDef module = modulesByName.get(moduleName);
@@ -328,26 +352,8 @@
     return module;
   }
 
-  protected boolean setServer(TreeLogger logger, String serverClassName) {
-    Throwable t;
-    try {
-      Class<?> clazz = Class.forName(serverClassName, true,
-          Thread.currentThread().getContextClassLoader());
-      Class<? extends ServletContainerLauncher> sclClass = clazz.asSubclass(ServletContainerLauncher.class);
-      launcher = sclClass.newInstance();
-      return true;
-    } catch (ClassCastException e) {
-      t = e;
-    } catch (ClassNotFoundException e) {
-      t = e;
-    } catch (InstantiationException e) {
-      t = e;
-    } catch (IllegalAccessException e) {
-      t = e;
-    }
-    logger.log(TreeLogger.ERROR, "Unable to load server class '"
-        + serverClassName + "'", t);
-    return false;
+  protected void setServerContainerLauncher(ServletContainerLauncher launcher) {
+    this.launcher = launcher;
   }
 
   /**
diff --git a/dev/core/src/com/google/gwt/dev/HostedModeBase.java b/dev/core/src/com/google/gwt/dev/HostedModeBase.java
index cbe3e0e..b0fd858 100644
--- a/dev/core/src/com/google/gwt/dev/HostedModeBase.java
+++ b/dev/core/src/com/google/gwt/dev/HostedModeBase.java
@@ -56,6 +56,7 @@
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -189,7 +190,7 @@
     }
   }
 
-  abstract class ArgProcessor extends ToolBase {
+  abstract class ArgProcessor extends ArgProcessorBase {
     public ArgProcessor() {
       registerHandler(getArgHandlerPort());
       registerHandler(new ArgHandlerWhitelist());
@@ -205,20 +206,6 @@
       registerHandler(new ArgHandlerEnableAssertions(options));
       registerHandler(new ArgHandlerDisableAggressiveOptimization(options));
     }
-
-    /*
-     * Overridden to make public.
-     */
-    @Override
-    public final boolean processArgs(String[] args) {
-      return super.processArgs(args);
-    }
-
-    /*
-     * Overridden to make abstract.
-     */
-    @Override
-    protected abstract String getName();
   }
 
   interface HostedModeBaseOptions extends JJSOptions, OptionLogLevel,
@@ -298,14 +285,6 @@
     }
   }
 
-  static {
-    // Force ToolBase to clinit, which causes SWT stuff to happen.
-    new ToolBase() {
-    };
-    // Correct menu on Mac OS X
-    Display.setAppName("GWT");
-  }
-
   protected final HostedModeBaseOptions options;
 
   /**
@@ -320,11 +299,7 @@
 
   private final List<Shell> browserShells = new ArrayList<Shell>();
 
-  /**
-   * Use the default display; constructing a new one would make instantiating
-   * multiple GWTShells fail with a mysterious exception.
-   */
-  private final Display display = Display.getDefault();
+  private Display display;
 
   private boolean headlessMode = false;
 
@@ -359,6 +334,10 @@
     return port;
   }
 
+  public final List<String> getStartupURLs() {
+    return Collections.unmodifiableList(startupUrls);
+  }
+
   public TreeLogger getTopLogger() {
     return mainWnd.getLogger();
   }
@@ -371,6 +350,10 @@
     }
   }
 
+  public boolean isRunTomcat() {
+    return runTomcat;
+  }
+
   /**
    * Launch the arguments as Urls in separate windows.
    */
@@ -538,6 +521,19 @@
   protected abstract void doShutDownServer();
 
   protected boolean doStartup() {
+    // Force ToolBase to clinit, which causes SWT stuff to happen.
+    new ToolBase() {
+    };
+
+    /**
+     * Use the default display; constructing a new one would make instantiating
+     * multiple GWTShells fail with a mysterious exception.
+     */
+    display = Display.getDefault();
+
+    // Correct menu on Mac OS X
+    Display.setAppName("GWT");
+
     loadRequiredNativeLibs();
 
     // Create the main app window.
diff --git a/dev/core/test/com/google/gwt/dev/ArgProcessorTestBase.java b/dev/core/test/com/google/gwt/dev/ArgProcessorTestBase.java
new file mode 100644
index 0000000..5faff0d
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/ArgProcessorTestBase.java
@@ -0,0 +1,76 @@
+package com.google.gwt.dev;
+
+import com.google.gwt.util.tools.Utility;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+/**
+ * Base class for argument processor testing.
+ */
+public abstract class ArgProcessorTestBase extends TestCase {
+
+  private static class MockOutputStream extends OutputStream {
+    private boolean isEmpty = true;
+
+    public boolean isEmpty() {
+      return isEmpty;
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+      isEmpty = false;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+      isEmpty = false;
+    }
+  }
+
+  /*
+   * The "compute installation directory" dance.
+   */
+  static {
+    String oldValue = System.getProperty("gwt.devjar");
+    System.setProperty("gwt.devjar", "gwt-dev-windows.jar");
+    Utility.getInstallPath();
+    if (oldValue == null) {
+      System.getProperties().remove("gwt.devjar");
+    } else {
+      System.setProperty("gwt.devjar", oldValue);
+    }
+  }
+
+  protected static void assertProcessFailure(ArgProcessorBase argProcessor,
+      String... args) {
+    PrintStream oldErrStream = System.err;
+    MockOutputStream myErrStream = new MockOutputStream();
+    try {
+      System.setErr(new PrintStream(myErrStream, true));
+      assertFalse(argProcessor.processArgs(args));
+    } finally {
+      System.setErr(oldErrStream);
+    }
+    assertFalse(myErrStream.isEmpty());
+  }
+
+  protected static void assertProcessSuccess(ArgProcessorBase argProcessor,
+      String... args) {
+    PrintStream oldErrStream = System.err;
+    ByteArrayOutputStream myErrStream = new ByteArrayOutputStream();
+    try {
+      System.setErr(new PrintStream(myErrStream, true));
+      if (!argProcessor.processArgs(args)) {
+        fail(new String(myErrStream.toByteArray()));
+      }
+      assertEquals(0, myErrStream.size());
+    } finally {
+      System.setErr(oldErrStream);
+    }
+  }
+}
diff --git a/dev/core/test/com/google/gwt/dev/CompilerTest.java b/dev/core/test/com/google/gwt/dev/CompilerTest.java
new file mode 100644
index 0000000..cda54e3
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/CompilerTest.java
@@ -0,0 +1,68 @@
+package com.google.gwt.dev;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.Compiler.CompilerOptionsImpl;
+import com.google.gwt.dev.jjs.JsOutputOption;
+
+import java.io.File;
+
+/**
+ * Test for {@link Compiler}.
+ */
+public class CompilerTest extends ArgProcessorTestBase {
+
+  private final Compiler.ArgProcessor argProcessor;
+  private final CompilerOptionsImpl options = new CompilerOptionsImpl();
+
+  public CompilerTest() {
+    argProcessor = new Compiler.ArgProcessor(options);
+  }
+
+  public void testAllValidArgs() {
+    assertProcessSuccess(argProcessor, "-logLevel", "DEBUG", "-style",
+        "PRETTY", "-ea", "-XdisableAggressiveOptimization", "-gen", "myGen",
+        "-war", "myWar", "-workDir", "myWork", "-extra", "myExtra",
+        "-localWorkers", "2", "c.g.g.h.H", "my.Module");
+
+    assertEquals(new File("myGen").getAbsoluteFile(),
+        options.getGenDir().getAbsoluteFile());
+    assertEquals(new File("myWar"), options.getWarDir());
+    assertEquals(new File("myWork"), options.getWorkDir());
+    assertEquals(new File("myExtra"), options.getExtraDir());
+
+    assertEquals(2, options.getLocalWorkers());
+
+    assertEquals(TreeLogger.DEBUG, options.getLogLevel());
+    assertEquals(JsOutputOption.PRETTY, options.getOutput());
+    assertTrue(options.isEnableAssertions());
+    assertFalse(options.isAggressivelyOptimize());
+
+    assertEquals(2, options.getModuleNames().size());
+    assertEquals("c.g.g.h.H", options.getModuleNames().get(0));
+    assertEquals("my.Module", options.getModuleNames().get(1));
+  }
+
+  public void testDefaultArgs() {
+    assertProcessSuccess(argProcessor, "c.g.g.h.H");
+
+    assertEquals(null, options.getGenDir());
+    assertEquals(new File("war").getAbsoluteFile(),
+        options.getWarDir().getAbsoluteFile());
+    assertEquals(null, options.getWorkDir());
+    assertEquals(null, options.getExtraDir());
+
+    assertEquals(TreeLogger.INFO, options.getLogLevel());
+    assertEquals(JsOutputOption.OBFUSCATED, options.getOutput());
+    assertFalse(options.isEnableAssertions());
+    assertTrue(options.isAggressivelyOptimize());
+
+    assertEquals(1, options.getLocalWorkers());
+
+    assertEquals(1, options.getModuleNames().size());
+    assertEquals("c.g.g.h.H", options.getModuleNames().get(0));
+  }
+
+  public void testForbiddenArgs() {
+    assertProcessFailure(argProcessor, "-out", "www");
+  }
+}
diff --git a/dev/core/test/com/google/gwt/dev/GWTCompilerTest.java b/dev/core/test/com/google/gwt/dev/GWTCompilerTest.java
new file mode 100644
index 0000000..fb4e07b
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/GWTCompilerTest.java
@@ -0,0 +1,63 @@
+package com.google.gwt.dev;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.GWTCompiler.GWTCompilerOptionsImpl;
+import com.google.gwt.dev.jjs.JsOutputOption;
+
+import java.io.File;
+
+/**
+ * Test for deprecated {@link GWTShell}.
+ */
+@SuppressWarnings("deprecation")
+public class GWTCompilerTest extends ArgProcessorTestBase {
+
+  private final GWTCompiler.ArgProcessor argProcessor;
+  private final GWTCompilerOptionsImpl options = new GWTCompilerOptionsImpl();
+
+  public GWTCompilerTest() {
+    argProcessor = new GWTCompiler.ArgProcessor(options);
+  }
+
+  public void testAllValidArgs() {
+    assertProcessSuccess(argProcessor, "-logLevel", "DEBUG", "-style",
+        "PRETTY", "-ea", "-XdisableAggressiveOptimization", "-out", "myWww",
+        "-gen", "myGen", "c.g.g.h.H", "my.Module");
+
+    assertEquals(new File("myGen").getAbsoluteFile(),
+        options.getGenDir().getAbsoluteFile());
+    assertEquals(new File("myWww"), options.getOutDir());
+
+    assertEquals(TreeLogger.DEBUG, options.getLogLevel());
+    assertEquals(JsOutputOption.PRETTY, options.getOutput());
+    assertTrue(options.isEnableAssertions());
+    assertFalse(options.isAggressivelyOptimize());
+
+    assertEquals(2, options.getModuleNames().size());
+    assertEquals("c.g.g.h.H", options.getModuleNames().get(0));
+    assertEquals("my.Module", options.getModuleNames().get(1));
+  }
+
+  public void testDefaultArgs() {
+    assertProcessSuccess(argProcessor, "c.g.g.h.H");
+
+    assertEquals(null, options.getGenDir());
+    assertEquals(new File("").getAbsoluteFile(),
+        options.getOutDir().getAbsoluteFile());
+
+    assertEquals(TreeLogger.INFO, options.getLogLevel());
+    assertEquals(JsOutputOption.OBFUSCATED, options.getOutput());
+    assertFalse(options.isEnableAssertions());
+    assertTrue(options.isAggressivelyOptimize());
+
+    assertEquals(1, options.getModuleNames().size());
+    assertEquals("c.g.g.h.H", options.getModuleNames().get(0));
+  }
+
+  public void testForbiddenArgs() {
+    assertProcessFailure(argProcessor, "-localWorkers", "2");
+    assertProcessFailure(argProcessor, "-extra", "extra");
+    assertProcessFailure(argProcessor, "-war", "war");
+    assertProcessFailure(argProcessor, "-work", "work");
+  }
+}
diff --git a/dev/core/test/com/google/gwt/dev/GWTShellTest.java b/dev/core/test/com/google/gwt/dev/GWTShellTest.java
new file mode 100644
index 0000000..1972908
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/GWTShellTest.java
@@ -0,0 +1,76 @@
+package com.google.gwt.dev;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.GWTShell.ShellOptionsImpl;
+import com.google.gwt.dev.HostedModeTest.MySCL;
+import com.google.gwt.dev.jjs.JsOutputOption;
+import com.google.gwt.dev.shell.BrowserWidgetHostChecker;
+
+import java.io.File;
+
+/**
+ * Test for deprecated {@link GWTShell}.
+ */
+@SuppressWarnings("deprecation")
+public class GWTShellTest extends ArgProcessorTestBase {
+
+  private final GWTShell.ArgProcessor argProcessor;
+  private final ShellOptionsImpl options;
+  private final GWTShell shell;
+
+  public GWTShellTest() {
+    shell = new GWTShell();
+    options = shell.options;
+    argProcessor = shell.new ArgProcessor(false, false);
+  }
+
+  public void testAllValidArgs() {
+    assertProcessSuccess(argProcessor, "-port", "8080", "-whitelist", "white",
+        "-blacklist", "black", "-logLevel", "DEBUG", "-style", "PRETTY", "-ea",
+        "-XdisableAggressiveOptimization", "-noserver", "-out", "myWww",
+        "-gen", "myGen", "http://www.google.com/", "foo");
+
+    assertNotNull(BrowserWidgetHostChecker.matchWhitelisted("white"));
+    assertNotNull(BrowserWidgetHostChecker.matchBlacklisted("black"));
+
+    assertEquals(new File("myGen").getAbsoluteFile(),
+        options.getGenDir().getAbsoluteFile());
+    assertEquals(new File("myWww"), options.getOutDir());
+
+    assertEquals(TreeLogger.DEBUG, options.getLogLevel());
+    assertEquals(JsOutputOption.PRETTY, options.getOutput());
+    assertTrue(options.isEnableAssertions());
+    assertFalse(options.isAggressivelyOptimize());
+
+    assertEquals(8080, shell.getPort());
+    assertFalse(shell.isRunTomcat());
+    assertEquals(2, shell.getStartupURLs().size());
+    assertEquals("http://www.google.com/", shell.getStartupURLs().get(0));
+    assertEquals("foo", shell.getStartupURLs().get(1));
+  }
+
+  public void testDefaultArgs() {
+    assertProcessSuccess(argProcessor);
+
+    assertEquals(null, options.getGenDir());
+    assertEquals(new File("").getAbsoluteFile(),
+        options.getOutDir().getAbsoluteFile());
+
+    assertEquals(TreeLogger.INFO, options.getLogLevel());
+    assertEquals(JsOutputOption.OBFUSCATED, options.getOutput());
+    assertFalse(options.isEnableAssertions());
+    assertTrue(options.isAggressivelyOptimize());
+
+    assertEquals(8888, shell.getPort());
+    assertTrue(shell.isRunTomcat());
+    assertEquals(0, shell.getStartupURLs().size());
+  }
+
+  public void testForbiddenArgs() {
+    assertProcessFailure(argProcessor, "-localWorkers", "2");
+    assertProcessFailure(argProcessor, "-extra", "extra");
+    assertProcessFailure(argProcessor, "-war", "war");
+    assertProcessFailure(argProcessor, "-work", "work");
+    assertProcessFailure(argProcessor, "-server", MySCL.class.getName());
+  }
+}
diff --git a/dev/core/test/com/google/gwt/dev/HostedModeTest.java b/dev/core/test/com/google/gwt/dev/HostedModeTest.java
new file mode 100644
index 0000000..e69a57b
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/HostedModeTest.java
@@ -0,0 +1,102 @@
+package com.google.gwt.dev;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.HostedMode.HostedModeOptionsImpl;
+import com.google.gwt.dev.jjs.JsOutputOption;
+import com.google.gwt.dev.shell.BrowserWidgetHostChecker;
+import com.google.gwt.dev.shell.ServletContainer;
+import com.google.gwt.dev.shell.ServletContainerLauncher;
+
+import java.io.File;
+import java.net.BindException;
+
+/**
+ * Test for {@link HostedMode}.
+ */
+public class HostedModeTest extends ArgProcessorTestBase {
+
+  public static class MySCL implements ServletContainerLauncher {
+    public ServletContainer start(TreeLogger logger, int port, File appRootDir)
+        throws BindException, Exception {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  private final HostedMode.ArgProcessor argProcessor;
+  private final HostedMode hostedMode;
+  private final HostedModeOptionsImpl options;
+
+  public HostedModeTest() {
+    hostedMode = new HostedMode();
+    options = hostedMode.options;
+    argProcessor = hostedMode.new ArgProcessor();
+  }
+
+  public void testAllValidArgs() {
+    assertProcessSuccess(argProcessor, "-port", "8080", "-whitelist", "white",
+        "-blacklist", "black", "-logLevel", "DEBUG", "-style", "PRETTY", "-ea",
+        "-XdisableAggressiveOptimization", "-noserver", "-server",
+        MySCL.class.getName(), "-gen", "myGen", "-war", "myWar", "-workDir",
+        "myWork", "-extra", "myExtra", "-localWorkers", "2", "-startupUrl",
+        "http://www.google.com/", "-startupUrl", "foo", "c.g.g.h.H",
+        "my.Module");
+
+    assertNotNull(BrowserWidgetHostChecker.matchWhitelisted("white"));
+    assertNotNull(BrowserWidgetHostChecker.matchBlacklisted("black"));
+
+    assertEquals(new File("myGen").getAbsoluteFile(),
+        options.getGenDir().getAbsoluteFile());
+    assertEquals(new File("myWar"), options.getWarDir());
+    assertEquals(new File("myWork"), options.getWorkDir());
+    assertEquals(new File("myExtra"), options.getExtraDir());
+
+    assertEquals(TreeLogger.DEBUG, options.getLogLevel());
+    assertEquals(JsOutputOption.PRETTY, options.getOutput());
+    assertTrue(options.isEnableAssertions());
+    assertFalse(options.isAggressivelyOptimize());
+
+    assertEquals(2, options.getLocalWorkers());
+
+    assertEquals(8080, hostedMode.getPort());
+    assertTrue(hostedMode.isRunTomcat());
+    assertSame(MySCL.class, hostedMode.getServerContainerLauncher().getClass());
+
+    assertEquals(2, hostedMode.getStartupURLs().size());
+    assertEquals("http://www.google.com/", hostedMode.getStartupURLs().get(0));
+    assertEquals("foo", hostedMode.getStartupURLs().get(1));
+
+    assertEquals(2, options.getModuleNames().size());
+    assertEquals("c.g.g.h.H", options.getModuleNames().get(0));
+    assertEquals("my.Module", options.getModuleNames().get(1));
+  }
+
+  public void testDefaultArgs() {
+    assertProcessSuccess(argProcessor, "c.g.g.h.H");
+
+    assertEquals(null, options.getGenDir());
+    assertEquals(new File("war").getAbsoluteFile(),
+        options.getWarDir().getAbsoluteFile());
+    assertEquals(null, options.getWorkDir());
+    assertEquals(null, options.getExtraDir());
+
+    assertEquals(TreeLogger.INFO, options.getLogLevel());
+    assertEquals(JsOutputOption.OBFUSCATED, options.getOutput());
+    assertFalse(options.isEnableAssertions());
+    assertTrue(options.isAggressivelyOptimize());
+
+    assertEquals(1, options.getLocalWorkers());
+
+    assertEquals(8888, hostedMode.getPort());
+    assertTrue(hostedMode.isRunTomcat());
+    assertNotNull(hostedMode.getServerContainerLauncher());
+
+    assertEquals(0, hostedMode.getStartupURLs().size());
+
+    assertEquals(1, options.getModuleNames().size());
+    assertEquals("c.g.g.h.H", options.getModuleNames().get(0));
+  }
+
+  public void testForbiddenArgs() {
+    assertProcessFailure(argProcessor, "-out", "www");
+  }
+}