joinAlignedDiffs.js
1 'use strict'; 2 3 Object.defineProperty(exports, '__esModule', { 4 value: true 5 }); 6 exports.joinAlignedDiffsExpand = exports.joinAlignedDiffsNoExpand = void 0; 7 8 var _cleanupSemantic = require('./cleanupSemantic'); 9 10 var _printDiffs = require('./printDiffs'); 11 12 /** 13 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. 14 * 15 * This source code is licensed under the MIT license found in the 16 * LICENSE file in the root directory of this source tree. 17 */ 18 // jest --no-expand 19 // 20 // Given array of aligned strings with inverse highlight formatting, 21 // return joined lines with diff formatting (and patch marks, if needed). 22 const joinAlignedDiffsNoExpand = (diffs, options) => { 23 const iLength = diffs.length; 24 const nContextLines = options.contextLines; 25 const nContextLines2 = nContextLines + nContextLines; // First pass: count output lines and see if it has patches. 26 27 let jLength = iLength; 28 let hasExcessAtStartOrEnd = false; 29 let nExcessesBetweenChanges = 0; 30 let i = 0; 31 32 while (i !== iLength) { 33 const iStart = i; 34 35 while (i !== iLength && diffs[i][0] === _cleanupSemantic.DIFF_EQUAL) { 36 i += 1; 37 } 38 39 if (iStart !== i) { 40 if (iStart === 0) { 41 // at start 42 if (i > nContextLines) { 43 jLength -= i - nContextLines; // subtract excess common lines 44 45 hasExcessAtStartOrEnd = true; 46 } 47 } else if (i === iLength) { 48 // at end 49 const n = i - iStart; 50 51 if (n > nContextLines) { 52 jLength -= n - nContextLines; // subtract excess common lines 53 54 hasExcessAtStartOrEnd = true; 55 } 56 } else { 57 // between changes 58 const n = i - iStart; 59 60 if (n > nContextLines2) { 61 jLength -= n - nContextLines2; // subtract excess common lines 62 63 nExcessesBetweenChanges += 1; 64 } 65 } 66 } 67 68 while (i !== iLength && diffs[i][0] !== _cleanupSemantic.DIFF_EQUAL) { 69 i += 1; 70 } 71 } 72 73 const hasPatch = nExcessesBetweenChanges !== 0 || hasExcessAtStartOrEnd; 74 75 if (nExcessesBetweenChanges !== 0) { 76 jLength += nExcessesBetweenChanges + 1; // add patch lines 77 } else if (hasExcessAtStartOrEnd) { 78 jLength += 1; // add patch line 79 } 80 81 const jLast = jLength - 1; 82 const lines = []; 83 let jPatchMark = 0; // index of placeholder line for current patch mark 84 85 if (hasPatch) { 86 lines.push(''); // placeholder line for first patch mark 87 } // Indexes of expected or received lines in current patch: 88 89 let aStart = 0; 90 let bStart = 0; 91 let aEnd = 0; 92 let bEnd = 0; 93 94 const pushCommonLine = line => { 95 const j = lines.length; 96 lines.push( 97 (0, _printDiffs.printCommonLine)(line, j === 0 || j === jLast, options) 98 ); 99 aEnd += 1; 100 bEnd += 1; 101 }; 102 103 const pushDeleteLine = line => { 104 const j = lines.length; 105 lines.push( 106 (0, _printDiffs.printDeleteLine)(line, j === 0 || j === jLast, options) 107 ); 108 aEnd += 1; 109 }; 110 111 const pushInsertLine = line => { 112 const j = lines.length; 113 lines.push( 114 (0, _printDiffs.printInsertLine)(line, j === 0 || j === jLast, options) 115 ); 116 bEnd += 1; 117 }; // Second pass: push lines with diff formatting (and patch marks, if needed). 118 119 i = 0; 120 121 while (i !== iLength) { 122 let iStart = i; 123 124 while (i !== iLength && diffs[i][0] === _cleanupSemantic.DIFF_EQUAL) { 125 i += 1; 126 } 127 128 if (iStart !== i) { 129 if (iStart === 0) { 130 // at beginning 131 if (i > nContextLines) { 132 iStart = i - nContextLines; 133 aStart = iStart; 134 bStart = iStart; 135 aEnd = aStart; 136 bEnd = bStart; 137 } 138 139 for (let iCommon = iStart; iCommon !== i; iCommon += 1) { 140 pushCommonLine(diffs[iCommon][1]); 141 } 142 } else if (i === iLength) { 143 // at end 144 const iEnd = i - iStart > nContextLines ? iStart + nContextLines : i; 145 146 for (let iCommon = iStart; iCommon !== iEnd; iCommon += 1) { 147 pushCommonLine(diffs[iCommon][1]); 148 } 149 } else { 150 // between changes 151 const nCommon = i - iStart; 152 153 if (nCommon > nContextLines2) { 154 const iEnd = iStart + nContextLines; 155 156 for (let iCommon = iStart; iCommon !== iEnd; iCommon += 1) { 157 pushCommonLine(diffs[iCommon][1]); 158 } 159 160 lines[jPatchMark] = (0, _printDiffs.createPatchMark)( 161 aStart, 162 aEnd, 163 bStart, 164 bEnd, 165 options 166 ); 167 jPatchMark = lines.length; 168 lines.push(''); // placeholder line for next patch mark 169 170 const nOmit = nCommon - nContextLines2; 171 aStart = aEnd + nOmit; 172 bStart = bEnd + nOmit; 173 aEnd = aStart; 174 bEnd = bStart; 175 176 for (let iCommon = i - nContextLines; iCommon !== i; iCommon += 1) { 177 pushCommonLine(diffs[iCommon][1]); 178 } 179 } else { 180 for (let iCommon = iStart; iCommon !== i; iCommon += 1) { 181 pushCommonLine(diffs[iCommon][1]); 182 } 183 } 184 } 185 } 186 187 while (i !== iLength && diffs[i][0] === _cleanupSemantic.DIFF_DELETE) { 188 pushDeleteLine(diffs[i][1]); 189 i += 1; 190 } 191 192 while (i !== iLength && diffs[i][0] === _cleanupSemantic.DIFF_INSERT) { 193 pushInsertLine(diffs[i][1]); 194 i += 1; 195 } 196 } 197 198 if (hasPatch) { 199 lines[jPatchMark] = (0, _printDiffs.createPatchMark)( 200 aStart, 201 aEnd, 202 bStart, 203 bEnd, 204 options 205 ); 206 } 207 208 return lines.join('\n'); 209 }; // jest --expand 210 // 211 // Given array of aligned strings with inverse highlight formatting, 212 // return joined lines with diff formatting. 213 214 exports.joinAlignedDiffsNoExpand = joinAlignedDiffsNoExpand; 215 216 const joinAlignedDiffsExpand = (diffs, options) => 217 diffs 218 .map((diff, i, diffs) => { 219 const line = diff[1]; 220 const isFirstOrLast = i === 0 || i === diffs.length - 1; 221 222 switch (diff[0]) { 223 case _cleanupSemantic.DIFF_DELETE: 224 return (0, _printDiffs.printDeleteLine)(line, isFirstOrLast, options); 225 226 case _cleanupSemantic.DIFF_INSERT: 227 return (0, _printDiffs.printInsertLine)(line, isFirstOrLast, options); 228 229 default: 230 return (0, _printDiffs.printCommonLine)(line, isFirstOrLast, options); 231 } 232 }) 233 .join('\n'); 234 235 exports.joinAlignedDiffsExpand = joinAlignedDiffsExpand;