private void assertMatches(final String pattern, String matches, String... otherNames) {
    final Task task1 = task(matches);
    final Task task2 = task(matches);
    final Set<Task> tasks = new HashSet<Task>();
    tasks.add(task2);
    for (String name : otherNames) {
      tasks.add(task(name));
    }
    tasks.add(task("."));
    tasks.add(task("other"));

    context.checking(
        new Expectations() {
          {
            one(project).getTasksByName(pattern, true);
            will(returnValue(toSet()));
            one(taskContainer).getAll();
            will(returnValue(toSet(task1)));
            one(subProjectTaskContainer).getAll();
            will(returnValue(tasks));
            one(taskExecuter).addTasks(toSet(task1, task2));
          }
        });

    TaskNameResolvingBuildExecuter executer = new TaskNameResolvingBuildExecuter(toList(pattern));
    executer.select(gradle);
    assertThat(executer.getDisplayName(), equalTo(String.format("primary task '%s'", matches)));
  }
  @Test
  public void treatsEachProvidedNameAsASeparateGroup() {
    final Task task1 = task("name1");
    final Task task2 = task("name2");

    context.checking(
        new Expectations() {
          {
            one(project).getTasksByName("name1", true);
            will(returnValue(toSet(task1)));
            one(project).getTasksByName("name2", true);
            will(returnValue(toSet(task2)));

            Sequence sequence = context.sequence("tasks");

            one(taskExecuter).addTasks(toSet(task1));
            inSequence(sequence);

            one(taskExecuter).addTasks(toSet(task2));
            inSequence(sequence);

            one(taskExecuter).execute();
            inSequence(sequence);
          }
        });

    TaskNameResolvingBuildExecuter executer =
        new TaskNameResolvingBuildExecuter(toList("name1", "name2"));
    executer.select(gradle);
    assertThat(executer.getDisplayName(), equalTo("primary tasks 'name1', 'name2'"));
    executer.execute();
  }
  @Test
  public void reportsTyposInTaskName() {
    final Task task1 = task("someTask");
    final Task task2 = task("someTasks");
    final Task task3 = task("sometask");
    final Task task4 = task("other");

    context.checking(
        new Expectations() {
          {
            one(project).getTasksByName("ssomeTask", true);
            will(returnValue(toSet()));
            one(taskContainer).getAll();
            will(returnValue(toSet(task1, task2)));
            one(subProjectTaskContainer).getAll();
            will(returnValue(toSet(task3, task4)));
          }
        });

    TaskNameResolvingBuildExecuter executer =
        new TaskNameResolvingBuildExecuter(toList("ssomeTask"));
    try {
      executer.select(gradle);
      fail();
    } catch (TaskSelectionException e) {
      assertThat(
          e.getMessage(),
          equalTo(
              "Task 'ssomeTask' not found in [project]. Some candidates are: 'someTask', 'someTasks', 'sometask'."));
    }
  }
  @Test
  public void failsWhenProvidedNameIsAmbiguous() {
    final Task task1 = task("someTask");
    final Task task2 = task("someTasks");

    context.checking(
        new Expectations() {
          {
            one(project).getTasksByName("soTa", true);
            will(returnValue(toSet()));
            one(taskContainer).getAll();
            will(returnValue(toSet(task1)));
            one(subProjectTaskContainer).getAll();
            will(returnValue(toSet(task2)));
          }
        });

    TaskNameResolvingBuildExecuter executer = new TaskNameResolvingBuildExecuter(toList("soTa"));
    try {
      executer.select(gradle);
      fail();
    } catch (TaskSelectionException e) {
      assertThat(
          e.getMessage(),
          equalTo(
              "Task 'soTa' is ambiguous in [project]. Candidates are: 'someTask', 'someTasks'."));
    }
  }
  @Test
  public void selectsAllTasksWithTheProvidedNameInCurrentProjectAndSubprojects() {
    final Task task1 = task("name");
    final Task task2 = task("name");

    context.checking(
        new Expectations() {
          {
            one(project).getTasksByName("name", true);
            will(returnValue(toSet(task1, task2)));
            one(taskExecuter).addTasks(toSet(task1, task2));
          }
        });

    TaskNameResolvingBuildExecuter executer = new TaskNameResolvingBuildExecuter(toList("name"));
    executer.select(gradle);
    assertThat(executer.getDisplayName(), equalTo("primary task 'name'"));
  }
  @Test
  public void executesAllSelectedTasks() {
    final Task task1 = task("name");
    final Task task2 = task("name");

    context.checking(
        new Expectations() {
          {
            one(project).getTasksByName("name", true);
            will(returnValue(toSet(task1, task2)));
            one(taskExecuter).addTasks(toSet(task1, task2));
            one(taskExecuter).execute();
          }
        });

    TaskNameResolvingBuildExecuter executer = new TaskNameResolvingBuildExecuter(toList("name"));
    executer.select(gradle);
    executer.execute();
  }
  @Test
  public void selectsTaskWithMatchingPath() {
    final Task task1 = task("b");

    context.checking(
        new Expectations() {
          {
            one(project).findProject("a");
            will(returnValue(subProject));
            one(subProjectTaskContainer).findByName("b");
            will(returnValue(task1));
            one(taskExecuter).addTasks(toSet(task1));
          }
        });

    TaskNameResolvingBuildExecuter executer = new TaskNameResolvingBuildExecuter(toList("a:b"));
    executer.select(gradle);
    assertThat(executer.getDisplayName(), equalTo("primary task 'a:b'"));
  }
  @Test
  public void usesCamelCaseAbbreviationToSelectTasksWhenNoExactMatchAndPathProvided() {
    final Task task1 = task("someTask");
    final Task task2 = task("other");

    context.checking(
        new Expectations() {
          {
            one(project).findProject("a:b:c");
            will(returnValue(subProject));
            one(subProjectTaskContainer).findByName("soTa");
            will(returnValue(null));
            one(subProjectTaskContainer).getAll();
            will(returnValue(toSet(task1, task2)));
            one(taskExecuter).addTasks(toSet(task1));
          }
        });

    TaskNameResolvingBuildExecuter executer =
        new TaskNameResolvingBuildExecuter(toList("a:b:c:soTa"));
    executer.select(gradle);
    assertThat(executer.getDisplayName(), equalTo("primary task 'a:b:c:someTask'"));
  }