/*
* Copyright 2016 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.diffplug.gradle.spotless;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Locale;
import java.util.SortedSet;
import java.util.TreeSet;
import org.junit.Assert;
import org.junit.Test;
import com.diffplug.common.base.Errors;
import com.diffplug.common.base.StringPrinter;
import com.diffplug.spotless.LineEnding;
public class GradleIncrementalResolutionTest extends GradleIntegrationTest {
private static final boolean IS_UNIX = LineEnding.PLATFORM_NATIVE.str().equals("\n");
@Test
public void failureDoesntTriggerAll() throws IOException {
write("build.gradle",
"plugins {",
" id 'com.diffplug.gradle.spotless'",
"}",
"spotless {",
" format 'misc', {",
" target '*.md'",
" custom 'lowercase', { str ->",
" String result = str.toLowerCase(Locale.ROOT)",
" println(\"<${result.trim()}>\")",
" return result",
" }",
" bumpThisNumberIfACustomStepChanges(1)",
" }",
"}");
// test our harness (build makes things lower case)
writeState("ABC");
assertState("ABC");
writeState("aBc");
assertState("aBc");
// check will run against all three the first time (and second and third)
checkRanAgainst("abc");
checkRanAgainst("abc");
checkRanAgainst("abc");
// apply will run against all three the first time
applyRanAgainst("abc");
// for some reason, it appears unix has higher resolution on which files need to be checked
applyRanAgainst(IS_UNIX ? "b" : "abc");
// but nobody the last time
applyRanAgainst("");
// if we change just one file
writeState("Abc");
// then check runs against just the changed file
checkRanAgainst("a");
// even after failing, still just the one
checkRanAgainst("a");
// and so does apply
applyRanAgainst("a");
applyRanAgainst("a");
// until the issue has been fixed
applyRanAgainst("");
}
private String filename(String name) {
return name.toLowerCase(Locale.ROOT) + ".md";
}
private void writeState(String state) throws IOException {
for (char c : state.toCharArray()) {
String letter = new String(new char[]{c});
boolean exists = new File(rootFolder(), filename(letter)).exists();
boolean needsChanging = exists && !read(filename(letter)).trim().equals(letter);
if (!exists || needsChanging) {
write(filename(letter), letter);
}
}
}
private void assertState(String state) throws IOException {
for (char c : state.toCharArray()) {
String letter = new String(new char[]{c});
if (Character.isLowerCase(c)) {
Assert.assertEquals(letter.toLowerCase(Locale.ROOT), read(filename(letter)).trim());
} else {
Assert.assertEquals(letter.toUpperCase(Locale.ROOT), read(filename(letter)).trim());
}
}
}
private void applyRanAgainst(String... ranAgainst) throws IOException {
taskRanAgainst("spotlessApply", ranAgainst);
}
private void checkRanAgainst(String... ranAgainst) throws IOException {
taskRanAgainst("spotlessCheck", ranAgainst);
}
private void taskRanAgainst(String task, String... ranAgainst) throws IOException {
pauseForFilesystem();
String console = StringPrinter.buildString(Errors.rethrow().wrap(printer -> {
boolean expectFailure = task.equals("spotlessCheck") && !isClean();
if (expectFailure) {
gradleRunner().withArguments(task).forwardStdOutput(printer.toWriter()).buildAndFail();
} else {
gradleRunner().withArguments(task).forwardStdOutput(printer.toWriter()).build();
}
}));
SortedSet<String> added = new TreeSet<>();
for (String line : console.split("\n")) {
String trimmed = line.trim();
if (trimmed.startsWith("<") && trimmed.endsWith(">")) {
added.add(trimmed.substring(1, trimmed.length() - 1));
}
}
Assert.assertEquals(concat(Arrays.asList(ranAgainst)), concat(added));
}
private String concat(Iterable<String> iterable) {
StringBuilder result = new StringBuilder();
for (String item : iterable) {
result.append(item);
}
return result.toString();
}
private boolean isClean() throws IOException {
for (File file : rootFolder().listFiles()) {
if (file.isFile() && file.getName().length() == 4 && file.getName().endsWith(".md")) {
String content = read(file.getName());
if (!content.toLowerCase(Locale.ROOT).equals(content)) {
return false;
}
}
}
return true;
}
}