aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ext_depends/D-YAML/source/dyaml/test/common.d
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext_depends/D-YAML/source/dyaml/test/common.d')
-rw-r--r--src/ext_depends/D-YAML/source/dyaml/test/common.d223
1 files changed, 223 insertions, 0 deletions
diff --git a/src/ext_depends/D-YAML/source/dyaml/test/common.d b/src/ext_depends/D-YAML/source/dyaml/test/common.d
new file mode 100644
index 0000000..a6bafa9
--- /dev/null
+++ b/src/ext_depends/D-YAML/source/dyaml/test/common.d
@@ -0,0 +1,223 @@
+
+// Copyright Ferdinand Majerech 2011.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+module dyaml.test.common;
+
+version(unittest)
+{
+
+import dyaml.node;
+import dyaml.event;
+
+import core.exception;
+import std.algorithm;
+import std.array;
+import std.conv;
+import std.file;
+import std.range;
+import std.path;
+import std.traits;
+import std.typecons;
+
+package:
+
+/**
+Run a test.
+
+Params:
+ testFunction = Unittest function.
+ unittestExt = Extensions of data files needed for the unittest.
+ skipExt = Extensions that must not be used for the unittest.
+ */
+void run(D)(D testFunction, string[] unittestExt, string[] skipExt = [])
+{
+ immutable string dataDir = __FILE_FULL_PATH__.dirName ~ "/../../../test/data";
+ auto testFilenames = findTestFilenames(dataDir);
+
+ if (unittestExt.length > 0)
+ {
+ outer: foreach (base, extensions; testFilenames)
+ {
+ string[] filenames;
+ foreach (ext; unittestExt)
+ {
+ if (!extensions.canFind(ext))
+ {
+ continue outer;
+ }
+ filenames ~= base ~ '.' ~ ext;
+ }
+ foreach (ext; skipExt)
+ {
+ if (extensions.canFind(ext))
+ {
+ continue outer;
+ }
+ }
+
+ execute(testFunction, filenames);
+ }
+ }
+ else
+ {
+ execute(testFunction, string[].init);
+ }
+}
+
+// TODO: remove when a @safe ubyte[] file read can be done.
+/**
+Reads a file as an array of bytes.
+
+Params:
+ filename = Full path to file to read.
+
+Returns: The file's data.
+*/
+ubyte[] readData(string filename) @trusted
+{
+ import std.file : read;
+ return cast(ubyte[])read(filename);
+}
+void assertNodesEqual(const scope Node gotNode, const scope Node expectedNode) @safe
+{
+ import std.format : format;
+ assert(gotNode == expectedNode, format!"got %s, expected %s"(gotNode.debugString, expectedNode.debugString));
+}
+
+/**
+Determine if events in events1 are equivalent to events in events2.
+
+Params:
+ events1 = A range of events to compare with.
+ events2 = A second range of events to compare.
+
+Returns: true if the events are equivalent, false otherwise.
+*/
+bool compareEvents(T, U)(T events1, U events2)
+if (isInputRange!T && isInputRange!U && is(ElementType!T == Event) && is(ElementType!U == Event))
+{
+ foreach (e1, e2; zip(events1, events2))
+ {
+ //Different event types.
+ if (e1.id != e2.id)
+ {
+ return false;
+ }
+ //Different anchor (if applicable).
+ if (e1.id.among!(EventID.sequenceStart, EventID.mappingStart, EventID.alias_, EventID.scalar)
+ && e1.anchor != e2.anchor)
+ {
+ return false;
+ }
+ //Different collection tag (if applicable).
+ if (e1.id.among!(EventID.sequenceStart, EventID.mappingStart) && e1.tag != e2.tag)
+ {
+ return false;
+ }
+ if (e1.id == EventID.scalar)
+ {
+ //Different scalar tag (if applicable).
+ if (!(e1.implicit || e2.implicit) && e1.tag != e2.tag)
+ {
+ return false;
+ }
+ //Different scalar value.
+ if (e1.value != e2.value)
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+/**
+Throw an Error if events in events1 aren't equivalent to events in events2.
+
+Params:
+ events1 = First event array to compare.
+ events2 = Second event array to compare.
+*/
+void assertEventsEqual(T, U)(T events1, U events2)
+if (isInputRange!T && isInputRange!U && is(ElementType!T == Event) && is(ElementType!U == Event))
+{
+ auto events1Copy = events1.array;
+ auto events2Copy = events2.array;
+ assert(compareEvents(events1Copy, events2Copy), text("Got '", events1Copy, "', expected '", events2Copy, "'"));
+}
+
+private:
+
+/**
+Find unittest input filenames.
+
+Params: dir = Directory to look in.
+
+Returns: Test input base filenames and their extensions.
+*/
+ //@trusted due to dirEntries
+string[][string] findTestFilenames(const string dir) @trusted
+{
+ //Groups of extensions indexed by base names.
+ string[][string] names;
+ foreach (string name; dirEntries(dir, SpanMode.shallow))
+ {
+ if (isFile(name))
+ {
+ string base = name.stripExtension();
+ string ext = name.extension();
+ if (ext is null)
+ {
+ ext = "";
+ }
+ if (ext[0] == '.')
+ {
+ ext = ext[1 .. $];
+ }
+
+ //If the base name doesn't exist yet, add it; otherwise add new extension.
+ names[base] = ((base in names) is null) ? [ext] : names[base] ~ ext;
+ }
+ }
+ return names;
+}
+
+/**
+Recursively copy an array of strings to a tuple to use for unittest function input.
+
+Params:
+ index = Current index in the array/tuple.
+ tuple = Tuple to copy to.
+ strings = Strings to copy.
+*/
+void stringsToTuple(uint index, F ...)(ref F tuple, const string[] strings)
+in(F.length == strings.length)
+do
+{
+ tuple[index] = strings[index];
+ static if (index > 0)
+ {
+ stringsToTuple!(index - 1, F)(tuple, strings);
+ }
+}
+
+/**
+Execute an unittest on specified files.
+
+Params:
+ testName = Name of the unittest.
+ testFunction = Unittest function.
+ filenames = Names of input files to test with.
+ */
+void execute(D)(D testFunction, string[] filenames)
+{
+ //Convert filenames to parameters tuple and call the test function.
+ alias F = Parameters!D[0..$];
+ F parameters;
+ stringsToTuple!(F.length - 1, F)(parameters, filenames);
+ testFunction(parameters);
+}
+
+} // version(unittest)