Skip to content

obsolete - Add support for linters #1097

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d5b0421
Define a `Lint`.
nedtwigg Jan 12, 2022
db676fc
Add a `lint` method to `FormatterStep` and let it wripple through.
nedtwigg Jan 12, 2022
5dc6271
Make Lint roundtrippable through a String.
nedtwigg Jan 13, 2022
cc71751
Formatter.lint
nedtwigg Jan 13, 2022
aac3972
Lint ripples through DirtyState and Formatter.
nedtwigg Jan 13, 2022
a25eded
SpotlessTaskImpl now generates both a formatted result and a lint res…
nedtwigg Jan 13, 2022
89339cd
SpotlessTaskImpl now generates a lint result for `check` and for `app…
nedtwigg Jan 14, 2022
cac4f70
Gradle spotlessCheck will now throw an error if all of the files are …
nedtwigg Jan 14, 2022
d4ec76b
Maven spotless:check will now throw an error if all of the files are …
nedtwigg Jan 14, 2022
7a1e72a
Default `FormatterFunc.lint` now traps errors from the formatter itse…
nedtwigg Jan 14, 2022
109c7fb
Remove `FormatExceptionPolicy`.
nedtwigg Jan 14, 2022
0049661
Remove `FormatExceptionPolicy` from the maven plugin.
nedtwigg Jan 14, 2022
dd5165f
Replace `FormatExceptionPolicy` with `LintPolicy` inside the Gradle p…
nedtwigg Jan 14, 2022
85fbe71
Lint.toFile might need to create parent directories.
nedtwigg Jan 14, 2022
e8e5df5
Lints are now quietly suppressed during `apply`, you have to do `chec…
nedtwigg Jan 14, 2022
6ec06cc
Fix spotbugs warnings.
nedtwigg Jan 14, 2022
9557c66
Fix the bug I made from fixing spotbugs :)
nedtwigg Jan 14, 2022
2844068
Make sure that FormatterFunc.Closeable's helpers support linting.
nedtwigg Jan 14, 2022
9134d8c
Fix FormatterFunc.Closeable earlier
nedtwigg Jan 14, 2022
5a9799d
Refactor PipeStepPair so that it can detect lost tags within our new …
nedtwigg Jan 14, 2022
07b39cb
Rename PipeStepPair to FenceStep.
nedtwigg Jan 14, 2022
78ddcd6
Removed `rootDir` property `Formatter` and its builder because it was…
nedtwigg Jan 14, 2022
f947c7b
`DiffMessageFormatter.Builder::formatter` needs a new `Path rootDir` …
nedtwigg Jan 14, 2022
a3eef1f
Adapt StepHarness for the new "exceptions never get thrown" environment.
nedtwigg Jan 15, 2022
3f72b7e
When a step throws an exception, we now accurately consider the entir…
nedtwigg Jan 14, 2022
1ed3149
Fix tests.
nedtwigg Jan 15, 2022
6e38887
Fix spotbugs.
nedtwigg Jan 15, 2022
eb0feed
Fix wrong SuppressFBWarnings import.
nedtwigg Jan 15, 2022
248ec28
Fix tests on windows.
nedtwigg Jan 15, 2022
3aa780e
Fix prettier error test.
nedtwigg Jan 15, 2022
e110426
Make our testing parallel.
nedtwigg Jan 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Adapt StepHarness for the new "exceptions never get thrown" environment.
  • Loading branch information
nedtwigg committed Jan 15, 2022
commit a3eef1f594873d9efbee3309decc36d354de52dd
26 changes: 15 additions & 11 deletions testlib/src/main/java/com/diffplug/spotless/ResourceHarness.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2021 DiffPlug
* Copyright 2016-2022 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -54,7 +54,7 @@ protected File rootFolder() {
}

/** Returns a new child of the root folder. */
protected File newFile(String subpath) throws IOException {
protected File newFile(String subpath) {
return new File(rootFolder(), subpath);
}

Expand Down Expand Up @@ -85,12 +85,12 @@ protected void replace(String path, String toReplace, String replaceWith) throws
}

/** Returns the contents of the given file from the src/test/resources directory. */
protected static String getTestResource(String filename) throws IOException {
protected static String getTestResource(String filename) {
URL url = ResourceHarness.class.getResource("/" + filename);
if (url == null) {
throw new IllegalArgumentException("No such resource " + filename);
}
return Resources.toString(url, StandardCharsets.UTF_8);
return ThrowingEx.get(() -> Resources.toString(url, StandardCharsets.UTF_8));
}

/** Returns Files (in a temporary folder) which has the contents of the given file from the src/test/resources directory. */
Expand Down Expand Up @@ -176,7 +176,7 @@ public void matches(Consumer<AbstractCharSequenceAssert<?, String>> conditions)
}
}

protected WriteAsserter setFile(String path) throws IOException {
protected WriteAsserter setFile(String path) {
return new WriteAsserter(newFile(path));
}

Expand All @@ -188,21 +188,25 @@ private WriteAsserter(File file) {
this.file = file;
}

public File toLines(String... lines) throws IOException {
public File toLines(String... lines) {
return toContent(String.join("\n", Arrays.asList(lines)));
}

public File toContent(String content) throws IOException {
public File toContent(String content) {
return toContent(content, StandardCharsets.UTF_8);
}

public File toContent(String content, Charset charset) throws IOException {
Files.write(file.toPath(), content.getBytes(charset));
public File toContent(String content, Charset charset) {
ThrowingEx.run(() -> {
Files.write(file.toPath(), content.getBytes(charset));
});
return file;
}

public File toResource(String path) throws IOException {
Files.write(file.toPath(), getTestResource(path).getBytes(StandardCharsets.UTF_8));
public File toResource(String path) {
ThrowingEx.run(() -> {
Files.write(file.toPath(), getTestResource(path).getBytes(StandardCharsets.UTF_8));
});
return file;
}

Expand Down
72 changes: 34 additions & 38 deletions testlib/src/main/java/com/diffplug/spotless/StepHarness.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2021 DiffPlug
* Copyright 2016-2022 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,34 +19,24 @@

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;

import org.assertj.core.api.AbstractThrowableAssert;
import org.assertj.core.api.AbstractStringAssert;
import org.assertj.core.api.Assertions;

/** An api for testing a {@code FormatterStep} that doesn't depend on the File path. DO NOT ADD FILE SUPPORT TO THIS, use {@link StepHarnessWithFile} if you need that. */
public class StepHarness implements AutoCloseable {
private final FormatterFunc formatter;
private final Formatter formatter;

private StepHarness(FormatterFunc formatter) {
private StepHarness(Formatter formatter) {
this.formatter = Objects.requireNonNull(formatter);
}

/** Creates a harness for testing steps which don't depend on the file. */
public static StepHarness forStep(FormatterStep step) {
// We don't care if an individual FormatterStep is misbehaving on line-endings, because
// Formatter fixes that. No reason to care in tests either. It's likely to pop up when
// running tests on Windows from time-to-time
return new StepHarness(FormatterFunc.Closeable.ofDangerous(
() -> {
if (step instanceof FormatterStepImpl.Standard) {
((FormatterStepImpl.Standard<?>) step).cleanupFormatterFunc();
}
},
input -> LineEnding.toUnix(step.format(input, new File("")))));
return forSteps(step);
}

/** Creates a harness for testing steps which don't depend on the file. */
Expand All @@ -55,61 +45,67 @@ public static StepHarness forSteps(FormatterStep... steps) {
.steps(Arrays.asList(steps))
.lineEndingsPolicy(LineEnding.UNIX.createPolicy())
.encoding(StandardCharsets.UTF_8)
.rootDir(Paths.get(""))
.build());
}

/** Creates a harness for testing a formatter whose steps don't depend on the file. */
public static StepHarness forFormatter(Formatter formatter) {
return new StepHarness(FormatterFunc.Closeable.ofDangerous(
formatter::close,
input -> formatter.compute(input, new File(""))));
return new StepHarness(formatter);
}

/** Asserts that the given element is transformed as expected, and that the result is idempotent. */
public StepHarness test(String before, String after) throws Exception {
String actual = formatter.apply(before);
public StepHarness test(String before, String after) {
String actual = formatter.compute(LineEnding.toUnix(before), new File(""));
assertEquals(after, actual, "Step application failed");
return testUnaffected(after);
}

/** Asserts that the given element is idempotent w.r.t the step under test. */
public StepHarness testUnaffected(String idempotentElement) throws Exception {
String actual = formatter.apply(idempotentElement);
public StepHarness testUnaffected(String idempotentElement) {
String actual = formatter.compute(LineEnding.toUnix(idempotentElement), new File(""));
assertEquals(idempotentElement, actual, "Step is not idempotent");
return this;
}

/** Asserts that the given elements in the resources directory are transformed as expected. */
public StepHarness testResource(String resourceBefore, String resourceAfter) throws Exception {
public StepHarness testResource(String resourceBefore, String resourceAfter) {
String before = ResourceHarness.getTestResource(resourceBefore);
String after = ResourceHarness.getTestResource(resourceAfter);
return test(before, after);
}

/** Asserts that the given elements in the resources directory are transformed as expected. */
public StepHarness testResourceUnaffected(String resourceIdempotent) throws Exception {
public StepHarness testResourceUnaffected(String resourceIdempotent) {
String idempotentElement = ResourceHarness.getTestResource(resourceIdempotent);
return testUnaffected(idempotentElement);
}

/** Asserts that the given elements in the resources directory are transformed as expected. */
public StepHarness testResourceException(String resourceBefore, Consumer<AbstractThrowableAssert<?, ? extends Throwable>> exceptionAssertion) throws Exception {
return testException(ResourceHarness.getTestResource(resourceBefore), exceptionAssertion);
public AbstractStringAssert<?> testResourceExceptionMsg(String resourceBefore) {
return testExceptionMsg(ResourceHarness.getTestResource(resourceBefore));
}

/** Asserts that the given elements in the resources directory are transformed as expected. */
public StepHarness testException(String before, Consumer<AbstractThrowableAssert<?, ? extends Throwable>> exceptionAssertion) throws Exception {
Throwable t = assertThrows(Throwable.class, () -> formatter.apply(before));
AbstractThrowableAssert<?, ? extends Throwable> abstractAssert = Assertions.assertThat(t);
exceptionAssertion.accept(abstractAssert);
return this;
public AbstractStringAssert<?> testExceptionMsg(String before) {
List<Lint> lints = formatter.lint(LineEnding.toUnix(before), FormatterStepImpl.SENTINEL);
if (lints.size() == 0) {
throw new AssertionError("No exception was thrown");
} else if (lints.size() >= 2) {
throw new AssertionError("Expected one lint, had " + lints.size());
} else {
return Assertions.assertThat(lints.get(0).getMsg());
}
}

public StepHarness assertZeroLints(String before) {
List<Lint> lints = formatter.lint(LineEnding.toUnix(before), FormatterStepImpl.SENTINEL);
if (lints.size() == 0) {
return this;
} else {
throw new AssertionError("Expected no lints, had " + lints);
}
}

@Override
public void close() {
if (formatter instanceof FormatterFunc.Closeable) {
((FormatterFunc.Closeable) formatter).close();
}
formatter.close();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2021 DiffPlug
* Copyright 2016-2022 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,78 +18,91 @@
import static org.junit.jupiter.api.Assertions.*;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import org.assertj.core.api.AbstractStringAssert;
import org.assertj.core.api.Assertions;

/** An api for testing a {@code FormatterStep} that depends on the File path. */
public class StepHarnessWithFile implements AutoCloseable {
private final FormatterFunc formatter;
private final Formatter formatter;
private ResourceHarness harness;

private StepHarnessWithFile(FormatterFunc formatter) {
private StepHarnessWithFile(ResourceHarness harness, Formatter formatter) {
this.harness = Objects.requireNonNull(harness);
this.formatter = Objects.requireNonNull(formatter);

}

/** Creates a harness for testing steps which do depend on the file. */
public static StepHarnessWithFile forStep(FormatterStep step) {
// We don't care if an individual FormatterStep is misbehaving on line-endings, because
// Formatter fixes that. No reason to care in tests either. It's likely to pop up when
// running tests on Windows from time-to-time
return new StepHarnessWithFile(FormatterFunc.Closeable.ofDangerous(
() -> {
if (step instanceof FormatterStepImpl.Standard) {
((FormatterStepImpl.Standard<?>) step).cleanupFormatterFunc();
}
},
new FormatterFunc() {
@Override
public String apply(String unix) throws Exception {
return apply(unix, new File(""));
}

@Override
public String apply(String unix, File file) throws Exception {
return LineEnding.toUnix(step.format(unix, file));
}
}));
public static StepHarnessWithFile forStep(ResourceHarness harness, FormatterStep step) {
return new StepHarnessWithFile(harness, Formatter.builder()
.encoding(StandardCharsets.UTF_8)
.lineEndingsPolicy(LineEnding.UNIX.createPolicy())
.steps(Arrays.asList(step))
.build());
}

/** Creates a harness for testing a formatter whose steps do depend on the file. */
public static StepHarnessWithFile forFormatter(Formatter formatter) {
return new StepHarnessWithFile(FormatterFunc.Closeable.ofDangerous(
formatter::close,
input -> formatter.compute(input, new File(""))));
public static StepHarnessWithFile forFormatter(ResourceHarness harness, Formatter formatter) {
return new StepHarnessWithFile(harness, formatter);
}

/** Asserts that the given element is transformed as expected, and that the result is idempotent. */
public StepHarnessWithFile test(File file, String before, String after) throws Exception {
String actual = formatter.apply(before, file);
public StepHarnessWithFile test(File file, String before, String after) {
String actual = formatter.compute(LineEnding.toUnix(before), file);
assertEquals(after, actual, "Step application failed");
return testUnaffected(file, after);
}

/** Asserts that the given element is idempotent w.r.t the step under test. */
public StepHarnessWithFile testUnaffected(File file, String idempotentElement) throws Exception {
String actual = formatter.apply(idempotentElement, file);
public StepHarnessWithFile testUnaffected(File file, String idempotentElement) {
String actual = formatter.compute(LineEnding.toUnix(idempotentElement), file);
assertEquals(idempotentElement, actual, "Step is not idempotent");
return this;
}

/** Asserts that the given elements in the resources directory are transformed as expected. */
public StepHarnessWithFile testResource(File file, String resourceBefore, String resourceAfter) throws Exception {
String before = ResourceHarness.getTestResource(resourceBefore);
String after = ResourceHarness.getTestResource(resourceAfter);
return test(file, before, after);
public StepHarnessWithFile testResource(String resourceBefore, String resourceAfter) {
return testResource(resourceBefore, resourceBefore, resourceAfter);
}

public StepHarnessWithFile testResource(String filename, String resourceBefore, String resourceAfter) {
String contentBefore = ResourceHarness.getTestResource(resourceBefore);
File file = harness.setFile(filename).toContent(contentBefore);
return test(file, contentBefore, ResourceHarness.getTestResource(resourceAfter));
}

/** Asserts that the given elements in the resources directory are transformed as expected. */
public StepHarnessWithFile testResourceUnaffected(File file, String resourceIdempotent) throws Exception {
String idempotentElement = ResourceHarness.getTestResource(resourceIdempotent);
return testUnaffected(file, idempotentElement);
public StepHarnessWithFile testResourceUnaffected(String resourceIdempotent) {
String contentBefore = ResourceHarness.getTestResource(resourceIdempotent);
File file = harness.setFile(resourceIdempotent).toContent(contentBefore);
return testUnaffected(file, contentBefore);
}

public AbstractStringAssert<?> testResourceExceptionMsg(String resourceBefore) throws IOException {
String contentBefore = ResourceHarness.getTestResource(resourceBefore);
File file = harness.setFile(resourceBefore).toContent(contentBefore);
return testExceptionMsg(file, contentBefore);
}

public AbstractStringAssert<?> testExceptionMsg(File file, String before) {
List<Lint> lints = formatter.lint(LineEnding.toUnix(before), file);
if (lints.size() == 0) {
throw new AssertionError("No exception was thrown");
} else if (lints.size() >= 2) {
throw new AssertionError("Expected one lint, had " + lints.size());
} else {
return Assertions.assertThat(lints.get(0).getMsg());
}
}

@Override
public void close() {
if (formatter instanceof FormatterFunc.Closeable) {
((FormatterFunc.Closeable) formatter).close();
}
formatter.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,11 @@

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Test;

import com.diffplug.common.base.StandardSystemProperty;
import com.diffplug.spotless.generic.EndWithNewlineStep;

class FormatterTest {
Expand All @@ -34,7 +31,6 @@ void equality() {
new SerializableEqualityTester() {
private LineEnding.Policy lineEndingsPolicy = LineEnding.UNIX.createPolicy();
private Charset encoding = StandardCharsets.UTF_8;
private Path rootDir = Paths.get(StandardSystemProperty.USER_DIR.value());
private List<FormatterStep> steps = new ArrayList<>();

@Override
Expand All @@ -47,9 +43,6 @@ protected void setupTest(API api) throws Exception {
encoding = StandardCharsets.UTF_16;
api.areDifferentThan();

rootDir = rootDir.getParent();
api.areDifferentThan();

steps.add(EndWithNewlineStep.create());
api.areDifferentThan();
}
Expand Down
Loading