private FileCopyDetails expectActionExecutedWhenFileVisited() {
    final Collector<FileCopyDetails> collectDetails = collector();
    final Action<FileCopyDetails> action = context.mock(Action.class, "action1");

    context.checking(
        new Expectations() {
          {
            Sequence seq = context.sequence("seq");
            one(delegate).visitSpec(spec);
            inSequence(seq);

            allowing(spec).getAllCopyActions();
            will(returnValue(toList(action)));

            one(action).execute(with(notNullValue(FileCopyDetails.class)));
            inSequence(seq);
            will(collectTo(collectDetails));

            one(delegate).visitFile(with(not(sameInstance(details))));
            inSequence(seq);
          }
        });

    visitor.visitSpec(spec);
    visitor.visitFile(details);

    FileCopyDetails copyDetails = collectDetails.get();
    return copyDetails;
  }
  @Test
  public void stopsAtFirstActionWhichThrowsException() {
    final Throwable failure = new RuntimeException("failure");
    final Collector<Throwable> wrappedFailure = collector();
    context.checking(
        new Expectations() {
          {
            allowing(task).getTaskActions();
            will(returnValue(toList(action1, action2)));

            one(listener).beforeActions(task);
            inSequence(sequence);

            one(state).setExecuting(true);
            inSequence(sequence);

            one(state).setDidWork(true);
            inSequence(sequence);

            one(standardOutputCapture).start();
            inSequence(sequence);

            one(action1).contextualise(executionContext);
            inSequence(sequence);

            one(action1).execute(task);
            will(throwException(failure));
            inSequence(sequence);

            one(action1).contextualise(null);
            inSequence(sequence);

            one(standardOutputCapture).stop();
            inSequence(sequence);

            one(state).executed(with(notNullValue(Throwable.class)));
            will(collectTo(wrappedFailure));
            inSequence(sequence);

            one(state).setExecuting(false);
            inSequence(sequence);

            one(listener).afterActions(task);
            inSequence(sequence);
          }
        });

    executer.execute(task, state, executionContext);

    assertThat(wrappedFailure.get(), instanceOf(TaskExecutionException.class));
    TaskExecutionException exception = (TaskExecutionException) wrappedFailure.get();
    assertThat(exception.getTask(), equalTo((Task) task));
    assertThat(exception.getMessage(), equalTo("Execution failed for <task>."));
    assertThat(exception.getCause(), sameInstance(failure));
  }
  private FileVisitDetails expectSpecAndDirVisited() {
    final Collector<FileVisitDetails> collector = collector();

    context.checking(
        new Expectations() {
          {
            one(delegate).visitSpec(spec);
            one(delegate).visitDir(with(not(sameInstance(details))));

            will(collectTo(collector));
          }
        });

    visitor.visitSpec(spec);
    visitor.visitDir(details);

    return collector.get();
  }
  @Test
  public void wrapsOnlyIfPredicateFailure() {
    final Throwable failure = new RuntimeException();
    final Collector<Throwable> wrappedFailure = collector();
    context.checking(
        new Expectations() {
          {
            allowing(task).getEnabled();
            will(returnValue(true));
            one(spec).isSatisfiedBy(task);
            will(throwException(failure));
            one(state).executed(with(notNullValue(GradleException.class)));
            will(collectTo(wrappedFailure));
          }
        });

    executer.execute(task, state, executionContext);

    GradleException exception = (GradleException) wrappedFailure.get();
    assertThat(exception.getMessage(), equalTo("Could not evaluate onlyIf predicate for <task>."));
    assertThat(exception.getCause(), sameInstance(failure));
  }
  @Test
  public void visitFileInvokesEachCopyAction() {
    final Action<FileCopyDetails> action1 = context.mock(Action.class, "action1");
    final Action<FileCopyDetails> action2 = context.mock(Action.class, "action2");
    final Collector<FileCopyDetails> collectDetails1 = collector();
    final Collector<Object> collectDetails2 = collector();
    final Collector<Object> collectDetails3 = collector();

    context.checking(
        new Expectations() {
          {
            Sequence seq = context.sequence("seq");
            one(delegate).visitSpec(spec);
            inSequence(seq);

            allowing(spec).getAllCopyActions();
            will(returnValue(toList(action1, action2)));

            one(action1).execute(with(notNullValue(FileCopyDetails.class)));
            inSequence(seq);
            will(collectTo(collectDetails1));

            one(action2).execute(with(notNullValue(FileCopyDetails.class)));
            inSequence(seq);
            will(collectTo(collectDetails2));

            one(delegate).visitFile(with(not(sameInstance(details))));
            inSequence(seq);
            will(collectTo(collectDetails3));
          }
        });

    visitor.visitSpec(spec);
    visitor.visitFile(details);

    assertThat(collectDetails1.get(), sameInstance(collectDetails2.get()));
    assertThat(collectDetails1.get(), sameInstance(collectDetails3.get()));
  }