### Question:
JavaccSourceFileCompiler implements SourceFileCompiler { @Override public void compile(File inputDirectory, RelativePath inputRelativePath) { logger.debug("Compiling {} file [{}] from [{}] into [{}]", programInvoker.getProgramName(), inputRelativePath, inputDirectory, getOutputDirectory()); ProgramArguments arguments = buildProgramArguments(inputDirectory, inputRelativePath); logger.debug("Invoking {} with arguments [{}]", programInvoker.getProgramName(), arguments); try { programInvoker.invokeCompiler(arguments); } catch (Exception exception) { final String errorMessage = String.format("Unable to compile '%s' from '%s' into '%s'", inputRelativePath, inputDirectory, getOutputDirectory()); throw new JavaccTaskException(errorMessage, exception); } } JavaccSourceFileCompiler(ProgramInvoker programInvoker, ProgramArguments argumentsProvidedByTask, CompilerInputOutputConfiguration configuration, Logger logger); @Override void compileSourceFilesToTempOutputDirectory(); @Override void copyNonJavaccFilesToOutputDirectory(); @Override void compile(File inputDirectory, RelativePath inputRelativePath); @Override void copyCompiledFilesFromTempOutputDirectoryToOutputDirectory(); @Override String supportedSuffix(); @Override String getProgramName(); @Override File getOutputDirectory(); @Override File getInputDirectory(); @Override void createTempOutputDirectory(); @Override void cleanTempOutputDirectory(); @Override Logger getLogger();  }### Answer:
@Test public void compileInvokesProgramCompiler() throws Exception { RelativePath fileToCompile = givenFileToCompile(); compiler.compile(inputFolder, fileToCompile); ArgumentCaptor<ProgramArguments> programArgumentsCaptor = ArgumentCaptor.forClass(ProgramArguments.class); verify(programInvoker).augmentArguments(same(inputFolder), same(fileToCompile), programArgumentsCaptor.capture()); assertThat(Arrays.asList(programArguments.toArray()), everyItem(isIn(programArgumentsCaptor.getValue().toArray()))); verify(programInvoker).invokeCompiler(programArgumentsCaptor.capture()); assertThat(Arrays.asList(programArguments.toArray()), everyItem(isIn(programArgumentsCaptor.getValue().toArray()))); }
@Test public void compileThrowsExceptionWhenUnderlyingProgramInvokerFails() throws Exception { Exception programFailure = new RuntimeException(); doThrow(programFailure).when(programInvoker).invokeCompiler(programArguments); RelativePath fileToCompile = givenFileToCompile(); thrown.expect(JavaccTaskException.class); thrown.expectCause(is(programFailure)); compiler.compile(inputFolder, fileToCompile); }