alsatian
Version:
TypeScript and JavaScript testing framework for beautiful and readable tests
101 lines • 3.58 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const diff_1 = require("diff");
const deep_diff_1 = require("deep-diff");
const chalk_1 = require("chalk");
function diff(firstItem, secondItem) {
if (typeof firstItem === "string") {
return diffString(firstItem, secondItem);
}
const diffs = deep_diff_1.diff(firstItem, secondItem) || [];
return buildDiff(diffs);
}
exports.diff = diff;
function diffString(firstString, secondString) {
if (firstString === secondString) {
return "no differences";
}
else if (!firstString) {
return chalk_1.default.green(secondString);
}
else if (!secondString) {
return chalk_1.default.red(firstString);
}
const diffs = /\s/.test(firstString) || /\s/.test(secondString)
? diff_1.diffWords(firstString, secondString)
: diff_1.diffChars(firstString, secondString);
return diffs.map(styleDiffItem).join("");
}
function styleDiffItem(diffItem) {
if (diffItem.added) {
return chalk_1.default.green(diffItem.value);
}
if (diffItem.removed) {
return chalk_1.default.red(diffItem.value);
}
return diffItem.value;
}
function buildDiff(diffs) {
if (diffs.every(d => d.path === undefined)) {
return buildNonObjectDiff(diffs);
}
return buildObjectDiff(diffs);
}
function buildNonObjectDiff(diffs) {
if (diffs.length === 0) {
return "no differences";
}
else if (diffs.length === 1) {
const onlyDiff = diffs[0];
return diffString(JSON.stringify(onlyDiff.lhs), JSON.stringify(onlyDiff.rhs));
}
else {
return `[\n${diffs
.map(diffItem => buildDiff([diffItem]))
.join("\n")}\n]`;
}
}
function buildObjectDiff(diffs, depth = 1) {
const padding = new Array(depth + 1).join(" ");
const deeperDiffs = groupDiffsByProperty(diffs, depth);
const properties = diffs
.filter(diffItem => diffItem.path.length === depth)
.map(diffItem => stringifyDiffProp(diffItem, padding))
.concat(Object.keys(deeperDiffs).map(key => {
const diffItems = deeperDiffs[key];
return ` ${padding}${diffItems[0].path[depth - 1]}: ${buildObjectDiff(diffItems, depth + 1)}`;
}))
.join(",\n");
return `{\n` + properties + `\n${depth === 1 ? "" : padding}}`;
}
function groupDiffsByProperty(diffs, depth) {
return diffs
.filter(diffItem => diffItem.path && diffItem.path.length > depth)
.reduce((concat, diffItem) => {
const prop = diffItem.path[depth];
const value = concat[prop];
concat[prop] = value ? [...value, diffItem] : [diffItem];
return concat;
}, {});
}
function buildDiffProp(diffInfo, value, padding) {
return `${padding}${diffInfo.path[diffInfo.path.length - 1] || ""}: ${typeof value === "string" ? `"${value}"` : JSON.stringify(value)}`;
}
function safeToString(val) {
if (val && val.toString) {
return val.toString();
}
return String(val).toString();
}
function stringifyDiffProp(diffInfo, padding) {
if (diffInfo.kind === "N") {
return chalk_1.default.green(`+ ${buildDiffProp(diffInfo, diffInfo.rhs, padding)}`);
}
else if (diffInfo.kind === "D") {
return chalk_1.default.red(`- ${buildDiffProp(diffInfo, diffInfo.lhs, padding)}`);
}
else if (diffInfo.kind === "E") {
return ` ${buildDiffProp(diffInfo, diffString(safeToString(diffInfo.lhs), safeToString(diffInfo.rhs)), padding)}`;
}
}
//# sourceMappingURL=diff.js.map
;