aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ext_depends/D-YAML/testsuite/source
diff options
context:
space:
mode:
authorRalph Amissah <ralph.amissah@gmail.com>2021-02-19 17:10:51 -0500
committerRalph Amissah <ralph.amissah@gmail.com>2021-02-24 16:46:47 -0500
commit02ca32ae0a5bc290918d2b2a3288e385b9cc6b11 (patch)
tree06379785e8a0165a7deb981c2eba362894820634 /src/ext_depends/D-YAML/testsuite/source
parentbuild from static source-tree pre fetch depends (diff)
external & build dependences in src tree
- external & build dependences boost licensed - ext_depends (external depends) - D-YAML - tinyendian - d2sqlite3 - imageformats - build_depends - dub2nix
Diffstat (limited to 'src/ext_depends/D-YAML/testsuite/source')
-rw-r--r--src/ext_depends/D-YAML/testsuite/source/app.d323
1 files changed, 323 insertions, 0 deletions
diff --git a/src/ext_depends/D-YAML/testsuite/source/app.d b/src/ext_depends/D-YAML/testsuite/source/app.d
new file mode 100644
index 0000000..6c26b32
--- /dev/null
+++ b/src/ext_depends/D-YAML/testsuite/source/app.d
@@ -0,0 +1,323 @@
+module dyaml.testsuite;
+
+import dyaml;
+import dyaml.event;
+
+import std.algorithm;
+import std.conv;
+import std.file;
+import std.format;
+import std.json;
+import std.path;
+import std.range;
+import std.stdio;
+import std.string;
+import std.typecons;
+import std.utf;
+
+auto dumpEventString(string str) @safe
+{
+ string[] output;
+ try
+ {
+ auto events = Loader.fromString(str).parse();
+ foreach (event; events)
+ {
+ string line;
+ final switch (event.id)
+ {
+ case EventID.scalar:
+ line = "=VAL ";
+ if (event.anchor != "")
+ {
+ line ~= text("&", event.anchor, " ");
+ }
+ if (event.tag != "")
+ {
+ line ~= text("<", event.tag, "> ");
+ }
+ switch(event.scalarStyle)
+ {
+ case ScalarStyle.singleQuoted:
+ line ~= "'";
+ break;
+ case ScalarStyle.doubleQuoted:
+ line ~= '"';
+ break;
+ case ScalarStyle.literal:
+ line ~= "|";
+ break;
+ case ScalarStyle.folded:
+ line ~= ">";
+ break;
+ default:
+ line ~= ":";
+ break;
+ }
+ if (event.value != "")
+ {
+ line ~= text(event.value.substitute("\n", "\\n", `\`, `\\`, "\r", "\\r", "\t", "\\t", "\b", "\\b"));
+ }
+ break;
+ case EventID.streamStart:
+ line = "+STR";
+ break;
+ case EventID.documentStart:
+ line = "+DOC";
+ if (event.explicitDocument)
+ {
+ line ~= text(" ---");
+ }
+ break;
+ case EventID.mappingStart:
+ line = "+MAP";
+ if (event.anchor != "")
+ {
+ line ~= text(" &", event.anchor);
+ }
+ if (event.tag != "")
+ {
+ line ~= text(" <", event.tag, ">");
+ }
+ break;
+ case EventID.sequenceStart:
+ line = "+SEQ";
+ if (event.anchor != "")
+ {
+ line ~= text(" &", event.anchor);
+ }
+ if (event.tag != "")
+ {
+ line ~= text(" <", event.tag, ">");
+ }
+ break;
+ case EventID.streamEnd:
+ line = "-STR";
+ break;
+ case EventID.documentEnd:
+ line = "-DOC";
+ if (event.explicitDocument)
+ {
+ line ~= " ...";
+ }
+ break;
+ case EventID.mappingEnd:
+ line = "-MAP";
+ break;
+ case EventID.sequenceEnd:
+ line = "-SEQ";
+ break;
+ case EventID.alias_:
+ line = text("=ALI *", event.anchor);
+ break;
+ case EventID.invalid:
+ assert(0, "Invalid EventID produced");
+ }
+ output ~= line;
+ }
+ }
+ catch (Exception) {} //Exceptions should just stop adding output
+ return output.join("\n");
+}
+
+enum TestState
+{
+ success,
+ skipped,
+ failure
+}
+
+struct TestResult
+{
+ string name;
+ TestState state;
+ string failMsg;
+
+ const void toString(OutputRange)(ref OutputRange writer)
+ if (isOutputRange!(OutputRange, char))
+ {
+ ubyte statusColour;
+ string statusString;
+ final switch (state) {
+ case TestState.success:
+ statusColour = 32;
+ statusString = "Succeeded";
+ break;
+ case TestState.failure:
+ statusColour = 31;
+ statusString = "Failed";
+ break;
+ case TestState.skipped:
+ statusColour = 93;
+ statusString = "Skipped";
+ break;
+ }
+ writer.formattedWrite!"[\033[%s;1m%s\033[0m] %s"(statusColour, statusString, name);
+ if (state != TestState.success)
+ {
+ writer.formattedWrite!" (%s)"(failMsg.replace("\n", " "));
+ }
+ }
+}
+
+TestResult runTests(string tml) @safe
+{
+ TestResult output;
+ output.state = TestState.success;
+ auto splitFile = tml.splitter("\n--- ");
+ output.name = splitFile.front.findSplit("=== ")[2];
+ bool loadFailed, shouldFail;
+ string failMsg;
+ JSONValue json;
+ Node[] nodes;
+ string yamlString;
+ Nullable!string compareYAMLString;
+ Nullable!string events;
+ ulong testsRun;
+
+ void fail(string msg) @safe
+ {
+ output.state = TestState.failure;
+ output.failMsg = msg;
+ }
+ void skip(string msg) @safe
+ {
+ output.state = TestState.skipped;
+ output.failMsg = msg;
+ }
+ void parseYAML(string yaml) @safe
+ {
+ yamlString = yaml;
+ try {
+ nodes = Loader.fromString(yamlString).array;
+ }
+ catch (Exception e)
+ {
+ loadFailed = true;
+ failMsg = e.msg;
+ }
+ }
+ void compareLineByLine(const string a, const string b, const string msg) @safe
+ {
+ foreach (line1, line2; zip(a.lineSplitter, b.lineSplitter))
+ {
+ if (line1 != line2)
+ {
+ fail(text(msg, " Got ", line1, ", expected ", line2));
+ break;
+ }
+ }
+ }
+ foreach (section; splitFile.drop(1))
+ {
+ auto splitSection = section.findSplit("\n");
+ auto splitSectionHeader = splitSection[0].findSplit(":");
+ const splitSectionName = splitSectionHeader[0].findSplit("(");
+ const sectionName = splitSectionName[0];
+ const sectionParams = splitSectionName[2].findSplit(")")[0];
+ string sectionData = splitSection[2];
+ if (sectionData != "")
+ {
+ //< means dedent.
+ if (sectionParams.canFind("<"))
+ {
+ sectionData = sectionData[4..$].substitute("\n ", "\n", "<SPC>", " ", "<TAB>", "\t").toUTF8;
+ }
+ else
+ {
+ sectionData = sectionData.substitute("<SPC>", " ", "<TAB>", "\t").toUTF8;
+ }
+ //Not sure what + means.
+ }
+ switch(sectionName)
+ {
+ case "in-yaml":
+ parseYAML(sectionData);
+ break;
+ case "in-json":
+ json = parseJSON(sectionData);
+ break;
+ case "test-event":
+ events = sectionData;
+ break;
+ case "error":
+ shouldFail = true;
+ testsRun++;
+ break;
+ case "out-yaml":
+ compareYAMLString = sectionData;
+ break;
+ case "emit-yaml":
+ // TODO: Figure out how/if to implement this
+ //fail("Unhandled test - emit-yaml");
+ break;
+ case "lex-token":
+ // TODO: Should this be implemented?
+ //fail("Unhandled test - lex-token");
+ break;
+ case "from": break;
+ case "tags": break;
+ default: assert(false, text("Unhandled section ", sectionName, "in ", output.name));
+ }
+ }
+ if (!loadFailed && !compareYAMLString.isNull && !shouldFail)
+ {
+ Appender!string buf;
+ dumper().dump(buf);
+ compareLineByLine(buf.data, compareYAMLString.get, "Dumped YAML mismatch");
+ testsRun++;
+ }
+ if (!loadFailed && !events.isNull && !shouldFail)
+ {
+ const compare = dumpEventString(yamlString);
+ compareLineByLine(compare, events.get, "Event mismatch");
+ testsRun++;
+ }
+ if (loadFailed && !shouldFail)
+ {
+ fail(failMsg);
+ }
+ if (shouldFail && !loadFailed)
+ {
+ fail("Invalid YAML accepted");
+ }
+ if ((testsRun == 0) && (output.state != TestState.failure))
+ {
+ skip("No tests run");
+ }
+ return output;
+}
+
+// Can't be @safe due to dirEntries()
+void main(string[] args) @system
+{
+ string path = "yaml-test-suite/test";
+
+ void printResult(string id, TestResult result)
+ {
+ writeln(id, " ", result);
+ }
+
+ if (args.length > 1)
+ {
+ path = args[1];
+ }
+
+ ulong total;
+ ulong successes;
+ foreach (file; dirEntries(path, "*.tml", SpanMode.shallow))
+ {
+ auto result = runTests(readText(file));
+ if (result.state == TestState.success)
+ {
+ debug(verbose) printResult(file.baseName, result);
+ successes++;
+ }
+ else
+ {
+ printResult(file.baseName, result);
+ }
+ total++;
+ }
+ writefln!"%d/%d tests passed"(successes, total);
+}