Adds underlines to differences in strings (#36409)
This commit is contained in:
parent
f883bf3acb
commit
2c4155c351
|
@ -4205,10 +4205,57 @@ namespace FourSlash {
|
|||
const actualMsg = "\x1b[1mActual\x1b[0m\x1b[31m";
|
||||
const expectedString = quoted ? "\"" + expected + "\"" : expected;
|
||||
const actualString = quoted ? "\"" + actual + "\"" : actual;
|
||||
return `\n${expectMsg}:\n${expectedString}\n\n${actualMsg}:\n${actualString}`;
|
||||
return `\n${expectMsg}:\n${expectedString}\n\n${actualMsg}:\n${highlightDifferenceBetweenStrings(expected, actualString)}`;
|
||||
}
|
||||
|
||||
function templateToRegExp(template: string) {
|
||||
return new RegExp(`^${ts.regExpEscape(template).replace(/\\\{\d+\\\}/g, ".*?")}$`);
|
||||
}
|
||||
|
||||
function rangesOfDiffBetweenTwoStrings(source: string, target: string) {
|
||||
const ranges = [] as { start: number; length: number }[];
|
||||
|
||||
const addToIndex = (index: number) => {
|
||||
const closestIndex = ranges[ranges.length - 1];
|
||||
if (closestIndex) {
|
||||
const doesAddToIndex = closestIndex.start + closestIndex.length === index - 1;
|
||||
if (doesAddToIndex) {
|
||||
closestIndex.length = closestIndex.length + 1;
|
||||
}
|
||||
else {
|
||||
ranges.push({ start: index - 1, length: 1 });
|
||||
}
|
||||
}
|
||||
else {
|
||||
ranges.push({ start: index - 1, length: 1 });
|
||||
}
|
||||
};
|
||||
|
||||
for (let index = 0; index < Math.max(source.length, target.length); index++) {
|
||||
const srcChar = source[index];
|
||||
const targetChar = target[index];
|
||||
if (srcChar !== targetChar) addToIndex(index);
|
||||
}
|
||||
|
||||
return ranges;
|
||||
}
|
||||
|
||||
// Adds an _ when the source string and the target string have a whitespace difference
|
||||
function highlightDifferenceBetweenStrings(source: string, target: string) {
|
||||
const ranges = rangesOfDiffBetweenTwoStrings(source, target);
|
||||
let emTarget = target;
|
||||
ranges.forEach((range, index) => {
|
||||
const lhs = `\x1b[4m`;
|
||||
const rhs = `\x1b[0m\x1b[31m`;
|
||||
const additionalOffset = index * lhs.length + index * rhs.length;
|
||||
const before = emTarget.slice(0, range.start + 1 + additionalOffset);
|
||||
const between = emTarget.slice(
|
||||
range.start + 1 + additionalOffset,
|
||||
range.start + range.length + 1 + additionalOffset
|
||||
);
|
||||
const after = emTarget.slice(range.start + range.length + 1 + additionalOffset, emTarget.length);
|
||||
emTarget = before + lhs + between + rhs + after;
|
||||
});
|
||||
return emTarget;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue