Skip to content

Commit c04a321

Browse files
committed
Test the Spotless step when the Gradle JVM does not export javac
Spotless turns whatever a step throws into a lint of the file, and spotlessJava succeeds with that lint as its output. Without the --add-exports flags the formatter's check fails inside the step, so spotlessJava succeeds, the lint goes into the build cache, and after the flags are added the same key hands the lint back: spotlessApply fails until the cache is cleared. SpotlessWithoutJavacExportsTest fails on both. Two more tests hold what is right today: a declared formatter that does not resolve fails the build, while storing the configuration cache entry or in spotlessJava, and a file the formatter cannot parse is still a lint of that file.
1 parent bcb07d8 commit c04a321

1 file changed

Lines changed: 123 additions & 0 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
15+
package com.palantir.javaformat.gradle;
16+
17+
import static org.assertj.core.api.Assertions.assertThat;
18+
19+
import com.palantir.javaformat.gradle.testing.GradleTestProject;
20+
import java.nio.file.Path;
21+
import org.gradle.testkit.runner.BuildResult;
22+
import org.gradle.testkit.runner.BuildTask;
23+
import org.gradle.testkit.runner.TaskOutcome;
24+
import org.junit.jupiter.api.Test;
25+
import org.junit.jupiter.api.io.TempDir;
26+
import org.junit.jupiter.params.Parameter;
27+
import org.junit.jupiter.params.ParameterizedClass;
28+
import org.junit.jupiter.params.provider.ValueSource;
29+
30+
/**
31+
* Spotless turns whatever a step throws into a lint of the file, and spotlessJava succeeds, with that lint as its
32+
* output. That is right for a file the formatter cannot parse, and wrong for a build the formatter cannot run in: the
33+
* lint goes into the build cache, the build cache hands it back after the build is fixed, and spotlessApply has
34+
* nothing to apply. The formatter's failures for the build, rather than for a file, fail spotlessJava itself.
35+
*/
36+
@ParameterizedClass(name = "configuration cache {0}")
37+
@ValueSource(booleans = {true, false})
38+
final class SpotlessWithoutJavacExportsTest {
39+
40+
private static final String MAIN_JAVA = "src/main/java/Main.java";
41+
private static final String UNFORMATTED = "class Main {\n int x;\n}\n";
42+
private static final String FORMATTED = "class Main {\n int x;\n}\n";
43+
44+
@Parameter
45+
private boolean configurationCache;
46+
47+
@TempDir
48+
private Path projectDir;
49+
50+
@TempDir
51+
private Path buildCacheDir;
52+
53+
@Test
54+
void spotlessApply_fails_and_names_both_settings_when_the_gradle_jvm_does_not_export_javac() {
55+
var project = project().writeFile(MAIN_JAVA, UNFORMATTED);
56+
57+
var result = project.fails("spotlessApply");
58+
59+
assertThat(spotlessJava(result)).isEqualTo(TaskOutcome.FAILED);
60+
assertThat(result.getOutput())
61+
.contains("open-java-format cannot run inside this Gradle JVM: module jdk.compiler does not export ")
62+
.contains("openjavaformat.native.formatter=true")
63+
.contains("org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED")
64+
.doesNotContain("lint error");
65+
assertThat(project.readFile(MAIN_JAVA)).isEqualTo(UNFORMATTED);
66+
}
67+
68+
@Test
69+
void spotlessApply_formats_once_the_gradle_jvm_exports_javac() {
70+
var project = project().writeFile(MAIN_JAVA, UNFORMATTED);
71+
project.fails("spotlessApply");
72+
73+
// Another daemon, with the flags. The same cache: what the failed build left there must not stand in for it.
74+
project.withJavacInternalExports().writeFile(MAIN_JAVA, UNFORMATTED);
75+
var result = project.succeeds("spotlessApply");
76+
77+
assertThat(spotlessJava(result)).isEqualTo(TaskOutcome.SUCCESS);
78+
// Spotless writes the platform's line endings, CRLF on Windows.
79+
assertThat(project.readFile(MAIN_JAVA)).isEqualToNormalizingNewlines(FORMATTED);
80+
}
81+
82+
@Test
83+
void spotlessApply_fails_when_the_declared_formatter_does_not_resolve() {
84+
var project = project().withJavacInternalExports().buildGradle("""
85+
dependencies {
86+
palantirJavaFormat 'does.not:exist:1.0'
87+
}
88+
""").writeFile(MAIN_JAVA, UNFORMATTED);
89+
90+
var result = project.fails("spotlessApply");
91+
92+
// With the configuration cache the build fails as it stores the entry, before any task runs.
93+
if (result.task(":spotlessJava") != null) {
94+
assertThat(spotlessJava(result)).isEqualTo(TaskOutcome.FAILED);
95+
}
96+
assertThat(result.getOutput()).contains("does.not:exist:1.0").doesNotContain("lint error");
97+
assertThat(project.readFile(MAIN_JAVA)).isEqualTo(UNFORMATTED);
98+
}
99+
100+
@Test
101+
void a_file_the_formatter_cannot_parse_is_still_a_lint_of_that_file() {
102+
var project = project().withJavacInternalExports().writeFile(MAIN_JAVA, "class Main {\n int x =\n");
103+
104+
var result = project.fails("spotlessCheck");
105+
106+
assertThat(spotlessJava(result)).isEqualTo(TaskOutcome.SUCCESS);
107+
assertThat(result.getOutput()).contains("lint error").contains("Main.java");
108+
}
109+
110+
/** No --add-exports, unless a test adds them: a Gradle JVM as it comes. */
111+
private GradleTestProject project() {
112+
return new GradleTestProject(projectDir)
113+
.configurationCache(configurationCache)
114+
.withBuildCache(buildCacheDir)
115+
.plugins("java", "dev.openjavaformat.java-format", "com.diffplug.spotless");
116+
}
117+
118+
private static TaskOutcome spotlessJava(BuildResult result) {
119+
BuildTask task = result.task(":spotlessJava");
120+
assertThat(task).isNotNull();
121+
return task.getOutcome();
122+
}
123+
}

0 commit comments

Comments
 (0)