Skip to content

Commit 49c254f

Browse files
committed
Implement JavaFileObjectSubject.containsElementsIn()
RELNOTES=Implement JavaFileObjectSubject.containsElementsIn() ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=177837393
1 parent 724d447 commit 49c254f

File tree

5 files changed

+743
-28
lines changed

5 files changed

+743
-28
lines changed

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<description>Utilities for testing compilation.</description>
1616

1717
<properties>
18+
<auto-common.version>0.8</auto-common.version>
1819
<auto-value.version>1.5</auto-value.version>
1920
<guava.version>23.1-jre</guava.version>
2021
<truth.version>0.36</truth.version>
@@ -82,6 +83,11 @@
8283
<artifactId>auto-value</artifactId>
8384
<version>${auto-value.version}</version>
8485
</dependency>
86+
<dependency>
87+
<groupId>com.google.auto</groupId>
88+
<artifactId>auto-common</artifactId>
89+
<version>${auto-common.version}</version>
90+
</dependency>
8591
</dependencies>
8692
<build>
8793
<plugins>

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

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static com.google.common.truth.Truth.assertAbout;
2020
import static com.google.testing.compile.JavaFileObjects.asByteSource;
2121
import static com.google.testing.compile.TreeDiffer.diffCompilationUnits;
22+
import static com.google.testing.compile.TreeDiffer.matchCompilationUnits;
2223
import static java.nio.charset.StandardCharsets.UTF_8;
2324

2425
import com.google.common.base.Joiner;
@@ -31,6 +32,7 @@
3132
import com.sun.source.tree.CompilationUnitTree;
3233
import java.io.IOException;
3334
import java.nio.charset.Charset;
35+
import java.util.function.BiFunction;
3436
import javax.annotation.Nullable;
3537
import javax.tools.JavaFileObject;
3638

@@ -113,17 +115,65 @@ public StringSubject contentsAsUtf8String() {
113115
}
114116

115117
/**
116-
* Asserts that the actual file is a source file with contents equivalent to {@code
118+
* Asserts that the actual file is a source file that has an equivalent <a
119+
* href="https://en.wikipedia.org/wiki/Abstract_syntax_tree">AST</a> to that of {@code
117120
* expectedSource}.
118121
*/
119122
public void hasSourceEquivalentTo(JavaFileObject expectedSource) {
123+
performTreeDifference(
124+
expectedSource,
125+
"is equivalent to",
126+
"Expected Source",
127+
(expectedResult, actualResult) ->
128+
diffCompilationUnits(
129+
getOnlyElement(expectedResult.compilationUnits()),
130+
getOnlyElement(actualResult.compilationUnits())));
131+
}
132+
133+
/**
134+
* Asserts that the every node in the <a
135+
* href="https://en.wikipedia.org/wiki/Abstract_syntax_tree">AST</a> of {@code expectedPattern}
136+
* exists in the actual file's AST, in the same order.
137+
*
138+
* <p>Methods, constructors, fields, and types that are in the pattern must have the exact same
139+
* modifiers and annotations as the actual AST. Ordering of AST nodes is also important (i.e. a
140+
* type with identical members in a different order will fail the assertion). Types must match the
141+
* entire type declaration: type parameters, {@code extends}/{@code implements} clauses, etc.
142+
* Methods must also match the throws clause as well.
143+
*
144+
* <p>The body of a method or constructor, or field initializer in the actual AST must match the
145+
* pattern in entirety if the member is present in the pattern.
146+
*
147+
* <p>Said in another way (from a graph-theoretic perspective): the pattern AST must be a subgraph
148+
* of the actual AST. If a method, constructor, or field is in the pattern, that entire subtree,
149+
* including modifiers and annotations, must be equal to the corresponding subtree in the actual
150+
* AST (no proper subgraphs).
151+
*/
152+
public void containsElementsIn(JavaFileObject expectedPattern) {
153+
performTreeDifference(
154+
expectedPattern,
155+
"contains elements in",
156+
"Expected Pattern",
157+
(expectedResult, actualResult) ->
158+
matchCompilationUnits(
159+
getOnlyElement(expectedResult.compilationUnits()),
160+
actualResult.trees(),
161+
getOnlyElement(actualResult.compilationUnits()),
162+
expectedResult.trees()));
163+
}
164+
165+
private void performTreeDifference(
166+
JavaFileObject expected,
167+
String failureVerb,
168+
String expectedTitle,
169+
BiFunction<ParseResult, ParseResult, TreeDifference> differencingFunction) {
120170
ParseResult actualResult = Parser.parse(ImmutableList.of(actual()));
121171
CompilationUnitTree actualTree = getOnlyElement(actualResult.compilationUnits());
122172

123-
ParseResult expectedResult = Parser.parse(ImmutableList.of(expectedSource));
173+
ParseResult expectedResult = Parser.parse(ImmutableList.of(expected));
124174
CompilationUnitTree expectedTree = getOnlyElement(expectedResult.compilationUnits());
125175

126-
TreeDifference treeDifference = diffCompilationUnits(expectedTree, actualTree);
176+
TreeDifference treeDifference = differencingFunction.apply(expectedResult, actualResult);
127177

128178
if (!treeDifference.isEmpty()) {
129179
String diffReport =
@@ -134,17 +184,17 @@ public void hasSourceEquivalentTo(JavaFileObject expectedSource) {
134184
fail(
135185
Joiner.on('\n')
136186
.join(
137-
String.format("is equivalent to <%s>.", expectedSource.toUri().getPath()),
187+
String.format("%s <%s>.", failureVerb, expected.toUri().getPath()),
138188
"",
139189
"Diffs:",
140190
"======",
141191
"",
142192
diffReport,
143193
"",
144-
"Expected Source:",
194+
expectedTitle + ":",
145195
"================",
146196
"",
147-
expectedSource.getCharContent(false),
197+
expected.getCharContent(false),
148198
"",
149199
"Actual Source:",
150200
"==============",

0 commit comments

Comments
 (0)