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 delegatesDidWork() {
    context.checking(
        new Expectations() {
          {
            allowing(delegate).getDidWork();
            will(onConsecutiveCalls(returnValue(true), returnValue(false)));
          }
        });

    assertTrue(visitor.getDidWork());
    assertFalse(visitor.getDidWork());
  }
  @Test
  public void delegatesStartAndEndVisitMethods() {
    final CopyAction action = context.mock(CopyAction.class);

    context.checking(
        new Expectations() {
          {
            one(delegate).startVisit(action);
            one(delegate).endVisit();
          }
        });

    visitor.startVisit(action);
    visitor.endVisit();
  }
  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 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()));
  }
  @Test
  public void copyActionCanExcludeFile() {
    final Action<FileCopyDetails> action1 = context.mock(Action.class, "action1");
    final Action<FileCopyDetails> action2 = context.mock(Action.class, "action2");

    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(excludeFile());
          }
        });

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