Skip to content

Commit 7933bde

Browse files
committed
Make the failsToCompile() and compilesWithoutError() clauses report the files they generate on failure.
------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=68173836
1 parent 353db30 commit 7933bde

File tree

2 files changed

+101
-3
lines changed

2 files changed

+101
-3
lines changed

src/main/java/com/google/testing/compile/JavaSourcesSubject.java

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package com.google.testing.compile;
1717

1818
import static com.google.common.base.Preconditions.checkArgument;
19+
import static javax.tools.JavaFileObject.Kind.CLASS;
1920

2021
import com.google.common.base.Function;
2122
import com.google.common.base.Joiner;
@@ -28,6 +29,7 @@
2829
import com.google.common.collect.Iterables;
2930
import com.google.common.collect.Lists;
3031
import com.google.common.collect.Maps;
32+
import com.google.common.io.ByteSource;
3133
import com.google.common.io.ByteStreams;
3234
import com.google.testing.compile.Compilation.Result;
3335

@@ -92,14 +94,58 @@ private CompilationClause(Iterable<? extends Processor> processors) {
9294
this.processors = ImmutableSet.copyOf(processors);
9395
}
9496

97+
/** Returns a {@code String} report describing the contents of a given generated file. */
98+
private String reportFileGenerated(JavaFileObject generatedFile) {
99+
try {
100+
StringBuilder entry =
101+
new StringBuilder().append(String.format("\n%s:\n", generatedFile.toUri().getPath()));
102+
if (generatedFile.getKind().equals(CLASS)) {
103+
entry.append(String.format("[generated class file (%s bytes)]",
104+
ByteSource.wrap(ByteStreams.toByteArray(generatedFile.openInputStream()))
105+
.size()));
106+
} else {
107+
entry.append(generatedFile.getCharContent(true));
108+
}
109+
return entry.append("\n").toString();
110+
} catch (IOException e) {
111+
throw new IllegalStateException("Couldn't read from JavaFileObject when it was "
112+
+ "already in memory.", e);
113+
}
114+
}
115+
116+
/**
117+
* Returns a {@code String} report describing what files were generated in the given
118+
* {@link Compilation.Result}
119+
*/
120+
private String reportFilesGenerated(Compilation.Result result) {
121+
FluentIterable<JavaFileObject> generatedFiles =
122+
FluentIterable.from(result.generatedSources());
123+
StringBuilder message = new StringBuilder("\n\n");
124+
if (generatedFiles.isEmpty()) {
125+
return message.append("(No files were generated.)\n").toString();
126+
} else {
127+
message.append("Generated Files\n")
128+
.append("===============\n");
129+
for (JavaFileObject generatedFile : generatedFiles) {
130+
message.append(reportFileGenerated(generatedFile));
131+
}
132+
return message.toString();
133+
}
134+
}
135+
95136
@Override
96137
public SuccessfulCompilationClause compilesWithoutError() {
97138
Compilation.Result result = Compilation.compile(processors, getSubject());
98139
if (!result.successful()) {
99140
ImmutableList<Diagnostic<? extends JavaFileObject>> errors =
100141
result.diagnosticsByKind().get(Kind.ERROR);
101142
StringBuilder message = new StringBuilder("Compilation produced the following errors:\n");
102-
Joiner.on('\n').appendTo(message, errors);
143+
for (Diagnostic<? extends JavaFileObject> error : errors) {
144+
message.append('\n');
145+
message.append(error);
146+
}
147+
message.append('\n');
148+
message.append(reportFilesGenerated(result));
103149
failureStrategy.fail(message.toString());
104150
}
105151
return new SuccessfulCompilationBuilder(result);
@@ -109,7 +155,11 @@ public SuccessfulCompilationClause compilesWithoutError() {
109155
public UnsuccessfulCompilationClause failsToCompile() {
110156
Result result = Compilation.compile(processors, getSubject());
111157
if (result.successful()) {
112-
failureStrategy.fail("Compilation was expected to fail, but contained no errors");
158+
String message = Joiner.on('\n').join(
159+
"Compilation was expected to fail, but contained no errors.",
160+
"",
161+
reportFilesGenerated(result));
162+
failureStrategy.fail(message);
113163
}
114164
return new UnsuccessfulCompilationBuilder(result);
115165
}

src/test/java/com/google/testing/compile/JavaSourcesSubjectFactoryTest.java

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,21 @@ public void compilesWithoutError() {
7676
.compilesWithoutError();
7777
}
7878

79+
@Test
80+
public void compilesWithoutError_failureReportsFiles() {
81+
try {
82+
VERIFY.about(javaSource())
83+
.that(JavaFileObjects.forResource(Resources.getResource("HelloWorld.java")))
84+
.processedWith(new FailingGeneratingProcessor())
85+
.compilesWithoutError();
86+
fail();
87+
} catch (VerificationException expected) {
88+
ASSERT.that(expected.getMessage()).contains("Compilation produced the following errors:\n");
89+
ASSERT.that(expected.getMessage()).contains(FailingGeneratingProcessor.GENERATED_CLASS_NAME);
90+
ASSERT.that(expected.getMessage()).contains(FailingGeneratingProcessor.GENERATED_SOURCE);
91+
}
92+
}
93+
7994
@Test
8095
public void compilesWithoutError_throws() {
8196
try {
@@ -85,6 +100,7 @@ public void compilesWithoutError_throws() {
85100
fail();
86101
} catch (VerificationException expected) {
87102
ASSERT.that(expected.getMessage()).startsWith("Compilation produced the following errors:\n");
103+
ASSERT.that(expected.getMessage()).contains("No files were generated.");
88104
}
89105
}
90106

@@ -124,8 +140,9 @@ public void failsToCompile_throws() {
124140
.failsToCompile();
125141
fail();
126142
} catch (VerificationException expected) {
127-
ASSERT.that(expected.getMessage()).isEqualTo(
143+
ASSERT.that(expected.getMessage()).startsWith(
128144
"Compilation was expected to fail, but contained no errors");
145+
ASSERT.that(expected.getMessage()).contains("No files were generated.");
129146
}
130147
}
131148

@@ -369,6 +386,37 @@ public SourceVersion getSupportedSourceVersion() {
369386
}
370387
}
371388

389+
private static final class FailingGeneratingProcessor extends AbstractProcessor {
390+
static final String GENERATED_CLASS_NAME = GeneratingProcessor.GENERATED_CLASS_NAME;
391+
static final String GENERATED_SOURCE = GeneratingProcessor.GENERATED_SOURCE;
392+
static final String ERROR_MESSAGE = "expected error!";
393+
final GeneratingProcessor delegate = new GeneratingProcessor();
394+
Messager messager;
395+
396+
@Override
397+
public synchronized void init(ProcessingEnvironment processingEnv) {
398+
delegate.init(processingEnv);
399+
this.messager = processingEnv.getMessager();
400+
}
401+
402+
@Override
403+
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
404+
delegate.process(annotations, roundEnv);
405+
messager.printMessage(Kind.ERROR, ERROR_MESSAGE);
406+
return false;
407+
}
408+
409+
@Override
410+
public Set<String> getSupportedAnnotationTypes() {
411+
return delegate.getSupportedAnnotationTypes();
412+
}
413+
414+
@Override
415+
public SourceVersion getSupportedSourceVersion() {
416+
return delegate.getSupportedSourceVersion();
417+
}
418+
}
419+
372420
private static final class NoOpProcessor extends AbstractProcessor {
373421
boolean invoked = false;
374422

0 commit comments

Comments
 (0)