@plugjs/expect5
Version:
Unit Testing for the PlugJS Build System ========================================
303 lines (301 loc) • 12.1 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// expectation/print.ts
var print_exports = {};
__export(print_exports, {
printDiff: () => printDiff
});
module.exports = __toCommonJS(print_exports);
var import_logging = require("@plugjs/plug/logging");
var import_utils = require("@plugjs/plug/utils");
var import_types = require("./types.cjs");
var _opnPar = (0, import_logging.$gry)("(");
var _clsPar = (0, import_logging.$gry)(")");
var _opnCrl = (0, import_logging.$gry)("{");
var _clsCrl = (0, import_logging.$gry)("}");
var _curls = (0, import_logging.$gry)("{}");
var _opnSqr = (0, import_logging.$gry)("[");
var _clsSqr = (0, import_logging.$gry)("]");
var _squares = (0, import_logging.$gry)("[]");
var _slash = (0, import_logging.$gry)("/");
var _tilde = (0, import_logging.$gry)("~");
var _error = `${_opnPar}${(0, import_logging.$gry)((0, import_logging.$und)("error"))}${_clsPar}`;
var _string = `${_opnPar}${(0, import_logging.$gry)((0, import_logging.$und)("string"))}${_clsPar}`;
var _matcher = (0, import_logging.$gry)("\u2026 matcher \u2026");
var _extraProps = (0, import_logging.$gry)("\u2026 extra props \u2026");
var _diffHeader = `${(0, import_logging.$wht)("Differences")} ${_opnPar}${(0, import_logging.$red)("actual")}${_slash}${(0, import_logging.$grn)("expected")}${_slash}${(0, import_logging.$ylw)("errors")}${_clsPar}:`;
function printBaseDiff(log, diff, prop, mapping, comma) {
if ("props" in diff) return printObjectDiff(log, diff, prop, mapping, comma);
if ("values" in diff) return printObjectDiff(log, diff, prop, mapping, comma);
if ("mappings" in diff) return printObjectDiff(log, diff, prop, mapping, comma);
if ("expected" in diff) return printExpectedDiff(log, diff, prop, mapping, comma);
if ("missing" in diff) return printMissingDiff(log, diff, prop, mapping, comma);
if ("extra" in diff) return printExtraDiff(log, diff, prop, mapping, comma);
const { prefix, suffix } = diff.error ? (
// default style if error is the only property
fixups(prop, mapping, comma, diff.error)
) : diff.diff ? (
// label as "differs" if no error was found
fixups(prop, mapping, comma, diff.error, import_logging.$red, "differs")
) : fixups(prop, mapping, comma, diff.error);
dump(log, diff.value, prefix, suffix, diff.diff ? import_logging.$red : import_logging.$wht);
}
function formatString(value, color) {
const characters = [];
for (let i = 0; i < value.length; i++) {
const c = value.charCodeAt(i);
if (c === 32) {
characters.push([import_logging.$gry, "\xB7"]);
} else if (c === 9) {
characters.push([import_logging.$gry, " \u2192 "]);
} else if (c < 16) {
characters.push([import_logging.$gry, `\\0${c.toString(16).toUpperCase()}`]);
} else if (c < 32) {
characters.push([import_logging.$gry, `\\${c.toString(16).toUpperCase()}`]);
} else if (c >= 127 && c <= 160) {
characters.push([import_logging.$gry, `\\${c.toString(16).toUpperCase()}`]);
} else {
characters.push([color, value[i]]);
}
}
const chunks = characters.reduce((acc, [color2, c]) => {
const prev = acc[acc.length - 1];
if (prev?.[0] === color2) prev[1] += c;
else acc.push([color2, c]);
return acc;
}, []);
return chunks.map(([color2, c]) => color2(c)).join("");
}
function printExpectedDiff(log, diff, prop, mapping, comma) {
if (typeof diff.value === "string" && typeof diff.expected === "string") {
const { prefix, suffix } = fixups(prop, mapping, false, diff.error);
log.warn(`${prefix}${_string}${suffix}`);
log.warn((0, import_utils.textDiff)(
diff.value,
diff.expected,
(add) => ` ${(0, import_logging.$gry)("+")} ${formatString(add, import_logging.$grn)}`,
(del) => ` ${(0, import_logging.$gry)("-")} ${formatString(del, import_logging.$red)}`,
(txt) => ` ${formatString(txt, (s) => s)}`
));
} else if (diff.value === null || typeof diff.value !== "object") {
const { prefix, suffix } = fixups(prop, mapping, comma, diff.error);
const joined = `${prefix}${(0, import_logging.$red)(stringify(diff.value))} ${_tilde} `;
dump(log, diff.expected, joined, suffix, import_logging.$grn);
} else if (diff.expected === null || typeof diff.expected !== "object") {
const { prefix, suffix } = fixups(prop, mapping, comma, diff.error);
const joined = ` ${_tilde} ${(0, import_logging.$grn)(stringify(diff.expected))}${suffix}`;
dump(log, diff.value, prefix, joined, import_logging.$red);
} else {
const { prefix, suffix: suffix1 } = fixups(prop, mapping, false, "");
const { suffix: suffix2 } = fixups(prop, mapping, comma, diff.error);
const lastLine = dumpAndContinue(log, diff.expected, prefix, suffix1, import_logging.$red);
dump(log, diff.value, `${lastLine} ${_tilde} `, suffix2, import_logging.$grn);
}
}
function printMissingDiff(log, diff, prop, mapping, comma) {
const { prefix, suffix } = fixups(prop, mapping, comma, diff.error, import_logging.$red, "missing");
dump(log, diff.missing, prefix, suffix, import_logging.$red);
}
function printExtraDiff(log, diff, prop, mapping, comma) {
const { prefix, suffix } = fixups(prop, mapping, comma, diff.error, import_logging.$red, "extra");
dump(log, diff.extra, prefix, suffix, import_logging.$red);
}
function printObjectDiff(log, diff, prop, mapping, comma) {
const { prefix, suffix } = fixups(prop, mapping, comma, diff.error);
const value = diff.value;
const ctor = Object.getPrototypeOf(value)?.constructor;
const string = ctor === Object || ctor === Array ? "" : (0, import_types.stringifyValue)(value);
let line = string ? `${prefix}${(0, import_logging.$wht)(string)} ` : prefix;
let marked = false;
if (diff.values) {
if (diff.values.length === 0) {
line = `${line}${_squares}`;
} else {
log.warn(`${line}${_opnSqr}`);
log.enter();
try {
for (const subdiff of diff.values) {
printBaseDiff(log, subdiff, "", false, true);
}
} finally {
log.leave();
}
line = _clsSqr;
}
marked = true;
} else if (diff.mappings) {
if (Object.keys(diff.mappings).length === 0) {
line = `${line}${_curls}`;
} else {
log.warn(`${line}${_opnCrl}`);
log.enter();
try {
for (const [key, subdiff] of diff.mappings) {
printBaseDiff(log, subdiff, (0, import_types.stringifyValue)(key), true, true);
}
} finally {
log.leave();
}
line = _clsCrl;
}
marked = true;
}
if (diff.props) {
if (marked) line = `${line} ${_extraProps} `;
if (Object.keys(diff.props).length === 0) {
line = `${line}${_curls}`;
} else {
log.warn(`${line}${_opnCrl}`);
log.enter();
try {
for (const [prop2, subdiff] of Object.entries(diff.props)) {
printBaseDiff(log, subdiff, (0, import_types.stringifyValue)(prop2), false, true);
}
} finally {
log.leave();
}
line = _clsCrl;
}
marked = true;
}
log.warn(`${line}${suffix}`);
}
function stringify(value) {
if (typeof value === "string") return JSON.stringify(value);
return (0, import_types.stringifyValue)(value);
}
function fixups(prop, mapping, comma, error, color, label) {
if (error) color = color || import_logging.$ylw;
const lbl = label ? `${_opnPar}${(0, import_logging.$gry)((0, import_logging.$und)(label))}${_clsPar} ` : "";
const sep = mapping ? " => " : ": ";
const prefix = prop ? color ? `${(0, import_logging.$gry)(lbl)}${color(prop)}${(0, import_logging.$gry)(sep)}` : `${(0, import_logging.$gry)(lbl)}${prop}${(0, import_logging.$gry)(sep)}` : label ? `${(0, import_logging.$gry)(lbl)}` : "";
error = error ? ` ${_error} ${(0, import_logging.$ylw)(error)}` : "";
const suffix = `${comma ? (0, import_logging.$gry)(",") : ""}${error}`;
return { prefix, suffix };
}
function dump(log, value, prefix, suffix, color, stack = []) {
log.warn(dumpAndContinue(log, value, prefix, suffix, color, stack));
}
function dumpAndContinue(log, value, prefix, suffix, color, stack = []) {
if (value === null || typeof value !== "object") {
return `${prefix}${color(stringify(value))}${suffix}`;
}
if ((0, import_types.isMatcher)(value)) {
return `${prefix}${_matcher}${suffix}`;
}
const circular = stack.indexOf(value);
if (circular >= 0) {
return `${prefix}${(0, import_logging.$gry)((0, import_logging.$und)(`<circular ${circular}>`))}${suffix}`;
}
const ctor = Object.getPrototypeOf(value)?.constructor;
const string = ctor === Object || ctor === Array ? "" : (0, import_types.stringifyValue)(value);
const keys = new Set(Object.keys(value));
let line = string ? `${prefix}${color(string)} ` : prefix;
let marked = false;
if (Array.isArray(value)) {
if (value.length === 0) {
line = `${line}${_squares}`;
} else {
log.warn(`${line}${_opnSqr}`);
log.enter();
try {
for (let i = 0; i < value.length; i++) {
const { prefix: prefix2, suffix: suffix2 } = fixups("", false, true, void 0, color);
dump(log, value[i], prefix2, suffix2, color, [...stack, value]);
keys.delete(String(i));
}
} finally {
log.leave();
}
line = _clsSqr;
}
marked = true;
} else if (value instanceof Set) {
if (value.size === 0) {
line = `${line}${_squares}`;
} else {
log.warn(`${line}${_opnSqr}`);
log.enter();
try {
const { prefix: prefix2, suffix: suffix2 } = fixups("", false, true, void 0, color);
value.forEach((v) => dump(log, v, prefix2, suffix2, color, [...stack, value]));
} finally {
log.leave();
}
line = _clsSqr;
}
marked = true;
} else if (value instanceof Map) {
if (value.size === 0) {
line = `${line}${_curls}`;
} else {
log.warn(`${line}${_opnCrl}`);
log.enter();
try {
for (const [key, subvalue] of value) {
const { prefix: prefix2, suffix: suffix2 } = fixups((0, import_types.stringifyValue)(key), true, true, void 0, color);
dump(log, subvalue, prefix2, suffix2, color, [...stack, value]);
}
} finally {
log.leave();
}
line = _clsCrl;
}
marked = true;
}
if (value instanceof String) {
const length = value.valueOf().length;
for (let i = 0; i < length; i++) keys.delete(String(i));
}
if (keys.size) {
if (marked) line = `${line} ${_extraProps} `;
log.warn(`${line}${_opnCrl}`);
log.enter();
try {
for (const key of keys) {
const { prefix: prefix2, suffix: suffix2 } = fixups((0, import_types.stringifyValue)(key), false, true, void 0, color);
dump(log, value[key], prefix2, suffix2, color, [...stack, value]);
}
} finally {
log.leave();
}
line = _clsCrl;
marked = true;
}
if (marked) {
return `${line}${suffix}`;
} else {
return `${line}${_curls}${suffix}`;
}
}
function printDiff(log, diff, header = true) {
if (!header) return printBaseDiff(log, diff, "", false, false);
log.warn(_diffHeader);
log.enter();
try {
printBaseDiff(log, diff, "", false, false);
} finally {
log.leave();
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
printDiff
});
//# sourceMappingURL=print.cjs.map