@Test
 public void withSpecifiedGradleUserHomeDirectoryBySystemProperty() {
   expectedGradleUserHome = testDir.file("home");
   String propName = "gradle.user.home";
   String propValue = expectedGradleUserHome.getAbsolutePath();
   expectedSystemProperties = toMap(propName, propValue);
   checkConversion("-D", propName + "=" + propValue);
 }
  @Test
  public void withSpecifiedProjectDirectory() {
    expectedProjectDir = testDir.file("project-dir");
    checkConversion("-p", expectedProjectDir.getAbsolutePath());

    expectedProjectDir = currentDir.file("project-dir");
    checkConversion("-p", "project-dir");
  }
  @Test
  public void withSpecifiedGradleUserHomeDirectory() {
    expectedGradleUserHome = testDir.file("home");
    checkConversion("-g", expectedGradleUserHome.getAbsolutePath());

    expectedGradleUserHome = currentDir.file("home");
    checkConversion("-g", "home");
  }
 @Test
 public void privilegeCmdLineOptionOverSystemPrefForGradleUserHome() {
   expectedGradleUserHome = testDir.file("home");
   String propName = "gradle.user.home";
   String propValue = "home2";
   expectedSystemProperties = toMap(propName, propValue);
   checkConversion(
       "-D", propName + "=" + propValue, "-g", expectedGradleUserHome.getAbsolutePath());
 }
  @Test
  public void withSpecifiedBuildFileName() throws IOException {
    expectedBuildFile = testDir.file("somename");
    expectedProjectDir = expectedBuildFile.getParentFile();
    checkConversion("-b", expectedBuildFile.getAbsolutePath());

    expectedBuildFile = currentDir.file("somename");
    expectedProjectDir = expectedBuildFile.getParentFile();
    checkConversion("-b", "somename");
  }
@RunWith(JMock.class)
public class WorkerProcessIntegrationTest {
  private final JUnit4Mockery context = new JUnit4Mockery();
  private final TestListenerInterface listenerMock = context.mock(TestListenerInterface.class);
  private final MessagingServices messagingServices =
      new MessagingServices(getClass().getClassLoader());
  private final MessagingServer server = messagingServices.get(MessagingServer.class);
  @Rule public final TestNameTestDirectoryProvider tmpDir = new TestNameTestDirectoryProvider();
  private final ProcessMetaDataProvider metaDataProvider =
      new DefaultProcessMetaDataProvider(
          NativeServices.getInstance().get(ProcessEnvironment.class));
  private final CacheFactory factory =
      new DefaultCacheFactory(
              new DefaultFileLockManager(metaDataProvider, new NoOpFileLockListener()))
          .create();
  private final CacheRepository cacheRepository =
      new DefaultCacheRepository(tmpDir.getTestDirectory(), null, CacheUsage.ON, factory);
  private final ModuleRegistry moduleRegistry = new DefaultModuleRegistry();
  private final ClassPathRegistry classPathRegistry =
      new DefaultClassPathRegistry(
          new DefaultClassPathProvider(moduleRegistry),
          new WorkerProcessClassPathProvider(cacheRepository, moduleRegistry));
  private final DefaultWorkerProcessFactory workerFactory =
      new DefaultWorkerProcessFactory(
          LogLevel.INFO,
          server,
          classPathRegistry,
          TestFiles.resolver(tmpDir.getTestDirectory()),
          new LongIdGenerator());
  private final ListenerBroadcast<TestListenerInterface> broadcast =
      new ListenerBroadcast<TestListenerInterface>(TestListenerInterface.class);
  private final RemoteExceptionListener exceptionListener = new RemoteExceptionListener(broadcast);

  @Before
  public void setUp() {
    broadcast.add(listenerMock);
  }

  @After
  public void tearDown() {
    messagingServices.stop();
  }

  @Test
  public void workerProcessCanSendMessagesToThisProcess() throws Throwable {
    context.checking(
        new Expectations() {
          {
            Sequence sequence = context.sequence("sequence");
            one(listenerMock).send("message 1", 1);
            inSequence(sequence);
            one(listenerMock).send("message 2", 2);
            inSequence(sequence);
          }
        });

    execute(worker(new RemoteProcess()));
  }

  @Test
  public void thisProcessCanSendEventsToWorkerProcess() throws Throwable {
    execute(
        worker(new PingRemoteProcess())
            .onServer(
                new Action<ObjectConnection>() {
                  public void execute(ObjectConnection objectConnection) {
                    TestListenerInterface listener =
                        objectConnection.addOutgoing(TestListenerInterface.class);
                    listener.send("1", 0);
                    listener.send("1", 1);
                    listener.send("1", 2);
                    listener.send("stop", 3);
                  }
                }));
  }

  @Test
  public void multipleWorkerProcessesCanSendMessagesToThisProcess() throws Throwable {
    context.checking(
        new Expectations() {
          {
            Sequence process1 = context.sequence("sequence1");
            one(listenerMock).send("message 1", 1);
            inSequence(process1);
            one(listenerMock).send("message 2", 2);
            inSequence(process1);
            Sequence process2 = context.sequence("sequence2");
            one(listenerMock).send("other 1", 1);
            inSequence(process2);
            one(listenerMock).send("other 2", 2);
            inSequence(process2);
          }
        });

    execute(worker(new RemoteProcess()), worker(new OtherRemoteProcess()));
  }

  @Test
  public void handlesWorkerProcessWhichCrashes() throws Throwable {
    context.checking(
        new Expectations() {
          {
            atMost(1).of(listenerMock).send("message 1", 1);
            atMost(1).of(listenerMock).send("message 2", 2);
          }
        });

    execute(worker(new CrashingRemoteProcess()).expectStopFailure());
  }

  @Test
  public void handlesWorkerActionWhichThrowsException() throws Throwable {
    execute(worker(new BrokenRemoteProcess()).expectStopFailure());
  }

  @Test
  public void handlesWorkerActionThatLeavesThreadsRunning() throws Throwable {
    context.checking(
        new Expectations() {
          {
            one(listenerMock).send("message 1", 1);
            one(listenerMock).send("message 2", 2);
          }
        });

    execute(worker(new NoCleanUpRemoteProcess()));
  }

  @Test
  public void handlesWorkerProcessWhichNeverConnects() throws Throwable {
    execute(worker(new NoConnectRemoteProcess()).expectStartFailure());
  }

  @Test
  public void handlesWorkerProcessWhenJvmFailsToStart() throws Throwable {
    execute(worker(Actions.doNothing()).jvmArgs("--broken").expectStartFailure());
  }

  private ChildProcess worker(Action<? super WorkerProcessContext> action) {
    return new ChildProcess(action);
  }

  void execute(ChildProcess... processes) throws Throwable {
    for (ChildProcess process : processes) {
      process.start();
    }
    for (ChildProcess process : processes) {
      process.waitForStop();
    }
    messagingServices.stop();
    exceptionListener.rethrow();
  }

  private class ChildProcess {
    private boolean stopFails;
    private boolean startFails;
    private WorkerProcess proc;
    private Action<? super WorkerProcessContext> action;
    private List<String> jvmArgs = Collections.emptyList();
    private Action<ObjectConnection> serverAction;

    public ChildProcess(Action<? super WorkerProcessContext> action) {
      this.action = action;
    }

    ChildProcess expectStopFailure() {
      stopFails = true;
      return this;
    }

    ChildProcess expectStartFailure() {
      startFails = true;
      return this;
    }

    public void start() {
      WorkerProcessBuilder builder = workerFactory.create();
      builder.applicationClasspath(classPathRegistry.getClassPath("ANT").getAsFiles());
      builder.sharedPackages("org.apache.tools.ant");
      builder.getJavaCommand().systemProperty("test.system.property", "value");
      builder.getJavaCommand().environment("TEST_ENV_VAR", "value");
      builder.worker(action);

      builder.getJavaCommand().jvmArgs(jvmArgs);

      proc = builder.build();
      try {
        proc.start();
        assertFalse(startFails);
      } catch (ExecException e) {
        assertTrue(startFails);
        return;
      }
      proc.getConnection().addIncoming(TestListenerInterface.class, exceptionListener);
      if (serverAction != null) {
        serverAction.execute(proc.getConnection());
      }
    }

    public void waitForStop() {
      if (startFails) {
        return;
      }
      try {
        proc.waitForStop();
        assertFalse("Expected process to fail", stopFails);
      } catch (ExecException e) {
        assertTrue("Unexpected failure in worker process", stopFails);
      }
    }

    public ChildProcess onServer(Action<ObjectConnection> action) {
      this.serverAction = action;
      return this;
    }

    public ChildProcess jvmArgs(String... jvmArgs) {
      this.jvmArgs = Arrays.asList(jvmArgs);
      return this;
    }
  }

  public static class RemoteExceptionListener implements Dispatch<MethodInvocation> {
    Throwable ex;
    final Dispatch<MethodInvocation> dispatch;

    public RemoteExceptionListener(Dispatch<MethodInvocation> dispatch) {
      this.dispatch = dispatch;
    }

    public void dispatch(MethodInvocation message) {
      try {
        dispatch.dispatch(message);
      } catch (Throwable e) {
        ex = e;
      }
    }

    public void rethrow() throws Throwable {
      if (ex != null) {
        throw ex;
      }
    }
  }

  public static class RemoteProcess implements Action<WorkerProcessContext>, Serializable {
    public void execute(WorkerProcessContext workerProcessContext) {
      // Check environment
      assertThat(System.getProperty("test.system.property"), equalTo("value"));
      assertThat(System.getenv().get("TEST_ENV_VAR"), equalTo("value"));

      // Check ClassLoaders
      ClassLoader antClassLoader = Project.class.getClassLoader();
      ClassLoader thisClassLoader = getClass().getClassLoader();
      ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();

      assertThat(antClassLoader, not(sameInstance(systemClassLoader)));
      assertThat(thisClassLoader, not(sameInstance(systemClassLoader)));
      assertThat(antClassLoader.getParent(), equalTo(systemClassLoader.getParent()));
      try {
        assertThat(
            thisClassLoader.loadClass(Project.class.getName()),
            sameInstance((Object) Project.class));
      } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
      }

      // Send some messages
      TestListenerInterface sender =
          workerProcessContext.getServerConnection().addOutgoing(TestListenerInterface.class);
      sender.send("message 1", 1);
      sender.send("message 2", 2);
    }
  }

  public static class OtherRemoteProcess implements Action<WorkerProcessContext>, Serializable {
    public void execute(WorkerProcessContext workerProcessContext) {
      TestListenerInterface sender =
          workerProcessContext.getServerConnection().addOutgoing(TestListenerInterface.class);
      sender.send("other 1", 1);
      sender.send("other 2", 2);
    }
  }

  public static class NoCleanUpRemoteProcess implements Action<WorkerProcessContext>, Serializable {
    public void execute(WorkerProcessContext workerProcessContext) {
      final Lock lock = new ReentrantLock();
      lock.lock();
      new Thread(
              new Runnable() {
                public void run() {
                  lock.lock();
                }
              })
          .start();

      TestListenerInterface sender =
          workerProcessContext.getServerConnection().addOutgoing(TestListenerInterface.class);
      sender.send("message 1", 1);
      sender.send("message 2", 2);
    }
  }

  public static class PingRemoteProcess
      implements Action<WorkerProcessContext>, Serializable, TestListenerInterface {
    CountDownLatch stopReceived;
    int count;

    public void send(String message, int count) {
      assertEquals(this.count, count);
      this.count++;
      if (message.equals("stop")) {
        assertEquals(4, this.count);
        stopReceived.countDown();
      }
    }

    public void execute(WorkerProcessContext workerProcessContext) {
      stopReceived = new CountDownLatch(1);
      workerProcessContext.getServerConnection().addIncoming(TestListenerInterface.class, this);
      try {
        stopReceived.await();
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }
    }
  }

  public static class CrashingRemoteProcess implements Action<WorkerProcessContext>, Serializable {
    public void execute(WorkerProcessContext workerProcessContext) {
      TestListenerInterface sender =
          workerProcessContext.getServerConnection().addOutgoing(TestListenerInterface.class);
      sender.send("message 1", 1);
      sender.send("message 2", 2);
      // crash
      Runtime.getRuntime().halt(1);
    }
  }

  public static class BrokenRemoteProcess implements Action<WorkerProcessContext>, Serializable {
    public void execute(WorkerProcessContext workerProcessContext) {
      throw new RuntimeException("broken");
    }
  }

  public static class NoConnectRemoteProcess implements Action<WorkerProcessContext>, Serializable {
    private void readObject(ObjectInputStream instr) {
      System.exit(0);
    }

    public void execute(WorkerProcessContext workerProcessContext) {
      throw new UnsupportedOperationException();
    }
  }

  public interface TestListenerInterface {
    public void send(String message, int count);
  }
}
public class DefaultCommandLineConverterTest {
  @Rule public TestNameTestDirectoryProvider testDir = new TestNameTestDirectoryProvider();

  private TestFile currentDir = testDir.file("current-dir");
  private File expectedBuildFile;
  private File expectedGradleUserHome = StartParameter.DEFAULT_GRADLE_USER_HOME;
  private File expectedProjectDir = currentDir;
  private List<String> expectedTaskNames = toList();
  private Set<String> expectedExcludedTasks = toSet();
  private boolean buildProjectDependencies = true;
  private Map<String, String> expectedSystemProperties = new HashMap<String, String>();
  private Map<String, String> expectedProjectProperties = new HashMap<String, String>();
  private List<File> expectedInitScripts = new ArrayList<File>();
  private CacheUsage expectedCacheUsage = CacheUsage.ON;
  private boolean expectedSearchUpwards = true;
  private boolean expectedDryRun;
  private ShowStacktrace expectedShowStackTrace = ShowStacktrace.INTERNAL_EXCEPTIONS;
  private LogLevel expectedLogLevel = LogLevel.LIFECYCLE;
  private boolean expectedColorOutput = true;
  private StartParameter actualStartParameter;
  private boolean expectedProfile;
  private File expectedProjectCacheDir;
  private boolean expectedRefreshDependencies;
  private boolean expectedRerunTasks;
  private final DefaultCommandLineConverter commandLineConverter =
      new DefaultCommandLineConverter();
  private boolean expectedContinue;
  private boolean expectedOffline;
  private RefreshOptions expectedRefreshOptions = RefreshOptions.NONE;
  private boolean expectedRecompileScripts;
  private int expectedParallelExecutorCount;
  private boolean expectedConfigureOnDemand;

  @Test
  public void withoutAnyOptions() {
    checkConversion();
  }

  private void checkConversion(String... args) {
    actualStartParameter = new StartParameter();
    actualStartParameter.setCurrentDir(currentDir);
    commandLineConverter.convert(asList(args), actualStartParameter);
    // We check the params passed to the build factory
    checkStartParameter(actualStartParameter);
  }

  private void checkStartParameter(StartParameter startParameter) {
    assertEquals(expectedBuildFile, startParameter.getBuildFile());
    assertEquals(expectedTaskNames, startParameter.getTaskNames());
    assertEquals(buildProjectDependencies, startParameter.isBuildProjectDependencies());
    assertEquals(
        expectedProjectDir.getAbsoluteFile(), startParameter.getCurrentDir().getAbsoluteFile());
    assertEquals(expectedCacheUsage, startParameter.getCacheUsage());
    assertEquals(expectedSearchUpwards, startParameter.isSearchUpwards());
    assertEquals(expectedProjectProperties, startParameter.getProjectProperties());
    assertEquals(expectedSystemProperties, startParameter.getSystemPropertiesArgs());
    assertEquals(
        expectedGradleUserHome.getAbsoluteFile(),
        startParameter.getGradleUserHomeDir().getAbsoluteFile());
    assertEquals(expectedLogLevel, startParameter.getLogLevel());
    assertEquals(expectedColorOutput, startParameter.isColorOutput());
    assertEquals(expectedDryRun, startParameter.isDryRun());
    assertEquals(expectedShowStackTrace, startParameter.getShowStacktrace());
    assertEquals(expectedExcludedTasks, startParameter.getExcludedTaskNames());
    assertEquals(expectedInitScripts, startParameter.getInitScripts());
    assertEquals(expectedProfile, startParameter.isProfile());
    assertEquals(expectedContinue, startParameter.isContinueOnFailure());
    assertEquals(expectedOffline, startParameter.isOffline());
    assertEquals(expectedRecompileScripts, startParameter.isRecompileScripts());
    assertEquals(expectedRerunTasks, startParameter.isRerunTasks());
    assertEquals(expectedRefreshOptions, startParameter.getRefreshOptions());
    assertEquals(expectedRefreshDependencies, startParameter.isRefreshDependencies());
    assertEquals(expectedProjectCacheDir, startParameter.getProjectCacheDir());
    assertEquals(expectedParallelExecutorCount, startParameter.getParallelThreadCount());
    assertEquals(expectedConfigureOnDemand, startParameter.isConfigureOnDemand());
  }

  @Test
  public void withSpecifiedGradleUserHomeDirectory() {
    expectedGradleUserHome = testDir.file("home");
    checkConversion("-g", expectedGradleUserHome.getAbsolutePath());

    expectedGradleUserHome = currentDir.file("home");
    checkConversion("-g", "home");
  }

  @Test
  public void withSpecifiedProjectCacheDir() {
    expectedProjectCacheDir = new File(currentDir, ".foo");
    checkConversion("--project-cache-dir", ".foo");
  }

  @Test
  public void withSpecifiedProjectDirectory() {
    expectedProjectDir = testDir.file("project-dir");
    checkConversion("-p", expectedProjectDir.getAbsolutePath());

    expectedProjectDir = currentDir.file("project-dir");
    checkConversion("-p", "project-dir");
  }

  @Test
  public void withSpecifiedBuildFileName() throws IOException {
    expectedBuildFile = testDir.file("somename");
    expectedProjectDir = expectedBuildFile.getParentFile();
    checkConversion("-b", expectedBuildFile.getAbsolutePath());

    expectedBuildFile = currentDir.file("somename");
    expectedProjectDir = expectedBuildFile.getParentFile();
    checkConversion("-b", "somename");
  }

  @Test
  public void withSpecifiedSettingsFileName() throws IOException {
    File expectedSettingsFile = currentDir.file("somesettings");
    expectedProjectDir = expectedSettingsFile.getParentFile();

    checkConversion("-c", "somesettings");

    assertThat(actualStartParameter.getSettingsFile(), equalTo(expectedSettingsFile));
  }

  @Test
  public void withInitScripts() {
    File script1 = currentDir.file("init1.gradle");
    expectedInitScripts.add(script1);
    checkConversion("-Iinit1.gradle");

    File script2 = currentDir.file("init2.gradle");
    expectedInitScripts.add(script2);
    checkConversion("-Iinit1.gradle", "-Iinit2.gradle");
  }

  @Test
  public void withSystemProperties() {
    final String prop1 = "gradle.prop1";
    final String valueProp1 = "value1";
    final String prop2 = "gradle.prop2";
    final String valueProp2 = "value2";
    expectedSystemProperties = toMap(prop1, valueProp1);
    expectedSystemProperties.put(prop2, valueProp2);
    checkConversion("-D", prop1 + "=" + valueProp1, "-D", prop2 + "=" + valueProp2);
  }

  @Test
  public void withSpecifiedGradleUserHomeDirectoryBySystemProperty() {
    expectedGradleUserHome = testDir.file("home");
    String propName = "gradle.user.home";
    String propValue = expectedGradleUserHome.getAbsolutePath();
    expectedSystemProperties = toMap(propName, propValue);
    checkConversion("-D", propName + "=" + propValue);
  }

  @Test
  public void privilegeCmdLineOptionOverSystemPrefForGradleUserHome() {
    expectedGradleUserHome = testDir.file("home");
    String propName = "gradle.user.home";
    String propValue = "home2";
    expectedSystemProperties = toMap(propName, propValue);
    checkConversion(
        "-D", propName + "=" + propValue, "-g", expectedGradleUserHome.getAbsolutePath());
  }

  @Test
  public void withStartProperties() {
    final String prop1 = "prop1";
    final String valueProp1 = "value1";
    final String prop2 = "prop2";
    final String valueProp2 = "value2";
    expectedProjectProperties = toMap(prop1, valueProp1);
    expectedProjectProperties.put(prop2, valueProp2);
    checkConversion("-P", prop1 + "=" + valueProp1, "-P", prop2 + "=" + valueProp2);
  }

  @Test
  public void withTaskNames() {
    expectedTaskNames = toList("a", "b");
    checkConversion("a", "b");
  }

  @Test
  public void withRebuildCacheFlagSet() {
    expectedCacheUsage = CacheUsage.REBUILD;
    checkConversion("-C", "rebuild");
  }

  @Test
  public void withCacheOnFlagSet() {
    checkConversion("-C", "on");
  }

  @Test(expected = CommandLineArgumentException.class)
  public void withUnknownCacheFlags() {
    checkConversion("-C", "unknown");
  }

  @Test
  public void withSearchUpwardsFlagSet() {
    expectedSearchUpwards = false;
    checkConversion("-u");
  }

  @Test
  public void withShowFullStacktrace() {
    expectedShowStackTrace = ShowStacktrace.ALWAYS_FULL;
    checkConversion("-S");
  }

  @Test
  public void withShowStacktrace() {
    expectedShowStackTrace = ShowStacktrace.ALWAYS;
    checkConversion("-s");
  }

  @Test
  public void withRerunTasks() {
    expectedRerunTasks = true;
    checkConversion("--rerun-tasks");
  }

  @Test(expected = CommandLineArgumentException.class)
  public void withShowStacktraceAndShowFullStacktraceShouldThrowCommandLineArgumentEx() {
    checkConversion("-sf");
  }

  @Test
  public void withDryRunFlagSet() {
    expectedDryRun = true;
    checkConversion("-m");
  }

  @Test
  public void withExcludeTask() {
    expectedExcludedTasks.add("excluded");
    checkConversion("-x", "excluded");
    expectedExcludedTasks.add("excluded2");
    checkConversion("-x", "excluded", "-x", "excluded2");
  }

  @Test(expected = CommandLineArgumentException.class)
  public void withEmbeddedScriptAndConflictingNoSearchUpwardsOption() {
    checkConversion("-e", "someScript", "-u", "clean");
  }

  @Test(expected = CommandLineArgumentException.class)
  public void withEmbeddedScriptAndConflictingSpecifyBuildFileOption() {
    checkConversion("-e", "someScript", "-bsomeFile", "clean");
  }

  @Test(expected = CommandLineArgumentException.class)
  public void withEmbeddedScriptAndConflictingSpecifySettingsFileOption() {
    checkConversion("-e", "someScript", "-csomeFile", "clean");
  }

  @Test
  public void withNoProjectDependencyRebuild() {
    buildProjectDependencies = false;
    checkConversion("-a");
  }

  @Test
  public void withQuietLoggingOptions() {
    expectedLogLevel = LogLevel.QUIET;
    checkConversion("-q");
  }

  @Test
  public void withInfoLoggingOptions() {
    expectedLogLevel = LogLevel.INFO;
    checkConversion("-i");
  }

  @Test
  public void withDebugLoggingOptions() {
    expectedLogLevel = LogLevel.DEBUG;
    checkConversion("-d");
  }

  @Test
  public void withNoColor() {
    expectedColorOutput = false;
    checkConversion("--no-color");
  }

  @Test(expected = CommandLineArgumentException.class)
  public void withLowerPParameterWithoutArgument() {
    checkConversion("-p");
  }

  @Test(expected = CommandLineArgumentException.class)
  public void withAParameterWithoutArgument() {
    checkConversion("-A");
  }

  @Test(expected = CommandLineArgumentException.class)
  public void withUpperAAndLowerAParameter() {
    checkConversion("-a", "-Atask1");
  }

  @Test
  public void withProfile() {
    expectedProfile = true;
    checkConversion("--profile");
  }

  @Test
  public void withContinue() {
    expectedContinue = true;
    checkConversion("--continue");
  }

  @Test
  public void withOffline() {
    expectedOffline = true;
    checkConversion("--offline");
    checkConversion("-offline");
  }

  @Test
  public void withRefreshDependencies() {
    expectedRefreshDependencies = true;
    expectedRefreshOptions = new RefreshOptions(asList(RefreshOptions.Option.DEPENDENCIES));
    checkConversion("--refresh-dependencies");
    checkConversion("-refresh-dependencies");
  }

  @Test
  public void withRecompileScripts() {
    expectedRecompileScripts = true;
    checkConversion("--recompile-scripts");
  }

  @Test
  public void withRefreshDependenciesSet() {
    expectedRefreshDependencies = true;
    expectedRefreshOptions = new RefreshOptions(Arrays.asList(RefreshOptions.Option.DEPENDENCIES));
    checkConversion("--refresh", "dependencies");
  }

  @Test(expected = CommandLineArgumentException.class)
  public void withUnknownRefreshOption() {
    checkConversion("--refresh", "unknown");
  }

  @Test(expected = CommandLineArgumentException.class)
  public void withUnknownOption() {
    checkConversion("--unknown");
  }

  @Test
  public void withTaskAndTaskOption() {
    expectedTaskNames = toList("someTask", "--some-task-option");
    checkConversion("someTask", "--some-task-option");
  }

  @Test
  public void withParallelExecutor() {
    expectedParallelExecutorCount = -1;
    checkConversion("--parallel");
  }

  @Test
  public void withParallelExecutorThreads() {
    expectedParallelExecutorCount = 5;
    checkConversion("--parallel-threads", "5");
  }

  @Test(expected = CommandLineArgumentException.class)
  public void withInvalidParallelExecutorThreads() {
    checkConversion("--parallel-threads", "foo");
  }

  @Test
  public void withConfigureOnDemand() {
    expectedConfigureOnDemand = true;
    checkConversion("--configure-on-demand");
  }
}