@plugjs/expect5
Version:
Unit Testing for the PlugJS Build System ========================================
144 lines (143 loc) • 5.16 kB
JavaScript
// expectation/types.ts
function typeOf(value) {
if (value === null) return "null";
const type = typeof value;
switch (type) {
case "bigint":
case "boolean":
case "function":
case "number":
case "string":
case "symbol":
case "undefined":
return type;
}
if (Array.isArray(value)) return "array";
if (value instanceof Promise) return "promise";
if (typeof value["then"] === "function") return "promise";
if (value instanceof Date) return "date";
if (value instanceof Buffer) return "buffer";
if (value instanceof RegExp) return "regexp";
if (value instanceof Map) return "map";
if (value instanceof Set) return "set";
return "object";
}
function constructorName(value) {
return Object.getPrototypeOf(value)?.constructor?.name;
}
function formatBinaryData(value, buffer) {
const binary = buffer.length > 20 ? `${buffer.toString("hex", 0, 20)}\u2026, length=${value.length}` : buffer.toString("hex");
return binary ? `[${constructorName(value)}: ${binary}]` : `[${constructorName(value)}: empty]`;
}
function stringifyObjectType(value) {
const proto = Object.getPrototypeOf(value);
if (!proto) return "[Object: null prototype]";
return stringifyConstructor(proto.constructor);
}
function stringifyConstructor(ctor) {
if (!ctor) return "[Object: no constructor]";
if (!ctor.name) return "[Object: anonymous]";
return `[${ctor.name}]`;
}
function stringifyValue(value) {
if (value === null) return "<null>";
if (value === void 0) return "<undefined>";
switch (typeof value) {
case "string":
if (value.length > 40) value = `${value.substring(0, 40)}\u2026, length=${value.length}`;
return JSON.stringify(value);
case "number":
if (value === Number.POSITIVE_INFINITY) return "+Infinity";
if (value === Number.NEGATIVE_INFINITY) return "-Infinity";
return String(value);
case "boolean":
return String(value);
case "bigint":
return `${value}n`;
case "function":
return value.name ? `<function ${value.name}>` : "<function>";
case "symbol":
return value.description ? `<symbol ${value.description}>` : "<symbol>";
}
if (value instanceof RegExp) return String(value);
if (value instanceof Date) return `[${constructorName(value)}: ${isNaN(value.getTime()) ? "Invalid date" : value.toISOString()}]`;
if (value instanceof Boolean) return `[${constructorName(value)}: ${value.valueOf()}]`;
if (value instanceof Number) return `[${constructorName(value)}: ${stringifyValue(value.valueOf())}]`;
if (value instanceof String) return `[${constructorName(value)}: ${stringifyValue(value.valueOf())}]`;
if (Array.isArray(value)) return `[${constructorName(value)} (${value.length})]`;
if (value instanceof Set) return `[${constructorName(value)} (${value.size})]`;
if (value instanceof Map) return `[${constructorName(value)} (${value.size})]`;
if (value instanceof Buffer) return formatBinaryData(value, value);
if (value instanceof Uint8Array) return formatBinaryData(value, Buffer.from(value));
if (value instanceof ArrayBuffer) return formatBinaryData(value, Buffer.from(value));
if (value instanceof SharedArrayBuffer) return formatBinaryData(value, Buffer.from(value));
return stringifyObjectType(value);
}
function prefixType(type) {
switch (type) {
case "bigint":
case "boolean":
case "buffer":
case "date":
case "function":
case "map":
case "number":
case "promise":
case "regexp":
case "set":
case "string":
case "symbol":
return `a <${type}>`;
case "array":
case "object":
return `an <${type}>`;
case "null":
case "undefined":
return `<${type}>`;
default:
return `of unknown type <${type}>`;
}
}
var matcherMarker = Symbol.for("plugjs:expect5:types:Matcher");
function isMatcher(what) {
return what && what[matcherMarker] === matcherMarker;
}
var ExpectationError = class extends Error {
remarks;
diff;
/**
* Create an {@link ExpectationError} from a {@link Expectations} instance
* and details message, including an optional {@link Diff}
*/
constructor(expectations, details, diff) {
const { value } = expectations;
let preamble = stringifyValue(value);
if (expectations.parent) {
const properties = [];
while (expectations.parent) {
properties.push(`[${stringifyValue(expectations.parent.prop)}]`);
expectations = expectations.parent.expectations;
}
preamble = properties.reverse().join("");
const type = typeof expectations.value === "object" ? stringifyObjectType(expectations.value) : (
// parent values can not be null!
stringifyValue(expectations.value)
);
preamble = `property ${preamble} of ${type} (${stringifyValue(value)})`;
}
super(`Expected ${preamble} ${details}`);
if (expectations.remarks) this.remarks = expectations.remarks;
if (diff) this.diff = diff;
}
};
export {
ExpectationError,
isMatcher,
matcherMarker,
prefixType,
stringifyConstructor,
stringifyObjectType,
stringifyValue,
typeOf
};
//# sourceMappingURL=types.mjs.map