Last active
May 19, 2017 08:13
-
-
Save nojvek/f91dbd8b850d74f442841ff4ef743be7 to your computer and use it in GitHub Desktop.
printDiff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
printDiff(expected, encoded_actual, referencePath(relativeFileName), actualFileName); | |
/** | |
* Prints a nice diff that is useful for debugging baseline failures | |
* It doesn't print the most optimum diff but does it in O(n) time and gives a `good enough` diff for humans | |
* It also emits a `cp tests/baselines/local/<file> tests/baselines/reference/<file>` | |
* Which makes experience of updating basefiles case by case much more bearable | |
*/ | |
export function printDiff(expectedText: string, actualText: string, expectedFileName: string, actualFileName: string) { | |
type LineNumMap = { [line: string]: number[] }; | |
function getLineNumMap(lines: string[]): LineNumMap { | |
const lineNumMap: LineNumMap = Object.create(null); | |
for (let i = 0, len = lines.length; i < len; ++i) { | |
const line = lines[i]; | |
if (!lineNumMap[line]) { | |
lineNumMap[line] = [] | |
} | |
lineNumMap[line].push(i); | |
} | |
return lineNumMap; | |
} | |
function nextMatchingOffset(lineToMatch: string, curIndex: number, numLines: number, lineNumMap: LineNumMap): number { | |
if (lineNumMap[lineToMatch]) { | |
const lineNums = lineNumMap[lineToMatch]; | |
for (let lineNum of lineNums) { | |
if (lineNum > curIndex) { | |
return (lineNum - curIndex); | |
} | |
} | |
} | |
return numLines - curIndex - 1; | |
} | |
const removedMarker = ` <-|`; | |
const addedMarker = ` ->|`; | |
const sameMarker = ` |`; | |
const expectedLines = expectedText.split(/\r?\n/g); | |
const actualLines = actualText.split(/\r?\n/g); | |
const numExpectedLines = expectedLines.length; | |
const numActualLines = actualLines.length; | |
const expectedLineMap = getLineNumMap(expectedLines); | |
const actualLineMap = getLineNumMap(actualLines); | |
console.log(`\ncp ${actualFileName} ${expectedFileName}`); | |
console.log(`${sameMarker} ${new Array(actualFileName.length).join('=')}`) | |
for ( | |
let iActual = 0, iExpected = 0; | |
(iActual < numActualLines) && (iExpected < numExpectedLines); | |
) { | |
// Print lines that are the same | |
for (; actualLines[iActual] == expectedLines[iExpected]; iExpected++, iActual++) { | |
console.log(`${sameMarker} ${expectedLines[iExpected]}`); | |
} | |
// Get index of next matching line | |
const actualMatchingOffset = nextMatchingOffset(expectedLines[iExpected], iActual, numActualLines, actualLineMap); | |
const expectedMatchingOffset = nextMatchingOffset(actualLines[iActual], iExpected, numExpectedLines, expectedLineMap); | |
actualMatchingOffset + expectedMatchingOffset; | |
// if (expectedMatchingOffset <= actualMatchingOffset) { | |
// console.log(`${removedMarker} ${expectedLines[iExpected]}`); | |
// iExpected++; | |
// } | |
// else if (actualMatchingOffset < expectedMatchingOffset) { | |
// console.log(`${addedMarker} ${actualLines[iActual]}`); | |
// iActual++; | |
// } | |
// Print removed lines | |
for (; iExpected < numExpectedLines; iExpected++) { | |
console.log(`${removedMarker} ${expectedLines[iExpected]}`); | |
} | |
// print added lines | |
for (; iActual < numActualLines; iActual++) { | |
console.log(`${addedMarker} ${actualLines[iActual]}`); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment