Skip to content

Commit

Permalink
Merge pull request #551 from veelo/d_test_script
Browse files Browse the repository at this point in the history
Port `test.sh` to platform independent D.
  • Loading branch information
maxhaton authored May 29, 2022
2 parents f81ddea + b8da7c5 commit ed5fc2f
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 0 deletions.
103 changes: 103 additions & 0 deletions tests/test.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/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;

// As long as dfmt defaults to LF line endings (issue #552), we'll have to default to ignore
// the line endings in our verification with the reference.
const keepTerminator = dfmtCommand.any!(a => a.canFind("--end_of_line")).to!(Flag!"keepTerminator");
const outText = outFileName.readText;
const refText = refFileName.readText;
const outLines = outText.splitLines(keepTerminator);
const refLines = refText.splitLines(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;
}

// As long as dfmt defaults to LF line endings (issue #552) we need an explicit trailing newline check.
// because a) splitLines gives the same number of lines regardless whether the last line ends with a newline,
// and b) when line endings are ignored the trailing endline is of course also ignored.
if (outText.endsWithNewline)
{
if (!refText.endsWithNewline)
{
writeln(outFileName, " ends with a newline, but ", refFileName, " does not.");
return 1;
}
}
else
{
if (refText.endsWithNewline)
{
writeln(refFileName, " ends with a newline, but ", outFileName, " does not.");
return 1;
}
}
}

foreach (entry; dirEntries("expected_failures", "*.d", SpanMode.shallow))
if (execute([dfmt, entry]).status == 0)
{
stderr.writeln("Expected failure on test ", entry, " but passed.");
return 1;
}

writeln("All tests succeeded.");
return 0;
}

bool endsWithNewline(string text) pure
{
// Same criteria as https://dlang.org/phobos/std_string.html#.lineSplitter
return
text.endsWith('\n') ||
text.endsWith('\r') ||
text.endsWith(lineSep) ||
text.endsWith(paraSep) ||
text.endsWith('\u0085') ||
text.endsWith('\v') ||
text.endsWith('\f');
}
2 changes: 2 additions & 0 deletions tests/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ do
exit 1
fi
done

echo "This script is superseded by test.d."

0 comments on commit ed5fc2f

Please sign in to comment.