(str, testDirectory)
| 28 | * @returns {string} normalized string |
| 29 | */ |
| 30 | const normalizeString = (str, testDirectory) => { |
| 31 | if (!str) return str; |
| 32 | const root = getWebpackRoot(testDirectory); |
| 33 | class="cm">// Replace more-specific test dir first, then the broader root |
| 34 | str = str.replace(new RegExp(quoteMeta(testDirectory), class="st">"g"), class="st">"<TEST_DIR>"); |
| 35 | if (root) { |
| 36 | str = str.replace(new RegExp(quoteMeta(root), class="st">"g"), class="st">"<WEBPACK_ROOT>"); |
| 37 | class="cm">// Replace ancestor directories above webpack root. |
| 38 | class="cm">// The resolver walks up to the filesystem root looking for |
| 39 | class="cm">// node_modules, producing paths like /Users/x/node_modules. |
| 40 | let ancestor = path.dirname(root); |
| 41 | while (ancestor !== path.dirname(ancestor)) { |
| 42 | str = str.replace(new RegExp(quoteMeta(ancestor), class="st">"g"), class="st">"<ANCESTOR>"); |
| 43 | ancestor = path.dirname(ancestor); |
| 44 | } |
| 45 | } |
| 46 | class="cm">// Normalize the output directory suite name (e.g. test/js/ConfigTestCases/ |
| 47 | class="cm">// vs test/js/ConfigCacheTestCases/) so all suites produce identical snapshots. |
| 48 | str = str.replace(/(<WEBPACK_ROOT>\/test\/js\/)[^/]+\class="cm">//g, class="st">"$1<OUTPUT>/"); |
| 49 | class="cm">// Strip stack trace lines — line numbers vary across Node.js versions |
| 50 | class="cm">// and between runs (e.g. processTicksAndRejections). |
| 51 | str = str |
| 52 | .split(class="st">"\n") |
| 53 | .filter((line) => !/^\s+at\s/.test(line)) |
| 54 | .join(class="st">"\n") |
| 55 | .replace(/\n{3,}/g, class="st">"\n\n") |
| 56 | .trim(); |
| 57 | class="cm">// Normalize engine-specific JSON.parse error text (V8 "Unexpected token … |
| 58 | class="cm">// (0x..)class="st">" / "… in JSON …class="st">" vs JSC/Bun "JSON Parse error: …") so JSON |
| 59 | class="cm">// type-import class="st">"Module parse failed" snapshots match across runtimes. The |
| 60 | class="cm">// acorn class="st">"(line:col)" parse errors are engine-independent and left as-is. |
| 61 | str = str.replace( |
| 62 | /Module parse failed: (?:JSON Parse error:|Unexpected token class="st">"[^"]*" \(0x|Unexpected \S+ in JSON|Unexpected end of JSON input|Unexpected non-whitespace character after JSON)[\s\S]*?(?=\nYou may need an appropriate loader)/g, |
| 63 | class="st">"Module parse failed: <JSON parse error>" |
| 64 | ); |
| 65 | class="cm">// Normalize JSC (Bun) magic-comment parse phrasing to the V8 form: JSC |
| 66 | class="cm">// quotes the token and appends class="st">"Expected …", V8 does neither. |
| 67 | str = str.replace(/(Unexpected token) class="st">'([^']*)'\. Expected[^\n]*/g, class="st">"$1 $2"); |
| 68 | str = str.replace(/(Unexpected identifier)\. Expected[^\n]*/g, class="st">"$1"); |
| 69 | class="cm">// Normalize class="st">"Unexpected token" messages — quoting and detail |
| 70 | class="cm">// format varies across Node.js versions (e.g. with/without quotes, |
| 71 | class="cm">// hex codes, trailing context). |
| 72 | str = str.replace(/(Unexpected token) class="st">'([^']*)'$/gm, class="st">"$1 $2"); |
| 73 | str = str.replace(/(Unexpected token[^)]*\))[^\n]*(?:\n['class="st">"])?/g, "$1"); |
| 74 | str = str.replace(/\\/g, class="st">"/"); |
| 75 | return str; |
| 76 | }; |
| 77 | |
| 78 | /** |
| 79 | * Serializes an array of error/warning objects into a normalized form |
no test coverage detected