dfmt/tests/test.d
WebFreak001 4a6078779a Fix #568, don't output empty files without error
Now when an error in formatting happens, it never outputs anything and
doesn't override the file when working inplace.

Additionally dfmt is no longer able to fail in the middle of a file, as
now we first write everything to a buffer and only if everything was
successful, that buffer is printed to stdout or written to the inplace
file.

This should also guard against segfaults with inplace file formatting
erasing parts of the file, as well as the user thinking it was
successful, even though dfmt didn't finish properly.
2022-10-15 02:33:04 +02:00

83 lines
2.9 KiB
D
Executable file

#!/usr/bin/env rdmd
/**
Platform independent port of `test.sh`. Runs the tests in this directory.
Ignores differences in line endings, unless the test uses `--end_of_line`.
**/
import std.algorithm, std.array, std.conv, std.file, std.path, std.process;
import std.stdio, std.string, std.typecons, std.range, std.uni;
version (Windows)
enum dfmt = `..\bin\dfmt.exe`;
else
enum dfmt = `../bin/dfmt`;
int main()
{
foreach (braceStyle; ["allman", "otbs", "knr"])
foreach (entry; dirEntries(".", "*.d", SpanMode.shallow).filter!(e => e.baseName(".d") != "test"))
{
const source = entry.baseName;
const outFileName = buildPath(braceStyle, source ~ ".out");
const refFileName = buildPath(braceStyle, source ~ ".ref");
const argsFile = source.stripExtension ~ ".args";
const dfmtCommand =
[dfmt, "--brace_style=" ~ braceStyle] ~
(argsFile.exists ? readText(argsFile).split : []) ~
[source];
writeln(dfmtCommand.join(" "));
if (const result = spawnProcess(dfmtCommand, stdin, File(outFileName, "w")).wait)
return result;
if (int ret = diff(refFileName, outFileName))
return ret;
}
foreach (entry; dirEntries("expected_failures", "*.d", SpanMode.shallow))
{
string copied = entry ~ ".out.d";
copy(entry, copied);
scope (exit)
remove(copied);
if (execute([dfmt, copied, "--inplace"]).status == 0)
{
stderr.writeln("Expected failure on test ", entry, " but passed.");
return 1;
}
if (int ret = diff(entry, copied))
return ret;
}
writeln("All tests succeeded.");
return 0;
}
int diff(string refFileName, string outFileName)
{
const outText = outFileName.readText;
const refText = refFileName.readText;
const outLines = outText.splitLines(Yes.keepTerminator);
const refLines = refText.splitLines(Yes.keepTerminator);
foreach (i; 0 .. min(refLines.length, outLines.length))
if (outLines[i] != refLines[i])
{
writeln("Found difference between ", outFileName, " and ", refFileName, " on line ", i + 1, ":");
writefln("out: %(%s%)", [outLines[i]]); // Wrapping in array shows line endings.
writefln("ref: %(%s%)", [refLines[i]]);
return 1;
}
if (outLines.length < refLines.length)
{
writeln("Line ", outLines.length + 1, " in ", refFileName, " not found in ", outFileName, ":");
writefln("%(%s%)", [refLines[outLines.length]]);
return 1;
}
if (outLines.length > refLines.length)
{
writeln("Line ", outLines.length + 1, " in ", outFileName, " not present in ", refFileName, ":");
writefln("%(%s%)", [outLines[refLines.length]]);
return 1;
}
return 0;
}