Skip to content

Commit b77c7f5

Browse files
committed
chore: simplify ForeignExeMock
instead of modifying the input somehow, we just output something completely different, so it should be easier to align windows and unix variants of the ForeignExeMock.
1 parent 0c5bcc9 commit b77c7f5

File tree

5 files changed

+51
-175
lines changed

5 files changed

+51
-175
lines changed

Diff for: app/src/test/java/com/diffplug/spotless/cli/steps/ClangFormatTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ void itFormatsFileType(String testFileName, String resourceName) throws Exceptio
6565
.run();
6666

6767
assertFile(testFile).notSameSasResource(resourceName);
68-
selfie().expectFileWithNormalizedLineEndings(testFile).toMatchDisk(testFileName);
68+
selfie().expectFile(testFile).toMatchDisk(testFileName);
6969
}
7070

7171
static Stream<Arguments> itFormatsFileType() {
@@ -92,6 +92,6 @@ void itFormatsWithSpecificStyle() throws Exception {
9292
.run();
9393

9494
assertFile(testFile).notSameSasResource("clang/example.java.dirty");
95-
selfie().expectFileWithNormalizedLineEndings(testFile).toMatchDisk();
95+
selfie().expectFile(testFile).toMatchDisk();
9696
}
9797
}
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,22 @@
11
╔═ itFormatsFileType/Test.java ═╗
2-
public class Java {
3-
public static void main(String[] args) {
4-
System.out.println("hello");
5-
}
2+
output written by clang-format
63

74
╔═ itFormatsFileType/Test.js ═╗
8-
var numbers=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
9-
];
10-
11-
const p = {
12-
first: "Peter",
13-
last : "Pan",
14-
get fullName() { return this.first + " " + this.last; }
15-
};
16-
17-
const str = "Hello, world!"
18-
;
19-
20-
var str2=str.charAt(3)+str[0];
21-
22-
var multilinestr = "Hello \
23-
World"
24-
;
25-
26-
function test (a, b = "world") { let combined =a+ b; return combined};
27-
28-
test ("Hello");
5+
output written by clang-format
296

307
╔═ itFormatsFileType/Test.m ═╗
31-
- (int)method:(int)i {
32-
return [self testing_123:i];
8+
output written by clang-format
339

3410
╔═ itFormatsFileType/Test.proto ═╗
35-
message Testing {
36-
required string field1 = 1;
37-
required int32 field2 = 2;
38-
optional string field3 = 3;
11+
output written by clang-format
3912

4013
╔═ itFormatsFileType/test.c ═╗
41-
#include <stdio.h>
14+
output written by clang-format
4215

4316
╔═ itFormatsFileType/test.cs ═╗
44-
using System;
45-
using System.Text;
46-
using System.Collections.Generic;
47-
using System.Threading.Tasks;
48-
using System.Linq;
49-
50-
namespace Testing
51-
{
52-
class Program
53-
{
54-
static void Main(string[] args)
55-
{
56-
string message = "Testing 1, 2, 3";
57-
Console.WriteLine(message);
58-
}
59-
}
17+
output written by clang-format
6018

6119
╔═ itFormatsWithSpecificStyle ═╗
62-
public class Java {
63-
public static void main(String[] args) {
64-
System.out.println("hello");
65-
}
20+
output written by clang-format
6621

6722
╔═ [end of file] ═╗

Diff for: testlib/src/main/java/com/diffplug/spotless/SelfieExpectations.java

-30
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@
2222
import org.jetbrains.annotations.NotNull;
2323

2424
import com.diffplug.selfie.Camera;
25-
import com.diffplug.selfie.Lens;
2625
import com.diffplug.selfie.Selfie;
2726
import com.diffplug.selfie.Snapshot;
28-
import com.diffplug.selfie.SnapshotValue;
2927
import com.diffplug.selfie.StringSelfie;
3028

3129
public class SelfieExpectations {
@@ -44,10 +42,6 @@ public static SelfieExpectations create(@NotNull File rootFolder) {
4442
return new SelfieExpectations(rootFolder);
4543
}
4644

47-
private static String normalizeLineEndings(String content) {
48-
return content.replace("\r\n", "\n");
49-
}
50-
5145
private static final Camera<Resource> RESOURCE_CAMERA = (Resource resource) -> {
5246
File file = new File(resource.rootFolder(), resource.resourcePath());
5347
if (!file.exists()) {
@@ -56,21 +50,6 @@ private static String normalizeLineEndings(String content) {
5650
return Snapshot.of(ThrowingEx.get(() -> Files.readString(file.toPath())));
5751
};
5852

59-
private static final Lens NORMALIZE_LINE_ENDINGS = (Snapshot snapshot) -> {
60-
String subject = snapshot.getSubject().valueString();
61-
if (subject.contains("\r\n")) {
62-
// the facet "" is another name for the subject
63-
return snapshot.plusOrReplace("", SnapshotValue.Companion.of(normalizeLineEndings(subject)));
64-
} else {
65-
return snapshot;
66-
}
67-
};
68-
69-
private static final Camera<String> CRLF_TO_LF_CAMERA = (String content) -> {
70-
String normalizedContent = content.replace("\r\n", "\n");
71-
return Snapshot.of(normalizedContent);
72-
};
73-
7453
record Resource(File rootFolder, String resourcePath) {}
7554

7655
public StringSelfie expectResource(String resourcePath) {
@@ -80,13 +59,4 @@ public StringSelfie expectResource(String resourcePath) {
8059
public StringSelfie expectFile(File file) {
8160
return Selfie.expectSelfie(new Resource(file.getParentFile(), file.getName()), RESOURCE_CAMERA);
8261
}
83-
84-
public StringSelfie expectFileWithNormalizedLineEndings(File file) {
85-
return Selfie.expectSelfie(
86-
new Resource(file.getParentFile(), file.getName()), RESOURCE_CAMERA.withLens(NORMALIZE_LINE_ENDINGS));
87-
}
88-
89-
public static StringSelfie expectNormalizedContent(String content) {
90-
return Selfie.expectSelfie(content, CRLF_TO_LF_CAMERA);
91-
}
9262
}

Diff for: testlib/src/main/java/com/diffplug/spotless/cli/ForeignExeMock.java

+39-86
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ public class ForeignExeMock {
3131
enum TargetOs {
3232
WINDOWS {
3333
@Override
34-
protected ForeignExeMockWriter mockWriter(PrintWriter output) {
35-
return new WindowsForeignExeMockWriter(output);
34+
protected ForeignExeMockWriter mockWriter(PrintWriter output, String name) {
35+
return new WindowsForeignExeMockWriter(output, "output written by " + name);
3636
}
3737

3838
@Override
@@ -42,8 +42,8 @@ protected String asFileName(String name) {
4242
},
4343
UNIX {
4444
@Override
45-
protected ForeignExeMockWriter mockWriter(PrintWriter output) {
46-
return new UnixForeignExeMockWriter(output);
45+
protected ForeignExeMockWriter mockWriter(PrintWriter output, String name) {
46+
return new UnixForeignExeMockWriter(output, "output written by " + name);
4747
}
4848

4949
@Override
@@ -60,7 +60,7 @@ static TargetOs current() {
6060
}
6161
}
6262

63-
protected abstract ForeignExeMockWriter mockWriter(PrintWriter output);
63+
protected abstract ForeignExeMockWriter mockWriter(PrintWriter output, String name);
6464

6565
protected abstract String asFileName(String name);
6666
}
@@ -149,10 +149,10 @@ private Map<String, String> optionDefaults() {
149149
return defaults;
150150
}
151151

152-
private String content(TargetOs os) {
152+
private String content(TargetOs os, String name) {
153153
try (StringWriter stringWriter = new StringWriter();
154154
PrintWriter printWriter = new PrintWriter(stringWriter)) {
155-
ForeignExeMockWriter writer = os.mockWriter(printWriter);
155+
ForeignExeMockWriter writer = os.mockWriter(printWriter, name);
156156
writer = writer.writeIntro(optionDefaults())
157157
.writeOptionParserIntro()
158158
.writeStringReturningOption("--version", "version " + version);
@@ -188,7 +188,7 @@ public ForeignExeMock build() {
188188
}
189189

190190
ForeignExeMock build(TargetOs os) {
191-
return new ForeignExeMock(name, content(os), os);
191+
return new ForeignExeMock(name, content(os, name), os);
192192
}
193193
}
194194

@@ -215,23 +215,26 @@ private interface ForeignExeMockWriter {
215215
private static class UnixForeignExeMockWriter implements ForeignExeMockWriter {
216216

217217
private final PrintWriter output;
218+
private final String constantOut; // text we always emit to stdout
218219

219-
UnixForeignExeMockWriter(@NotNull PrintWriter output) {
220+
UnixForeignExeMockWriter(@NotNull PrintWriter output, @NotNull String constantOut) {
220221
this.output = Objects.requireNonNull(output);
222+
this.constantOut = Objects.requireNonNull(constantOut);
221223
}
222224

223225
private String asVarName(String optionName) {
224226
return optionName.replaceAll("[^a-zA-Z0-9]", "_");
225227
}
226228

229+
/* ───────────────────────── intro ───────────────────────── */
227230
@Override
228231
public ForeignExeMockWriter writeIntro(@NotNull Map<String, String> optionDefaults) {
229232
Objects.requireNonNull(optionDefaults);
230-
output.println("#!/bin/bash");
233+
output.println("#!/usr/bin/env bash");
234+
output.println("set -euo pipefail");
235+
output.println();
236+
optionDefaults.forEach((k, v) -> output.printf("%s=\"%s\"%n", asVarName(k), v));
231237
output.println();
232-
optionDefaults.forEach((k, v) -> output.printf("%s=\"%s\"\n", asVarName(k), v));
233-
// collect value from stdin
234-
output.println("stdin_value=\"\"");
235238
return this;
236239
}
237240

@@ -305,38 +308,44 @@ public ForeignExeMockWriter writeOptionParserOutro() {
305308
return this;
306309
}
307310

311+
/* ─────────────────── stdin → /dev/null (drain) ─────────────────── */
308312
@Override
309313
public ForeignExeMockWriter writeReadFromStdin() {
310-
// collect the stdin to stdin_value
311-
output.println("while IFS= read -r line; do");
312-
output.println(" stdin_value+=\"${line}\"$'\\n'");
313-
output.println("done");
314+
output.println("# consume everything the caller pipes into us -------------");
315+
output.println("cat > /dev/null");
314316
output.println();
315317
return this;
316318
}
317319

320+
/* ─────────────── constant text → stdout ─────────────── */
321+
/** Quote a literal for POSIX shells using single‑quotes. */
322+
private static String shQuote(String s) {
323+
// close quote, insert escaped single‑quote, reopen quote: ' --> '\''
324+
return "'" + s.replace("'", "'\"'\"'") + "'";
325+
}
326+
318327
@Override
319328
public ForeignExeMockWriter writeWriteToStdout() {
320-
// write the stdin_value to stdout but add 4 spaces at the end of each line that does not already end with 4
321-
// spaces
322-
// output.println("echo \"${stdin_value}\" | sed '/ $/! s/$/ /'");
323-
output.println("printf \"%s\" \"$stdin_value\" | sed '/ $/! s/$/ /'");
329+
output.printf("echo %s%n", shQuote(constantOut));
330+
output.println();
324331
return this;
325332
}
326333

334+
/* ─────────────────────── exit ─────────────────────── */
327335
@Override
328336
public ForeignExeMockWriter writeExitCode(int exitCode) {
329-
output.printf("exit %d\n", exitCode);
337+
output.printf("exit %d%n", exitCode);
330338
return this;
331339
}
332340
}
333341

334342
private static class WindowsForeignExeMockWriter implements ForeignExeMockWriter {
335-
336343
private final PrintWriter output;
344+
private final String constantOut; // what we will echo to stdout
337345

338-
WindowsForeignExeMockWriter(@NotNull PrintWriter output) {
346+
WindowsForeignExeMockWriter(@NotNull PrintWriter output, @NotNull String constantOut) {
339347
this.output = Objects.requireNonNull(output);
348+
this.constantOut = Objects.requireNonNull(constantOut);
340349
}
341350

342351
private String asVarName(String optionName) {
@@ -352,9 +361,7 @@ public ForeignExeMockWriter writeIntro(@NotNull Map<String, String> optionDefaul
352361
output.println();
353362

354363
optionDefaults.forEach((k, v) -> output.printf("set \"%s=%s\"%n", asVarName(k), v));
355-
356-
output.println("set \"stdin_file=%TEMP%\\foreign_mock_%RANDOM%%RANDOM%.tmp\"");
357-
output.println();
364+
output.println(); // nothing else needed here
358365
return this;
359366
}
360367

@@ -441,75 +448,21 @@ public ForeignExeMockWriter writeOptionParserOutro() {
441448
// ───────────────────── stdin → file ─────────────────────
442449
@Override
443450
public ForeignExeMockWriter writeReadFromStdin() {
444-
output.println("rem -- read everything the caller pipes into us ------------");
445-
output.println("more > \"!stdin_file!\"");
451+
output.println("rem -- consume everything the caller pipes into us -----");
452+
output.println("more > nul"); // reads stdin until EOF, discards it
446453
output.println();
447454
return this;
448455
}
449456

450457
// ─────────────── file → stdout (pad lines) ──────────────
451458
@Override
452459
public ForeignExeMockWriter writeWriteToStdout() {
453-
454-
// rolling buffer
455-
output.println("set \"prev_line=\"");
456-
output.println("set \"have_prev=0\"");
457-
458-
/*
459-
read each physical record (trailing blanks intact)
460-
findstr /n /R ".*" prefixes lines with N: (even empty ones)
461-
*/
462-
output.println("for /f \"usebackq delims=\" %%L in (`findstr /n /R \".*\" \"!stdin_file!\"`) do (");
463-
output.println(" set \"raw=%%L\"");
464-
output.println(" set \"curr_line=!raw:*:=!\""); // strip N:
465-
output.println(" if \"!have_prev!\"==\"1\" (");
466-
output.println(" call :emit_with_nl"); // print previous line + NL
467-
output.println(" )");
468-
output.println(" set \"prev_line=!curr_line!\"");
469-
output.println(" set \"have_prev=1\"");
470-
output.println(")");
471-
472-
/*
473-
After the loop prev_line holds LAST record.
474-
If that record is empty, the input *did* end with an EOL, so nothing more
475-
to print. If it is non‑empty, the input lacked a final EOL — print the
476-
line *without* adding a new one.
477-
*/
478-
output.println("if \"!prev_line!\"==\"\" (");
479-
output.println(" rem input ended with newline – nothing left to write");
480-
output.println(") else (");
481-
output.println(" call :emit_no_nl"); // print last line, no NL
482-
output.println(")");
483-
484-
output.println("del \"!stdin_file!\" >nul 2>&1");
485-
output.println("goto :finish");
486-
output.println();
487-
488-
/* ---------- helpers --------------------------------------- */
489-
490-
// prev_line → stdout, padding rule, WITH trailing newline
491-
output.println(":emit_with_nl");
492-
output.println("if \"!prev_line:~-4!\"==\" \" (");
493-
output.println(" <nul set /p \"=!prev_line!\"");
494-
output.println(") else (");
495-
output.println(" <nul set /p \"=!prev_line! \"");
496-
output.println(")");
497-
output.println("echo("); // newline
498-
output.println("exit /b");
460+
output.printf("echo %s%n", constantOut.replace("\"", "\"\""));
461+
output.println("goto :finish"); // skip anything that might follow
499462
output.println();
500-
501-
// prev_line → stdout, padding rule, NO trailing newline
502-
output.println(":emit_no_nl");
503-
output.println("if \"!prev_line:~-4!\"==\" \" (");
504-
output.println(" <nul set /p \"=!prev_line!\"");
505-
output.println(") else (");
506-
output.println(" <nul set /p \"=!prev_line! \"");
507-
output.println(")");
508-
output.println("exit /b");
509-
output.println();
510-
511463
return this;
512464
}
465+
513466
// ───────────────────────── exit ─────────────────────────
514467
/* writeExitCode – central, always‑reached exit point */
515468
@Override

0 commit comments

Comments
 (0)