mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-26 10:21:55 +00:00
202 lines
7.1 KiB
JavaScript
202 lines
7.1 KiB
JavaScript
const chalk = require("chalk");
|
|
const process = require("process");
|
|
const { pathToFileURL } = require("url");
|
|
const { testDefinitions } = require("@deno/shim-deno/test-internals");
|
|
const filePaths = [
|
|
"config/index.test.js",
|
|
"emver-lite/test.js",
|
|
"test.js",
|
|
"utils/propertiesMatcher.test.js",
|
|
];
|
|
async function main() {
|
|
const testContext = {
|
|
process,
|
|
chalk,
|
|
};
|
|
for (const [i, filePath] of filePaths.entries()) {
|
|
if (i > 0) {
|
|
console.log("");
|
|
}
|
|
const scriptPath = "./script/" + filePath;
|
|
console.log("Running tests in " + chalk.underline(scriptPath) + "...\n");
|
|
process.chdir(__dirname + "/script");
|
|
const scriptTestContext = {
|
|
origin: pathToFileURL(filePath).toString(),
|
|
...testContext,
|
|
};
|
|
try {
|
|
require(scriptPath);
|
|
}
|
|
catch (err) {
|
|
console.error(err);
|
|
process.exit(1);
|
|
}
|
|
await runTestDefinitions(testDefinitions.splice(0, testDefinitions.length), scriptTestContext);
|
|
const esmPath = "./esm/" + filePath;
|
|
console.log("\nRunning tests in " + chalk.underline(esmPath) + "...\n");
|
|
process.chdir(__dirname + "/esm");
|
|
const esmTestContext = {
|
|
origin: pathToFileURL(filePath).toString(),
|
|
...testContext,
|
|
};
|
|
await import(esmPath);
|
|
await runTestDefinitions(testDefinitions.splice(0, testDefinitions.length), esmTestContext);
|
|
}
|
|
}
|
|
async function runTestDefinitions(testDefinitions, options) {
|
|
const testFailures = [];
|
|
for (const definition of testDefinitions) {
|
|
options.process.stdout.write("test " + definition.name + " ...");
|
|
if (definition.ignore) {
|
|
options.process.stdout.write(` ${options.chalk.gray("ignored")}\n`);
|
|
continue;
|
|
}
|
|
const context = getTestContext(definition, undefined);
|
|
let pass = false;
|
|
try {
|
|
await definition.fn(context);
|
|
if (context.hasFailingChild) {
|
|
testFailures.push({
|
|
name: definition.name,
|
|
err: new Error("Had failing test step.")
|
|
});
|
|
}
|
|
else {
|
|
pass = true;
|
|
}
|
|
}
|
|
catch (err) {
|
|
testFailures.push({
|
|
name: definition.name,
|
|
err
|
|
});
|
|
}
|
|
const testStepOutput = context.getOutput();
|
|
if (testStepOutput.length > 0) {
|
|
options.process.stdout.write(testStepOutput);
|
|
}
|
|
else {
|
|
options.process.stdout.write(" ");
|
|
}
|
|
options.process.stdout.write(getStatusText(pass ? "ok" : "fail"));
|
|
options.process.stdout.write("\n");
|
|
}
|
|
if (testFailures.length > 0) {
|
|
options.process.stdout.write("\nFAILURES");
|
|
for (const failure of testFailures) {
|
|
options.process.stdout.write("\n\n");
|
|
options.process.stdout.write(failure.name + "\n");
|
|
options.process.stdout.write(indentText((failure.err?.stack ?? failure.err).toString(), 1));
|
|
}
|
|
options.process.exit(1);
|
|
}
|
|
function getTestContext(definition, parent) {
|
|
return {
|
|
name: definition.name,
|
|
parent,
|
|
origin: options.origin,
|
|
/** @type {any} */ err: undefined,
|
|
status: "ok",
|
|
children: [],
|
|
get hasFailingChild() {
|
|
return this.children.some((c) => c.status === "fail" || c.status === "pending");
|
|
},
|
|
getOutput() {
|
|
let output = "";
|
|
if (this.parent) {
|
|
output += "test " + this.name + " ...";
|
|
}
|
|
if (this.children.length > 0) {
|
|
output += "\n" + this.children.map((c) => indentText(c.getOutput(), 1)).join("\n") + "\n";
|
|
}
|
|
else if (!this.err) {
|
|
output += " ";
|
|
}
|
|
if (this.parent && this.err) {
|
|
output += "\n";
|
|
}
|
|
if (this.err) {
|
|
output += indentText((this.err.stack ?? this.err).toString(), 1);
|
|
if (this.parent) {
|
|
output += "\n";
|
|
}
|
|
}
|
|
if (this.parent) {
|
|
output += getStatusText(this.status);
|
|
}
|
|
return output;
|
|
},
|
|
async step(nameOrTestDefinition, fn) {
|
|
const definition = getDefinition();
|
|
const context = getTestContext(definition, this);
|
|
context.status = "pending";
|
|
this.children.push(context);
|
|
if (definition.ignore) {
|
|
context.status = "ignored";
|
|
return false;
|
|
}
|
|
try {
|
|
await definition.fn(context);
|
|
context.status = "ok";
|
|
if (context.hasFailingChild) {
|
|
context.status = "fail";
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
catch (err) {
|
|
context.status = "fail";
|
|
context.err = err;
|
|
return false;
|
|
}
|
|
/** @returns {TestDefinition} */ function getDefinition() {
|
|
if (typeof nameOrTestDefinition === "string") {
|
|
if (!(fn instanceof Function)) {
|
|
throw new TypeError("Expected function for second argument.");
|
|
}
|
|
return {
|
|
name: nameOrTestDefinition,
|
|
fn
|
|
};
|
|
}
|
|
else if (typeof nameOrTestDefinition === "object") {
|
|
return nameOrTestDefinition;
|
|
}
|
|
else {
|
|
throw new TypeError("Expected a test definition or name and function.");
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
function getStatusText(status) {
|
|
switch (status) {
|
|
case "ok":
|
|
return options.chalk.green(status);
|
|
case "fail":
|
|
case "pending":
|
|
return options.chalk.red(status);
|
|
case "ignored":
|
|
return options.chalk.gray(status);
|
|
default:
|
|
{
|
|
const _assertNever = status;
|
|
return status;
|
|
}
|
|
}
|
|
}
|
|
function indentText(text, indentLevel) {
|
|
if (text === undefined) {
|
|
text = "[undefined]";
|
|
}
|
|
else if (text === null) {
|
|
text = "[null]";
|
|
}
|
|
else {
|
|
text = text.toString();
|
|
}
|
|
return text.split(/\r?\n/).map((line) => " ".repeat(indentLevel) + line).join("\n");
|
|
}
|
|
}
|
|
main();
|